UNPKG

961 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define('leancloud-realtime', ['exports'], factory) :
4 (global = global || self, factory(global.AV = global.AV || {}));
5}(this, function (exports) { 'use strict';
6
7 var define = undefined;
8 var require = require || function(id) {throw new Error('Unexpected required ' + id)};
9
10
11
12 var process = (typeof window !== 'undefined' && window.process) || {};
13 process.env = process.env || {};
14
15 function _typeof(obj) {
16 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
17 _typeof = function (obj) {
18 return typeof obj;
19 };
20 } else {
21 _typeof = function (obj) {
22 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
23 };
24 }
25
26 return _typeof(obj);
27 }
28
29 function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
30 try {
31 var info = gen[key](arg);
32 var value = info.value;
33 } catch (error) {
34 reject(error);
35 return;
36 }
37
38 if (info.done) {
39 resolve(value);
40 } else {
41 Promise.resolve(value).then(_next, _throw);
42 }
43 }
44
45 function _asyncToGenerator(fn) {
46 return function () {
47 var self = this,
48 args = arguments;
49 return new Promise(function (resolve, reject) {
50 var gen = fn.apply(self, args);
51
52 function _next(value) {
53 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
54 }
55
56 function _throw(err) {
57 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
58 }
59
60 _next(undefined);
61 });
62 };
63 }
64
65 function _defineProperties(target, props) {
66 for (var i = 0; i < props.length; i++) {
67 var descriptor = props[i];
68 descriptor.enumerable = descriptor.enumerable || false;
69 descriptor.configurable = true;
70 if ("value" in descriptor) descriptor.writable = true;
71 Object.defineProperty(target, descriptor.key, descriptor);
72 }
73 }
74
75 function _createClass(Constructor, protoProps, staticProps) {
76 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
77 if (staticProps) _defineProperties(Constructor, staticProps);
78 return Constructor;
79 }
80
81 function _defineProperty(obj, key, value) {
82 if (key in obj) {
83 Object.defineProperty(obj, key, {
84 value: value,
85 enumerable: true,
86 configurable: true,
87 writable: true
88 });
89 } else {
90 obj[key] = value;
91 }
92
93 return obj;
94 }
95
96 function _objectSpread(target) {
97 for (var i = 1; i < arguments.length; i++) {
98 var source = arguments[i] != null ? arguments[i] : {};
99 var ownKeys = Object.keys(source);
100
101 if (typeof Object.getOwnPropertySymbols === 'function') {
102 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
103 return Object.getOwnPropertyDescriptor(source, sym).enumerable;
104 }));
105 }
106
107 ownKeys.forEach(function (key) {
108 _defineProperty(target, key, source[key]);
109 });
110 }
111
112 return target;
113 }
114
115 function _inheritsLoose(subClass, superClass) {
116 subClass.prototype = Object.create(superClass.prototype);
117 subClass.prototype.constructor = subClass;
118 subClass.__proto__ = superClass;
119 }
120
121 function _objectWithoutPropertiesLoose(source, excluded) {
122 if (source == null) return {};
123 var target = {};
124 var sourceKeys = Object.keys(source);
125 var key, i;
126
127 for (i = 0; i < sourceKeys.length; i++) {
128 key = sourceKeys[i];
129 if (excluded.indexOf(key) >= 0) continue;
130 target[key] = source[key];
131 }
132
133 return target;
134 }
135
136 function _objectWithoutProperties(source, excluded) {
137 if (source == null) return {};
138
139 var target = _objectWithoutPropertiesLoose(source, excluded);
140
141 var key, i;
142
143 if (Object.getOwnPropertySymbols) {
144 var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
145
146 for (i = 0; i < sourceSymbolKeys.length; i++) {
147 key = sourceSymbolKeys[i];
148 if (excluded.indexOf(key) >= 0) continue;
149 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
150 target[key] = source[key];
151 }
152 }
153
154 return target;
155 }
156
157 function _assertThisInitialized(self) {
158 if (self === void 0) {
159 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
160 }
161
162 return self;
163 }
164
165 function _slicedToArray(arr, i) {
166 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
167 }
168
169 function _toArray(arr) {
170 return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();
171 }
172
173 function _toConsumableArray(arr) {
174 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
175 }
176
177 function _arrayWithoutHoles(arr) {
178 if (Array.isArray(arr)) {
179 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
180
181 return arr2;
182 }
183 }
184
185 function _arrayWithHoles(arr) {
186 if (Array.isArray(arr)) return arr;
187 }
188
189 function _iterableToArray(iter) {
190 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
191 }
192
193 function _iterableToArrayLimit(arr, i) {
194 var _arr = [];
195 var _n = true;
196 var _d = false;
197 var _e = undefined;
198
199 try {
200 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
201 _arr.push(_s.value);
202
203 if (i && _arr.length === i) break;
204 }
205 } catch (err) {
206 _d = true;
207 _e = err;
208 } finally {
209 try {
210 if (!_n && _i["return"] != null) _i["return"]();
211 } finally {
212 if (_d) throw _e;
213 }
214 }
215
216 return _arr;
217 }
218
219 function _nonIterableSpread() {
220 throw new TypeError("Invalid attempt to spread non-iterable instance");
221 }
222
223 function _nonIterableRest() {
224 throw new TypeError("Invalid attempt to destructure non-iterable instance");
225 }
226
227 function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
228 var desc = {};
229 Object['ke' + 'ys'](descriptor).forEach(function (key) {
230 desc[key] = descriptor[key];
231 });
232 desc.enumerable = !!desc.enumerable;
233 desc.configurable = !!desc.configurable;
234
235 if ('value' in desc || desc.initializer) {
236 desc.writable = true;
237 }
238
239 desc = decorators.slice().reverse().reduce(function (desc, decorator) {
240 return decorator(target, property, desc) || desc;
241 }, desc);
242
243 if (context && desc.initializer !== void 0) {
244 desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
245 desc.initializer = undefined;
246 }
247
248 if (desc.initializer === void 0) {
249 Object['define' + 'Property'](target, property, desc);
250 desc = null;
251 }
252
253 return desc;
254 }
255
256 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
257
258 function commonjsRequire () {
259 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
260 }
261
262 function createCommonjsModule(fn, module) {
263 return module = { exports: {} }, fn(module, module.exports), module.exports;
264 }
265
266 var long_1 = createCommonjsModule(function (module) {
267 /*
268 Copyright 2013 Daniel Wirtz <dcode@dcode.io>
269 Copyright 2009 The Closure Library Authors. All Rights Reserved.
270
271 Licensed under the Apache License, Version 2.0 (the "License");
272 you may not use this file except in compliance with the License.
273 You may obtain a copy of the License at
274
275 http://www.apache.org/licenses/LICENSE-2.0
276
277 Unless required by applicable law or agreed to in writing, software
278 distributed under the License is distributed on an "AS-IS" BASIS,
279 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
280 See the License for the specific language governing permissions and
281 limitations under the License.
282 */
283
284 /**
285 * @license long.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
286 * Released under the Apache License, Version 2.0
287 * see: https://github.com/dcodeIO/long.js for details
288 */
289 (function(global, factory) {
290
291 /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
292 module["exports"] = factory();
293 /* Global */ else
294 (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
295
296 })(commonjsGlobal, function() {
297
298 /**
299 * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
300 * See the from* functions below for more convenient ways of constructing Longs.
301 * @exports Long
302 * @class A Long class for representing a 64 bit two's-complement integer value.
303 * @param {number} low The low (signed) 32 bits of the long
304 * @param {number} high The high (signed) 32 bits of the long
305 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
306 * @constructor
307 */
308 function Long(low, high, unsigned) {
309
310 /**
311 * The low 32 bits as a signed value.
312 * @type {number}
313 */
314 this.low = low | 0;
315
316 /**
317 * The high 32 bits as a signed value.
318 * @type {number}
319 */
320 this.high = high | 0;
321
322 /**
323 * Whether unsigned or not.
324 * @type {boolean}
325 */
326 this.unsigned = !!unsigned;
327 }
328
329 // The internal representation of a long is the two given signed, 32-bit values.
330 // We use 32-bit pieces because these are the size of integers on which
331 // Javascript performs bit-operations. For operations like addition and
332 // multiplication, we split each number into 16 bit pieces, which can easily be
333 // multiplied within Javascript's floating-point representation without overflow
334 // or change in sign.
335 //
336 // In the algorithms below, we frequently reduce the negative case to the
337 // positive case by negating the input(s) and then post-processing the result.
338 // Note that we must ALWAYS check specially whether those values are MIN_VALUE
339 // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
340 // a positive number, it overflows back into a negative). Not handling this
341 // case would often result in infinite recursion.
342 //
343 // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
344 // methods on which they depend.
345
346 /**
347 * An indicator used to reliably determine if an object is a Long or not.
348 * @type {boolean}
349 * @const
350 * @private
351 */
352 Long.prototype.__isLong__;
353
354 Object.defineProperty(Long.prototype, "__isLong__", {
355 value: true,
356 enumerable: false,
357 configurable: false
358 });
359
360 /**
361 * @function
362 * @param {*} obj Object
363 * @returns {boolean}
364 * @inner
365 */
366 function isLong(obj) {
367 return (obj && obj["__isLong__"]) === true;
368 }
369
370 /**
371 * Tests if the specified object is a Long.
372 * @function
373 * @param {*} obj Object
374 * @returns {boolean}
375 */
376 Long.isLong = isLong;
377
378 /**
379 * A cache of the Long representations of small integer values.
380 * @type {!Object}
381 * @inner
382 */
383 var INT_CACHE = {};
384
385 /**
386 * A cache of the Long representations of small unsigned integer values.
387 * @type {!Object}
388 * @inner
389 */
390 var UINT_CACHE = {};
391
392 /**
393 * @param {number} value
394 * @param {boolean=} unsigned
395 * @returns {!Long}
396 * @inner
397 */
398 function fromInt(value, unsigned) {
399 var obj, cachedObj, cache;
400 if (unsigned) {
401 value >>>= 0;
402 if (cache = (0 <= value && value < 256)) {
403 cachedObj = UINT_CACHE[value];
404 if (cachedObj)
405 return cachedObj;
406 }
407 obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
408 if (cache)
409 UINT_CACHE[value] = obj;
410 return obj;
411 } else {
412 value |= 0;
413 if (cache = (-128 <= value && value < 128)) {
414 cachedObj = INT_CACHE[value];
415 if (cachedObj)
416 return cachedObj;
417 }
418 obj = fromBits(value, value < 0 ? -1 : 0, false);
419 if (cache)
420 INT_CACHE[value] = obj;
421 return obj;
422 }
423 }
424
425 /**
426 * Returns a Long representing the given 32 bit integer value.
427 * @function
428 * @param {number} value The 32 bit integer in question
429 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
430 * @returns {!Long} The corresponding Long value
431 */
432 Long.fromInt = fromInt;
433
434 /**
435 * @param {number} value
436 * @param {boolean=} unsigned
437 * @returns {!Long}
438 * @inner
439 */
440 function fromNumber(value, unsigned) {
441 if (isNaN(value) || !isFinite(value))
442 return unsigned ? UZERO : ZERO;
443 if (unsigned) {
444 if (value < 0)
445 return UZERO;
446 if (value >= TWO_PWR_64_DBL)
447 return MAX_UNSIGNED_VALUE;
448 } else {
449 if (value <= -TWO_PWR_63_DBL)
450 return MIN_VALUE;
451 if (value + 1 >= TWO_PWR_63_DBL)
452 return MAX_VALUE;
453 }
454 if (value < 0)
455 return fromNumber(-value, unsigned).neg();
456 return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
457 }
458
459 /**
460 * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
461 * @function
462 * @param {number} value The number in question
463 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
464 * @returns {!Long} The corresponding Long value
465 */
466 Long.fromNumber = fromNumber;
467
468 /**
469 * @param {number} lowBits
470 * @param {number} highBits
471 * @param {boolean=} unsigned
472 * @returns {!Long}
473 * @inner
474 */
475 function fromBits(lowBits, highBits, unsigned) {
476 return new Long(lowBits, highBits, unsigned);
477 }
478
479 /**
480 * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
481 * assumed to use 32 bits.
482 * @function
483 * @param {number} lowBits The low 32 bits
484 * @param {number} highBits The high 32 bits
485 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
486 * @returns {!Long} The corresponding Long value
487 */
488 Long.fromBits = fromBits;
489
490 /**
491 * @function
492 * @param {number} base
493 * @param {number} exponent
494 * @returns {number}
495 * @inner
496 */
497 var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
498
499 /**
500 * @param {string} str
501 * @param {(boolean|number)=} unsigned
502 * @param {number=} radix
503 * @returns {!Long}
504 * @inner
505 */
506 function fromString(str, unsigned, radix) {
507 if (str.length === 0)
508 throw Error('empty string');
509 if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
510 return ZERO;
511 if (typeof unsigned === 'number') {
512 // For goog.math.long compatibility
513 radix = unsigned,
514 unsigned = false;
515 } else {
516 unsigned = !! unsigned;
517 }
518 radix = radix || 10;
519 if (radix < 2 || 36 < radix)
520 throw RangeError('radix');
521
522 var p;
523 if ((p = str.indexOf('-')) > 0)
524 throw Error('interior hyphen');
525 else if (p === 0) {
526 return fromString(str.substring(1), unsigned, radix).neg();
527 }
528
529 // Do several (8) digits each time through the loop, so as to
530 // minimize the calls to the very expensive emulated div.
531 var radixToPower = fromNumber(pow_dbl(radix, 8));
532
533 var result = ZERO;
534 for (var i = 0; i < str.length; i += 8) {
535 var size = Math.min(8, str.length - i),
536 value = parseInt(str.substring(i, i + size), radix);
537 if (size < 8) {
538 var power = fromNumber(pow_dbl(radix, size));
539 result = result.mul(power).add(fromNumber(value));
540 } else {
541 result = result.mul(radixToPower);
542 result = result.add(fromNumber(value));
543 }
544 }
545 result.unsigned = unsigned;
546 return result;
547 }
548
549 /**
550 * Returns a Long representation of the given string, written using the specified radix.
551 * @function
552 * @param {string} str The textual representation of the Long
553 * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
554 * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
555 * @returns {!Long} The corresponding Long value
556 */
557 Long.fromString = fromString;
558
559 /**
560 * @function
561 * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
562 * @returns {!Long}
563 * @inner
564 */
565 function fromValue(val) {
566 if (val /* is compatible */ instanceof Long)
567 return val;
568 if (typeof val === 'number')
569 return fromNumber(val);
570 if (typeof val === 'string')
571 return fromString(val);
572 // Throws for non-objects, converts non-instanceof Long:
573 return fromBits(val.low, val.high, val.unsigned);
574 }
575
576 /**
577 * Converts the specified value to a Long.
578 * @function
579 * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
580 * @returns {!Long}
581 */
582 Long.fromValue = fromValue;
583
584 // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
585 // no runtime penalty for these.
586
587 /**
588 * @type {number}
589 * @const
590 * @inner
591 */
592 var TWO_PWR_16_DBL = 1 << 16;
593
594 /**
595 * @type {number}
596 * @const
597 * @inner
598 */
599 var TWO_PWR_24_DBL = 1 << 24;
600
601 /**
602 * @type {number}
603 * @const
604 * @inner
605 */
606 var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
607
608 /**
609 * @type {number}
610 * @const
611 * @inner
612 */
613 var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
614
615 /**
616 * @type {number}
617 * @const
618 * @inner
619 */
620 var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
621
622 /**
623 * @type {!Long}
624 * @const
625 * @inner
626 */
627 var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
628
629 /**
630 * @type {!Long}
631 * @inner
632 */
633 var ZERO = fromInt(0);
634
635 /**
636 * Signed zero.
637 * @type {!Long}
638 */
639 Long.ZERO = ZERO;
640
641 /**
642 * @type {!Long}
643 * @inner
644 */
645 var UZERO = fromInt(0, true);
646
647 /**
648 * Unsigned zero.
649 * @type {!Long}
650 */
651 Long.UZERO = UZERO;
652
653 /**
654 * @type {!Long}
655 * @inner
656 */
657 var ONE = fromInt(1);
658
659 /**
660 * Signed one.
661 * @type {!Long}
662 */
663 Long.ONE = ONE;
664
665 /**
666 * @type {!Long}
667 * @inner
668 */
669 var UONE = fromInt(1, true);
670
671 /**
672 * Unsigned one.
673 * @type {!Long}
674 */
675 Long.UONE = UONE;
676
677 /**
678 * @type {!Long}
679 * @inner
680 */
681 var NEG_ONE = fromInt(-1);
682
683 /**
684 * Signed negative one.
685 * @type {!Long}
686 */
687 Long.NEG_ONE = NEG_ONE;
688
689 /**
690 * @type {!Long}
691 * @inner
692 */
693 var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
694
695 /**
696 * Maximum signed value.
697 * @type {!Long}
698 */
699 Long.MAX_VALUE = MAX_VALUE;
700
701 /**
702 * @type {!Long}
703 * @inner
704 */
705 var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
706
707 /**
708 * Maximum unsigned value.
709 * @type {!Long}
710 */
711 Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
712
713 /**
714 * @type {!Long}
715 * @inner
716 */
717 var MIN_VALUE = fromBits(0, 0x80000000|0, false);
718
719 /**
720 * Minimum signed value.
721 * @type {!Long}
722 */
723 Long.MIN_VALUE = MIN_VALUE;
724
725 /**
726 * @alias Long.prototype
727 * @inner
728 */
729 var LongPrototype = Long.prototype;
730
731 /**
732 * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
733 * @returns {number}
734 */
735 LongPrototype.toInt = function toInt() {
736 return this.unsigned ? this.low >>> 0 : this.low;
737 };
738
739 /**
740 * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
741 * @returns {number}
742 */
743 LongPrototype.toNumber = function toNumber() {
744 if (this.unsigned)
745 return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
746 return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
747 };
748
749 /**
750 * Converts the Long to a string written in the specified radix.
751 * @param {number=} radix Radix (2-36), defaults to 10
752 * @returns {string}
753 * @override
754 * @throws {RangeError} If `radix` is out of range
755 */
756 LongPrototype.toString = function toString(radix) {
757 radix = radix || 10;
758 if (radix < 2 || 36 < radix)
759 throw RangeError('radix');
760 if (this.isZero())
761 return '0';
762 if (this.isNegative()) { // Unsigned Longs are never negative
763 if (this.eq(MIN_VALUE)) {
764 // We need to change the Long value before it can be negated, so we remove
765 // the bottom-most digit in this base and then recurse to do the rest.
766 var radixLong = fromNumber(radix),
767 div = this.div(radixLong),
768 rem1 = div.mul(radixLong).sub(this);
769 return div.toString(radix) + rem1.toInt().toString(radix);
770 } else
771 return '-' + this.neg().toString(radix);
772 }
773
774 // Do several (6) digits each time through the loop, so as to
775 // minimize the calls to the very expensive emulated div.
776 var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
777 rem = this;
778 var result = '';
779 while (true) {
780 var remDiv = rem.div(radixToPower),
781 intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
782 digits = intval.toString(radix);
783 rem = remDiv;
784 if (rem.isZero())
785 return digits + result;
786 else {
787 while (digits.length < 6)
788 digits = '0' + digits;
789 result = '' + digits + result;
790 }
791 }
792 };
793
794 /**
795 * Gets the high 32 bits as a signed integer.
796 * @returns {number} Signed high bits
797 */
798 LongPrototype.getHighBits = function getHighBits() {
799 return this.high;
800 };
801
802 /**
803 * Gets the high 32 bits as an unsigned integer.
804 * @returns {number} Unsigned high bits
805 */
806 LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
807 return this.high >>> 0;
808 };
809
810 /**
811 * Gets the low 32 bits as a signed integer.
812 * @returns {number} Signed low bits
813 */
814 LongPrototype.getLowBits = function getLowBits() {
815 return this.low;
816 };
817
818 /**
819 * Gets the low 32 bits as an unsigned integer.
820 * @returns {number} Unsigned low bits
821 */
822 LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
823 return this.low >>> 0;
824 };
825
826 /**
827 * Gets the number of bits needed to represent the absolute value of this Long.
828 * @returns {number}
829 */
830 LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
831 if (this.isNegative()) // Unsigned Longs are never negative
832 return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
833 var val = this.high != 0 ? this.high : this.low;
834 for (var bit = 31; bit > 0; bit--)
835 if ((val & (1 << bit)) != 0)
836 break;
837 return this.high != 0 ? bit + 33 : bit + 1;
838 };
839
840 /**
841 * Tests if this Long's value equals zero.
842 * @returns {boolean}
843 */
844 LongPrototype.isZero = function isZero() {
845 return this.high === 0 && this.low === 0;
846 };
847
848 /**
849 * Tests if this Long's value is negative.
850 * @returns {boolean}
851 */
852 LongPrototype.isNegative = function isNegative() {
853 return !this.unsigned && this.high < 0;
854 };
855
856 /**
857 * Tests if this Long's value is positive.
858 * @returns {boolean}
859 */
860 LongPrototype.isPositive = function isPositive() {
861 return this.unsigned || this.high >= 0;
862 };
863
864 /**
865 * Tests if this Long's value is odd.
866 * @returns {boolean}
867 */
868 LongPrototype.isOdd = function isOdd() {
869 return (this.low & 1) === 1;
870 };
871
872 /**
873 * Tests if this Long's value is even.
874 * @returns {boolean}
875 */
876 LongPrototype.isEven = function isEven() {
877 return (this.low & 1) === 0;
878 };
879
880 /**
881 * Tests if this Long's value equals the specified's.
882 * @param {!Long|number|string} other Other value
883 * @returns {boolean}
884 */
885 LongPrototype.equals = function equals(other) {
886 if (!isLong(other))
887 other = fromValue(other);
888 if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
889 return false;
890 return this.high === other.high && this.low === other.low;
891 };
892
893 /**
894 * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
895 * @function
896 * @param {!Long|number|string} other Other value
897 * @returns {boolean}
898 */
899 LongPrototype.eq = LongPrototype.equals;
900
901 /**
902 * Tests if this Long's value differs from the specified's.
903 * @param {!Long|number|string} other Other value
904 * @returns {boolean}
905 */
906 LongPrototype.notEquals = function notEquals(other) {
907 return !this.eq(/* validates */ other);
908 };
909
910 /**
911 * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
912 * @function
913 * @param {!Long|number|string} other Other value
914 * @returns {boolean}
915 */
916 LongPrototype.neq = LongPrototype.notEquals;
917
918 /**
919 * Tests if this Long's value is less than the specified's.
920 * @param {!Long|number|string} other Other value
921 * @returns {boolean}
922 */
923 LongPrototype.lessThan = function lessThan(other) {
924 return this.comp(/* validates */ other) < 0;
925 };
926
927 /**
928 * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
929 * @function
930 * @param {!Long|number|string} other Other value
931 * @returns {boolean}
932 */
933 LongPrototype.lt = LongPrototype.lessThan;
934
935 /**
936 * Tests if this Long's value is less than or equal the specified's.
937 * @param {!Long|number|string} other Other value
938 * @returns {boolean}
939 */
940 LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
941 return this.comp(/* validates */ other) <= 0;
942 };
943
944 /**
945 * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
946 * @function
947 * @param {!Long|number|string} other Other value
948 * @returns {boolean}
949 */
950 LongPrototype.lte = LongPrototype.lessThanOrEqual;
951
952 /**
953 * Tests if this Long's value is greater than the specified's.
954 * @param {!Long|number|string} other Other value
955 * @returns {boolean}
956 */
957 LongPrototype.greaterThan = function greaterThan(other) {
958 return this.comp(/* validates */ other) > 0;
959 };
960
961 /**
962 * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
963 * @function
964 * @param {!Long|number|string} other Other value
965 * @returns {boolean}
966 */
967 LongPrototype.gt = LongPrototype.greaterThan;
968
969 /**
970 * Tests if this Long's value is greater than or equal the specified's.
971 * @param {!Long|number|string} other Other value
972 * @returns {boolean}
973 */
974 LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
975 return this.comp(/* validates */ other) >= 0;
976 };
977
978 /**
979 * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
980 * @function
981 * @param {!Long|number|string} other Other value
982 * @returns {boolean}
983 */
984 LongPrototype.gte = LongPrototype.greaterThanOrEqual;
985
986 /**
987 * Compares this Long's value with the specified's.
988 * @param {!Long|number|string} other Other value
989 * @returns {number} 0 if they are the same, 1 if the this is greater and -1
990 * if the given one is greater
991 */
992 LongPrototype.compare = function compare(other) {
993 if (!isLong(other))
994 other = fromValue(other);
995 if (this.eq(other))
996 return 0;
997 var thisNeg = this.isNegative(),
998 otherNeg = other.isNegative();
999 if (thisNeg && !otherNeg)
1000 return -1;
1001 if (!thisNeg && otherNeg)
1002 return 1;
1003 // At this point the sign bits are the same
1004 if (!this.unsigned)
1005 return this.sub(other).isNegative() ? -1 : 1;
1006 // Both are positive if at least one is unsigned
1007 return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
1008 };
1009
1010 /**
1011 * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
1012 * @function
1013 * @param {!Long|number|string} other Other value
1014 * @returns {number} 0 if they are the same, 1 if the this is greater and -1
1015 * if the given one is greater
1016 */
1017 LongPrototype.comp = LongPrototype.compare;
1018
1019 /**
1020 * Negates this Long's value.
1021 * @returns {!Long} Negated Long
1022 */
1023 LongPrototype.negate = function negate() {
1024 if (!this.unsigned && this.eq(MIN_VALUE))
1025 return MIN_VALUE;
1026 return this.not().add(ONE);
1027 };
1028
1029 /**
1030 * Negates this Long's value. This is an alias of {@link Long#negate}.
1031 * @function
1032 * @returns {!Long} Negated Long
1033 */
1034 LongPrototype.neg = LongPrototype.negate;
1035
1036 /**
1037 * Returns the sum of this and the specified Long.
1038 * @param {!Long|number|string} addend Addend
1039 * @returns {!Long} Sum
1040 */
1041 LongPrototype.add = function add(addend) {
1042 if (!isLong(addend))
1043 addend = fromValue(addend);
1044
1045 // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
1046
1047 var a48 = this.high >>> 16;
1048 var a32 = this.high & 0xFFFF;
1049 var a16 = this.low >>> 16;
1050 var a00 = this.low & 0xFFFF;
1051
1052 var b48 = addend.high >>> 16;
1053 var b32 = addend.high & 0xFFFF;
1054 var b16 = addend.low >>> 16;
1055 var b00 = addend.low & 0xFFFF;
1056
1057 var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
1058 c00 += a00 + b00;
1059 c16 += c00 >>> 16;
1060 c00 &= 0xFFFF;
1061 c16 += a16 + b16;
1062 c32 += c16 >>> 16;
1063 c16 &= 0xFFFF;
1064 c32 += a32 + b32;
1065 c48 += c32 >>> 16;
1066 c32 &= 0xFFFF;
1067 c48 += a48 + b48;
1068 c48 &= 0xFFFF;
1069 return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
1070 };
1071
1072 /**
1073 * Returns the difference of this and the specified Long.
1074 * @param {!Long|number|string} subtrahend Subtrahend
1075 * @returns {!Long} Difference
1076 */
1077 LongPrototype.subtract = function subtract(subtrahend) {
1078 if (!isLong(subtrahend))
1079 subtrahend = fromValue(subtrahend);
1080 return this.add(subtrahend.neg());
1081 };
1082
1083 /**
1084 * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
1085 * @function
1086 * @param {!Long|number|string} subtrahend Subtrahend
1087 * @returns {!Long} Difference
1088 */
1089 LongPrototype.sub = LongPrototype.subtract;
1090
1091 /**
1092 * Returns the product of this and the specified Long.
1093 * @param {!Long|number|string} multiplier Multiplier
1094 * @returns {!Long} Product
1095 */
1096 LongPrototype.multiply = function multiply(multiplier) {
1097 if (this.isZero())
1098 return ZERO;
1099 if (!isLong(multiplier))
1100 multiplier = fromValue(multiplier);
1101 if (multiplier.isZero())
1102 return ZERO;
1103 if (this.eq(MIN_VALUE))
1104 return multiplier.isOdd() ? MIN_VALUE : ZERO;
1105 if (multiplier.eq(MIN_VALUE))
1106 return this.isOdd() ? MIN_VALUE : ZERO;
1107
1108 if (this.isNegative()) {
1109 if (multiplier.isNegative())
1110 return this.neg().mul(multiplier.neg());
1111 else
1112 return this.neg().mul(multiplier).neg();
1113 } else if (multiplier.isNegative())
1114 return this.mul(multiplier.neg()).neg();
1115
1116 // If both longs are small, use float multiplication
1117 if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
1118 return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
1119
1120 // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
1121 // We can skip products that would overflow.
1122
1123 var a48 = this.high >>> 16;
1124 var a32 = this.high & 0xFFFF;
1125 var a16 = this.low >>> 16;
1126 var a00 = this.low & 0xFFFF;
1127
1128 var b48 = multiplier.high >>> 16;
1129 var b32 = multiplier.high & 0xFFFF;
1130 var b16 = multiplier.low >>> 16;
1131 var b00 = multiplier.low & 0xFFFF;
1132
1133 var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
1134 c00 += a00 * b00;
1135 c16 += c00 >>> 16;
1136 c00 &= 0xFFFF;
1137 c16 += a16 * b00;
1138 c32 += c16 >>> 16;
1139 c16 &= 0xFFFF;
1140 c16 += a00 * b16;
1141 c32 += c16 >>> 16;
1142 c16 &= 0xFFFF;
1143 c32 += a32 * b00;
1144 c48 += c32 >>> 16;
1145 c32 &= 0xFFFF;
1146 c32 += a16 * b16;
1147 c48 += c32 >>> 16;
1148 c32 &= 0xFFFF;
1149 c32 += a00 * b32;
1150 c48 += c32 >>> 16;
1151 c32 &= 0xFFFF;
1152 c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
1153 c48 &= 0xFFFF;
1154 return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
1155 };
1156
1157 /**
1158 * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
1159 * @function
1160 * @param {!Long|number|string} multiplier Multiplier
1161 * @returns {!Long} Product
1162 */
1163 LongPrototype.mul = LongPrototype.multiply;
1164
1165 /**
1166 * Returns this Long divided by the specified. The result is signed if this Long is signed or
1167 * unsigned if this Long is unsigned.
1168 * @param {!Long|number|string} divisor Divisor
1169 * @returns {!Long} Quotient
1170 */
1171 LongPrototype.divide = function divide(divisor) {
1172 if (!isLong(divisor))
1173 divisor = fromValue(divisor);
1174 if (divisor.isZero())
1175 throw Error('division by zero');
1176 if (this.isZero())
1177 return this.unsigned ? UZERO : ZERO;
1178 var approx, rem, res;
1179 if (!this.unsigned) {
1180 // This section is only relevant for signed longs and is derived from the
1181 // closure library as a whole.
1182 if (this.eq(MIN_VALUE)) {
1183 if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
1184 return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
1185 else if (divisor.eq(MIN_VALUE))
1186 return ONE;
1187 else {
1188 // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
1189 var halfThis = this.shr(1);
1190 approx = halfThis.div(divisor).shl(1);
1191 if (approx.eq(ZERO)) {
1192 return divisor.isNegative() ? ONE : NEG_ONE;
1193 } else {
1194 rem = this.sub(divisor.mul(approx));
1195 res = approx.add(rem.div(divisor));
1196 return res;
1197 }
1198 }
1199 } else if (divisor.eq(MIN_VALUE))
1200 return this.unsigned ? UZERO : ZERO;
1201 if (this.isNegative()) {
1202 if (divisor.isNegative())
1203 return this.neg().div(divisor.neg());
1204 return this.neg().div(divisor).neg();
1205 } else if (divisor.isNegative())
1206 return this.div(divisor.neg()).neg();
1207 res = ZERO;
1208 } else {
1209 // The algorithm below has not been made for unsigned longs. It's therefore
1210 // required to take special care of the MSB prior to running it.
1211 if (!divisor.unsigned)
1212 divisor = divisor.toUnsigned();
1213 if (divisor.gt(this))
1214 return UZERO;
1215 if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
1216 return UONE;
1217 res = UZERO;
1218 }
1219
1220 // Repeat the following until the remainder is less than other: find a
1221 // floating-point that approximates remainder / other *from below*, add this
1222 // into the result, and subtract it from the remainder. It is critical that
1223 // the approximate value is less than or equal to the real value so that the
1224 // remainder never becomes negative.
1225 rem = this;
1226 while (rem.gte(divisor)) {
1227 // Approximate the result of division. This may be a little greater or
1228 // smaller than the actual value.
1229 approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
1230
1231 // We will tweak the approximate result by changing it in the 48-th digit or
1232 // the smallest non-fractional digit, whichever is larger.
1233 var log2 = Math.ceil(Math.log(approx) / Math.LN2),
1234 delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
1235
1236 // Decrease the approximation until it is smaller than the remainder. Note
1237 // that if it is too large, the product overflows and is negative.
1238 approxRes = fromNumber(approx),
1239 approxRem = approxRes.mul(divisor);
1240 while (approxRem.isNegative() || approxRem.gt(rem)) {
1241 approx -= delta;
1242 approxRes = fromNumber(approx, this.unsigned);
1243 approxRem = approxRes.mul(divisor);
1244 }
1245
1246 // We know the answer can't be zero... and actually, zero would cause
1247 // infinite recursion since we would make no progress.
1248 if (approxRes.isZero())
1249 approxRes = ONE;
1250
1251 res = res.add(approxRes);
1252 rem = rem.sub(approxRem);
1253 }
1254 return res;
1255 };
1256
1257 /**
1258 * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
1259 * @function
1260 * @param {!Long|number|string} divisor Divisor
1261 * @returns {!Long} Quotient
1262 */
1263 LongPrototype.div = LongPrototype.divide;
1264
1265 /**
1266 * Returns this Long modulo the specified.
1267 * @param {!Long|number|string} divisor Divisor
1268 * @returns {!Long} Remainder
1269 */
1270 LongPrototype.modulo = function modulo(divisor) {
1271 if (!isLong(divisor))
1272 divisor = fromValue(divisor);
1273 return this.sub(this.div(divisor).mul(divisor));
1274 };
1275
1276 /**
1277 * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
1278 * @function
1279 * @param {!Long|number|string} divisor Divisor
1280 * @returns {!Long} Remainder
1281 */
1282 LongPrototype.mod = LongPrototype.modulo;
1283
1284 /**
1285 * Returns the bitwise NOT of this Long.
1286 * @returns {!Long}
1287 */
1288 LongPrototype.not = function not() {
1289 return fromBits(~this.low, ~this.high, this.unsigned);
1290 };
1291
1292 /**
1293 * Returns the bitwise AND of this Long and the specified.
1294 * @param {!Long|number|string} other Other Long
1295 * @returns {!Long}
1296 */
1297 LongPrototype.and = function and(other) {
1298 if (!isLong(other))
1299 other = fromValue(other);
1300 return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
1301 };
1302
1303 /**
1304 * Returns the bitwise OR of this Long and the specified.
1305 * @param {!Long|number|string} other Other Long
1306 * @returns {!Long}
1307 */
1308 LongPrototype.or = function or(other) {
1309 if (!isLong(other))
1310 other = fromValue(other);
1311 return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
1312 };
1313
1314 /**
1315 * Returns the bitwise XOR of this Long and the given one.
1316 * @param {!Long|number|string} other Other Long
1317 * @returns {!Long}
1318 */
1319 LongPrototype.xor = function xor(other) {
1320 if (!isLong(other))
1321 other = fromValue(other);
1322 return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
1323 };
1324
1325 /**
1326 * Returns this Long with bits shifted to the left by the given amount.
1327 * @param {number|!Long} numBits Number of bits
1328 * @returns {!Long} Shifted Long
1329 */
1330 LongPrototype.shiftLeft = function shiftLeft(numBits) {
1331 if (isLong(numBits))
1332 numBits = numBits.toInt();
1333 if ((numBits &= 63) === 0)
1334 return this;
1335 else if (numBits < 32)
1336 return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
1337 else
1338 return fromBits(0, this.low << (numBits - 32), this.unsigned);
1339 };
1340
1341 /**
1342 * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
1343 * @function
1344 * @param {number|!Long} numBits Number of bits
1345 * @returns {!Long} Shifted Long
1346 */
1347 LongPrototype.shl = LongPrototype.shiftLeft;
1348
1349 /**
1350 * Returns this Long with bits arithmetically shifted to the right by the given amount.
1351 * @param {number|!Long} numBits Number of bits
1352 * @returns {!Long} Shifted Long
1353 */
1354 LongPrototype.shiftRight = function shiftRight(numBits) {
1355 if (isLong(numBits))
1356 numBits = numBits.toInt();
1357 if ((numBits &= 63) === 0)
1358 return this;
1359 else if (numBits < 32)
1360 return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
1361 else
1362 return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
1363 };
1364
1365 /**
1366 * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
1367 * @function
1368 * @param {number|!Long} numBits Number of bits
1369 * @returns {!Long} Shifted Long
1370 */
1371 LongPrototype.shr = LongPrototype.shiftRight;
1372
1373 /**
1374 * Returns this Long with bits logically shifted to the right by the given amount.
1375 * @param {number|!Long} numBits Number of bits
1376 * @returns {!Long} Shifted Long
1377 */
1378 LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
1379 if (isLong(numBits))
1380 numBits = numBits.toInt();
1381 numBits &= 63;
1382 if (numBits === 0)
1383 return this;
1384 else {
1385 var high = this.high;
1386 if (numBits < 32) {
1387 var low = this.low;
1388 return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
1389 } else if (numBits === 32)
1390 return fromBits(high, 0, this.unsigned);
1391 else
1392 return fromBits(high >>> (numBits - 32), 0, this.unsigned);
1393 }
1394 };
1395
1396 /**
1397 * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
1398 * @function
1399 * @param {number|!Long} numBits Number of bits
1400 * @returns {!Long} Shifted Long
1401 */
1402 LongPrototype.shru = LongPrototype.shiftRightUnsigned;
1403
1404 /**
1405 * Converts this Long to signed.
1406 * @returns {!Long} Signed long
1407 */
1408 LongPrototype.toSigned = function toSigned() {
1409 if (!this.unsigned)
1410 return this;
1411 return fromBits(this.low, this.high, false);
1412 };
1413
1414 /**
1415 * Converts this Long to unsigned.
1416 * @returns {!Long} Unsigned long
1417 */
1418 LongPrototype.toUnsigned = function toUnsigned() {
1419 if (this.unsigned)
1420 return this;
1421 return fromBits(this.low, this.high, true);
1422 };
1423
1424 /**
1425 * Converts this Long to its byte representation.
1426 * @param {boolean=} le Whether little or big endian, defaults to big endian
1427 * @returns {!Array.<number>} Byte representation
1428 */
1429 LongPrototype.toBytes = function(le) {
1430 return le ? this.toBytesLE() : this.toBytesBE();
1431 };
1432
1433 /**
1434 * Converts this Long to its little endian byte representation.
1435 * @returns {!Array.<number>} Little endian byte representation
1436 */
1437 LongPrototype.toBytesLE = function() {
1438 var hi = this.high,
1439 lo = this.low;
1440 return [
1441 lo & 0xff,
1442 (lo >>> 8) & 0xff,
1443 (lo >>> 16) & 0xff,
1444 (lo >>> 24) & 0xff,
1445 hi & 0xff,
1446 (hi >>> 8) & 0xff,
1447 (hi >>> 16) & 0xff,
1448 (hi >>> 24) & 0xff
1449 ];
1450 };
1451
1452 /**
1453 * Converts this Long to its big endian byte representation.
1454 * @returns {!Array.<number>} Big endian byte representation
1455 */
1456 LongPrototype.toBytesBE = function() {
1457 var hi = this.high,
1458 lo = this.low;
1459 return [
1460 (hi >>> 24) & 0xff,
1461 (hi >>> 16) & 0xff,
1462 (hi >>> 8) & 0xff,
1463 hi & 0xff,
1464 (lo >>> 24) & 0xff,
1465 (lo >>> 16) & 0xff,
1466 (lo >>> 8) & 0xff,
1467 lo & 0xff
1468 ];
1469 };
1470
1471 return Long;
1472 });
1473 });
1474
1475 var bytebuffer = createCommonjsModule(function (module) {
1476 /*
1477 Copyright 2013-2014 Daniel Wirtz <dcode@dcode.io>
1478
1479 Licensed under the Apache License, Version 2.0 (the "License");
1480 you may not use this file except in compliance with the License.
1481 You may obtain a copy of the License at
1482
1483 http://www.apache.org/licenses/LICENSE-2.0
1484
1485 Unless required by applicable law or agreed to in writing, software
1486 distributed under the License is distributed on an "AS IS" BASIS,
1487 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1488 See the License for the specific language governing permissions and
1489 limitations under the License.
1490 */
1491
1492 /**
1493 * @license bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
1494 * Backing buffer: ArrayBuffer, Accessor: Uint8Array
1495 * Released under the Apache License, Version 2.0
1496 * see: https://github.com/dcodeIO/bytebuffer.js for details
1497 */
1498 (function(global, factory) {
1499
1500 /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
1501 module['exports'] = (function() {
1502 var Long; try { Long = long_1; } catch (e) {}
1503 return factory(Long);
1504 })();
1505 /* Global */ else
1506 (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]);
1507
1508 })(commonjsGlobal, function(Long) {
1509
1510 /**
1511 * Constructs a new ByteBuffer.
1512 * @class The swiss army knife for binary data in JavaScript.
1513 * @exports ByteBuffer
1514 * @constructor
1515 * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
1516 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
1517 * {@link ByteBuffer.DEFAULT_ENDIAN}.
1518 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
1519 * {@link ByteBuffer.DEFAULT_NOASSERT}.
1520 * @expose
1521 */
1522 var ByteBuffer = function(capacity, littleEndian, noAssert) {
1523 if (typeof capacity === 'undefined')
1524 capacity = ByteBuffer.DEFAULT_CAPACITY;
1525 if (typeof littleEndian === 'undefined')
1526 littleEndian = ByteBuffer.DEFAULT_ENDIAN;
1527 if (typeof noAssert === 'undefined')
1528 noAssert = ByteBuffer.DEFAULT_NOASSERT;
1529 if (!noAssert) {
1530 capacity = capacity | 0;
1531 if (capacity < 0)
1532 throw RangeError("Illegal capacity");
1533 littleEndian = !!littleEndian;
1534 noAssert = !!noAssert;
1535 }
1536
1537 /**
1538 * Backing ArrayBuffer.
1539 * @type {!ArrayBuffer}
1540 * @expose
1541 */
1542 this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
1543
1544 /**
1545 * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
1546 * @type {?Uint8Array}
1547 * @expose
1548 */
1549 this.view = capacity === 0 ? null : new Uint8Array(this.buffer);
1550
1551 /**
1552 * Absolute read/write offset.
1553 * @type {number}
1554 * @expose
1555 * @see ByteBuffer#flip
1556 * @see ByteBuffer#clear
1557 */
1558 this.offset = 0;
1559
1560 /**
1561 * Marked offset.
1562 * @type {number}
1563 * @expose
1564 * @see ByteBuffer#mark
1565 * @see ByteBuffer#reset
1566 */
1567 this.markedOffset = -1;
1568
1569 /**
1570 * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
1571 * @type {number}
1572 * @expose
1573 * @see ByteBuffer#flip
1574 * @see ByteBuffer#clear
1575 */
1576 this.limit = capacity;
1577
1578 /**
1579 * Whether to use little endian byte order, defaults to `false` for big endian.
1580 * @type {boolean}
1581 * @expose
1582 */
1583 this.littleEndian = littleEndian;
1584
1585 /**
1586 * Whether to skip assertions of offsets and values, defaults to `false`.
1587 * @type {boolean}
1588 * @expose
1589 */
1590 this.noAssert = noAssert;
1591 };
1592
1593 /**
1594 * ByteBuffer version.
1595 * @type {string}
1596 * @const
1597 * @expose
1598 */
1599 ByteBuffer.VERSION = "5.0.1";
1600
1601 /**
1602 * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
1603 * @type {boolean}
1604 * @const
1605 * @expose
1606 */
1607 ByteBuffer.LITTLE_ENDIAN = true;
1608
1609 /**
1610 * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
1611 * @type {boolean}
1612 * @const
1613 * @expose
1614 */
1615 ByteBuffer.BIG_ENDIAN = false;
1616
1617 /**
1618 * Default initial capacity of `16`.
1619 * @type {number}
1620 * @expose
1621 */
1622 ByteBuffer.DEFAULT_CAPACITY = 16;
1623
1624 /**
1625 * Default endianess of `false` for big endian.
1626 * @type {boolean}
1627 * @expose
1628 */
1629 ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
1630
1631 /**
1632 * Default no assertions flag of `false`.
1633 * @type {boolean}
1634 * @expose
1635 */
1636 ByteBuffer.DEFAULT_NOASSERT = false;
1637
1638 /**
1639 * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
1640 * and int64 support is not available.
1641 * @type {?Long}
1642 * @const
1643 * @see https://github.com/dcodeIO/long.js
1644 * @expose
1645 */
1646 ByteBuffer.Long = Long || null;
1647
1648 /**
1649 * @alias ByteBuffer.prototype
1650 * @inner
1651 */
1652 var ByteBufferPrototype = ByteBuffer.prototype;
1653
1654 /**
1655 * An indicator used to reliably determine if an object is a ByteBuffer or not.
1656 * @type {boolean}
1657 * @const
1658 * @expose
1659 * @private
1660 */
1661 ByteBufferPrototype.__isByteBuffer__;
1662
1663 Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", {
1664 value: true,
1665 enumerable: false,
1666 configurable: false
1667 });
1668
1669 // helpers
1670
1671 /**
1672 * @type {!ArrayBuffer}
1673 * @inner
1674 */
1675 var EMPTY_BUFFER = new ArrayBuffer(0);
1676
1677 /**
1678 * String.fromCharCode reference for compile-time renaming.
1679 * @type {function(...number):string}
1680 * @inner
1681 */
1682 var stringFromCharCode = String.fromCharCode;
1683
1684 /**
1685 * Creates a source function for a string.
1686 * @param {string} s String to read from
1687 * @returns {function():number|null} Source function returning the next char code respectively `null` if there are
1688 * no more characters left.
1689 * @throws {TypeError} If the argument is invalid
1690 * @inner
1691 */
1692 function stringSource(s) {
1693 var i=0; return function() {
1694 return i < s.length ? s.charCodeAt(i++) : null;
1695 };
1696 }
1697
1698 /**
1699 * Creates a destination function for a string.
1700 * @returns {function(number=):undefined|string} Destination function successively called with the next char code.
1701 * Returns the final string when called without arguments.
1702 * @inner
1703 */
1704 function stringDestination() {
1705 var cs = [], ps = []; return function() {
1706 if (arguments.length === 0)
1707 return ps.join('')+stringFromCharCode.apply(String, cs);
1708 if (cs.length + arguments.length > 1024)
1709 ps.push(stringFromCharCode.apply(String, cs)),
1710 cs.length = 0;
1711 Array.prototype.push.apply(cs, arguments);
1712 };
1713 }
1714
1715 /**
1716 * Gets the accessor type.
1717 * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
1718 * @expose
1719 */
1720 ByteBuffer.accessor = function() {
1721 return Uint8Array;
1722 };
1723 /**
1724 * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
1725 * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
1726 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
1727 * {@link ByteBuffer.DEFAULT_ENDIAN}.
1728 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
1729 * {@link ByteBuffer.DEFAULT_NOASSERT}.
1730 * @returns {!ByteBuffer}
1731 * @expose
1732 */
1733 ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
1734 return new ByteBuffer(capacity, littleEndian, noAssert);
1735 };
1736
1737 /**
1738 * Concatenates multiple ByteBuffers into one.
1739 * @param {!Array.<!ByteBuffer|!ArrayBuffer|!Uint8Array|string>} buffers Buffers to concatenate
1740 * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
1741 * defaults to "utf8")
1742 * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
1743 * to {@link ByteBuffer.DEFAULT_ENDIAN}.
1744 * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
1745 * {@link ByteBuffer.DEFAULT_NOASSERT}.
1746 * @returns {!ByteBuffer} Concatenated ByteBuffer
1747 * @expose
1748 */
1749 ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
1750 if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
1751 noAssert = littleEndian;
1752 littleEndian = encoding;
1753 encoding = undefined;
1754 }
1755 var capacity = 0;
1756 for (var i=0, k=buffers.length, length; i<k; ++i) {
1757 if (!ByteBuffer.isByteBuffer(buffers[i]))
1758 buffers[i] = ByteBuffer.wrap(buffers[i], encoding);
1759 length = buffers[i].limit - buffers[i].offset;
1760 if (length > 0) capacity += length;
1761 }
1762 if (capacity === 0)
1763 return new ByteBuffer(0, littleEndian, noAssert);
1764 var bb = new ByteBuffer(capacity, littleEndian, noAssert),
1765 bi;
1766 i=0; while (i<k) {
1767 bi = buffers[i++];
1768 length = bi.limit - bi.offset;
1769 if (length <= 0) continue;
1770 bb.view.set(bi.view.subarray(bi.offset, bi.limit), bb.offset);
1771 bb.offset += length;
1772 }
1773 bb.limit = bb.offset;
1774 bb.offset = 0;
1775 return bb;
1776 };
1777
1778 /**
1779 * Tests if the specified type is a ByteBuffer.
1780 * @param {*} bb ByteBuffer to test
1781 * @returns {boolean} `true` if it is a ByteBuffer, otherwise `false`
1782 * @expose
1783 */
1784 ByteBuffer.isByteBuffer = function(bb) {
1785 return (bb && bb["__isByteBuffer__"]) === true;
1786 };
1787 /**
1788 * Gets the backing buffer type.
1789 * @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
1790 * @expose
1791 */
1792 ByteBuffer.type = function() {
1793 return ArrayBuffer;
1794 };
1795 /**
1796 * Wraps a buffer or a string. Sets the allocated ByteBuffer's {@link ByteBuffer#offset} to `0` and its
1797 * {@link ByteBuffer#limit} to the length of the wrapped data.
1798 * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
1799 * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
1800 * "utf8")
1801 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
1802 * {@link ByteBuffer.DEFAULT_ENDIAN}.
1803 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
1804 * {@link ByteBuffer.DEFAULT_NOASSERT}.
1805 * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
1806 * @expose
1807 */
1808 ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
1809 if (typeof encoding !== 'string') {
1810 noAssert = littleEndian;
1811 littleEndian = encoding;
1812 encoding = undefined;
1813 }
1814 if (typeof buffer === 'string') {
1815 if (typeof encoding === 'undefined')
1816 encoding = "utf8";
1817 switch (encoding) {
1818 case "base64":
1819 return ByteBuffer.fromBase64(buffer, littleEndian);
1820 case "hex":
1821 return ByteBuffer.fromHex(buffer, littleEndian);
1822 case "binary":
1823 return ByteBuffer.fromBinary(buffer, littleEndian);
1824 case "utf8":
1825 return ByteBuffer.fromUTF8(buffer, littleEndian);
1826 case "debug":
1827 return ByteBuffer.fromDebug(buffer, littleEndian);
1828 default:
1829 throw Error("Unsupported encoding: "+encoding);
1830 }
1831 }
1832 if (buffer === null || typeof buffer !== 'object')
1833 throw TypeError("Illegal buffer");
1834 var bb;
1835 if (ByteBuffer.isByteBuffer(buffer)) {
1836 bb = ByteBufferPrototype.clone.call(buffer);
1837 bb.markedOffset = -1;
1838 return bb;
1839 }
1840 if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
1841 bb = new ByteBuffer(0, littleEndian, noAssert);
1842 if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
1843 bb.buffer = buffer.buffer;
1844 bb.offset = buffer.byteOffset;
1845 bb.limit = buffer.byteOffset + buffer.byteLength;
1846 bb.view = new Uint8Array(buffer.buffer);
1847 }
1848 } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
1849 bb = new ByteBuffer(0, littleEndian, noAssert);
1850 if (buffer.byteLength > 0) {
1851 bb.buffer = buffer;
1852 bb.offset = 0;
1853 bb.limit = buffer.byteLength;
1854 bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null;
1855 }
1856 } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
1857 bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
1858 bb.limit = buffer.length;
1859 for (var i=0; i<buffer.length; ++i)
1860 bb.view[i] = buffer[i];
1861 } else
1862 throw TypeError("Illegal buffer"); // Otherwise fail
1863 return bb;
1864 };
1865
1866 /**
1867 * Writes the array as a bitset.
1868 * @param {Array<boolean>} value Array of booleans to write
1869 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
1870 * @returns {!ByteBuffer}
1871 * @expose
1872 */
1873 ByteBufferPrototype.writeBitSet = function(value, offset) {
1874 var relative = typeof offset === 'undefined';
1875 if (relative) offset = this.offset;
1876 if (!this.noAssert) {
1877 if (!(value instanceof Array))
1878 throw TypeError("Illegal BitSet: Not an array");
1879 if (typeof offset !== 'number' || offset % 1 !== 0)
1880 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1881 offset >>>= 0;
1882 if (offset < 0 || offset + 0 > this.buffer.byteLength)
1883 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1884 }
1885
1886 var start = offset,
1887 bits = value.length,
1888 bytes = (bits >> 3),
1889 bit = 0,
1890 k;
1891
1892 offset += this.writeVarint32(bits,offset);
1893
1894 while(bytes--) {
1895 k = (!!value[bit++] & 1) |
1896 ((!!value[bit++] & 1) << 1) |
1897 ((!!value[bit++] & 1) << 2) |
1898 ((!!value[bit++] & 1) << 3) |
1899 ((!!value[bit++] & 1) << 4) |
1900 ((!!value[bit++] & 1) << 5) |
1901 ((!!value[bit++] & 1) << 6) |
1902 ((!!value[bit++] & 1) << 7);
1903 this.writeByte(k,offset++);
1904 }
1905
1906 if(bit < bits) {
1907 var m = 0; k = 0;
1908 while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++));
1909 this.writeByte(k,offset++);
1910 }
1911
1912 if (relative) {
1913 this.offset = offset;
1914 return this;
1915 }
1916 return offset - start;
1917 };
1918
1919 /**
1920 * Reads a BitSet as an array of booleans.
1921 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
1922 * @returns {Array<boolean>
1923 * @expose
1924 */
1925 ByteBufferPrototype.readBitSet = function(offset) {
1926 var relative = typeof offset === 'undefined';
1927 if (relative) offset = this.offset;
1928
1929 var ret = this.readVarint32(offset),
1930 bits = ret.value,
1931 bytes = (bits >> 3),
1932 bit = 0,
1933 value = [],
1934 k;
1935
1936 offset += ret.length;
1937
1938 while(bytes--) {
1939 k = this.readByte(offset++);
1940 value[bit++] = !!(k & 0x01);
1941 value[bit++] = !!(k & 0x02);
1942 value[bit++] = !!(k & 0x04);
1943 value[bit++] = !!(k & 0x08);
1944 value[bit++] = !!(k & 0x10);
1945 value[bit++] = !!(k & 0x20);
1946 value[bit++] = !!(k & 0x40);
1947 value[bit++] = !!(k & 0x80);
1948 }
1949
1950 if(bit < bits) {
1951 var m = 0;
1952 k = this.readByte(offset++);
1953 while(bit < bits) value[bit++] = !!((k >> (m++)) & 1);
1954 }
1955
1956 if (relative) {
1957 this.offset = offset;
1958 }
1959 return value;
1960 };
1961 /**
1962 * Reads the specified number of bytes.
1963 * @param {number} length Number of bytes to read
1964 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
1965 * @returns {!ByteBuffer}
1966 * @expose
1967 */
1968 ByteBufferPrototype.readBytes = function(length, offset) {
1969 var relative = typeof offset === 'undefined';
1970 if (relative) offset = this.offset;
1971 if (!this.noAssert) {
1972 if (typeof offset !== 'number' || offset % 1 !== 0)
1973 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1974 offset >>>= 0;
1975 if (offset < 0 || offset + length > this.buffer.byteLength)
1976 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
1977 }
1978 var slice = this.slice(offset, offset + length);
1979 if (relative) this.offset += length;
1980 return slice;
1981 };
1982
1983 /**
1984 * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
1985 * @function
1986 * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
1987 * will be modified according to the performed read operation.
1988 * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
1989 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1990 * written if omitted.
1991 * @returns {!ByteBuffer} this
1992 * @expose
1993 */
1994 ByteBufferPrototype.writeBytes = ByteBufferPrototype.append;
1995
1996 // types/ints/int8
1997
1998 /**
1999 * Writes an 8bit signed integer.
2000 * @param {number} value Value to write
2001 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
2002 * @returns {!ByteBuffer} this
2003 * @expose
2004 */
2005 ByteBufferPrototype.writeInt8 = function(value, offset) {
2006 var relative = typeof offset === 'undefined';
2007 if (relative) offset = this.offset;
2008 if (!this.noAssert) {
2009 if (typeof value !== 'number' || value % 1 !== 0)
2010 throw TypeError("Illegal value: "+value+" (not an integer)");
2011 value |= 0;
2012 if (typeof offset !== 'number' || offset % 1 !== 0)
2013 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2014 offset >>>= 0;
2015 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2016 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2017 }
2018 offset += 1;
2019 var capacity0 = this.buffer.byteLength;
2020 if (offset > capacity0)
2021 this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
2022 offset -= 1;
2023 this.view[offset] = value;
2024 if (relative) this.offset += 1;
2025 return this;
2026 };
2027
2028 /**
2029 * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
2030 * @function
2031 * @param {number} value Value to write
2032 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
2033 * @returns {!ByteBuffer} this
2034 * @expose
2035 */
2036 ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
2037
2038 /**
2039 * Reads an 8bit signed integer.
2040 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
2041 * @returns {number} Value read
2042 * @expose
2043 */
2044 ByteBufferPrototype.readInt8 = function(offset) {
2045 var relative = typeof offset === 'undefined';
2046 if (relative) offset = this.offset;
2047 if (!this.noAssert) {
2048 if (typeof offset !== 'number' || offset % 1 !== 0)
2049 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2050 offset >>>= 0;
2051 if (offset < 0 || offset + 1 > this.buffer.byteLength)
2052 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
2053 }
2054 var value = this.view[offset];
2055 if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed
2056 if (relative) this.offset += 1;
2057 return value;
2058 };
2059
2060 /**
2061 * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
2062 * @function
2063 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
2064 * @returns {number} Value read
2065 * @expose
2066 */
2067 ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
2068
2069 /**
2070 * Writes an 8bit unsigned integer.
2071 * @param {number} value Value to write
2072 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
2073 * @returns {!ByteBuffer} this
2074 * @expose
2075 */
2076 ByteBufferPrototype.writeUint8 = function(value, offset) {
2077 var relative = typeof offset === 'undefined';
2078 if (relative) offset = this.offset;
2079 if (!this.noAssert) {
2080 if (typeof value !== 'number' || value % 1 !== 0)
2081 throw TypeError("Illegal value: "+value+" (not an integer)");
2082 value >>>= 0;
2083 if (typeof offset !== 'number' || offset % 1 !== 0)
2084 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2085 offset >>>= 0;
2086 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2087 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2088 }
2089 offset += 1;
2090 var capacity1 = this.buffer.byteLength;
2091 if (offset > capacity1)
2092 this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
2093 offset -= 1;
2094 this.view[offset] = value;
2095 if (relative) this.offset += 1;
2096 return this;
2097 };
2098
2099 /**
2100 * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
2101 * @function
2102 * @param {number} value Value to write
2103 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
2104 * @returns {!ByteBuffer} this
2105 * @expose
2106 */
2107 ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8;
2108
2109 /**
2110 * Reads an 8bit unsigned integer.
2111 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
2112 * @returns {number} Value read
2113 * @expose
2114 */
2115 ByteBufferPrototype.readUint8 = function(offset) {
2116 var relative = typeof offset === 'undefined';
2117 if (relative) offset = this.offset;
2118 if (!this.noAssert) {
2119 if (typeof offset !== 'number' || offset % 1 !== 0)
2120 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2121 offset >>>= 0;
2122 if (offset < 0 || offset + 1 > this.buffer.byteLength)
2123 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
2124 }
2125 var value = this.view[offset];
2126 if (relative) this.offset += 1;
2127 return value;
2128 };
2129
2130 /**
2131 * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
2132 * @function
2133 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
2134 * @returns {number} Value read
2135 * @expose
2136 */
2137 ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8;
2138
2139 // types/ints/int16
2140
2141 /**
2142 * Writes a 16bit signed integer.
2143 * @param {number} value Value to write
2144 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2145 * @throws {TypeError} If `offset` or `value` is not a valid number
2146 * @throws {RangeError} If `offset` is out of bounds
2147 * @expose
2148 */
2149 ByteBufferPrototype.writeInt16 = function(value, offset) {
2150 var relative = typeof offset === 'undefined';
2151 if (relative) offset = this.offset;
2152 if (!this.noAssert) {
2153 if (typeof value !== 'number' || value % 1 !== 0)
2154 throw TypeError("Illegal value: "+value+" (not an integer)");
2155 value |= 0;
2156 if (typeof offset !== 'number' || offset % 1 !== 0)
2157 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2158 offset >>>= 0;
2159 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2160 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2161 }
2162 offset += 2;
2163 var capacity2 = this.buffer.byteLength;
2164 if (offset > capacity2)
2165 this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
2166 offset -= 2;
2167 if (this.littleEndian) {
2168 this.view[offset+1] = (value & 0xFF00) >>> 8;
2169 this.view[offset ] = value & 0x00FF;
2170 } else {
2171 this.view[offset] = (value & 0xFF00) >>> 8;
2172 this.view[offset+1] = value & 0x00FF;
2173 }
2174 if (relative) this.offset += 2;
2175 return this;
2176 };
2177
2178 /**
2179 * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
2180 * @function
2181 * @param {number} value Value to write
2182 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2183 * @throws {TypeError} If `offset` or `value` is not a valid number
2184 * @throws {RangeError} If `offset` is out of bounds
2185 * @expose
2186 */
2187 ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
2188
2189 /**
2190 * Reads a 16bit signed integer.
2191 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2192 * @returns {number} Value read
2193 * @throws {TypeError} If `offset` is not a valid number
2194 * @throws {RangeError} If `offset` is out of bounds
2195 * @expose
2196 */
2197 ByteBufferPrototype.readInt16 = function(offset) {
2198 var relative = typeof offset === 'undefined';
2199 if (relative) offset = this.offset;
2200 if (!this.noAssert) {
2201 if (typeof offset !== 'number' || offset % 1 !== 0)
2202 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2203 offset >>>= 0;
2204 if (offset < 0 || offset + 2 > this.buffer.byteLength)
2205 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
2206 }
2207 var value = 0;
2208 if (this.littleEndian) {
2209 value = this.view[offset ];
2210 value |= this.view[offset+1] << 8;
2211 } else {
2212 value = this.view[offset ] << 8;
2213 value |= this.view[offset+1];
2214 }
2215 if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed
2216 if (relative) this.offset += 2;
2217 return value;
2218 };
2219
2220 /**
2221 * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
2222 * @function
2223 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2224 * @returns {number} Value read
2225 * @throws {TypeError} If `offset` is not a valid number
2226 * @throws {RangeError} If `offset` is out of bounds
2227 * @expose
2228 */
2229 ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
2230
2231 /**
2232 * Writes a 16bit unsigned integer.
2233 * @param {number} value Value to write
2234 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2235 * @throws {TypeError} If `offset` or `value` is not a valid number
2236 * @throws {RangeError} If `offset` is out of bounds
2237 * @expose
2238 */
2239 ByteBufferPrototype.writeUint16 = function(value, offset) {
2240 var relative = typeof offset === 'undefined';
2241 if (relative) offset = this.offset;
2242 if (!this.noAssert) {
2243 if (typeof value !== 'number' || value % 1 !== 0)
2244 throw TypeError("Illegal value: "+value+" (not an integer)");
2245 value >>>= 0;
2246 if (typeof offset !== 'number' || offset % 1 !== 0)
2247 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2248 offset >>>= 0;
2249 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2250 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2251 }
2252 offset += 2;
2253 var capacity3 = this.buffer.byteLength;
2254 if (offset > capacity3)
2255 this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
2256 offset -= 2;
2257 if (this.littleEndian) {
2258 this.view[offset+1] = (value & 0xFF00) >>> 8;
2259 this.view[offset ] = value & 0x00FF;
2260 } else {
2261 this.view[offset] = (value & 0xFF00) >>> 8;
2262 this.view[offset+1] = value & 0x00FF;
2263 }
2264 if (relative) this.offset += 2;
2265 return this;
2266 };
2267
2268 /**
2269 * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
2270 * @function
2271 * @param {number} value Value to write
2272 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2273 * @throws {TypeError} If `offset` or `value` is not a valid number
2274 * @throws {RangeError} If `offset` is out of bounds
2275 * @expose
2276 */
2277 ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16;
2278
2279 /**
2280 * Reads a 16bit unsigned integer.
2281 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2282 * @returns {number} Value read
2283 * @throws {TypeError} If `offset` is not a valid number
2284 * @throws {RangeError} If `offset` is out of bounds
2285 * @expose
2286 */
2287 ByteBufferPrototype.readUint16 = function(offset) {
2288 var relative = typeof offset === 'undefined';
2289 if (relative) offset = this.offset;
2290 if (!this.noAssert) {
2291 if (typeof offset !== 'number' || offset % 1 !== 0)
2292 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2293 offset >>>= 0;
2294 if (offset < 0 || offset + 2 > this.buffer.byteLength)
2295 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
2296 }
2297 var value = 0;
2298 if (this.littleEndian) {
2299 value = this.view[offset ];
2300 value |= this.view[offset+1] << 8;
2301 } else {
2302 value = this.view[offset ] << 8;
2303 value |= this.view[offset+1];
2304 }
2305 if (relative) this.offset += 2;
2306 return value;
2307 };
2308
2309 /**
2310 * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
2311 * @function
2312 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2313 * @returns {number} Value read
2314 * @throws {TypeError} If `offset` is not a valid number
2315 * @throws {RangeError} If `offset` is out of bounds
2316 * @expose
2317 */
2318 ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16;
2319
2320 // types/ints/int32
2321
2322 /**
2323 * Writes a 32bit signed integer.
2324 * @param {number} value Value to write
2325 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2326 * @expose
2327 */
2328 ByteBufferPrototype.writeInt32 = function(value, offset) {
2329 var relative = typeof offset === 'undefined';
2330 if (relative) offset = this.offset;
2331 if (!this.noAssert) {
2332 if (typeof value !== 'number' || value % 1 !== 0)
2333 throw TypeError("Illegal value: "+value+" (not an integer)");
2334 value |= 0;
2335 if (typeof offset !== 'number' || offset % 1 !== 0)
2336 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2337 offset >>>= 0;
2338 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2339 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2340 }
2341 offset += 4;
2342 var capacity4 = this.buffer.byteLength;
2343 if (offset > capacity4)
2344 this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
2345 offset -= 4;
2346 if (this.littleEndian) {
2347 this.view[offset+3] = (value >>> 24) & 0xFF;
2348 this.view[offset+2] = (value >>> 16) & 0xFF;
2349 this.view[offset+1] = (value >>> 8) & 0xFF;
2350 this.view[offset ] = value & 0xFF;
2351 } else {
2352 this.view[offset ] = (value >>> 24) & 0xFF;
2353 this.view[offset+1] = (value >>> 16) & 0xFF;
2354 this.view[offset+2] = (value >>> 8) & 0xFF;
2355 this.view[offset+3] = value & 0xFF;
2356 }
2357 if (relative) this.offset += 4;
2358 return this;
2359 };
2360
2361 /**
2362 * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
2363 * @param {number} value Value to write
2364 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2365 * @expose
2366 */
2367 ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
2368
2369 /**
2370 * Reads a 32bit signed integer.
2371 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2372 * @returns {number} Value read
2373 * @expose
2374 */
2375 ByteBufferPrototype.readInt32 = function(offset) {
2376 var relative = typeof offset === 'undefined';
2377 if (relative) offset = this.offset;
2378 if (!this.noAssert) {
2379 if (typeof offset !== 'number' || offset % 1 !== 0)
2380 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2381 offset >>>= 0;
2382 if (offset < 0 || offset + 4 > this.buffer.byteLength)
2383 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
2384 }
2385 var value = 0;
2386 if (this.littleEndian) {
2387 value = this.view[offset+2] << 16;
2388 value |= this.view[offset+1] << 8;
2389 value |= this.view[offset ];
2390 value += this.view[offset+3] << 24 >>> 0;
2391 } else {
2392 value = this.view[offset+1] << 16;
2393 value |= this.view[offset+2] << 8;
2394 value |= this.view[offset+3];
2395 value += this.view[offset ] << 24 >>> 0;
2396 }
2397 value |= 0; // Cast to signed
2398 if (relative) this.offset += 4;
2399 return value;
2400 };
2401
2402 /**
2403 * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
2404 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
2405 * @returns {number} Value read
2406 * @expose
2407 */
2408 ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
2409
2410 /**
2411 * Writes a 32bit unsigned integer.
2412 * @param {number} value Value to write
2413 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2414 * @expose
2415 */
2416 ByteBufferPrototype.writeUint32 = function(value, offset) {
2417 var relative = typeof offset === 'undefined';
2418 if (relative) offset = this.offset;
2419 if (!this.noAssert) {
2420 if (typeof value !== 'number' || value % 1 !== 0)
2421 throw TypeError("Illegal value: "+value+" (not an integer)");
2422 value >>>= 0;
2423 if (typeof offset !== 'number' || offset % 1 !== 0)
2424 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2425 offset >>>= 0;
2426 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2427 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2428 }
2429 offset += 4;
2430 var capacity5 = this.buffer.byteLength;
2431 if (offset > capacity5)
2432 this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
2433 offset -= 4;
2434 if (this.littleEndian) {
2435 this.view[offset+3] = (value >>> 24) & 0xFF;
2436 this.view[offset+2] = (value >>> 16) & 0xFF;
2437 this.view[offset+1] = (value >>> 8) & 0xFF;
2438 this.view[offset ] = value & 0xFF;
2439 } else {
2440 this.view[offset ] = (value >>> 24) & 0xFF;
2441 this.view[offset+1] = (value >>> 16) & 0xFF;
2442 this.view[offset+2] = (value >>> 8) & 0xFF;
2443 this.view[offset+3] = value & 0xFF;
2444 }
2445 if (relative) this.offset += 4;
2446 return this;
2447 };
2448
2449 /**
2450 * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
2451 * @function
2452 * @param {number} value Value to write
2453 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2454 * @expose
2455 */
2456 ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32;
2457
2458 /**
2459 * Reads a 32bit unsigned integer.
2460 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2461 * @returns {number} Value read
2462 * @expose
2463 */
2464 ByteBufferPrototype.readUint32 = function(offset) {
2465 var relative = typeof offset === 'undefined';
2466 if (relative) offset = this.offset;
2467 if (!this.noAssert) {
2468 if (typeof offset !== 'number' || offset % 1 !== 0)
2469 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2470 offset >>>= 0;
2471 if (offset < 0 || offset + 4 > this.buffer.byteLength)
2472 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
2473 }
2474 var value = 0;
2475 if (this.littleEndian) {
2476 value = this.view[offset+2] << 16;
2477 value |= this.view[offset+1] << 8;
2478 value |= this.view[offset ];
2479 value += this.view[offset+3] << 24 >>> 0;
2480 } else {
2481 value = this.view[offset+1] << 16;
2482 value |= this.view[offset+2] << 8;
2483 value |= this.view[offset+3];
2484 value += this.view[offset ] << 24 >>> 0;
2485 }
2486 if (relative) this.offset += 4;
2487 return value;
2488 };
2489
2490 /**
2491 * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
2492 * @function
2493 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2494 * @returns {number} Value read
2495 * @expose
2496 */
2497 ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32;
2498
2499 // types/ints/int64
2500
2501 if (Long) {
2502
2503 /**
2504 * Writes a 64bit signed integer.
2505 * @param {number|!Long} value Value to write
2506 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2507 * @returns {!ByteBuffer} this
2508 * @expose
2509 */
2510 ByteBufferPrototype.writeInt64 = function(value, offset) {
2511 var relative = typeof offset === 'undefined';
2512 if (relative) offset = this.offset;
2513 if (!this.noAssert) {
2514 if (typeof value === 'number')
2515 value = Long.fromNumber(value);
2516 else if (typeof value === 'string')
2517 value = Long.fromString(value);
2518 else if (!(value && value instanceof Long))
2519 throw TypeError("Illegal value: "+value+" (not an integer or Long)");
2520 if (typeof offset !== 'number' || offset % 1 !== 0)
2521 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2522 offset >>>= 0;
2523 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2524 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2525 }
2526 if (typeof value === 'number')
2527 value = Long.fromNumber(value);
2528 else if (typeof value === 'string')
2529 value = Long.fromString(value);
2530 offset += 8;
2531 var capacity6 = this.buffer.byteLength;
2532 if (offset > capacity6)
2533 this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
2534 offset -= 8;
2535 var lo = value.low,
2536 hi = value.high;
2537 if (this.littleEndian) {
2538 this.view[offset+3] = (lo >>> 24) & 0xFF;
2539 this.view[offset+2] = (lo >>> 16) & 0xFF;
2540 this.view[offset+1] = (lo >>> 8) & 0xFF;
2541 this.view[offset ] = lo & 0xFF;
2542 offset += 4;
2543 this.view[offset+3] = (hi >>> 24) & 0xFF;
2544 this.view[offset+2] = (hi >>> 16) & 0xFF;
2545 this.view[offset+1] = (hi >>> 8) & 0xFF;
2546 this.view[offset ] = hi & 0xFF;
2547 } else {
2548 this.view[offset ] = (hi >>> 24) & 0xFF;
2549 this.view[offset+1] = (hi >>> 16) & 0xFF;
2550 this.view[offset+2] = (hi >>> 8) & 0xFF;
2551 this.view[offset+3] = hi & 0xFF;
2552 offset += 4;
2553 this.view[offset ] = (lo >>> 24) & 0xFF;
2554 this.view[offset+1] = (lo >>> 16) & 0xFF;
2555 this.view[offset+2] = (lo >>> 8) & 0xFF;
2556 this.view[offset+3] = lo & 0xFF;
2557 }
2558 if (relative) this.offset += 8;
2559 return this;
2560 };
2561
2562 /**
2563 * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
2564 * @param {number|!Long} value Value to write
2565 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2566 * @returns {!ByteBuffer} this
2567 * @expose
2568 */
2569 ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
2570
2571 /**
2572 * Reads a 64bit signed integer.
2573 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2574 * @returns {!Long}
2575 * @expose
2576 */
2577 ByteBufferPrototype.readInt64 = function(offset) {
2578 var relative = typeof offset === 'undefined';
2579 if (relative) offset = this.offset;
2580 if (!this.noAssert) {
2581 if (typeof offset !== 'number' || offset % 1 !== 0)
2582 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2583 offset >>>= 0;
2584 if (offset < 0 || offset + 8 > this.buffer.byteLength)
2585 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
2586 }
2587 var lo = 0,
2588 hi = 0;
2589 if (this.littleEndian) {
2590 lo = this.view[offset+2] << 16;
2591 lo |= this.view[offset+1] << 8;
2592 lo |= this.view[offset ];
2593 lo += this.view[offset+3] << 24 >>> 0;
2594 offset += 4;
2595 hi = this.view[offset+2] << 16;
2596 hi |= this.view[offset+1] << 8;
2597 hi |= this.view[offset ];
2598 hi += this.view[offset+3] << 24 >>> 0;
2599 } else {
2600 hi = this.view[offset+1] << 16;
2601 hi |= this.view[offset+2] << 8;
2602 hi |= this.view[offset+3];
2603 hi += this.view[offset ] << 24 >>> 0;
2604 offset += 4;
2605 lo = this.view[offset+1] << 16;
2606 lo |= this.view[offset+2] << 8;
2607 lo |= this.view[offset+3];
2608 lo += this.view[offset ] << 24 >>> 0;
2609 }
2610 var value = new Long(lo, hi, false);
2611 if (relative) this.offset += 8;
2612 return value;
2613 };
2614
2615 /**
2616 * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
2617 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2618 * @returns {!Long}
2619 * @expose
2620 */
2621 ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
2622
2623 /**
2624 * Writes a 64bit unsigned integer.
2625 * @param {number|!Long} value Value to write
2626 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2627 * @returns {!ByteBuffer} this
2628 * @expose
2629 */
2630 ByteBufferPrototype.writeUint64 = function(value, offset) {
2631 var relative = typeof offset === 'undefined';
2632 if (relative) offset = this.offset;
2633 if (!this.noAssert) {
2634 if (typeof value === 'number')
2635 value = Long.fromNumber(value);
2636 else if (typeof value === 'string')
2637 value = Long.fromString(value);
2638 else if (!(value && value instanceof Long))
2639 throw TypeError("Illegal value: "+value+" (not an integer or Long)");
2640 if (typeof offset !== 'number' || offset % 1 !== 0)
2641 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2642 offset >>>= 0;
2643 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2644 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2645 }
2646 if (typeof value === 'number')
2647 value = Long.fromNumber(value);
2648 else if (typeof value === 'string')
2649 value = Long.fromString(value);
2650 offset += 8;
2651 var capacity7 = this.buffer.byteLength;
2652 if (offset > capacity7)
2653 this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
2654 offset -= 8;
2655 var lo = value.low,
2656 hi = value.high;
2657 if (this.littleEndian) {
2658 this.view[offset+3] = (lo >>> 24) & 0xFF;
2659 this.view[offset+2] = (lo >>> 16) & 0xFF;
2660 this.view[offset+1] = (lo >>> 8) & 0xFF;
2661 this.view[offset ] = lo & 0xFF;
2662 offset += 4;
2663 this.view[offset+3] = (hi >>> 24) & 0xFF;
2664 this.view[offset+2] = (hi >>> 16) & 0xFF;
2665 this.view[offset+1] = (hi >>> 8) & 0xFF;
2666 this.view[offset ] = hi & 0xFF;
2667 } else {
2668 this.view[offset ] = (hi >>> 24) & 0xFF;
2669 this.view[offset+1] = (hi >>> 16) & 0xFF;
2670 this.view[offset+2] = (hi >>> 8) & 0xFF;
2671 this.view[offset+3] = hi & 0xFF;
2672 offset += 4;
2673 this.view[offset ] = (lo >>> 24) & 0xFF;
2674 this.view[offset+1] = (lo >>> 16) & 0xFF;
2675 this.view[offset+2] = (lo >>> 8) & 0xFF;
2676 this.view[offset+3] = lo & 0xFF;
2677 }
2678 if (relative) this.offset += 8;
2679 return this;
2680 };
2681
2682 /**
2683 * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
2684 * @function
2685 * @param {number|!Long} value Value to write
2686 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2687 * @returns {!ByteBuffer} this
2688 * @expose
2689 */
2690 ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64;
2691
2692 /**
2693 * Reads a 64bit unsigned integer.
2694 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2695 * @returns {!Long}
2696 * @expose
2697 */
2698 ByteBufferPrototype.readUint64 = function(offset) {
2699 var relative = typeof offset === 'undefined';
2700 if (relative) offset = this.offset;
2701 if (!this.noAssert) {
2702 if (typeof offset !== 'number' || offset % 1 !== 0)
2703 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2704 offset >>>= 0;
2705 if (offset < 0 || offset + 8 > this.buffer.byteLength)
2706 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
2707 }
2708 var lo = 0,
2709 hi = 0;
2710 if (this.littleEndian) {
2711 lo = this.view[offset+2] << 16;
2712 lo |= this.view[offset+1] << 8;
2713 lo |= this.view[offset ];
2714 lo += this.view[offset+3] << 24 >>> 0;
2715 offset += 4;
2716 hi = this.view[offset+2] << 16;
2717 hi |= this.view[offset+1] << 8;
2718 hi |= this.view[offset ];
2719 hi += this.view[offset+3] << 24 >>> 0;
2720 } else {
2721 hi = this.view[offset+1] << 16;
2722 hi |= this.view[offset+2] << 8;
2723 hi |= this.view[offset+3];
2724 hi += this.view[offset ] << 24 >>> 0;
2725 offset += 4;
2726 lo = this.view[offset+1] << 16;
2727 lo |= this.view[offset+2] << 8;
2728 lo |= this.view[offset+3];
2729 lo += this.view[offset ] << 24 >>> 0;
2730 }
2731 var value = new Long(lo, hi, true);
2732 if (relative) this.offset += 8;
2733 return value;
2734 };
2735
2736 /**
2737 * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}.
2738 * @function
2739 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2740 * @returns {!Long}
2741 * @expose
2742 */
2743 ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64;
2744
2745 } // Long
2746
2747
2748 // types/floats/float32
2749
2750 /*
2751 ieee754 - https://github.com/feross/ieee754
2752
2753 The MIT License (MIT)
2754
2755 Copyright (c) Feross Aboukhadijeh
2756
2757 Permission is hereby granted, free of charge, to any person obtaining a copy
2758 of this software and associated documentation files (the "Software"), to deal
2759 in the Software without restriction, including without limitation the rights
2760 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2761 copies of the Software, and to permit persons to whom the Software is
2762 furnished to do so, subject to the following conditions:
2763
2764 The above copyright notice and this permission notice shall be included in
2765 all copies or substantial portions of the Software.
2766
2767 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2768 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2769 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2770 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2771 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2772 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2773 THE SOFTWARE.
2774 */
2775
2776 /**
2777 * Reads an IEEE754 float from a byte array.
2778 * @param {!Array} buffer
2779 * @param {number} offset
2780 * @param {boolean} isLE
2781 * @param {number} mLen
2782 * @param {number} nBytes
2783 * @returns {number}
2784 * @inner
2785 */
2786 function ieee754_read(buffer, offset, isLE, mLen, nBytes) {
2787 var e, m,
2788 eLen = nBytes * 8 - mLen - 1,
2789 eMax = (1 << eLen) - 1,
2790 eBias = eMax >> 1,
2791 nBits = -7,
2792 i = isLE ? (nBytes - 1) : 0,
2793 d = isLE ? -1 : 1,
2794 s = buffer[offset + i];
2795
2796 i += d;
2797
2798 e = s & ((1 << (-nBits)) - 1);
2799 s >>= (-nBits);
2800 nBits += eLen;
2801 for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
2802
2803 m = e & ((1 << (-nBits)) - 1);
2804 e >>= (-nBits);
2805 nBits += mLen;
2806 for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
2807
2808 if (e === 0) {
2809 e = 1 - eBias;
2810 } else if (e === eMax) {
2811 return m ? NaN : ((s ? -1 : 1) * Infinity);
2812 } else {
2813 m = m + Math.pow(2, mLen);
2814 e = e - eBias;
2815 }
2816 return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
2817 }
2818
2819 /**
2820 * Writes an IEEE754 float to a byte array.
2821 * @param {!Array} buffer
2822 * @param {number} value
2823 * @param {number} offset
2824 * @param {boolean} isLE
2825 * @param {number} mLen
2826 * @param {number} nBytes
2827 * @inner
2828 */
2829 function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) {
2830 var e, m, c,
2831 eLen = nBytes * 8 - mLen - 1,
2832 eMax = (1 << eLen) - 1,
2833 eBias = eMax >> 1,
2834 rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
2835 i = isLE ? 0 : (nBytes - 1),
2836 d = isLE ? 1 : -1,
2837 s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
2838
2839 value = Math.abs(value);
2840
2841 if (isNaN(value) || value === Infinity) {
2842 m = isNaN(value) ? 1 : 0;
2843 e = eMax;
2844 } else {
2845 e = Math.floor(Math.log(value) / Math.LN2);
2846 if (value * (c = Math.pow(2, -e)) < 1) {
2847 e--;
2848 c *= 2;
2849 }
2850 if (e + eBias >= 1) {
2851 value += rt / c;
2852 } else {
2853 value += rt * Math.pow(2, 1 - eBias);
2854 }
2855 if (value * c >= 2) {
2856 e++;
2857 c /= 2;
2858 }
2859
2860 if (e + eBias >= eMax) {
2861 m = 0;
2862 e = eMax;
2863 } else if (e + eBias >= 1) {
2864 m = (value * c - 1) * Math.pow(2, mLen);
2865 e = e + eBias;
2866 } else {
2867 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
2868 e = 0;
2869 }
2870 }
2871
2872 for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
2873
2874 e = (e << mLen) | m;
2875 eLen += mLen;
2876 for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
2877
2878 buffer[offset + i - d] |= s * 128;
2879 }
2880
2881 /**
2882 * Writes a 32bit float.
2883 * @param {number} value Value to write
2884 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2885 * @returns {!ByteBuffer} this
2886 * @expose
2887 */
2888 ByteBufferPrototype.writeFloat32 = function(value, offset) {
2889 var relative = typeof offset === 'undefined';
2890 if (relative) offset = this.offset;
2891 if (!this.noAssert) {
2892 if (typeof value !== 'number')
2893 throw TypeError("Illegal value: "+value+" (not a number)");
2894 if (typeof offset !== 'number' || offset % 1 !== 0)
2895 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2896 offset >>>= 0;
2897 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2898 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2899 }
2900 offset += 4;
2901 var capacity8 = this.buffer.byteLength;
2902 if (offset > capacity8)
2903 this.resize((capacity8 *= 2) > offset ? capacity8 : offset);
2904 offset -= 4;
2905 ieee754_write(this.view, value, offset, this.littleEndian, 23, 4);
2906 if (relative) this.offset += 4;
2907 return this;
2908 };
2909
2910 /**
2911 * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
2912 * @function
2913 * @param {number} value Value to write
2914 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2915 * @returns {!ByteBuffer} this
2916 * @expose
2917 */
2918 ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32;
2919
2920 /**
2921 * Reads a 32bit float.
2922 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2923 * @returns {number}
2924 * @expose
2925 */
2926 ByteBufferPrototype.readFloat32 = function(offset) {
2927 var relative = typeof offset === 'undefined';
2928 if (relative) offset = this.offset;
2929 if (!this.noAssert) {
2930 if (typeof offset !== 'number' || offset % 1 !== 0)
2931 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2932 offset >>>= 0;
2933 if (offset < 0 || offset + 4 > this.buffer.byteLength)
2934 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
2935 }
2936 var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4);
2937 if (relative) this.offset += 4;
2938 return value;
2939 };
2940
2941 /**
2942 * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
2943 * @function
2944 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2945 * @returns {number}
2946 * @expose
2947 */
2948 ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32;
2949
2950 // types/floats/float64
2951
2952 /**
2953 * Writes a 64bit float.
2954 * @param {number} value Value to write
2955 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2956 * @returns {!ByteBuffer} this
2957 * @expose
2958 */
2959 ByteBufferPrototype.writeFloat64 = function(value, offset) {
2960 var relative = typeof offset === 'undefined';
2961 if (relative) offset = this.offset;
2962 if (!this.noAssert) {
2963 if (typeof value !== 'number')
2964 throw TypeError("Illegal value: "+value+" (not a number)");
2965 if (typeof offset !== 'number' || offset % 1 !== 0)
2966 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2967 offset >>>= 0;
2968 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2969 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2970 }
2971 offset += 8;
2972 var capacity9 = this.buffer.byteLength;
2973 if (offset > capacity9)
2974 this.resize((capacity9 *= 2) > offset ? capacity9 : offset);
2975 offset -= 8;
2976 ieee754_write(this.view, value, offset, this.littleEndian, 52, 8);
2977 if (relative) this.offset += 8;
2978 return this;
2979 };
2980
2981 /**
2982 * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
2983 * @function
2984 * @param {number} value Value to write
2985 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2986 * @returns {!ByteBuffer} this
2987 * @expose
2988 */
2989 ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64;
2990
2991 /**
2992 * Reads a 64bit float.
2993 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2994 * @returns {number}
2995 * @expose
2996 */
2997 ByteBufferPrototype.readFloat64 = function(offset) {
2998 var relative = typeof offset === 'undefined';
2999 if (relative) offset = this.offset;
3000 if (!this.noAssert) {
3001 if (typeof offset !== 'number' || offset % 1 !== 0)
3002 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3003 offset >>>= 0;
3004 if (offset < 0 || offset + 8 > this.buffer.byteLength)
3005 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
3006 }
3007 var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8);
3008 if (relative) this.offset += 8;
3009 return value;
3010 };
3011
3012 /**
3013 * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
3014 * @function
3015 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
3016 * @returns {number}
3017 * @expose
3018 */
3019 ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64;
3020
3021
3022 // types/varints/varint32
3023
3024 /**
3025 * Maximum number of bytes required to store a 32bit base 128 variable-length integer.
3026 * @type {number}
3027 * @const
3028 * @expose
3029 */
3030 ByteBuffer.MAX_VARINT32_BYTES = 5;
3031
3032 /**
3033 * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer.
3034 * @param {number} value Value to encode
3035 * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES}
3036 * @expose
3037 */
3038 ByteBuffer.calculateVarint32 = function(value) {
3039 // ref: src/google/protobuf/io/coded_stream.cc
3040 value = value >>> 0;
3041 if (value < 1 << 7 ) return 1;
3042 else if (value < 1 << 14) return 2;
3043 else if (value < 1 << 21) return 3;
3044 else if (value < 1 << 28) return 4;
3045 else return 5;
3046 };
3047
3048 /**
3049 * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding.
3050 * @param {number} n Signed 32bit integer
3051 * @returns {number} Unsigned zigzag encoded 32bit integer
3052 * @expose
3053 */
3054 ByteBuffer.zigZagEncode32 = function(n) {
3055 return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h
3056 };
3057
3058 /**
3059 * Decodes a zigzag encoded signed 32bit integer.
3060 * @param {number} n Unsigned zigzag encoded 32bit integer
3061 * @returns {number} Signed 32bit integer
3062 * @expose
3063 */
3064 ByteBuffer.zigZagDecode32 = function(n) {
3065 return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h
3066 };
3067
3068 /**
3069 * Writes a 32bit base 128 variable-length integer.
3070 * @param {number} value Value to write
3071 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3072 * written if omitted.
3073 * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
3074 * @expose
3075 */
3076 ByteBufferPrototype.writeVarint32 = function(value, offset) {
3077 var relative = typeof offset === 'undefined';
3078 if (relative) offset = this.offset;
3079 if (!this.noAssert) {
3080 if (typeof value !== 'number' || value % 1 !== 0)
3081 throw TypeError("Illegal value: "+value+" (not an integer)");
3082 value |= 0;
3083 if (typeof offset !== 'number' || offset % 1 !== 0)
3084 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3085 offset >>>= 0;
3086 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3087 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3088 }
3089 var size = ByteBuffer.calculateVarint32(value),
3090 b;
3091 offset += size;
3092 var capacity10 = this.buffer.byteLength;
3093 if (offset > capacity10)
3094 this.resize((capacity10 *= 2) > offset ? capacity10 : offset);
3095 offset -= size;
3096 value >>>= 0;
3097 while (value >= 0x80) {
3098 b = (value & 0x7f) | 0x80;
3099 this.view[offset++] = b;
3100 value >>>= 7;
3101 }
3102 this.view[offset++] = value;
3103 if (relative) {
3104 this.offset = offset;
3105 return this;
3106 }
3107 return size;
3108 };
3109
3110 /**
3111 * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer.
3112 * @param {number} value Value to write
3113 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3114 * written if omitted.
3115 * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
3116 * @expose
3117 */
3118 ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) {
3119 return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset);
3120 };
3121
3122 /**
3123 * Reads a 32bit base 128 variable-length integer.
3124 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3125 * written if omitted.
3126 * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
3127 * and the actual number of bytes read.
3128 * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available
3129 * to fully decode the varint.
3130 * @expose
3131 */
3132 ByteBufferPrototype.readVarint32 = function(offset) {
3133 var relative = typeof offset === 'undefined';
3134 if (relative) offset = this.offset;
3135 if (!this.noAssert) {
3136 if (typeof offset !== 'number' || offset % 1 !== 0)
3137 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3138 offset >>>= 0;
3139 if (offset < 0 || offset + 1 > this.buffer.byteLength)
3140 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
3141 }
3142 var c = 0,
3143 value = 0 >>> 0,
3144 b;
3145 do {
3146 if (!this.noAssert && offset > this.limit) {
3147 var err = Error("Truncated");
3148 err['truncated'] = true;
3149 throw err;
3150 }
3151 b = this.view[offset++];
3152 if (c < 5)
3153 value |= (b & 0x7f) << (7*c);
3154 ++c;
3155 } while ((b & 0x80) !== 0);
3156 value |= 0;
3157 if (relative) {
3158 this.offset = offset;
3159 return value;
3160 }
3161 return {
3162 "value": value,
3163 "length": c
3164 };
3165 };
3166
3167 /**
3168 * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer.
3169 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3170 * written if omitted.
3171 * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
3172 * and the actual number of bytes read.
3173 * @throws {Error} If it's not a valid varint
3174 * @expose
3175 */
3176 ByteBufferPrototype.readVarint32ZigZag = function(offset) {
3177 var val = this.readVarint32(offset);
3178 if (typeof val === 'object')
3179 val["value"] = ByteBuffer.zigZagDecode32(val["value"]);
3180 else
3181 val = ByteBuffer.zigZagDecode32(val);
3182 return val;
3183 };
3184
3185 // types/varints/varint64
3186
3187 if (Long) {
3188
3189 /**
3190 * Maximum number of bytes required to store a 64bit base 128 variable-length integer.
3191 * @type {number}
3192 * @const
3193 * @expose
3194 */
3195 ByteBuffer.MAX_VARINT64_BYTES = 10;
3196
3197 /**
3198 * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer.
3199 * @param {number|!Long} value Value to encode
3200 * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES}
3201 * @expose
3202 */
3203 ByteBuffer.calculateVarint64 = function(value) {
3204 if (typeof value === 'number')
3205 value = Long.fromNumber(value);
3206 else if (typeof value === 'string')
3207 value = Long.fromString(value);
3208 // ref: src/google/protobuf/io/coded_stream.cc
3209 var part0 = value.toInt() >>> 0,
3210 part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
3211 part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
3212 if (part2 == 0) {
3213 if (part1 == 0) {
3214 if (part0 < 1 << 14)
3215 return part0 < 1 << 7 ? 1 : 2;
3216 else
3217 return part0 < 1 << 21 ? 3 : 4;
3218 } else {
3219 if (part1 < 1 << 14)
3220 return part1 < 1 << 7 ? 5 : 6;
3221 else
3222 return part1 < 1 << 21 ? 7 : 8;
3223 }
3224 } else
3225 return part2 < 1 << 7 ? 9 : 10;
3226 };
3227
3228 /**
3229 * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding.
3230 * @param {number|!Long} value Signed long
3231 * @returns {!Long} Unsigned zigzag encoded long
3232 * @expose
3233 */
3234 ByteBuffer.zigZagEncode64 = function(value) {
3235 if (typeof value === 'number')
3236 value = Long.fromNumber(value, false);
3237 else if (typeof value === 'string')
3238 value = Long.fromString(value, false);
3239 else if (value.unsigned !== false) value = value.toSigned();
3240 // ref: src/google/protobuf/wire_format_lite.h
3241 return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned();
3242 };
3243
3244 /**
3245 * Decodes a zigzag encoded signed 64bit integer.
3246 * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number
3247 * @returns {!Long} Signed long
3248 * @expose
3249 */
3250 ByteBuffer.zigZagDecode64 = function(value) {
3251 if (typeof value === 'number')
3252 value = Long.fromNumber(value, false);
3253 else if (typeof value === 'string')
3254 value = Long.fromString(value, false);
3255 else if (value.unsigned !== false) value = value.toSigned();
3256 // ref: src/google/protobuf/wire_format_lite.h
3257 return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned();
3258 };
3259
3260 /**
3261 * Writes a 64bit base 128 variable-length integer.
3262 * @param {number|Long} value Value to write
3263 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3264 * written if omitted.
3265 * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
3266 * @expose
3267 */
3268 ByteBufferPrototype.writeVarint64 = function(value, offset) {
3269 var relative = typeof offset === 'undefined';
3270 if (relative) offset = this.offset;
3271 if (!this.noAssert) {
3272 if (typeof value === 'number')
3273 value = Long.fromNumber(value);
3274 else if (typeof value === 'string')
3275 value = Long.fromString(value);
3276 else if (!(value && value instanceof Long))
3277 throw TypeError("Illegal value: "+value+" (not an integer or Long)");
3278 if (typeof offset !== 'number' || offset % 1 !== 0)
3279 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3280 offset >>>= 0;
3281 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3282 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3283 }
3284 if (typeof value === 'number')
3285 value = Long.fromNumber(value, false);
3286 else if (typeof value === 'string')
3287 value = Long.fromString(value, false);
3288 else if (value.unsigned !== false) value = value.toSigned();
3289 var size = ByteBuffer.calculateVarint64(value),
3290 part0 = value.toInt() >>> 0,
3291 part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
3292 part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
3293 offset += size;
3294 var capacity11 = this.buffer.byteLength;
3295 if (offset > capacity11)
3296 this.resize((capacity11 *= 2) > offset ? capacity11 : offset);
3297 offset -= size;
3298 switch (size) {
3299 case 10: this.view[offset+9] = (part2 >>> 7) & 0x01;
3300 case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F;
3301 case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F;
3302 case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F;
3303 case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F;
3304 case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F;
3305 case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F;
3306 case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F;
3307 case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F;
3308 case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F;
3309 }
3310 if (relative) {
3311 this.offset += size;
3312 return this;
3313 } else {
3314 return size;
3315 }
3316 };
3317
3318 /**
3319 * Writes a zig-zag encoded 64bit base 128 variable-length integer.
3320 * @param {number|Long} value Value to write
3321 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3322 * written if omitted.
3323 * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
3324 * @expose
3325 */
3326 ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) {
3327 return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset);
3328 };
3329
3330 /**
3331 * Reads a 64bit base 128 variable-length integer. Requires Long.js.
3332 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3333 * read if omitted.
3334 * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
3335 * the actual number of bytes read.
3336 * @throws {Error} If it's not a valid varint
3337 * @expose
3338 */
3339 ByteBufferPrototype.readVarint64 = function(offset) {
3340 var relative = typeof offset === 'undefined';
3341 if (relative) offset = this.offset;
3342 if (!this.noAssert) {
3343 if (typeof offset !== 'number' || offset % 1 !== 0)
3344 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3345 offset >>>= 0;
3346 if (offset < 0 || offset + 1 > this.buffer.byteLength)
3347 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
3348 }
3349 // ref: src/google/protobuf/io/coded_stream.cc
3350 var start = offset,
3351 part0 = 0,
3352 part1 = 0,
3353 part2 = 0,
3354 b = 0;
3355 b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) {
3356 b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3357 b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3358 b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3359 b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3360 b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3361 b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3362 b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3363 b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3364 b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3365 throw Error("Buffer overrun"); }}}}}}}}}}
3366 var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
3367 if (relative) {
3368 this.offset = offset;
3369 return value;
3370 } else {
3371 return {
3372 'value': value,
3373 'length': offset-start
3374 };
3375 }
3376 };
3377
3378 /**
3379 * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js.
3380 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3381 * read if omitted.
3382 * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
3383 * the actual number of bytes read.
3384 * @throws {Error} If it's not a valid varint
3385 * @expose
3386 */
3387 ByteBufferPrototype.readVarint64ZigZag = function(offset) {
3388 var val = this.readVarint64(offset);
3389 if (val && val['value'] instanceof Long)
3390 val["value"] = ByteBuffer.zigZagDecode64(val["value"]);
3391 else
3392 val = ByteBuffer.zigZagDecode64(val);
3393 return val;
3394 };
3395
3396 } // Long
3397
3398
3399 // types/strings/cstring
3400
3401 /**
3402 * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL
3403 * characters itself.
3404 * @param {string} str String to write
3405 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3406 * contained in `str` + 1 if omitted.
3407 * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written
3408 * @expose
3409 */
3410 ByteBufferPrototype.writeCString = function(str, offset) {
3411 var relative = typeof offset === 'undefined';
3412 if (relative) offset = this.offset;
3413 var i,
3414 k = str.length;
3415 if (!this.noAssert) {
3416 if (typeof str !== 'string')
3417 throw TypeError("Illegal str: Not a string");
3418 for (i=0; i<k; ++i) {
3419 if (str.charCodeAt(i) === 0)
3420 throw RangeError("Illegal str: Contains NULL-characters");
3421 }
3422 if (typeof offset !== 'number' || offset % 1 !== 0)
3423 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3424 offset >>>= 0;
3425 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3426 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3427 }
3428 // UTF8 strings do not contain zero bytes in between except for the zero character, so:
3429 k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
3430 offset += k+1;
3431 var capacity12 = this.buffer.byteLength;
3432 if (offset > capacity12)
3433 this.resize((capacity12 *= 2) > offset ? capacity12 : offset);
3434 offset -= k+1;
3435 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3436 this.view[offset++] = b;
3437 }.bind(this));
3438 this.view[offset++] = 0;
3439 if (relative) {
3440 this.offset = offset;
3441 return this;
3442 }
3443 return k;
3444 };
3445
3446 /**
3447 * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters
3448 * itself.
3449 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3450 * read if omitted.
3451 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3452 * read and the actual number of bytes read.
3453 * @expose
3454 */
3455 ByteBufferPrototype.readCString = function(offset) {
3456 var relative = typeof offset === 'undefined';
3457 if (relative) offset = this.offset;
3458 if (!this.noAssert) {
3459 if (typeof offset !== 'number' || offset % 1 !== 0)
3460 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3461 offset >>>= 0;
3462 if (offset < 0 || offset + 1 > this.buffer.byteLength)
3463 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
3464 }
3465 var start = offset;
3466 // UTF8 strings do not contain zero bytes in between except for the zero character itself, so:
3467 var sd, b = -1;
3468 utfx.decodeUTF8toUTF16(function() {
3469 if (b === 0) return null;
3470 if (offset >= this.limit)
3471 throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit);
3472 b = this.view[offset++];
3473 return b === 0 ? null : b;
3474 }.bind(this), sd = stringDestination(), true);
3475 if (relative) {
3476 this.offset = offset;
3477 return sd();
3478 } else {
3479 return {
3480 "string": sd(),
3481 "length": offset - start
3482 };
3483 }
3484 };
3485
3486 // types/strings/istring
3487
3488 /**
3489 * Writes a length as uint32 prefixed UTF8 encoded string.
3490 * @param {string} str String to write
3491 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3492 * written if omitted.
3493 * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
3494 * @expose
3495 * @see ByteBuffer#writeVarint32
3496 */
3497 ByteBufferPrototype.writeIString = function(str, offset) {
3498 var relative = typeof offset === 'undefined';
3499 if (relative) offset = this.offset;
3500 if (!this.noAssert) {
3501 if (typeof str !== 'string')
3502 throw TypeError("Illegal str: Not a string");
3503 if (typeof offset !== 'number' || offset % 1 !== 0)
3504 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3505 offset >>>= 0;
3506 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3507 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3508 }
3509 var start = offset,
3510 k;
3511 k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
3512 offset += 4+k;
3513 var capacity13 = this.buffer.byteLength;
3514 if (offset > capacity13)
3515 this.resize((capacity13 *= 2) > offset ? capacity13 : offset);
3516 offset -= 4+k;
3517 if (this.littleEndian) {
3518 this.view[offset+3] = (k >>> 24) & 0xFF;
3519 this.view[offset+2] = (k >>> 16) & 0xFF;
3520 this.view[offset+1] = (k >>> 8) & 0xFF;
3521 this.view[offset ] = k & 0xFF;
3522 } else {
3523 this.view[offset ] = (k >>> 24) & 0xFF;
3524 this.view[offset+1] = (k >>> 16) & 0xFF;
3525 this.view[offset+2] = (k >>> 8) & 0xFF;
3526 this.view[offset+3] = k & 0xFF;
3527 }
3528 offset += 4;
3529 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3530 this.view[offset++] = b;
3531 }.bind(this));
3532 if (offset !== start + 4 + k)
3533 throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k));
3534 if (relative) {
3535 this.offset = offset;
3536 return this;
3537 }
3538 return offset - start;
3539 };
3540
3541 /**
3542 * Reads a length as uint32 prefixed UTF8 encoded string.
3543 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3544 * read if omitted.
3545 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3546 * read and the actual number of bytes read.
3547 * @expose
3548 * @see ByteBuffer#readVarint32
3549 */
3550 ByteBufferPrototype.readIString = function(offset) {
3551 var relative = typeof offset === 'undefined';
3552 if (relative) offset = this.offset;
3553 if (!this.noAssert) {
3554 if (typeof offset !== 'number' || offset % 1 !== 0)
3555 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3556 offset >>>= 0;
3557 if (offset < 0 || offset + 4 > this.buffer.byteLength)
3558 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
3559 }
3560 var start = offset;
3561 var len = this.readUint32(offset);
3562 var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4);
3563 offset += str['length'];
3564 if (relative) {
3565 this.offset = offset;
3566 return str['string'];
3567 } else {
3568 return {
3569 'string': str['string'],
3570 'length': offset - start
3571 };
3572 }
3573 };
3574
3575 // types/strings/utf8string
3576
3577 /**
3578 * Metrics representing number of UTF8 characters. Evaluates to `c`.
3579 * @type {string}
3580 * @const
3581 * @expose
3582 */
3583 ByteBuffer.METRICS_CHARS = 'c';
3584
3585 /**
3586 * Metrics representing number of bytes. Evaluates to `b`.
3587 * @type {string}
3588 * @const
3589 * @expose
3590 */
3591 ByteBuffer.METRICS_BYTES = 'b';
3592
3593 /**
3594 * Writes an UTF8 encoded string.
3595 * @param {string} str String to write
3596 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
3597 * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
3598 * @expose
3599 */
3600 ByteBufferPrototype.writeUTF8String = function(str, offset) {
3601 var relative = typeof offset === 'undefined';
3602 if (relative) offset = this.offset;
3603 if (!this.noAssert) {
3604 if (typeof offset !== 'number' || offset % 1 !== 0)
3605 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3606 offset >>>= 0;
3607 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3608 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3609 }
3610 var k;
3611 var start = offset;
3612 k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
3613 offset += k;
3614 var capacity14 = this.buffer.byteLength;
3615 if (offset > capacity14)
3616 this.resize((capacity14 *= 2) > offset ? capacity14 : offset);
3617 offset -= k;
3618 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3619 this.view[offset++] = b;
3620 }.bind(this));
3621 if (relative) {
3622 this.offset = offset;
3623 return this;
3624 }
3625 return offset - start;
3626 };
3627
3628 /**
3629 * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}.
3630 * @function
3631 * @param {string} str String to write
3632 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
3633 * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
3634 * @expose
3635 */
3636 ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String;
3637
3638 /**
3639 * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's
3640 * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF.
3641 * @param {string} str String to calculate
3642 * @returns {number} Number of UTF8 characters
3643 * @expose
3644 */
3645 ByteBuffer.calculateUTF8Chars = function(str) {
3646 return utfx.calculateUTF16asUTF8(stringSource(str))[0];
3647 };
3648
3649 /**
3650 * Calculates the number of UTF8 bytes of a string.
3651 * @param {string} str String to calculate
3652 * @returns {number} Number of UTF8 bytes
3653 * @expose
3654 */
3655 ByteBuffer.calculateUTF8Bytes = function(str) {
3656 return utfx.calculateUTF16asUTF8(stringSource(str))[1];
3657 };
3658
3659 /**
3660 * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}.
3661 * @function
3662 * @param {string} str String to calculate
3663 * @returns {number} Number of UTF8 bytes
3664 * @expose
3665 */
3666 ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes;
3667
3668 /**
3669 * Reads an UTF8 encoded string.
3670 * @param {number} length Number of characters or bytes to read.
3671 * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to
3672 * {@link ByteBuffer.METRICS_CHARS}.
3673 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3674 * read if omitted.
3675 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3676 * read and the actual number of bytes read.
3677 * @expose
3678 */
3679 ByteBufferPrototype.readUTF8String = function(length, metrics, offset) {
3680 if (typeof metrics === 'number') {
3681 offset = metrics;
3682 metrics = undefined;
3683 }
3684 var relative = typeof offset === 'undefined';
3685 if (relative) offset = this.offset;
3686 if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS;
3687 if (!this.noAssert) {
3688 if (typeof length !== 'number' || length % 1 !== 0)
3689 throw TypeError("Illegal length: "+length+" (not an integer)");
3690 length |= 0;
3691 if (typeof offset !== 'number' || offset % 1 !== 0)
3692 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3693 offset >>>= 0;
3694 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3695 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3696 }
3697 var i = 0,
3698 start = offset,
3699 sd;
3700 if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser
3701 sd = stringDestination();
3702 utfx.decodeUTF8(function() {
3703 return i < length && offset < this.limit ? this.view[offset++] : null;
3704 }.bind(this), function(cp) {
3705 ++i; utfx.UTF8toUTF16(cp, sd);
3706 });
3707 if (i !== length)
3708 throw RangeError("Illegal range: Truncated data, "+i+" == "+length);
3709 if (relative) {
3710 this.offset = offset;
3711 return sd();
3712 } else {
3713 return {
3714 "string": sd(),
3715 "length": offset - start
3716 };
3717 }
3718 } else if (metrics === ByteBuffer.METRICS_BYTES) {
3719 if (!this.noAssert) {
3720 if (typeof offset !== 'number' || offset % 1 !== 0)
3721 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3722 offset >>>= 0;
3723 if (offset < 0 || offset + length > this.buffer.byteLength)
3724 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
3725 }
3726 var k = offset + length;
3727 utfx.decodeUTF8toUTF16(function() {
3728 return offset < k ? this.view[offset++] : null;
3729 }.bind(this), sd = stringDestination(), this.noAssert);
3730 if (offset !== k)
3731 throw RangeError("Illegal range: Truncated data, "+offset+" == "+k);
3732 if (relative) {
3733 this.offset = offset;
3734 return sd();
3735 } else {
3736 return {
3737 'string': sd(),
3738 'length': offset - start
3739 };
3740 }
3741 } else
3742 throw TypeError("Unsupported metrics: "+metrics);
3743 };
3744
3745 /**
3746 * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}.
3747 * @function
3748 * @param {number} length Number of characters or bytes to read
3749 * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to
3750 * {@link ByteBuffer.METRICS_CHARS}.
3751 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3752 * read if omitted.
3753 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3754 * read and the actual number of bytes read.
3755 * @expose
3756 */
3757 ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String;
3758
3759 // types/strings/vstring
3760
3761 /**
3762 * Writes a length as varint32 prefixed UTF8 encoded string.
3763 * @param {string} str String to write
3764 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3765 * written if omitted.
3766 * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
3767 * @expose
3768 * @see ByteBuffer#writeVarint32
3769 */
3770 ByteBufferPrototype.writeVString = function(str, offset) {
3771 var relative = typeof offset === 'undefined';
3772 if (relative) offset = this.offset;
3773 if (!this.noAssert) {
3774 if (typeof str !== 'string')
3775 throw TypeError("Illegal str: Not a string");
3776 if (typeof offset !== 'number' || offset % 1 !== 0)
3777 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3778 offset >>>= 0;
3779 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3780 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3781 }
3782 var start = offset,
3783 k, l;
3784 k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
3785 l = ByteBuffer.calculateVarint32(k);
3786 offset += l+k;
3787 var capacity15 = this.buffer.byteLength;
3788 if (offset > capacity15)
3789 this.resize((capacity15 *= 2) > offset ? capacity15 : offset);
3790 offset -= l+k;
3791 offset += this.writeVarint32(k, offset);
3792 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3793 this.view[offset++] = b;
3794 }.bind(this));
3795 if (offset !== start+k+l)
3796 throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l));
3797 if (relative) {
3798 this.offset = offset;
3799 return this;
3800 }
3801 return offset - start;
3802 };
3803
3804 /**
3805 * Reads a length as varint32 prefixed UTF8 encoded string.
3806 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3807 * read if omitted.
3808 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3809 * read and the actual number of bytes read.
3810 * @expose
3811 * @see ByteBuffer#readVarint32
3812 */
3813 ByteBufferPrototype.readVString = function(offset) {
3814 var relative = typeof offset === 'undefined';
3815 if (relative) offset = this.offset;
3816 if (!this.noAssert) {
3817 if (typeof offset !== 'number' || offset % 1 !== 0)
3818 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3819 offset >>>= 0;
3820 if (offset < 0 || offset + 1 > this.buffer.byteLength)
3821 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
3822 }
3823 var start = offset;
3824 var len = this.readVarint32(offset);
3825 var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']);
3826 offset += str['length'];
3827 if (relative) {
3828 this.offset = offset;
3829 return str['string'];
3830 } else {
3831 return {
3832 'string': str['string'],
3833 'length': offset - start
3834 };
3835 }
3836 };
3837
3838
3839 /**
3840 * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
3841 * data's length.
3842 * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets
3843 * will be modified according to the performed read operation.
3844 * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
3845 * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3846 * written if omitted.
3847 * @returns {!ByteBuffer} this
3848 * @expose
3849 * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
3850 * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
3851 */
3852 ByteBufferPrototype.append = function(source, encoding, offset) {
3853 if (typeof encoding === 'number' || typeof encoding !== 'string') {
3854 offset = encoding;
3855 encoding = undefined;
3856 }
3857 var relative = typeof offset === 'undefined';
3858 if (relative) offset = this.offset;
3859 if (!this.noAssert) {
3860 if (typeof offset !== 'number' || offset % 1 !== 0)
3861 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3862 offset >>>= 0;
3863 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3864 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3865 }
3866 if (!(source instanceof ByteBuffer))
3867 source = ByteBuffer.wrap(source, encoding);
3868 var length = source.limit - source.offset;
3869 if (length <= 0) return this; // Nothing to append
3870 offset += length;
3871 var capacity16 = this.buffer.byteLength;
3872 if (offset > capacity16)
3873 this.resize((capacity16 *= 2) > offset ? capacity16 : offset);
3874 offset -= length;
3875 this.view.set(source.view.subarray(source.offset, source.limit), offset);
3876 source.offset += length;
3877 if (relative) this.offset += length;
3878 return this;
3879 };
3880
3881 /**
3882 * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
3883 specified offset up to the length of this ByteBuffer's data.
3884 * @param {!ByteBuffer} target Target ByteBuffer
3885 * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3886 * read if omitted.
3887 * @returns {!ByteBuffer} this
3888 * @expose
3889 * @see ByteBuffer#append
3890 */
3891 ByteBufferPrototype.appendTo = function(target, offset) {
3892 target.append(this, offset);
3893 return this;
3894 };
3895
3896 /**
3897 * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
3898 * disable them if your code already makes sure that everything is valid.
3899 * @param {boolean} assert `true` to enable assertions, otherwise `false`
3900 * @returns {!ByteBuffer} this
3901 * @expose
3902 */
3903 ByteBufferPrototype.assert = function(assert) {
3904 this.noAssert = !assert;
3905 return this;
3906 };
3907
3908 /**
3909 * Gets the capacity of this ByteBuffer's backing buffer.
3910 * @returns {number} Capacity of the backing buffer
3911 * @expose
3912 */
3913 ByteBufferPrototype.capacity = function() {
3914 return this.buffer.byteLength;
3915 };
3916 /**
3917 * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
3918 * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
3919 * @returns {!ByteBuffer} this
3920 * @expose
3921 */
3922 ByteBufferPrototype.clear = function() {
3923 this.offset = 0;
3924 this.limit = this.buffer.byteLength;
3925 this.markedOffset = -1;
3926 return this;
3927 };
3928
3929 /**
3930 * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
3931 * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
3932 * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
3933 * @returns {!ByteBuffer} Cloned instance
3934 * @expose
3935 */
3936 ByteBufferPrototype.clone = function(copy) {
3937 var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
3938 if (copy) {
3939 bb.buffer = new ArrayBuffer(this.buffer.byteLength);
3940 bb.view = new Uint8Array(bb.buffer);
3941 } else {
3942 bb.buffer = this.buffer;
3943 bb.view = this.view;
3944 }
3945 bb.offset = this.offset;
3946 bb.markedOffset = this.markedOffset;
3947 bb.limit = this.limit;
3948 return bb;
3949 };
3950
3951 /**
3952 * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
3953 * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
3954 * adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
3955 * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
3956 * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
3957 * @returns {!ByteBuffer} this
3958 * @expose
3959 */
3960 ByteBufferPrototype.compact = function(begin, end) {
3961 if (typeof begin === 'undefined') begin = this.offset;
3962 if (typeof end === 'undefined') end = this.limit;
3963 if (!this.noAssert) {
3964 if (typeof begin !== 'number' || begin % 1 !== 0)
3965 throw TypeError("Illegal begin: Not an integer");
3966 begin >>>= 0;
3967 if (typeof end !== 'number' || end % 1 !== 0)
3968 throw TypeError("Illegal end: Not an integer");
3969 end >>>= 0;
3970 if (begin < 0 || begin > end || end > this.buffer.byteLength)
3971 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
3972 }
3973 if (begin === 0 && end === this.buffer.byteLength)
3974 return this; // Already compacted
3975 var len = end - begin;
3976 if (len === 0) {
3977 this.buffer = EMPTY_BUFFER;
3978 this.view = null;
3979 if (this.markedOffset >= 0) this.markedOffset -= begin;
3980 this.offset = 0;
3981 this.limit = 0;
3982 return this;
3983 }
3984 var buffer = new ArrayBuffer(len);
3985 var view = new Uint8Array(buffer);
3986 view.set(this.view.subarray(begin, end));
3987 this.buffer = buffer;
3988 this.view = view;
3989 if (this.markedOffset >= 0) this.markedOffset -= begin;
3990 this.offset = 0;
3991 this.limit = len;
3992 return this;
3993 };
3994
3995 /**
3996 * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
3997 * {@link ByteBuffer#limit}.
3998 * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
3999 * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
4000 * @returns {!ByteBuffer} Copy
4001 * @expose
4002 */
4003 ByteBufferPrototype.copy = function(begin, end) {
4004 if (typeof begin === 'undefined') begin = this.offset;
4005 if (typeof end === 'undefined') end = this.limit;
4006 if (!this.noAssert) {
4007 if (typeof begin !== 'number' || begin % 1 !== 0)
4008 throw TypeError("Illegal begin: Not an integer");
4009 begin >>>= 0;
4010 if (typeof end !== 'number' || end % 1 !== 0)
4011 throw TypeError("Illegal end: Not an integer");
4012 end >>>= 0;
4013 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4014 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4015 }
4016 if (begin === end)
4017 return new ByteBuffer(0, this.littleEndian, this.noAssert);
4018 var capacity = end - begin,
4019 bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
4020 bb.offset = 0;
4021 bb.limit = capacity;
4022 if (bb.markedOffset >= 0) bb.markedOffset -= begin;
4023 this.copyTo(bb, 0, begin, end);
4024 return bb;
4025 };
4026
4027 /**
4028 * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
4029 * {@link ByteBuffer#limit}.
4030 * @param {!ByteBuffer} target Target ByteBuffer
4031 * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
4032 * by the number of bytes copied if omitted.
4033 * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
4034 * number of bytes copied if omitted.
4035 * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
4036 * @returns {!ByteBuffer} this
4037 * @expose
4038 */
4039 ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
4040 var relative,
4041 targetRelative;
4042 if (!this.noAssert) {
4043 if (!ByteBuffer.isByteBuffer(target))
4044 throw TypeError("Illegal target: Not a ByteBuffer");
4045 }
4046 targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
4047 sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
4048 sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
4049
4050 if (targetOffset < 0 || targetOffset > target.buffer.byteLength)
4051 throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength);
4052 if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength)
4053 throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength);
4054
4055 var len = sourceLimit - sourceOffset;
4056 if (len === 0)
4057 return target; // Nothing to copy
4058
4059 target.ensureCapacity(targetOffset + len);
4060
4061 target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset);
4062
4063 if (relative) this.offset += len;
4064 if (targetRelative) target.offset += len;
4065
4066 return this;
4067 };
4068
4069 /**
4070 * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
4071 * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
4072 * the required capacity will be used instead.
4073 * @param {number} capacity Required capacity
4074 * @returns {!ByteBuffer} this
4075 * @expose
4076 */
4077 ByteBufferPrototype.ensureCapacity = function(capacity) {
4078 var current = this.buffer.byteLength;
4079 if (current < capacity)
4080 return this.resize((current *= 2) > capacity ? current : capacity);
4081 return this;
4082 };
4083
4084 /**
4085 * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
4086 * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
4087 * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
4088 * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
4089 * written if omitted. defaults to {@link ByteBuffer#offset}.
4090 * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
4091 * @returns {!ByteBuffer} this
4092 * @expose
4093 * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
4094 */
4095 ByteBufferPrototype.fill = function(value, begin, end) {
4096 var relative = typeof begin === 'undefined';
4097 if (relative) begin = this.offset;
4098 if (typeof value === 'string' && value.length > 0)
4099 value = value.charCodeAt(0);
4100 if (typeof begin === 'undefined') begin = this.offset;
4101 if (typeof end === 'undefined') end = this.limit;
4102 if (!this.noAssert) {
4103 if (typeof value !== 'number' || value % 1 !== 0)
4104 throw TypeError("Illegal value: "+value+" (not an integer)");
4105 value |= 0;
4106 if (typeof begin !== 'number' || begin % 1 !== 0)
4107 throw TypeError("Illegal begin: Not an integer");
4108 begin >>>= 0;
4109 if (typeof end !== 'number' || end % 1 !== 0)
4110 throw TypeError("Illegal end: Not an integer");
4111 end >>>= 0;
4112 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4113 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4114 }
4115 if (begin >= end)
4116 return this; // Nothing to fill
4117 while (begin < end) this.view[begin++] = value;
4118 if (relative) this.offset = begin;
4119 return this;
4120 };
4121
4122 /**
4123 * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
4124 * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
4125 * @returns {!ByteBuffer} this
4126 * @expose
4127 */
4128 ByteBufferPrototype.flip = function() {
4129 this.limit = this.offset;
4130 this.offset = 0;
4131 return this;
4132 };
4133 /**
4134 * Marks an offset on this ByteBuffer to be used later.
4135 * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
4136 * @returns {!ByteBuffer} this
4137 * @throws {TypeError} If `offset` is not a valid number
4138 * @throws {RangeError} If `offset` is out of bounds
4139 * @see ByteBuffer#reset
4140 * @expose
4141 */
4142 ByteBufferPrototype.mark = function(offset) {
4143 offset = typeof offset === 'undefined' ? this.offset : offset;
4144 if (!this.noAssert) {
4145 if (typeof offset !== 'number' || offset % 1 !== 0)
4146 throw TypeError("Illegal offset: "+offset+" (not an integer)");
4147 offset >>>= 0;
4148 if (offset < 0 || offset + 0 > this.buffer.byteLength)
4149 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
4150 }
4151 this.markedOffset = offset;
4152 return this;
4153 };
4154 /**
4155 * Sets the byte order.
4156 * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
4157 * @returns {!ByteBuffer} this
4158 * @expose
4159 */
4160 ByteBufferPrototype.order = function(littleEndian) {
4161 if (!this.noAssert) {
4162 if (typeof littleEndian !== 'boolean')
4163 throw TypeError("Illegal littleEndian: Not a boolean");
4164 }
4165 this.littleEndian = !!littleEndian;
4166 return this;
4167 };
4168
4169 /**
4170 * Switches (to) little endian byte order.
4171 * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
4172 * @returns {!ByteBuffer} this
4173 * @expose
4174 */
4175 ByteBufferPrototype.LE = function(littleEndian) {
4176 this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
4177 return this;
4178 };
4179
4180 /**
4181 * Switches (to) big endian byte order.
4182 * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
4183 * @returns {!ByteBuffer} this
4184 * @expose
4185 */
4186 ByteBufferPrototype.BE = function(bigEndian) {
4187 this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
4188 return this;
4189 };
4190 /**
4191 * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
4192 * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
4193 * will be resized and its contents moved accordingly.
4194 * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
4195 * modified according to the performed read operation.
4196 * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
4197 * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
4198 * prepended if omitted.
4199 * @returns {!ByteBuffer} this
4200 * @expose
4201 * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
4202 * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
4203 */
4204 ByteBufferPrototype.prepend = function(source, encoding, offset) {
4205 if (typeof encoding === 'number' || typeof encoding !== 'string') {
4206 offset = encoding;
4207 encoding = undefined;
4208 }
4209 var relative = typeof offset === 'undefined';
4210 if (relative) offset = this.offset;
4211 if (!this.noAssert) {
4212 if (typeof offset !== 'number' || offset % 1 !== 0)
4213 throw TypeError("Illegal offset: "+offset+" (not an integer)");
4214 offset >>>= 0;
4215 if (offset < 0 || offset + 0 > this.buffer.byteLength)
4216 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
4217 }
4218 if (!(source instanceof ByteBuffer))
4219 source = ByteBuffer.wrap(source, encoding);
4220 var len = source.limit - source.offset;
4221 if (len <= 0) return this; // Nothing to prepend
4222 var diff = len - offset;
4223 if (diff > 0) { // Not enough space before offset, so resize + move
4224 var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
4225 var view = new Uint8Array(buffer);
4226 view.set(this.view.subarray(offset, this.buffer.byteLength), len);
4227 this.buffer = buffer;
4228 this.view = view;
4229 this.offset += diff;
4230 if (this.markedOffset >= 0) this.markedOffset += diff;
4231 this.limit += diff;
4232 offset += diff;
4233 } else {
4234 var arrayView = new Uint8Array(this.buffer);
4235 }
4236 this.view.set(source.view.subarray(source.offset, source.limit), offset - len);
4237
4238 source.offset = source.limit;
4239 if (relative)
4240 this.offset -= len;
4241 return this;
4242 };
4243
4244 /**
4245 * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
4246 * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
4247 * will be resized and its contents moved accordingly.
4248 * @param {!ByteBuffer} target Target ByteBuffer
4249 * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
4250 * prepended if omitted.
4251 * @returns {!ByteBuffer} this
4252 * @expose
4253 * @see ByteBuffer#prepend
4254 */
4255 ByteBufferPrototype.prependTo = function(target, offset) {
4256 target.prepend(this, offset);
4257 return this;
4258 };
4259 /**
4260 * Prints debug information about this ByteBuffer's contents.
4261 * @param {function(string)=} out Output function to call, defaults to console.log
4262 * @expose
4263 */
4264 ByteBufferPrototype.printDebug = function(out) {
4265 if (typeof out !== 'function') out = console.log.bind(console);
4266 out(
4267 this.toString()+"\n"+
4268 "-------------------------------------------------------------------\n"+
4269 this.toDebug(/* columns */ true)
4270 );
4271 };
4272
4273 /**
4274 * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
4275 * {@link ByteBuffer#limit}, so this returns `limit - offset`.
4276 * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
4277 * @expose
4278 */
4279 ByteBufferPrototype.remaining = function() {
4280 return this.limit - this.offset;
4281 };
4282 /**
4283 * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
4284 * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
4285 * marked, sets `offset = 0`.
4286 * @returns {!ByteBuffer} this
4287 * @see ByteBuffer#mark
4288 * @expose
4289 */
4290 ByteBufferPrototype.reset = function() {
4291 if (this.markedOffset >= 0) {
4292 this.offset = this.markedOffset;
4293 this.markedOffset = -1;
4294 } else {
4295 this.offset = 0;
4296 }
4297 return this;
4298 };
4299 /**
4300 * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
4301 * large or larger.
4302 * @param {number} capacity Capacity required
4303 * @returns {!ByteBuffer} this
4304 * @throws {TypeError} If `capacity` is not a number
4305 * @throws {RangeError} If `capacity < 0`
4306 * @expose
4307 */
4308 ByteBufferPrototype.resize = function(capacity) {
4309 if (!this.noAssert) {
4310 if (typeof capacity !== 'number' || capacity % 1 !== 0)
4311 throw TypeError("Illegal capacity: "+capacity+" (not an integer)");
4312 capacity |= 0;
4313 if (capacity < 0)
4314 throw RangeError("Illegal capacity: 0 <= "+capacity);
4315 }
4316 if (this.buffer.byteLength < capacity) {
4317 var buffer = new ArrayBuffer(capacity);
4318 var view = new Uint8Array(buffer);
4319 view.set(this.view);
4320 this.buffer = buffer;
4321 this.view = view;
4322 }
4323 return this;
4324 };
4325 /**
4326 * Reverses this ByteBuffer's contents.
4327 * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
4328 * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
4329 * @returns {!ByteBuffer} this
4330 * @expose
4331 */
4332 ByteBufferPrototype.reverse = function(begin, end) {
4333 if (typeof begin === 'undefined') begin = this.offset;
4334 if (typeof end === 'undefined') end = this.limit;
4335 if (!this.noAssert) {
4336 if (typeof begin !== 'number' || begin % 1 !== 0)
4337 throw TypeError("Illegal begin: Not an integer");
4338 begin >>>= 0;
4339 if (typeof end !== 'number' || end % 1 !== 0)
4340 throw TypeError("Illegal end: Not an integer");
4341 end >>>= 0;
4342 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4343 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4344 }
4345 if (begin === end)
4346 return this; // Nothing to reverse
4347 Array.prototype.reverse.call(this.view.subarray(begin, end));
4348 return this;
4349 };
4350 /**
4351 * Skips the next `length` bytes. This will just advance
4352 * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
4353 * @returns {!ByteBuffer} this
4354 * @expose
4355 */
4356 ByteBufferPrototype.skip = function(length) {
4357 if (!this.noAssert) {
4358 if (typeof length !== 'number' || length % 1 !== 0)
4359 throw TypeError("Illegal length: "+length+" (not an integer)");
4360 length |= 0;
4361 }
4362 var offset = this.offset + length;
4363 if (!this.noAssert) {
4364 if (offset < 0 || offset > this.buffer.byteLength)
4365 throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength);
4366 }
4367 this.offset = offset;
4368 return this;
4369 };
4370
4371 /**
4372 * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
4373 * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
4374 * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
4375 * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
4376 * @expose
4377 */
4378 ByteBufferPrototype.slice = function(begin, end) {
4379 if (typeof begin === 'undefined') begin = this.offset;
4380 if (typeof end === 'undefined') end = this.limit;
4381 if (!this.noAssert) {
4382 if (typeof begin !== 'number' || begin % 1 !== 0)
4383 throw TypeError("Illegal begin: Not an integer");
4384 begin >>>= 0;
4385 if (typeof end !== 'number' || end % 1 !== 0)
4386 throw TypeError("Illegal end: Not an integer");
4387 end >>>= 0;
4388 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4389 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4390 }
4391 var bb = this.clone();
4392 bb.offset = begin;
4393 bb.limit = end;
4394 return bb;
4395 };
4396 /**
4397 * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
4398 * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
4399 * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
4400 * possible. Defaults to `false`
4401 * @returns {!ArrayBuffer} Contents as an ArrayBuffer
4402 * @expose
4403 */
4404 ByteBufferPrototype.toBuffer = function(forceCopy) {
4405 var offset = this.offset,
4406 limit = this.limit;
4407 if (!this.noAssert) {
4408 if (typeof offset !== 'number' || offset % 1 !== 0)
4409 throw TypeError("Illegal offset: Not an integer");
4410 offset >>>= 0;
4411 if (typeof limit !== 'number' || limit % 1 !== 0)
4412 throw TypeError("Illegal limit: Not an integer");
4413 limit >>>= 0;
4414 if (offset < 0 || offset > limit || limit > this.buffer.byteLength)
4415 throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength);
4416 }
4417 // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
4418 // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
4419 if (!forceCopy && offset === 0 && limit === this.buffer.byteLength)
4420 return this.buffer;
4421 if (offset === limit)
4422 return EMPTY_BUFFER;
4423 var buffer = new ArrayBuffer(limit - offset);
4424 new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
4425 return buffer;
4426 };
4427
4428 /**
4429 * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
4430 * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
4431 * @function
4432 * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
4433 * Defaults to `false`
4434 * @returns {!ArrayBuffer} Contents as an ArrayBuffer
4435 * @expose
4436 */
4437 ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
4438
4439 /**
4440 * Converts the ByteBuffer's contents to a string.
4441 * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
4442 * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
4443 * highlighted offsets.
4444 * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
4445 * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
4446 * @returns {string} String representation
4447 * @throws {Error} If `encoding` is invalid
4448 * @expose
4449 */
4450 ByteBufferPrototype.toString = function(encoding, begin, end) {
4451 if (typeof encoding === 'undefined')
4452 return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
4453 if (typeof encoding === 'number')
4454 encoding = "utf8",
4455 begin = encoding,
4456 end = begin;
4457 switch (encoding) {
4458 case "utf8":
4459 return this.toUTF8(begin, end);
4460 case "base64":
4461 return this.toBase64(begin, end);
4462 case "hex":
4463 return this.toHex(begin, end);
4464 case "binary":
4465 return this.toBinary(begin, end);
4466 case "debug":
4467 return this.toDebug();
4468 case "columns":
4469 return this.toColumns();
4470 default:
4471 throw Error("Unsupported encoding: "+encoding);
4472 }
4473 };
4474
4475 // lxiv-embeddable
4476
4477 /**
4478 * lxiv-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
4479 * Released under the Apache License, Version 2.0
4480 * see: https://github.com/dcodeIO/lxiv for details
4481 */
4482 var lxiv = function() {
4483
4484 /**
4485 * lxiv namespace.
4486 * @type {!Object.<string,*>}
4487 * @exports lxiv
4488 */
4489 var lxiv = {};
4490
4491 /**
4492 * Character codes for output.
4493 * @type {!Array.<number>}
4494 * @inner
4495 */
4496 var aout = [
4497 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
4498 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
4499 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
4500 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
4501 ];
4502
4503 /**
4504 * Character codes for input.
4505 * @type {!Array.<number>}
4506 * @inner
4507 */
4508 var ain = [];
4509 for (var i=0, k=aout.length; i<k; ++i)
4510 ain[aout[i]] = i;
4511
4512 /**
4513 * Encodes bytes to base64 char codes.
4514 * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if
4515 * there are no more bytes left.
4516 * @param {!function(number)} dst Characters destination as a function successively called with each encoded char
4517 * code.
4518 */
4519 lxiv.encode = function(src, dst) {
4520 var b, t;
4521 while ((b = src()) !== null) {
4522 dst(aout[(b>>2)&0x3f]);
4523 t = (b&0x3)<<4;
4524 if ((b = src()) !== null) {
4525 t |= (b>>4)&0xf;
4526 dst(aout[(t|((b>>4)&0xf))&0x3f]);
4527 t = (b&0xf)<<2;
4528 if ((b = src()) !== null)
4529 dst(aout[(t|((b>>6)&0x3))&0x3f]),
4530 dst(aout[b&0x3f]);
4531 else
4532 dst(aout[t&0x3f]),
4533 dst(61);
4534 } else
4535 dst(aout[t&0x3f]),
4536 dst(61),
4537 dst(61);
4538 }
4539 };
4540
4541 /**
4542 * Decodes base64 char codes to bytes.
4543 * @param {!function():number|null} src Characters source as a function returning the next char code respectively
4544 * `null` if there are no more characters left.
4545 * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
4546 * @throws {Error} If a character code is invalid
4547 */
4548 lxiv.decode = function(src, dst) {
4549 var c, t1, t2;
4550 function fail(c) {
4551 throw Error("Illegal character code: "+c);
4552 }
4553 while ((c = src()) !== null) {
4554 t1 = ain[c];
4555 if (typeof t1 === 'undefined') fail(c);
4556 if ((c = src()) !== null) {
4557 t2 = ain[c];
4558 if (typeof t2 === 'undefined') fail(c);
4559 dst((t1<<2)>>>0|(t2&0x30)>>4);
4560 if ((c = src()) !== null) {
4561 t1 = ain[c];
4562 if (typeof t1 === 'undefined')
4563 if (c === 61) break; else fail(c);
4564 dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2);
4565 if ((c = src()) !== null) {
4566 t2 = ain[c];
4567 if (typeof t2 === 'undefined')
4568 if (c === 61) break; else fail(c);
4569 dst(((t1&0x3)<<6)>>>0|t2);
4570 }
4571 }
4572 }
4573 }
4574 };
4575
4576 /**
4577 * Tests if a string is valid base64.
4578 * @param {string} str String to test
4579 * @returns {boolean} `true` if valid, otherwise `false`
4580 */
4581 lxiv.test = function(str) {
4582 return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str);
4583 };
4584
4585 return lxiv;
4586 }();
4587
4588 // encodings/base64
4589
4590 /**
4591 * Encodes this ByteBuffer's contents to a base64 encoded string.
4592 * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}.
4593 * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}.
4594 * @returns {string} Base64 encoded string
4595 * @throws {RangeError} If `begin` or `end` is out of bounds
4596 * @expose
4597 */
4598 ByteBufferPrototype.toBase64 = function(begin, end) {
4599 if (typeof begin === 'undefined')
4600 begin = this.offset;
4601 if (typeof end === 'undefined')
4602 end = this.limit;
4603 begin = begin | 0; end = end | 0;
4604 if (begin < 0 || end > this.capacity || begin > end)
4605 throw RangeError("begin, end");
4606 var sd; lxiv.encode(function() {
4607 return begin < end ? this.view[begin++] : null;
4608 }.bind(this), sd = stringDestination());
4609 return sd();
4610 };
4611
4612 /**
4613 * Decodes a base64 encoded string to a ByteBuffer.
4614 * @param {string} str String to decode
4615 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4616 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4617 * @returns {!ByteBuffer} ByteBuffer
4618 * @expose
4619 */
4620 ByteBuffer.fromBase64 = function(str, littleEndian) {
4621 if (typeof str !== 'string')
4622 throw TypeError("str");
4623 var bb = new ByteBuffer(str.length/4*3, littleEndian),
4624 i = 0;
4625 lxiv.decode(stringSource(str), function(b) {
4626 bb.view[i++] = b;
4627 });
4628 bb.limit = i;
4629 return bb;
4630 };
4631
4632 /**
4633 * Encodes a binary string to base64 like `window.btoa` does.
4634 * @param {string} str Binary string
4635 * @returns {string} Base64 encoded string
4636 * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
4637 * @expose
4638 */
4639 ByteBuffer.btoa = function(str) {
4640 return ByteBuffer.fromBinary(str).toBase64();
4641 };
4642
4643 /**
4644 * Decodes a base64 encoded string to binary like `window.atob` does.
4645 * @param {string} b64 Base64 encoded string
4646 * @returns {string} Binary string
4647 * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
4648 * @expose
4649 */
4650 ByteBuffer.atob = function(b64) {
4651 return ByteBuffer.fromBase64(b64).toBinary();
4652 };
4653
4654 // encodings/binary
4655
4656 /**
4657 * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes.
4658 * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
4659 * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
4660 * @returns {string} Binary encoded string
4661 * @throws {RangeError} If `offset > limit`
4662 * @expose
4663 */
4664 ByteBufferPrototype.toBinary = function(begin, end) {
4665 if (typeof begin === 'undefined')
4666 begin = this.offset;
4667 if (typeof end === 'undefined')
4668 end = this.limit;
4669 begin |= 0; end |= 0;
4670 if (begin < 0 || end > this.capacity() || begin > end)
4671 throw RangeError("begin, end");
4672 if (begin === end)
4673 return "";
4674 var chars = [],
4675 parts = [];
4676 while (begin < end) {
4677 chars.push(this.view[begin++]);
4678 if (chars.length >= 1024)
4679 parts.push(String.fromCharCode.apply(String, chars)),
4680 chars = [];
4681 }
4682 return parts.join('') + String.fromCharCode.apply(String, chars);
4683 };
4684
4685 /**
4686 * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer.
4687 * @param {string} str String to decode
4688 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4689 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4690 * @returns {!ByteBuffer} ByteBuffer
4691 * @expose
4692 */
4693 ByteBuffer.fromBinary = function(str, littleEndian) {
4694 if (typeof str !== 'string')
4695 throw TypeError("str");
4696 var i = 0,
4697 k = str.length,
4698 charCode,
4699 bb = new ByteBuffer(k, littleEndian);
4700 while (i<k) {
4701 charCode = str.charCodeAt(i);
4702 if (charCode > 0xff)
4703 throw RangeError("illegal char code: "+charCode);
4704 bb.view[i++] = charCode;
4705 }
4706 bb.limit = k;
4707 return bb;
4708 };
4709
4710 // encodings/debug
4711
4712 /**
4713 * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are:
4714 * * `<` : offset,
4715 * * `'` : markedOffset,
4716 * * `>` : limit,
4717 * * `|` : offset and limit,
4718 * * `[` : offset and markedOffset,
4719 * * `]` : markedOffset and limit,
4720 * * `!` : offset, markedOffset and limit
4721 * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false`
4722 * @returns {string|!Array.<string>} Debug string or array of lines if `asArray = true`
4723 * @expose
4724 * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3`
4725 * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4`
4726 * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1`
4727 * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1`
4728 */
4729 ByteBufferPrototype.toDebug = function(columns) {
4730 var i = -1,
4731 k = this.buffer.byteLength,
4732 b,
4733 hex = "",
4734 asc = "",
4735 out = "";
4736 while (i<k) {
4737 if (i !== -1) {
4738 b = this.view[i];
4739 if (b < 0x10) hex += "0"+b.toString(16).toUpperCase();
4740 else hex += b.toString(16).toUpperCase();
4741 if (columns)
4742 asc += b > 32 && b < 127 ? String.fromCharCode(b) : '.';
4743 }
4744 ++i;
4745 if (columns) {
4746 if (i > 0 && i % 16 === 0 && i !== k) {
4747 while (hex.length < 3*16+3) hex += " ";
4748 out += hex+asc+"\n";
4749 hex = asc = "";
4750 }
4751 }
4752 if (i === this.offset && i === this.limit)
4753 hex += i === this.markedOffset ? "!" : "|";
4754 else if (i === this.offset)
4755 hex += i === this.markedOffset ? "[" : "<";
4756 else if (i === this.limit)
4757 hex += i === this.markedOffset ? "]" : ">";
4758 else
4759 hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : "");
4760 }
4761 if (columns && hex !== " ") {
4762 while (hex.length < 3*16+3)
4763 hex += " ";
4764 out += hex + asc + "\n";
4765 }
4766 return columns ? out : hex;
4767 };
4768
4769 /**
4770 * Decodes a hex encoded string with marked offsets to a ByteBuffer.
4771 * @param {string} str Debug string to decode (not be generated with `columns = true`)
4772 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4773 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4774 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
4775 * {@link ByteBuffer.DEFAULT_NOASSERT}.
4776 * @returns {!ByteBuffer} ByteBuffer
4777 * @expose
4778 * @see ByteBuffer#toDebug
4779 */
4780 ByteBuffer.fromDebug = function(str, littleEndian, noAssert) {
4781 var k = str.length,
4782 bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert);
4783 var i = 0, j = 0, ch, b,
4784 rs = false, // Require symbol next
4785 ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)?
4786 fail = false;
4787 while (i<k) {
4788 switch (ch = str.charAt(i++)) {
4789 case '!':
4790 if (!noAssert) {
4791 if (ho || hm || hl) {
4792 fail = true;
4793 break;
4794 }
4795 ho = hm = hl = true;
4796 }
4797 bb.offset = bb.markedOffset = bb.limit = j;
4798 rs = false;
4799 break;
4800 case '|':
4801 if (!noAssert) {
4802 if (ho || hl) {
4803 fail = true;
4804 break;
4805 }
4806 ho = hl = true;
4807 }
4808 bb.offset = bb.limit = j;
4809 rs = false;
4810 break;
4811 case '[':
4812 if (!noAssert) {
4813 if (ho || hm) {
4814 fail = true;
4815 break;
4816 }
4817 ho = hm = true;
4818 }
4819 bb.offset = bb.markedOffset = j;
4820 rs = false;
4821 break;
4822 case '<':
4823 if (!noAssert) {
4824 if (ho) {
4825 fail = true;
4826 break;
4827 }
4828 ho = true;
4829 }
4830 bb.offset = j;
4831 rs = false;
4832 break;
4833 case ']':
4834 if (!noAssert) {
4835 if (hl || hm) {
4836 fail = true;
4837 break;
4838 }
4839 hl = hm = true;
4840 }
4841 bb.limit = bb.markedOffset = j;
4842 rs = false;
4843 break;
4844 case '>':
4845 if (!noAssert) {
4846 if (hl) {
4847 fail = true;
4848 break;
4849 }
4850 hl = true;
4851 }
4852 bb.limit = j;
4853 rs = false;
4854 break;
4855 case "'":
4856 if (!noAssert) {
4857 if (hm) {
4858 fail = true;
4859 break;
4860 }
4861 hm = true;
4862 }
4863 bb.markedOffset = j;
4864 rs = false;
4865 break;
4866 case ' ':
4867 rs = false;
4868 break;
4869 default:
4870 if (!noAssert) {
4871 if (rs) {
4872 fail = true;
4873 break;
4874 }
4875 }
4876 b = parseInt(ch+str.charAt(i++), 16);
4877 if (!noAssert) {
4878 if (isNaN(b) || b < 0 || b > 255)
4879 throw TypeError("Illegal str: Not a debug encoded string");
4880 }
4881 bb.view[j++] = b;
4882 rs = true;
4883 }
4884 if (fail)
4885 throw TypeError("Illegal str: Invalid symbol at "+i);
4886 }
4887 if (!noAssert) {
4888 if (!ho || !hl)
4889 throw TypeError("Illegal str: Missing offset or limit");
4890 if (j<bb.buffer.byteLength)
4891 throw TypeError("Illegal str: Not a debug encoded string (is it hex?) "+j+" < "+k);
4892 }
4893 return bb;
4894 };
4895
4896 // encodings/hex
4897
4898 /**
4899 * Encodes this ByteBuffer's contents to a hex encoded string.
4900 * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
4901 * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
4902 * @returns {string} Hex encoded string
4903 * @expose
4904 */
4905 ByteBufferPrototype.toHex = function(begin, end) {
4906 begin = typeof begin === 'undefined' ? this.offset : begin;
4907 end = typeof end === 'undefined' ? this.limit : end;
4908 if (!this.noAssert) {
4909 if (typeof begin !== 'number' || begin % 1 !== 0)
4910 throw TypeError("Illegal begin: Not an integer");
4911 begin >>>= 0;
4912 if (typeof end !== 'number' || end % 1 !== 0)
4913 throw TypeError("Illegal end: Not an integer");
4914 end >>>= 0;
4915 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4916 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4917 }
4918 var out = new Array(end - begin),
4919 b;
4920 while (begin < end) {
4921 b = this.view[begin++];
4922 if (b < 0x10)
4923 out.push("0", b.toString(16));
4924 else out.push(b.toString(16));
4925 }
4926 return out.join('');
4927 };
4928
4929 /**
4930 * Decodes a hex encoded string to a ByteBuffer.
4931 * @param {string} str String to decode
4932 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4933 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4934 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
4935 * {@link ByteBuffer.DEFAULT_NOASSERT}.
4936 * @returns {!ByteBuffer} ByteBuffer
4937 * @expose
4938 */
4939 ByteBuffer.fromHex = function(str, littleEndian, noAssert) {
4940 if (!noAssert) {
4941 if (typeof str !== 'string')
4942 throw TypeError("Illegal str: Not a string");
4943 if (str.length % 2 !== 0)
4944 throw TypeError("Illegal str: Length not a multiple of 2");
4945 }
4946 var k = str.length,
4947 bb = new ByteBuffer((k / 2) | 0, littleEndian),
4948 b;
4949 for (var i=0, j=0; i<k; i+=2) {
4950 b = parseInt(str.substring(i, i+2), 16);
4951 if (!noAssert)
4952 if (!isFinite(b) || b < 0 || b > 255)
4953 throw TypeError("Illegal str: Contains non-hex characters");
4954 bb.view[j++] = b;
4955 }
4956 bb.limit = j;
4957 return bb;
4958 };
4959
4960 // utfx-embeddable
4961
4962 /**
4963 * utfx-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
4964 * Released under the Apache License, Version 2.0
4965 * see: https://github.com/dcodeIO/utfx for details
4966 */
4967 var utfx = function() {
4968
4969 /**
4970 * utfx namespace.
4971 * @inner
4972 * @type {!Object.<string,*>}
4973 */
4974 var utfx = {};
4975
4976 /**
4977 * Maximum valid code point.
4978 * @type {number}
4979 * @const
4980 */
4981 utfx.MAX_CODEPOINT = 0x10FFFF;
4982
4983 /**
4984 * Encodes UTF8 code points to UTF8 bytes.
4985 * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
4986 * respectively `null` if there are no more code points left or a single numeric code point.
4987 * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
4988 */
4989 utfx.encodeUTF8 = function(src, dst) {
4990 var cp = null;
4991 if (typeof src === 'number')
4992 cp = src,
4993 src = function() { return null; };
4994 while (cp !== null || (cp = src()) !== null) {
4995 if (cp < 0x80)
4996 dst(cp&0x7F);
4997 else if (cp < 0x800)
4998 dst(((cp>>6)&0x1F)|0xC0),
4999 dst((cp&0x3F)|0x80);
5000 else if (cp < 0x10000)
5001 dst(((cp>>12)&0x0F)|0xE0),
5002 dst(((cp>>6)&0x3F)|0x80),
5003 dst((cp&0x3F)|0x80);
5004 else
5005 dst(((cp>>18)&0x07)|0xF0),
5006 dst(((cp>>12)&0x3F)|0x80),
5007 dst(((cp>>6)&0x3F)|0x80),
5008 dst((cp&0x3F)|0x80);
5009 cp = null;
5010 }
5011 };
5012
5013 /**
5014 * Decodes UTF8 bytes to UTF8 code points.
5015 * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
5016 * are no more bytes left.
5017 * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
5018 * @throws {RangeError} If a starting byte is invalid in UTF8
5019 * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
5020 * remaining bytes.
5021 */
5022 utfx.decodeUTF8 = function(src, dst) {
5023 var a, b, c, d, fail = function(b) {
5024 b = b.slice(0, b.indexOf(null));
5025 var err = Error(b.toString());
5026 err.name = "TruncatedError";
5027 err['bytes'] = b;
5028 throw err;
5029 };
5030 while ((a = src()) !== null) {
5031 if ((a&0x80) === 0)
5032 dst(a);
5033 else if ((a&0xE0) === 0xC0)
5034 ((b = src()) === null) && fail([a, b]),
5035 dst(((a&0x1F)<<6) | (b&0x3F));
5036 else if ((a&0xF0) === 0xE0)
5037 ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
5038 dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
5039 else if ((a&0xF8) === 0xF0)
5040 ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
5041 dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
5042 else throw RangeError("Illegal starting byte: "+a);
5043 }
5044 };
5045
5046 /**
5047 * Converts UTF16 characters to UTF8 code points.
5048 * @param {!function():number|null} src Characters source as a function returning the next char code respectively
5049 * `null` if there are no more characters left.
5050 * @param {!function(number)} dst Code points destination as a function successively called with each converted code
5051 * point.
5052 */
5053 utfx.UTF16toUTF8 = function(src, dst) {
5054 var c1, c2 = null;
5055 while (true) {
5056 if ((c1 = c2 !== null ? c2 : src()) === null)
5057 break;
5058 if (c1 >= 0xD800 && c1 <= 0xDFFF) {
5059 if ((c2 = src()) !== null) {
5060 if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
5061 dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
5062 c2 = null; continue;
5063 }
5064 }
5065 }
5066 dst(c1);
5067 }
5068 if (c2 !== null) dst(c2);
5069 };
5070
5071 /**
5072 * Converts UTF8 code points to UTF16 characters.
5073 * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
5074 * respectively `null` if there are no more code points left or a single numeric code point.
5075 * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
5076 * @throws {RangeError} If a code point is out of range
5077 */
5078 utfx.UTF8toUTF16 = function(src, dst) {
5079 var cp = null;
5080 if (typeof src === 'number')
5081 cp = src, src = function() { return null; };
5082 while (cp !== null || (cp = src()) !== null) {
5083 if (cp <= 0xFFFF)
5084 dst(cp);
5085 else
5086 cp -= 0x10000,
5087 dst((cp>>10)+0xD800),
5088 dst((cp%0x400)+0xDC00);
5089 cp = null;
5090 }
5091 };
5092
5093 /**
5094 * Converts and encodes UTF16 characters to UTF8 bytes.
5095 * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
5096 * if there are no more characters left.
5097 * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
5098 */
5099 utfx.encodeUTF16toUTF8 = function(src, dst) {
5100 utfx.UTF16toUTF8(src, function(cp) {
5101 utfx.encodeUTF8(cp, dst);
5102 });
5103 };
5104
5105 /**
5106 * Decodes and converts UTF8 bytes to UTF16 characters.
5107 * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
5108 * are no more bytes left.
5109 * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
5110 * @throws {RangeError} If a starting byte is invalid in UTF8
5111 * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
5112 */
5113 utfx.decodeUTF8toUTF16 = function(src, dst) {
5114 utfx.decodeUTF8(src, function(cp) {
5115 utfx.UTF8toUTF16(cp, dst);
5116 });
5117 };
5118
5119 /**
5120 * Calculates the byte length of an UTF8 code point.
5121 * @param {number} cp UTF8 code point
5122 * @returns {number} Byte length
5123 */
5124 utfx.calculateCodePoint = function(cp) {
5125 return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
5126 };
5127
5128 /**
5129 * Calculates the number of UTF8 bytes required to store UTF8 code points.
5130 * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
5131 * `null` if there are no more code points left.
5132 * @returns {number} The number of UTF8 bytes required
5133 */
5134 utfx.calculateUTF8 = function(src) {
5135 var cp, l=0;
5136 while ((cp = src()) !== null)
5137 l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
5138 return l;
5139 };
5140
5141 /**
5142 * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
5143 * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
5144 * `null` if there are no more characters left.
5145 * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
5146 */
5147 utfx.calculateUTF16asUTF8 = function(src) {
5148 var n=0, l=0;
5149 utfx.UTF16toUTF8(src, function(cp) {
5150 ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
5151 });
5152 return [n,l];
5153 };
5154
5155 return utfx;
5156 }();
5157
5158 // encodings/utf8
5159
5160 /**
5161 * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded
5162 * string.
5163 * @returns {string} Hex encoded string
5164 * @throws {RangeError} If `offset > limit`
5165 * @expose
5166 */
5167 ByteBufferPrototype.toUTF8 = function(begin, end) {
5168 if (typeof begin === 'undefined') begin = this.offset;
5169 if (typeof end === 'undefined') end = this.limit;
5170 if (!this.noAssert) {
5171 if (typeof begin !== 'number' || begin % 1 !== 0)
5172 throw TypeError("Illegal begin: Not an integer");
5173 begin >>>= 0;
5174 if (typeof end !== 'number' || end % 1 !== 0)
5175 throw TypeError("Illegal end: Not an integer");
5176 end >>>= 0;
5177 if (begin < 0 || begin > end || end > this.buffer.byteLength)
5178 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
5179 }
5180 var sd; try {
5181 utfx.decodeUTF8toUTF16(function() {
5182 return begin < end ? this.view[begin++] : null;
5183 }.bind(this), sd = stringDestination());
5184 } catch (e) {
5185 if (begin !== end)
5186 throw RangeError("Illegal range: Truncated data, "+begin+" != "+end);
5187 }
5188 return sd();
5189 };
5190
5191 /**
5192 * Decodes an UTF8 encoded string to a ByteBuffer.
5193 * @param {string} str String to decode
5194 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
5195 * {@link ByteBuffer.DEFAULT_ENDIAN}.
5196 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
5197 * {@link ByteBuffer.DEFAULT_NOASSERT}.
5198 * @returns {!ByteBuffer} ByteBuffer
5199 * @expose
5200 */
5201 ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) {
5202 if (!noAssert)
5203 if (typeof str !== 'string')
5204 throw TypeError("Illegal str: Not a string");
5205 var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert),
5206 i = 0;
5207 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
5208 bb.view[i++] = b;
5209 });
5210 bb.limit = i;
5211 return bb;
5212 };
5213
5214 return ByteBuffer;
5215 });
5216 });
5217
5218 var require$$2 = {};
5219
5220 var protobufLight = createCommonjsModule(function (module) {
5221 /*
5222 Copyright 2013 Daniel Wirtz <dcode@dcode.io>
5223
5224 Licensed under the Apache License, Version 2.0 (the "License");
5225 you may not use this file except in compliance with the License.
5226 You may obtain a copy of the License at
5227
5228 http://www.apache.org/licenses/LICENSE-2.0
5229
5230 Unless required by applicable law or agreed to in writing, software
5231 distributed under the License is distributed on an "AS IS" BASIS,
5232 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5233 See the License for the specific language governing permissions and
5234 limitations under the License.
5235 */
5236
5237 /**
5238 * @license protobuf.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
5239 * Released under the Apache License, Version 2.0
5240 * see: https://github.com/dcodeIO/protobuf.js for details
5241 */
5242 (function(global, factory) {
5243
5244 /* AMD */ if (typeof commonjsRequire === "function" && 'object' === "object" && module && module["exports"])
5245 module["exports"] = factory(bytebuffer, true);
5246 /* Global */ else
5247 (global["dcodeIO"] = global["dcodeIO"] || {})["ProtoBuf"] = factory(global["dcodeIO"]["ByteBuffer"]);
5248
5249 })(commonjsGlobal, function(ByteBuffer, isCommonJS) {
5250
5251 /**
5252 * The ProtoBuf namespace.
5253 * @exports ProtoBuf
5254 * @namespace
5255 * @expose
5256 */
5257 var ProtoBuf = {};
5258
5259 /**
5260 * @type {!function(new: ByteBuffer, ...[*])}
5261 * @expose
5262 */
5263 ProtoBuf.ByteBuffer = ByteBuffer;
5264
5265 /**
5266 * @type {?function(new: Long, ...[*])}
5267 * @expose
5268 */
5269 ProtoBuf.Long = ByteBuffer.Long || null;
5270
5271 /**
5272 * ProtoBuf.js version.
5273 * @type {string}
5274 * @const
5275 * @expose
5276 */
5277 ProtoBuf.VERSION = "5.0.3";
5278
5279 /**
5280 * Wire types.
5281 * @type {Object.<string,number>}
5282 * @const
5283 * @expose
5284 */
5285 ProtoBuf.WIRE_TYPES = {};
5286
5287 /**
5288 * Varint wire type.
5289 * @type {number}
5290 * @expose
5291 */
5292 ProtoBuf.WIRE_TYPES.VARINT = 0;
5293
5294 /**
5295 * Fixed 64 bits wire type.
5296 * @type {number}
5297 * @const
5298 * @expose
5299 */
5300 ProtoBuf.WIRE_TYPES.BITS64 = 1;
5301
5302 /**
5303 * Length delimited wire type.
5304 * @type {number}
5305 * @const
5306 * @expose
5307 */
5308 ProtoBuf.WIRE_TYPES.LDELIM = 2;
5309
5310 /**
5311 * Start group wire type.
5312 * @type {number}
5313 * @const
5314 * @expose
5315 */
5316 ProtoBuf.WIRE_TYPES.STARTGROUP = 3;
5317
5318 /**
5319 * End group wire type.
5320 * @type {number}
5321 * @const
5322 * @expose
5323 */
5324 ProtoBuf.WIRE_TYPES.ENDGROUP = 4;
5325
5326 /**
5327 * Fixed 32 bits wire type.
5328 * @type {number}
5329 * @const
5330 * @expose
5331 */
5332 ProtoBuf.WIRE_TYPES.BITS32 = 5;
5333
5334 /**
5335 * Packable wire types.
5336 * @type {!Array.<number>}
5337 * @const
5338 * @expose
5339 */
5340 ProtoBuf.PACKABLE_WIRE_TYPES = [
5341 ProtoBuf.WIRE_TYPES.VARINT,
5342 ProtoBuf.WIRE_TYPES.BITS64,
5343 ProtoBuf.WIRE_TYPES.BITS32
5344 ];
5345
5346 /**
5347 * Types.
5348 * @dict
5349 * @type {!Object.<string,{name: string, wireType: number, defaultValue: *}>}
5350 * @const
5351 * @expose
5352 */
5353 ProtoBuf.TYPES = {
5354 // According to the protobuf spec.
5355 "int32": {
5356 name: "int32",
5357 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5358 defaultValue: 0
5359 },
5360 "uint32": {
5361 name: "uint32",
5362 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5363 defaultValue: 0
5364 },
5365 "sint32": {
5366 name: "sint32",
5367 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5368 defaultValue: 0
5369 },
5370 "int64": {
5371 name: "int64",
5372 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5373 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
5374 },
5375 "uint64": {
5376 name: "uint64",
5377 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5378 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
5379 },
5380 "sint64": {
5381 name: "sint64",
5382 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5383 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
5384 },
5385 "bool": {
5386 name: "bool",
5387 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5388 defaultValue: false
5389 },
5390 "double": {
5391 name: "double",
5392 wireType: ProtoBuf.WIRE_TYPES.BITS64,
5393 defaultValue: 0
5394 },
5395 "string": {
5396 name: "string",
5397 wireType: ProtoBuf.WIRE_TYPES.LDELIM,
5398 defaultValue: ""
5399 },
5400 "bytes": {
5401 name: "bytes",
5402 wireType: ProtoBuf.WIRE_TYPES.LDELIM,
5403 defaultValue: null // overridden in the code, must be a unique instance
5404 },
5405 "fixed32": {
5406 name: "fixed32",
5407 wireType: ProtoBuf.WIRE_TYPES.BITS32,
5408 defaultValue: 0
5409 },
5410 "sfixed32": {
5411 name: "sfixed32",
5412 wireType: ProtoBuf.WIRE_TYPES.BITS32,
5413 defaultValue: 0
5414 },
5415 "fixed64": {
5416 name: "fixed64",
5417 wireType: ProtoBuf.WIRE_TYPES.BITS64,
5418 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
5419 },
5420 "sfixed64": {
5421 name: "sfixed64",
5422 wireType: ProtoBuf.WIRE_TYPES.BITS64,
5423 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
5424 },
5425 "float": {
5426 name: "float",
5427 wireType: ProtoBuf.WIRE_TYPES.BITS32,
5428 defaultValue: 0
5429 },
5430 "enum": {
5431 name: "enum",
5432 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5433 defaultValue: 0
5434 },
5435 "message": {
5436 name: "message",
5437 wireType: ProtoBuf.WIRE_TYPES.LDELIM,
5438 defaultValue: null
5439 },
5440 "group": {
5441 name: "group",
5442 wireType: ProtoBuf.WIRE_TYPES.STARTGROUP,
5443 defaultValue: null
5444 }
5445 };
5446
5447 /**
5448 * Valid map key types.
5449 * @type {!Array.<!Object.<string,{name: string, wireType: number, defaultValue: *}>>}
5450 * @const
5451 * @expose
5452 */
5453 ProtoBuf.MAP_KEY_TYPES = [
5454 ProtoBuf.TYPES["int32"],
5455 ProtoBuf.TYPES["sint32"],
5456 ProtoBuf.TYPES["sfixed32"],
5457 ProtoBuf.TYPES["uint32"],
5458 ProtoBuf.TYPES["fixed32"],
5459 ProtoBuf.TYPES["int64"],
5460 ProtoBuf.TYPES["sint64"],
5461 ProtoBuf.TYPES["sfixed64"],
5462 ProtoBuf.TYPES["uint64"],
5463 ProtoBuf.TYPES["fixed64"],
5464 ProtoBuf.TYPES["bool"],
5465 ProtoBuf.TYPES["string"],
5466 ProtoBuf.TYPES["bytes"]
5467 ];
5468
5469 /**
5470 * Minimum field id.
5471 * @type {number}
5472 * @const
5473 * @expose
5474 */
5475 ProtoBuf.ID_MIN = 1;
5476
5477 /**
5478 * Maximum field id.
5479 * @type {number}
5480 * @const
5481 * @expose
5482 */
5483 ProtoBuf.ID_MAX = 0x1FFFFFFF;
5484
5485 /**
5486 * If set to `true`, field names will be converted from underscore notation to camel case. Defaults to `false`.
5487 * Must be set prior to parsing.
5488 * @type {boolean}
5489 * @expose
5490 */
5491 ProtoBuf.convertFieldsToCamelCase = false;
5492
5493 /**
5494 * By default, messages are populated with (setX, set_x) accessors for each field. This can be disabled by
5495 * setting this to `false` prior to building messages.
5496 * @type {boolean}
5497 * @expose
5498 */
5499 ProtoBuf.populateAccessors = true;
5500
5501 /**
5502 * By default, messages are populated with default values if a field is not present on the wire. To disable
5503 * this behavior, set this setting to `false`.
5504 * @type {boolean}
5505 * @expose
5506 */
5507 ProtoBuf.populateDefaults = true;
5508
5509 /**
5510 * @alias ProtoBuf.Util
5511 * @expose
5512 */
5513 ProtoBuf.Util = (function() {
5514
5515 /**
5516 * ProtoBuf utilities.
5517 * @exports ProtoBuf.Util
5518 * @namespace
5519 */
5520 var Util = {};
5521
5522 /**
5523 * Flag if running in node or not.
5524 * @type {boolean}
5525 * @const
5526 * @expose
5527 */
5528 Util.IS_NODE = !!(
5529 typeof process === 'object' && process+'' === '[object process]' && !process['browser']
5530 );
5531
5532 /**
5533 * Constructs a XMLHttpRequest object.
5534 * @return {XMLHttpRequest}
5535 * @throws {Error} If XMLHttpRequest is not supported
5536 * @expose
5537 */
5538 Util.XHR = function() {
5539 // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
5540 var XMLHttpFactories = [
5541 function () {return new XMLHttpRequest()},
5542 function () {return new ActiveXObject("Msxml2.XMLHTTP")},
5543 function () {return new ActiveXObject("Msxml3.XMLHTTP")},
5544 function () {return new ActiveXObject("Microsoft.XMLHTTP")}
5545 ];
5546 /** @type {?XMLHttpRequest} */
5547 var xhr = null;
5548 for (var i=0;i<XMLHttpFactories.length;i++) {
5549 try { xhr = XMLHttpFactories[i](); }
5550 catch (e) { continue; }
5551 break;
5552 }
5553 if (!xhr)
5554 throw Error("XMLHttpRequest is not supported");
5555 return xhr;
5556 };
5557
5558 /**
5559 * Fetches a resource.
5560 * @param {string} path Resource path
5561 * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
5562 * be fetched synchronously. If the request failed, contents will be null.
5563 * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
5564 * @expose
5565 */
5566 Util.fetch = function(path, callback) {
5567 if (callback && typeof callback != 'function')
5568 callback = null;
5569 if (Util.IS_NODE) {
5570 var fs = require$$2;
5571 if (callback) {
5572 fs.readFile(path, function(err, data) {
5573 if (err)
5574 callback(null);
5575 else
5576 callback(""+data);
5577 });
5578 } else
5579 try {
5580 return fs.readFileSync(path);
5581 } catch (e) {
5582 return null;
5583 }
5584 } else {
5585 var xhr = Util.XHR();
5586 xhr.open('GET', path, callback ? true : false);
5587 // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
5588 xhr.setRequestHeader('Accept', 'text/plain');
5589 if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
5590 if (callback) {
5591 xhr.onreadystatechange = function() {
5592 if (xhr.readyState != 4) return;
5593 if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
5594 callback(xhr.responseText);
5595 else
5596 callback(null);
5597 };
5598 if (xhr.readyState == 4)
5599 return;
5600 xhr.send(null);
5601 } else {
5602 xhr.send(null);
5603 if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
5604 return xhr.responseText;
5605 return null;
5606 }
5607 }
5608 };
5609
5610 /**
5611 * Converts a string to camel case.
5612 * @param {string} str
5613 * @returns {string}
5614 * @expose
5615 */
5616 Util.toCamelCase = function(str) {
5617 return str.replace(/_([a-zA-Z])/g, function ($0, $1) {
5618 return $1.toUpperCase();
5619 });
5620 };
5621
5622 return Util;
5623 })();
5624
5625 /**
5626 * Language expressions.
5627 * @type {!Object.<string,!RegExp>}
5628 * @expose
5629 */
5630 ProtoBuf.Lang = {
5631
5632 // Characters always ending a statement
5633 DELIM: /[\s\{\}=;:\[\],'"\(\)<>]/g,
5634
5635 // Field rules
5636 RULE: /^(?:required|optional|repeated|map)$/,
5637
5638 // Field types
5639 TYPE: /^(?:double|float|int32|uint32|sint32|int64|uint64|sint64|fixed32|sfixed32|fixed64|sfixed64|bool|string|bytes)$/,
5640
5641 // Names
5642 NAME: /^[a-zA-Z_][a-zA-Z_0-9]*$/,
5643
5644 // Type definitions
5645 TYPEDEF: /^[a-zA-Z][a-zA-Z_0-9]*$/,
5646
5647 // Type references
5648 TYPEREF: /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
5649
5650 // Fully qualified type references
5651 FQTYPEREF: /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/,
5652
5653 // All numbers
5654 NUMBER: /^-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+|([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?)|inf|nan)$/,
5655
5656 // Decimal numbers
5657 NUMBER_DEC: /^(?:[1-9][0-9]*|0)$/,
5658
5659 // Hexadecimal numbers
5660 NUMBER_HEX: /^0[xX][0-9a-fA-F]+$/,
5661
5662 // Octal numbers
5663 NUMBER_OCT: /^0[0-7]+$/,
5664
5665 // Floating point numbers
5666 NUMBER_FLT: /^([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?|inf|nan)$/,
5667
5668 // Booleans
5669 BOOL: /^(?:true|false)$/i,
5670
5671 // Id numbers
5672 ID: /^(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
5673
5674 // Negative id numbers (enum values)
5675 NEGID: /^\-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
5676
5677 // Whitespaces
5678 WHITESPACE: /\s/,
5679
5680 // All strings
5681 STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,
5682
5683 // Double quoted strings
5684 STRING_DQ: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")/g,
5685
5686 // Single quoted strings
5687 STRING_SQ: /(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g
5688 };
5689
5690
5691 /**
5692 * @alias ProtoBuf.Reflect
5693 * @expose
5694 */
5695 ProtoBuf.Reflect = (function(ProtoBuf) {
5696
5697 /**
5698 * Reflection types.
5699 * @exports ProtoBuf.Reflect
5700 * @namespace
5701 */
5702 var Reflect = {};
5703
5704 /**
5705 * Constructs a Reflect base class.
5706 * @exports ProtoBuf.Reflect.T
5707 * @constructor
5708 * @abstract
5709 * @param {!ProtoBuf.Builder} builder Builder reference
5710 * @param {?ProtoBuf.Reflect.T} parent Parent object
5711 * @param {string} name Object name
5712 */
5713 var T = function(builder, parent, name) {
5714
5715 /**
5716 * Builder reference.
5717 * @type {!ProtoBuf.Builder}
5718 * @expose
5719 */
5720 this.builder = builder;
5721
5722 /**
5723 * Parent object.
5724 * @type {?ProtoBuf.Reflect.T}
5725 * @expose
5726 */
5727 this.parent = parent;
5728
5729 /**
5730 * Object name in namespace.
5731 * @type {string}
5732 * @expose
5733 */
5734 this.name = name;
5735
5736 /**
5737 * Fully qualified class name
5738 * @type {string}
5739 * @expose
5740 */
5741 this.className;
5742 };
5743
5744 /**
5745 * @alias ProtoBuf.Reflect.T.prototype
5746 * @inner
5747 */
5748 var TPrototype = T.prototype;
5749
5750 /**
5751 * Returns the fully qualified name of this object.
5752 * @returns {string} Fully qualified name as of ".PATH.TO.THIS"
5753 * @expose
5754 */
5755 TPrototype.fqn = function() {
5756 var name = this.name,
5757 ptr = this;
5758 do {
5759 ptr = ptr.parent;
5760 if (ptr == null)
5761 break;
5762 name = ptr.name+"."+name;
5763 } while (true);
5764 return name;
5765 };
5766
5767 /**
5768 * Returns a string representation of this Reflect object (its fully qualified name).
5769 * @param {boolean=} includeClass Set to true to include the class name. Defaults to false.
5770 * @return String representation
5771 * @expose
5772 */
5773 TPrototype.toString = function(includeClass) {
5774 return (includeClass ? this.className + " " : "") + this.fqn();
5775 };
5776
5777 /**
5778 * Builds this type.
5779 * @throws {Error} If this type cannot be built directly
5780 * @expose
5781 */
5782 TPrototype.build = function() {
5783 throw Error(this.toString(true)+" cannot be built directly");
5784 };
5785
5786 /**
5787 * @alias ProtoBuf.Reflect.T
5788 * @expose
5789 */
5790 Reflect.T = T;
5791
5792 /**
5793 * Constructs a new Namespace.
5794 * @exports ProtoBuf.Reflect.Namespace
5795 * @param {!ProtoBuf.Builder} builder Builder reference
5796 * @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent
5797 * @param {string} name Namespace name
5798 * @param {Object.<string,*>=} options Namespace options
5799 * @param {string?} syntax The syntax level of this definition (e.g., proto3)
5800 * @constructor
5801 * @extends ProtoBuf.Reflect.T
5802 */
5803 var Namespace = function(builder, parent, name, options, syntax) {
5804 T.call(this, builder, parent, name);
5805
5806 /**
5807 * @override
5808 */
5809 this.className = "Namespace";
5810
5811 /**
5812 * Children inside the namespace.
5813 * @type {!Array.<ProtoBuf.Reflect.T>}
5814 */
5815 this.children = [];
5816
5817 /**
5818 * Options.
5819 * @type {!Object.<string, *>}
5820 */
5821 this.options = options || {};
5822
5823 /**
5824 * Syntax level (e.g., proto2 or proto3).
5825 * @type {!string}
5826 */
5827 this.syntax = syntax || "proto2";
5828 };
5829
5830 /**
5831 * @alias ProtoBuf.Reflect.Namespace.prototype
5832 * @inner
5833 */
5834 var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);
5835
5836 /**
5837 * Returns an array of the namespace's children.
5838 * @param {ProtoBuf.Reflect.T=} type Filter type (returns instances of this type only). Defaults to null (all children).
5839 * @return {Array.<ProtoBuf.Reflect.T>}
5840 * @expose
5841 */
5842 NamespacePrototype.getChildren = function(type) {
5843 type = type || null;
5844 if (type == null)
5845 return this.children.slice();
5846 var children = [];
5847 for (var i=0, k=this.children.length; i<k; ++i)
5848 if (this.children[i] instanceof type)
5849 children.push(this.children[i]);
5850 return children;
5851 };
5852
5853 /**
5854 * Adds a child to the namespace.
5855 * @param {ProtoBuf.Reflect.T} child Child
5856 * @throws {Error} If the child cannot be added (duplicate)
5857 * @expose
5858 */
5859 NamespacePrototype.addChild = function(child) {
5860 var other;
5861 if (other = this.getChild(child.name)) {
5862 // Try to revert camelcase transformation on collision
5863 if (other instanceof Message.Field && other.name !== other.originalName && this.getChild(other.originalName) === null)
5864 other.name = other.originalName; // Revert previous first (effectively keeps both originals)
5865 else if (child instanceof Message.Field && child.name !== child.originalName && this.getChild(child.originalName) === null)
5866 child.name = child.originalName;
5867 else
5868 throw Error("Duplicate name in namespace "+this.toString(true)+": "+child.name);
5869 }
5870 this.children.push(child);
5871 };
5872
5873 /**
5874 * Gets a child by its name or id.
5875 * @param {string|number} nameOrId Child name or id
5876 * @return {?ProtoBuf.Reflect.T} The child or null if not found
5877 * @expose
5878 */
5879 NamespacePrototype.getChild = function(nameOrId) {
5880 var key = typeof nameOrId === 'number' ? 'id' : 'name';
5881 for (var i=0, k=this.children.length; i<k; ++i)
5882 if (this.children[i][key] === nameOrId)
5883 return this.children[i];
5884 return null;
5885 };
5886
5887 /**
5888 * Resolves a reflect object inside of this namespace.
5889 * @param {string|!Array.<string>} qn Qualified name to resolve
5890 * @param {boolean=} excludeNonNamespace Excludes non-namespace types, defaults to `false`
5891 * @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found
5892 * @expose
5893 */
5894 NamespacePrototype.resolve = function(qn, excludeNonNamespace) {
5895 var part = typeof qn === 'string' ? qn.split(".") : qn,
5896 ptr = this,
5897 i = 0;
5898 if (part[i] === "") { // Fully qualified name, e.g. ".My.Message'
5899 while (ptr.parent !== null)
5900 ptr = ptr.parent;
5901 i++;
5902 }
5903 var child;
5904 do {
5905 do {
5906 if (!(ptr instanceof Reflect.Namespace)) {
5907 ptr = null;
5908 break;
5909 }
5910 child = ptr.getChild(part[i]);
5911 if (!child || !(child instanceof Reflect.T) || (excludeNonNamespace && !(child instanceof Reflect.Namespace))) {
5912 ptr = null;
5913 break;
5914 }
5915 ptr = child; i++;
5916 } while (i < part.length);
5917 if (ptr != null)
5918 break; // Found
5919 // Else search the parent
5920 if (this.parent !== null)
5921 return this.parent.resolve(qn, excludeNonNamespace);
5922 } while (ptr != null);
5923 return ptr;
5924 };
5925
5926 /**
5927 * Determines the shortest qualified name of the specified type, if any, relative to this namespace.
5928 * @param {!ProtoBuf.Reflect.T} t Reflection type
5929 * @returns {string} The shortest qualified name or, if there is none, the fqn
5930 * @expose
5931 */
5932 NamespacePrototype.qn = function(t) {
5933 var part = [], ptr = t;
5934 do {
5935 part.unshift(ptr.name);
5936 ptr = ptr.parent;
5937 } while (ptr !== null);
5938 for (var len=1; len <= part.length; len++) {
5939 var qn = part.slice(part.length-len);
5940 if (t === this.resolve(qn, t instanceof Reflect.Namespace))
5941 return qn.join(".");
5942 }
5943 return t.fqn();
5944 };
5945
5946 /**
5947 * Builds the namespace and returns the runtime counterpart.
5948 * @return {Object.<string,Function|Object>} Runtime namespace
5949 * @expose
5950 */
5951 NamespacePrototype.build = function() {
5952 /** @dict */
5953 var ns = {};
5954 var children = this.children;
5955 for (var i=0, k=children.length, child; i<k; ++i) {
5956 child = children[i];
5957 if (child instanceof Namespace)
5958 ns[child.name] = child.build();
5959 }
5960 if (Object.defineProperty)
5961 Object.defineProperty(ns, "$options", { "value": this.buildOpt() });
5962 return ns;
5963 };
5964
5965 /**
5966 * Builds the namespace's '$options' property.
5967 * @return {Object.<string,*>}
5968 */
5969 NamespacePrototype.buildOpt = function() {
5970 var opt = {},
5971 keys = Object.keys(this.options);
5972 for (var i=0, k=keys.length; i<k; ++i) {
5973 var key = keys[i],
5974 val = this.options[keys[i]];
5975 // TODO: Options are not resolved, yet.
5976 // if (val instanceof Namespace) {
5977 // opt[key] = val.build();
5978 // } else {
5979 opt[key] = val;
5980 // }
5981 }
5982 return opt;
5983 };
5984
5985 /**
5986 * Gets the value assigned to the option with the specified name.
5987 * @param {string=} name Returns the option value if specified, otherwise all options are returned.
5988 * @return {*|Object.<string,*>}null} Option value or NULL if there is no such option
5989 */
5990 NamespacePrototype.getOption = function(name) {
5991 if (typeof name === 'undefined')
5992 return this.options;
5993 return typeof this.options[name] !== 'undefined' ? this.options[name] : null;
5994 };
5995
5996 /**
5997 * @alias ProtoBuf.Reflect.Namespace
5998 * @expose
5999 */
6000 Reflect.Namespace = Namespace;
6001
6002 /**
6003 * Constructs a new Element implementation that checks and converts values for a
6004 * particular field type, as appropriate.
6005 *
6006 * An Element represents a single value: either the value of a singular field,
6007 * or a value contained in one entry of a repeated field or map field. This
6008 * class does not implement these higher-level concepts; it only encapsulates
6009 * the low-level typechecking and conversion.
6010 *
6011 * @exports ProtoBuf.Reflect.Element
6012 * @param {{name: string, wireType: number}} type Resolved data type
6013 * @param {ProtoBuf.Reflect.T|null} resolvedType Resolved type, if relevant
6014 * (e.g. submessage field).
6015 * @param {boolean} isMapKey Is this element a Map key? The value will be
6016 * converted to string form if so.
6017 * @param {string} syntax Syntax level of defining message type, e.g.,
6018 * proto2 or proto3.
6019 * @param {string} name Name of the field containing this element (for error
6020 * messages)
6021 * @constructor
6022 */
6023 var Element = function(type, resolvedType, isMapKey, syntax, name) {
6024
6025 /**
6026 * Element type, as a string (e.g., int32).
6027 * @type {{name: string, wireType: number}}
6028 */
6029 this.type = type;
6030
6031 /**
6032 * Element type reference to submessage or enum definition, if needed.
6033 * @type {ProtoBuf.Reflect.T|null}
6034 */
6035 this.resolvedType = resolvedType;
6036
6037 /**
6038 * Element is a map key.
6039 * @type {boolean}
6040 */
6041 this.isMapKey = isMapKey;
6042
6043 /**
6044 * Syntax level of defining message type, e.g., proto2 or proto3.
6045 * @type {string}
6046 */
6047 this.syntax = syntax;
6048
6049 /**
6050 * Name of the field containing this element (for error messages)
6051 * @type {string}
6052 */
6053 this.name = name;
6054
6055 if (isMapKey && ProtoBuf.MAP_KEY_TYPES.indexOf(type) < 0)
6056 throw Error("Invalid map key type: " + type.name);
6057 };
6058
6059 var ElementPrototype = Element.prototype;
6060
6061 /**
6062 * Obtains a (new) default value for the specified type.
6063 * @param type {string|{name: string, wireType: number}} Field type
6064 * @returns {*} Default value
6065 * @inner
6066 */
6067 function mkDefault(type) {
6068 if (typeof type === 'string')
6069 type = ProtoBuf.TYPES[type];
6070 if (typeof type.defaultValue === 'undefined')
6071 throw Error("default value for type "+type.name+" is not supported");
6072 if (type == ProtoBuf.TYPES["bytes"])
6073 return new ByteBuffer(0);
6074 return type.defaultValue;
6075 }
6076
6077 /**
6078 * Returns the default value for this field in proto3.
6079 * @function
6080 * @param type {string|{name: string, wireType: number}} the field type
6081 * @returns {*} Default value
6082 */
6083 Element.defaultFieldValue = mkDefault;
6084
6085 /**
6086 * Makes a Long from a value.
6087 * @param {{low: number, high: number, unsigned: boolean}|string|number} value Value
6088 * @param {boolean=} unsigned Whether unsigned or not, defaults to reuse it from Long-like objects or to signed for
6089 * strings and numbers
6090 * @returns {!Long}
6091 * @throws {Error} If the value cannot be converted to a Long
6092 * @inner
6093 */
6094 function mkLong(value, unsigned) {
6095 if (value && typeof value.low === 'number' && typeof value.high === 'number' && typeof value.unsigned === 'boolean'
6096 && value.low === value.low && value.high === value.high)
6097 return new ProtoBuf.Long(value.low, value.high, typeof unsigned === 'undefined' ? value.unsigned : unsigned);
6098 if (typeof value === 'string')
6099 return ProtoBuf.Long.fromString(value, unsigned || false, 10);
6100 if (typeof value === 'number')
6101 return ProtoBuf.Long.fromNumber(value, unsigned || false);
6102 throw Error("not convertible to Long");
6103 }
6104
6105 ElementPrototype.toString = function() {
6106 return (this.name || '') + (this.isMapKey ? 'map' : 'value') + ' element';
6107 };
6108
6109 /**
6110 * Checks if the given value can be set for an element of this type (singular
6111 * field or one element of a repeated field or map).
6112 * @param {*} value Value to check
6113 * @return {*} Verified, maybe adjusted, value
6114 * @throws {Error} If the value cannot be verified for this element slot
6115 * @expose
6116 */
6117 ElementPrototype.verifyValue = function(value) {
6118 var self = this;
6119 function fail(val, msg) {
6120 throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
6121 }
6122 switch (this.type) {
6123 // Signed 32bit
6124 case ProtoBuf.TYPES["int32"]:
6125 case ProtoBuf.TYPES["sint32"]:
6126 case ProtoBuf.TYPES["sfixed32"]:
6127 // Account for !NaN: value === value
6128 if (typeof value !== 'number' || (value === value && value % 1 !== 0))
6129 fail(typeof value, "not an integer");
6130 return value > 4294967295 ? value | 0 : value;
6131
6132 // Unsigned 32bit
6133 case ProtoBuf.TYPES["uint32"]:
6134 case ProtoBuf.TYPES["fixed32"]:
6135 if (typeof value !== 'number' || (value === value && value % 1 !== 0))
6136 fail(typeof value, "not an integer");
6137 return value < 0 ? value >>> 0 : value;
6138
6139 // Signed 64bit
6140 case ProtoBuf.TYPES["int64"]:
6141 case ProtoBuf.TYPES["sint64"]:
6142 case ProtoBuf.TYPES["sfixed64"]: {
6143 if (ProtoBuf.Long)
6144 try {
6145 return mkLong(value, false);
6146 } catch (e) {
6147 fail(typeof value, e.message);
6148 }
6149 else
6150 fail(typeof value, "requires Long.js");
6151 }
6152
6153 // Unsigned 64bit
6154 case ProtoBuf.TYPES["uint64"]:
6155 case ProtoBuf.TYPES["fixed64"]: {
6156 if (ProtoBuf.Long)
6157 try {
6158 return mkLong(value, true);
6159 } catch (e) {
6160 fail(typeof value, e.message);
6161 }
6162 else
6163 fail(typeof value, "requires Long.js");
6164 }
6165
6166 // Bool
6167 case ProtoBuf.TYPES["bool"]:
6168 if (typeof value !== 'boolean')
6169 fail(typeof value, "not a boolean");
6170 return value;
6171
6172 // Float
6173 case ProtoBuf.TYPES["float"]:
6174 case ProtoBuf.TYPES["double"]:
6175 if (typeof value !== 'number')
6176 fail(typeof value, "not a number");
6177 return value;
6178
6179 // Length-delimited string
6180 case ProtoBuf.TYPES["string"]:
6181 if (typeof value !== 'string' && !(value && value instanceof String))
6182 fail(typeof value, "not a string");
6183 return ""+value; // Convert String object to string
6184
6185 // Length-delimited bytes
6186 case ProtoBuf.TYPES["bytes"]:
6187 if (ByteBuffer.isByteBuffer(value))
6188 return value;
6189 return ByteBuffer.wrap(value, "base64");
6190
6191 // Constant enum value
6192 case ProtoBuf.TYPES["enum"]: {
6193 var values = this.resolvedType.getChildren(ProtoBuf.Reflect.Enum.Value);
6194 for (i=0; i<values.length; i++)
6195 if (values[i].name == value)
6196 return values[i].id;
6197 else if (values[i].id == value)
6198 return values[i].id;
6199
6200 if (this.syntax === 'proto3') {
6201 // proto3: just make sure it's an integer.
6202 if (typeof value !== 'number' || (value === value && value % 1 !== 0))
6203 fail(typeof value, "not an integer");
6204 if (value > 4294967295 || value < 0)
6205 fail(typeof value, "not in range for uint32");
6206 return value;
6207 } else {
6208 // proto2 requires enum values to be valid.
6209 fail(value, "not a valid enum value");
6210 }
6211 }
6212 // Embedded message
6213 case ProtoBuf.TYPES["group"]:
6214 case ProtoBuf.TYPES["message"]: {
6215 if (!value || typeof value !== 'object')
6216 fail(typeof value, "object expected");
6217 if (value instanceof this.resolvedType.clazz)
6218 return value;
6219 if (value instanceof ProtoBuf.Builder.Message) {
6220 // Mismatched type: Convert to object (see: https://github.com/dcodeIO/ProtoBuf.js/issues/180)
6221 var obj = {};
6222 for (var i in value)
6223 if (value.hasOwnProperty(i))
6224 obj[i] = value[i];
6225 value = obj;
6226 }
6227 // Else let's try to construct one from a key-value object
6228 return new (this.resolvedType.clazz)(value); // May throw for a hundred of reasons
6229 }
6230 }
6231
6232 // We should never end here
6233 throw Error("[INTERNAL] Illegal value for "+this.toString(true)+": "+value+" (undefined type "+this.type+")");
6234 };
6235
6236 /**
6237 * Calculates the byte length of an element on the wire.
6238 * @param {number} id Field number
6239 * @param {*} value Field value
6240 * @returns {number} Byte length
6241 * @throws {Error} If the value cannot be calculated
6242 * @expose
6243 */
6244 ElementPrototype.calculateLength = function(id, value) {
6245 if (value === null) return 0; // Nothing to encode
6246 // Tag has already been written
6247 var n;
6248 switch (this.type) {
6249 case ProtoBuf.TYPES["int32"]:
6250 return value < 0 ? ByteBuffer.calculateVarint64(value) : ByteBuffer.calculateVarint32(value);
6251 case ProtoBuf.TYPES["uint32"]:
6252 return ByteBuffer.calculateVarint32(value);
6253 case ProtoBuf.TYPES["sint32"]:
6254 return ByteBuffer.calculateVarint32(ByteBuffer.zigZagEncode32(value));
6255 case ProtoBuf.TYPES["fixed32"]:
6256 case ProtoBuf.TYPES["sfixed32"]:
6257 case ProtoBuf.TYPES["float"]:
6258 return 4;
6259 case ProtoBuf.TYPES["int64"]:
6260 case ProtoBuf.TYPES["uint64"]:
6261 return ByteBuffer.calculateVarint64(value);
6262 case ProtoBuf.TYPES["sint64"]:
6263 return ByteBuffer.calculateVarint64(ByteBuffer.zigZagEncode64(value));
6264 case ProtoBuf.TYPES["fixed64"]:
6265 case ProtoBuf.TYPES["sfixed64"]:
6266 return 8;
6267 case ProtoBuf.TYPES["bool"]:
6268 return 1;
6269 case ProtoBuf.TYPES["enum"]:
6270 return ByteBuffer.calculateVarint32(value);
6271 case ProtoBuf.TYPES["double"]:
6272 return 8;
6273 case ProtoBuf.TYPES["string"]:
6274 n = ByteBuffer.calculateUTF8Bytes(value);
6275 return ByteBuffer.calculateVarint32(n) + n;
6276 case ProtoBuf.TYPES["bytes"]:
6277 if (value.remaining() < 0)
6278 throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
6279 return ByteBuffer.calculateVarint32(value.remaining()) + value.remaining();
6280 case ProtoBuf.TYPES["message"]:
6281 n = this.resolvedType.calculate(value);
6282 return ByteBuffer.calculateVarint32(n) + n;
6283 case ProtoBuf.TYPES["group"]:
6284 n = this.resolvedType.calculate(value);
6285 return n + ByteBuffer.calculateVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
6286 }
6287 // We should never end here
6288 throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
6289 };
6290
6291 /**
6292 * Encodes a value to the specified buffer. Does not encode the key.
6293 * @param {number} id Field number
6294 * @param {*} value Field value
6295 * @param {ByteBuffer} buffer ByteBuffer to encode to
6296 * @return {ByteBuffer} The ByteBuffer for chaining
6297 * @throws {Error} If the value cannot be encoded
6298 * @expose
6299 */
6300 ElementPrototype.encodeValue = function(id, value, buffer) {
6301 if (value === null) return buffer; // Nothing to encode
6302 // Tag has already been written
6303
6304 switch (this.type) {
6305 // 32bit signed varint
6306 case ProtoBuf.TYPES["int32"]:
6307 // "If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes
6308 // long – it is, effectively, treated like a very large unsigned integer." (see #122)
6309 if (value < 0)
6310 buffer.writeVarint64(value);
6311 else
6312 buffer.writeVarint32(value);
6313 break;
6314
6315 // 32bit unsigned varint
6316 case ProtoBuf.TYPES["uint32"]:
6317 buffer.writeVarint32(value);
6318 break;
6319
6320 // 32bit varint zig-zag
6321 case ProtoBuf.TYPES["sint32"]:
6322 buffer.writeVarint32ZigZag(value);
6323 break;
6324
6325 // Fixed unsigned 32bit
6326 case ProtoBuf.TYPES["fixed32"]:
6327 buffer.writeUint32(value);
6328 break;
6329
6330 // Fixed signed 32bit
6331 case ProtoBuf.TYPES["sfixed32"]:
6332 buffer.writeInt32(value);
6333 break;
6334
6335 // 64bit varint as-is
6336 case ProtoBuf.TYPES["int64"]:
6337 case ProtoBuf.TYPES["uint64"]:
6338 buffer.writeVarint64(value); // throws
6339 break;
6340
6341 // 64bit varint zig-zag
6342 case ProtoBuf.TYPES["sint64"]:
6343 buffer.writeVarint64ZigZag(value); // throws
6344 break;
6345
6346 // Fixed unsigned 64bit
6347 case ProtoBuf.TYPES["fixed64"]:
6348 buffer.writeUint64(value); // throws
6349 break;
6350
6351 // Fixed signed 64bit
6352 case ProtoBuf.TYPES["sfixed64"]:
6353 buffer.writeInt64(value); // throws
6354 break;
6355
6356 // Bool
6357 case ProtoBuf.TYPES["bool"]:
6358 if (typeof value === 'string')
6359 buffer.writeVarint32(value.toLowerCase() === 'false' ? 0 : !!value);
6360 else
6361 buffer.writeVarint32(value ? 1 : 0);
6362 break;
6363
6364 // Constant enum value
6365 case ProtoBuf.TYPES["enum"]:
6366 buffer.writeVarint32(value);
6367 break;
6368
6369 // 32bit float
6370 case ProtoBuf.TYPES["float"]:
6371 buffer.writeFloat32(value);
6372 break;
6373
6374 // 64bit float
6375 case ProtoBuf.TYPES["double"]:
6376 buffer.writeFloat64(value);
6377 break;
6378
6379 // Length-delimited string
6380 case ProtoBuf.TYPES["string"]:
6381 buffer.writeVString(value);
6382 break;
6383
6384 // Length-delimited bytes
6385 case ProtoBuf.TYPES["bytes"]:
6386 if (value.remaining() < 0)
6387 throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
6388 var prevOffset = value.offset;
6389 buffer.writeVarint32(value.remaining());
6390 buffer.append(value);
6391 value.offset = prevOffset;
6392 break;
6393
6394 // Embedded message
6395 case ProtoBuf.TYPES["message"]:
6396 var bb = new ByteBuffer().LE();
6397 this.resolvedType.encode(value, bb);
6398 buffer.writeVarint32(bb.offset);
6399 buffer.append(bb.flip());
6400 break;
6401
6402 // Legacy group
6403 case ProtoBuf.TYPES["group"]:
6404 this.resolvedType.encode(value, buffer);
6405 buffer.writeVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
6406 break;
6407
6408 default:
6409 // We should never end here
6410 throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
6411 }
6412 return buffer;
6413 };
6414
6415 /**
6416 * Decode one element value from the specified buffer.
6417 * @param {ByteBuffer} buffer ByteBuffer to decode from
6418 * @param {number} wireType The field wire type
6419 * @param {number} id The field number
6420 * @return {*} Decoded value
6421 * @throws {Error} If the field cannot be decoded
6422 * @expose
6423 */
6424 ElementPrototype.decode = function(buffer, wireType, id) {
6425 if (wireType != this.type.wireType)
6426 throw Error("Unexpected wire type for element");
6427
6428 var value, nBytes;
6429 switch (this.type) {
6430 // 32bit signed varint
6431 case ProtoBuf.TYPES["int32"]:
6432 return buffer.readVarint32() | 0;
6433
6434 // 32bit unsigned varint
6435 case ProtoBuf.TYPES["uint32"]:
6436 return buffer.readVarint32() >>> 0;
6437
6438 // 32bit signed varint zig-zag
6439 case ProtoBuf.TYPES["sint32"]:
6440 return buffer.readVarint32ZigZag() | 0;
6441
6442 // Fixed 32bit unsigned
6443 case ProtoBuf.TYPES["fixed32"]:
6444 return buffer.readUint32() >>> 0;
6445
6446 case ProtoBuf.TYPES["sfixed32"]:
6447 return buffer.readInt32() | 0;
6448
6449 // 64bit signed varint
6450 case ProtoBuf.TYPES["int64"]:
6451 return buffer.readVarint64();
6452
6453 // 64bit unsigned varint
6454 case ProtoBuf.TYPES["uint64"]:
6455 return buffer.readVarint64().toUnsigned();
6456
6457 // 64bit signed varint zig-zag
6458 case ProtoBuf.TYPES["sint64"]:
6459 return buffer.readVarint64ZigZag();
6460
6461 // Fixed 64bit unsigned
6462 case ProtoBuf.TYPES["fixed64"]:
6463 return buffer.readUint64();
6464
6465 // Fixed 64bit signed
6466 case ProtoBuf.TYPES["sfixed64"]:
6467 return buffer.readInt64();
6468
6469 // Bool varint
6470 case ProtoBuf.TYPES["bool"]:
6471 return !!buffer.readVarint32();
6472
6473 // Constant enum value (varint)
6474 case ProtoBuf.TYPES["enum"]:
6475 // The following Builder.Message#set will already throw
6476 return buffer.readVarint32();
6477
6478 // 32bit float
6479 case ProtoBuf.TYPES["float"]:
6480 return buffer.readFloat();
6481
6482 // 64bit float
6483 case ProtoBuf.TYPES["double"]:
6484 return buffer.readDouble();
6485
6486 // Length-delimited string
6487 case ProtoBuf.TYPES["string"]:
6488 return buffer.readVString();
6489
6490 // Length-delimited bytes
6491 case ProtoBuf.TYPES["bytes"]: {
6492 nBytes = buffer.readVarint32();
6493 if (buffer.remaining() < nBytes)
6494 throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
6495 value = buffer.clone(); // Offset already set
6496 value.limit = value.offset+nBytes;
6497 buffer.offset += nBytes;
6498 return value;
6499 }
6500
6501 // Length-delimited embedded message
6502 case ProtoBuf.TYPES["message"]: {
6503 nBytes = buffer.readVarint32();
6504 return this.resolvedType.decode(buffer, nBytes);
6505 }
6506
6507 // Legacy group
6508 case ProtoBuf.TYPES["group"]:
6509 return this.resolvedType.decode(buffer, -1, id);
6510 }
6511
6512 // We should never end here
6513 throw Error("[INTERNAL] Illegal decode type");
6514 };
6515
6516 /**
6517 * Converts a value from a string to the canonical element type.
6518 *
6519 * Legal only when isMapKey is true.
6520 *
6521 * @param {string} str The string value
6522 * @returns {*} The value
6523 */
6524 ElementPrototype.valueFromString = function(str) {
6525 if (!this.isMapKey) {
6526 throw Error("valueFromString() called on non-map-key element");
6527 }
6528
6529 switch (this.type) {
6530 case ProtoBuf.TYPES["int32"]:
6531 case ProtoBuf.TYPES["sint32"]:
6532 case ProtoBuf.TYPES["sfixed32"]:
6533 case ProtoBuf.TYPES["uint32"]:
6534 case ProtoBuf.TYPES["fixed32"]:
6535 return this.verifyValue(parseInt(str));
6536
6537 case ProtoBuf.TYPES["int64"]:
6538 case ProtoBuf.TYPES["sint64"]:
6539 case ProtoBuf.TYPES["sfixed64"]:
6540 case ProtoBuf.TYPES["uint64"]:
6541 case ProtoBuf.TYPES["fixed64"]:
6542 // Long-based fields support conversions from string already.
6543 return this.verifyValue(str);
6544
6545 case ProtoBuf.TYPES["bool"]:
6546 return str === "true";
6547
6548 case ProtoBuf.TYPES["string"]:
6549 return this.verifyValue(str);
6550
6551 case ProtoBuf.TYPES["bytes"]:
6552 return ByteBuffer.fromBinary(str);
6553 }
6554 };
6555
6556 /**
6557 * Converts a value from the canonical element type to a string.
6558 *
6559 * It should be the case that `valueFromString(valueToString(val))` returns
6560 * a value equivalent to `verifyValue(val)` for every legal value of `val`
6561 * according to this element type.
6562 *
6563 * This may be used when the element must be stored or used as a string,
6564 * e.g., as a map key on an Object.
6565 *
6566 * Legal only when isMapKey is true.
6567 *
6568 * @param {*} val The value
6569 * @returns {string} The string form of the value.
6570 */
6571 ElementPrototype.valueToString = function(value) {
6572 if (!this.isMapKey) {
6573 throw Error("valueToString() called on non-map-key element");
6574 }
6575
6576 if (this.type === ProtoBuf.TYPES["bytes"]) {
6577 return value.toString("binary");
6578 } else {
6579 return value.toString();
6580 }
6581 };
6582
6583 /**
6584 * @alias ProtoBuf.Reflect.Element
6585 * @expose
6586 */
6587 Reflect.Element = Element;
6588
6589 /**
6590 * Constructs a new Message.
6591 * @exports ProtoBuf.Reflect.Message
6592 * @param {!ProtoBuf.Builder} builder Builder reference
6593 * @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace
6594 * @param {string} name Message name
6595 * @param {Object.<string,*>=} options Message options
6596 * @param {boolean=} isGroup `true` if this is a legacy group
6597 * @param {string?} syntax The syntax level of this definition (e.g., proto3)
6598 * @constructor
6599 * @extends ProtoBuf.Reflect.Namespace
6600 */
6601 var Message = function(builder, parent, name, options, isGroup, syntax) {
6602 Namespace.call(this, builder, parent, name, options, syntax);
6603
6604 /**
6605 * @override
6606 */
6607 this.className = "Message";
6608
6609 /**
6610 * Extensions range.
6611 * @type {!Array.<number>|undefined}
6612 * @expose
6613 */
6614 this.extensions = undefined;
6615
6616 /**
6617 * Runtime message class.
6618 * @type {?function(new:ProtoBuf.Builder.Message)}
6619 * @expose
6620 */
6621 this.clazz = null;
6622
6623 /**
6624 * Whether this is a legacy group or not.
6625 * @type {boolean}
6626 * @expose
6627 */
6628 this.isGroup = !!isGroup;
6629
6630 // The following cached collections are used to efficiently iterate over or look up fields when decoding.
6631
6632 /**
6633 * Cached fields.
6634 * @type {?Array.<!ProtoBuf.Reflect.Message.Field>}
6635 * @private
6636 */
6637 this._fields = null;
6638
6639 /**
6640 * Cached fields by id.
6641 * @type {?Object.<number,!ProtoBuf.Reflect.Message.Field>}
6642 * @private
6643 */
6644 this._fieldsById = null;
6645
6646 /**
6647 * Cached fields by name.
6648 * @type {?Object.<string,!ProtoBuf.Reflect.Message.Field>}
6649 * @private
6650 */
6651 this._fieldsByName = null;
6652 };
6653
6654 /**
6655 * @alias ProtoBuf.Reflect.Message.prototype
6656 * @inner
6657 */
6658 var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);
6659
6660 /**
6661 * Builds the message and returns the runtime counterpart, which is a fully functional class.
6662 * @see ProtoBuf.Builder.Message
6663 * @param {boolean=} rebuild Whether to rebuild or not, defaults to false
6664 * @return {ProtoBuf.Reflect.Message} Message class
6665 * @throws {Error} If the message cannot be built
6666 * @expose
6667 */
6668 MessagePrototype.build = function(rebuild) {
6669 if (this.clazz && !rebuild)
6670 return this.clazz;
6671
6672 // Create the runtime Message class in its own scope
6673 var clazz = (function(ProtoBuf, T) {
6674
6675 var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),
6676 oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);
6677
6678 /**
6679 * Constructs a new runtime Message.
6680 * @name ProtoBuf.Builder.Message
6681 * @class Barebone of all runtime messages.
6682 * @param {!Object.<string,*>|string} values Preset values
6683 * @param {...string} var_args
6684 * @constructor
6685 * @throws {Error} If the message cannot be created
6686 */
6687 var Message = function(values, var_args) {
6688 ProtoBuf.Builder.Message.call(this);
6689
6690 // Create virtual oneof properties
6691 for (var i=0, k=oneofs.length; i<k; ++i)
6692 this[oneofs[i].name] = null;
6693 // Create fields and set default values
6694 for (i=0, k=fields.length; i<k; ++i) {
6695 var field = fields[i];
6696 this[field.name] =
6697 field.repeated ? [] :
6698 (field.map ? new ProtoBuf.Map(field) : null);
6699 if ((field.required || T.syntax === 'proto3') &&
6700 field.defaultValue !== null)
6701 this[field.name] = field.defaultValue;
6702 }
6703
6704 if (arguments.length > 0) {
6705 var value;
6706 // Set field values from a values object
6707 if (arguments.length === 1 && values !== null && typeof values === 'object' &&
6708 /* not _another_ Message */ (typeof values.encode !== 'function' || values instanceof Message) &&
6709 /* not a repeated field */ !Array.isArray(values) &&
6710 /* not a Map */ !(values instanceof ProtoBuf.Map) &&
6711 /* not a ByteBuffer */ !ByteBuffer.isByteBuffer(values) &&
6712 /* not an ArrayBuffer */ !(values instanceof ArrayBuffer) &&
6713 /* not a Long */ !(ProtoBuf.Long && values instanceof ProtoBuf.Long)) {
6714 this.$set(values);
6715 } else // Set field values from arguments, in declaration order
6716 for (i=0, k=arguments.length; i<k; ++i)
6717 if (typeof (value = arguments[i]) !== 'undefined')
6718 this.$set(fields[i].name, value); // May throw
6719 }
6720 };
6721
6722 /**
6723 * @alias ProtoBuf.Builder.Message.prototype
6724 * @inner
6725 */
6726 var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
6727
6728 /**
6729 * Adds a value to a repeated field.
6730 * @name ProtoBuf.Builder.Message#add
6731 * @function
6732 * @param {string} key Field name
6733 * @param {*} value Value to add
6734 * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
6735 * @returns {!ProtoBuf.Builder.Message} this
6736 * @throws {Error} If the value cannot be added
6737 * @expose
6738 */
6739 MessagePrototype.add = function(key, value, noAssert) {
6740 var field = T._fieldsByName[key];
6741 if (!noAssert) {
6742 if (!field)
6743 throw Error(this+"#"+key+" is undefined");
6744 if (!(field instanceof ProtoBuf.Reflect.Message.Field))
6745 throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
6746 if (!field.repeated)
6747 throw Error(this+"#"+key+" is not a repeated field");
6748 value = field.verifyValue(value, true);
6749 }
6750 if (this[key] === null)
6751 this[key] = [];
6752 this[key].push(value);
6753 return this;
6754 };
6755
6756 /**
6757 * Adds a value to a repeated field. This is an alias for {@link ProtoBuf.Builder.Message#add}.
6758 * @name ProtoBuf.Builder.Message#$add
6759 * @function
6760 * @param {string} key Field name
6761 * @param {*} value Value to add
6762 * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
6763 * @returns {!ProtoBuf.Builder.Message} this
6764 * @throws {Error} If the value cannot be added
6765 * @expose
6766 */
6767 MessagePrototype.$add = MessagePrototype.add;
6768
6769 /**
6770 * Sets a field's value.
6771 * @name ProtoBuf.Builder.Message#set
6772 * @function
6773 * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
6774 * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
6775 * @param {boolean=} noAssert Whether to not assert for an actual field / proper value type, defaults to `false`
6776 * @returns {!ProtoBuf.Builder.Message} this
6777 * @throws {Error} If the value cannot be set
6778 * @expose
6779 */
6780 MessagePrototype.set = function(keyOrObj, value, noAssert) {
6781 if (keyOrObj && typeof keyOrObj === 'object') {
6782 noAssert = value;
6783 for (var ikey in keyOrObj) {
6784 // Check if virtual oneof field - don't set these
6785 if (keyOrObj.hasOwnProperty(ikey) && typeof (value = keyOrObj[ikey]) !== 'undefined' && T._oneofsByName[ikey] === undefined)
6786 this.$set(ikey, value, noAssert);
6787 }
6788 return this;
6789 }
6790 var field = T._fieldsByName[keyOrObj];
6791 if (!noAssert) {
6792 if (!field)
6793 throw Error(this+"#"+keyOrObj+" is not a field: undefined");
6794 if (!(field instanceof ProtoBuf.Reflect.Message.Field))
6795 throw Error(this+"#"+keyOrObj+" is not a field: "+field.toString(true));
6796 this[field.name] = (value = field.verifyValue(value)); // May throw
6797 } else
6798 this[keyOrObj] = value;
6799 if (field && field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
6800 var currentField = this[field.oneof.name]; // Virtual field references currently set field
6801 if (value !== null) {
6802 if (currentField !== null && currentField !== field.name)
6803 this[currentField] = null; // Clear currently set field
6804 this[field.oneof.name] = field.name; // Point virtual field at this field
6805 } else if (/* value === null && */currentField === keyOrObj)
6806 this[field.oneof.name] = null; // Clear virtual field (current field explicitly cleared)
6807 }
6808 return this;
6809 };
6810
6811 /**
6812 * Sets a field's value. This is an alias for [@link ProtoBuf.Builder.Message#set}.
6813 * @name ProtoBuf.Builder.Message#$set
6814 * @function
6815 * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
6816 * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
6817 * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
6818 * @throws {Error} If the value cannot be set
6819 * @expose
6820 */
6821 MessagePrototype.$set = MessagePrototype.set;
6822
6823 /**
6824 * Gets a field's value.
6825 * @name ProtoBuf.Builder.Message#get
6826 * @function
6827 * @param {string} key Key
6828 * @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`
6829 * @return {*} Value
6830 * @throws {Error} If there is no such field
6831 * @expose
6832 */
6833 MessagePrototype.get = function(key, noAssert) {
6834 if (noAssert)
6835 return this[key];
6836 var field = T._fieldsByName[key];
6837 if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))
6838 throw Error(this+"#"+key+" is not a field: undefined");
6839 if (!(field instanceof ProtoBuf.Reflect.Message.Field))
6840 throw Error(this+"#"+key+" is not a field: "+field.toString(true));
6841 return this[field.name];
6842 };
6843
6844 /**
6845 * Gets a field's value. This is an alias for {@link ProtoBuf.Builder.Message#$get}.
6846 * @name ProtoBuf.Builder.Message#$get
6847 * @function
6848 * @param {string} key Key
6849 * @return {*} Value
6850 * @throws {Error} If there is no such field
6851 * @expose
6852 */
6853 MessagePrototype.$get = MessagePrototype.get;
6854
6855 // Getters and setters
6856
6857 for (var i=0; i<fields.length; i++) {
6858 var field = fields[i];
6859 // no setters for extension fields as these are named by their fqn
6860 if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)
6861 continue;
6862
6863 if (T.builder.options['populateAccessors'])
6864 (function(field) {
6865 // set/get[SomeValue]
6866 var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {
6867 return match.toUpperCase().replace('_','');
6868 });
6869 Name = Name.substring(0,1).toUpperCase() + Name.substring(1);
6870
6871 // set/get_[some_value] FIXME: Do we really need these?
6872 var name = field.originalName.replace(/([A-Z])/g, function(match) {
6873 return "_"+match;
6874 });
6875
6876 /**
6877 * The current field's unbound setter function.
6878 * @function
6879 * @param {*} value
6880 * @param {boolean=} noAssert
6881 * @returns {!ProtoBuf.Builder.Message}
6882 * @inner
6883 */
6884 var setter = function(value, noAssert) {
6885 this[field.name] = noAssert ? value : field.verifyValue(value);
6886 return this;
6887 };
6888
6889 /**
6890 * The current field's unbound getter function.
6891 * @function
6892 * @returns {*}
6893 * @inner
6894 */
6895 var getter = function() {
6896 return this[field.name];
6897 };
6898
6899 if (T.getChild("set"+Name) === null)
6900 /**
6901 * Sets a value. This method is present for each field, but only if there is no name conflict with
6902 * another field.
6903 * @name ProtoBuf.Builder.Message#set[SomeField]
6904 * @function
6905 * @param {*} value Value to set
6906 * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
6907 * @returns {!ProtoBuf.Builder.Message} this
6908 * @abstract
6909 * @throws {Error} If the value cannot be set
6910 */
6911 MessagePrototype["set"+Name] = setter;
6912
6913 if (T.getChild("set_"+name) === null)
6914 /**
6915 * Sets a value. This method is present for each field, but only if there is no name conflict with
6916 * another field.
6917 * @name ProtoBuf.Builder.Message#set_[some_field]
6918 * @function
6919 * @param {*} value Value to set
6920 * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
6921 * @returns {!ProtoBuf.Builder.Message} this
6922 * @abstract
6923 * @throws {Error} If the value cannot be set
6924 */
6925 MessagePrototype["set_"+name] = setter;
6926
6927 if (T.getChild("get"+Name) === null)
6928 /**
6929 * Gets a value. This method is present for each field, but only if there is no name conflict with
6930 * another field.
6931 * @name ProtoBuf.Builder.Message#get[SomeField]
6932 * @function
6933 * @abstract
6934 * @return {*} The value
6935 */
6936 MessagePrototype["get"+Name] = getter;
6937
6938 if (T.getChild("get_"+name) === null)
6939 /**
6940 * Gets a value. This method is present for each field, but only if there is no name conflict with
6941 * another field.
6942 * @name ProtoBuf.Builder.Message#get_[some_field]
6943 * @function
6944 * @return {*} The value
6945 * @abstract
6946 */
6947 MessagePrototype["get_"+name] = getter;
6948
6949 })(field);
6950 }
6951
6952 // En-/decoding
6953
6954 /**
6955 * Encodes the message.
6956 * @name ProtoBuf.Builder.Message#$encode
6957 * @function
6958 * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
6959 * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
6960 * @return {!ByteBuffer} Encoded message as a ByteBuffer
6961 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
6962 * returns the encoded ByteBuffer in the `encoded` property on the error.
6963 * @expose
6964 * @see ProtoBuf.Builder.Message#encode64
6965 * @see ProtoBuf.Builder.Message#encodeHex
6966 * @see ProtoBuf.Builder.Message#encodeAB
6967 */
6968 MessagePrototype.encode = function(buffer, noVerify) {
6969 if (typeof buffer === 'boolean')
6970 noVerify = buffer,
6971 buffer = undefined;
6972 var isNew = false;
6973 if (!buffer)
6974 buffer = new ByteBuffer(),
6975 isNew = true;
6976 var le = buffer.littleEndian;
6977 try {
6978 T.encode(this, buffer.LE(), noVerify);
6979 return (isNew ? buffer.flip() : buffer).LE(le);
6980 } catch (e) {
6981 buffer.LE(le);
6982 throw(e);
6983 }
6984 };
6985
6986 /**
6987 * Encodes a message using the specified data payload.
6988 * @param {!Object.<string,*>} data Data payload
6989 * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
6990 * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
6991 * @return {!ByteBuffer} Encoded message as a ByteBuffer
6992 * @expose
6993 */
6994 Message.encode = function(data, buffer, noVerify) {
6995 return new Message(data).encode(buffer, noVerify);
6996 };
6997
6998 /**
6999 * Calculates the byte length of the message.
7000 * @name ProtoBuf.Builder.Message#calculate
7001 * @function
7002 * @returns {number} Byte length
7003 * @throws {Error} If the message cannot be calculated or if required fields are missing.
7004 * @expose
7005 */
7006 MessagePrototype.calculate = function() {
7007 return T.calculate(this);
7008 };
7009
7010 /**
7011 * Encodes the varint32 length-delimited message.
7012 * @name ProtoBuf.Builder.Message#encodeDelimited
7013 * @function
7014 * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
7015 * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
7016 * @return {!ByteBuffer} Encoded message as a ByteBuffer
7017 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
7018 * returns the encoded ByteBuffer in the `encoded` property on the error.
7019 * @expose
7020 */
7021 MessagePrototype.encodeDelimited = function(buffer, noVerify) {
7022 var isNew = false;
7023 if (!buffer)
7024 buffer = new ByteBuffer(),
7025 isNew = true;
7026 var enc = new ByteBuffer().LE();
7027 T.encode(this, enc, noVerify).flip();
7028 buffer.writeVarint32(enc.remaining());
7029 buffer.append(enc);
7030 return isNew ? buffer.flip() : buffer;
7031 };
7032
7033 /**
7034 * Directly encodes the message to an ArrayBuffer.
7035 * @name ProtoBuf.Builder.Message#encodeAB
7036 * @function
7037 * @return {ArrayBuffer} Encoded message as ArrayBuffer
7038 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
7039 * returns the encoded ArrayBuffer in the `encoded` property on the error.
7040 * @expose
7041 */
7042 MessagePrototype.encodeAB = function() {
7043 try {
7044 return this.encode().toArrayBuffer();
7045 } catch (e) {
7046 if (e["encoded"]) e["encoded"] = e["encoded"].toArrayBuffer();
7047 throw(e);
7048 }
7049 };
7050
7051 /**
7052 * Returns the message as an ArrayBuffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeAB}.
7053 * @name ProtoBuf.Builder.Message#toArrayBuffer
7054 * @function
7055 * @return {ArrayBuffer} Encoded message as ArrayBuffer
7056 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
7057 * returns the encoded ArrayBuffer in the `encoded` property on the error.
7058 * @expose
7059 */
7060 MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;
7061
7062 /**
7063 * Directly encodes the message to a node Buffer.
7064 * @name ProtoBuf.Builder.Message#encodeNB
7065 * @function
7066 * @return {!Buffer}
7067 * @throws {Error} If the message cannot be encoded, not running under node.js or if required fields are
7068 * missing. The later still returns the encoded node Buffer in the `encoded` property on the error.
7069 * @expose
7070 */
7071 MessagePrototype.encodeNB = function() {
7072 try {
7073 return this.encode().toBuffer();
7074 } catch (e) {
7075 if (e["encoded"]) e["encoded"] = e["encoded"].toBuffer();
7076 throw(e);
7077 }
7078 };
7079
7080 /**
7081 * Returns the message as a node Buffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeNB}.
7082 * @name ProtoBuf.Builder.Message#toBuffer
7083 * @function
7084 * @return {!Buffer}
7085 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
7086 * returns the encoded node Buffer in the `encoded` property on the error.
7087 * @expose
7088 */
7089 MessagePrototype.toBuffer = MessagePrototype.encodeNB;
7090
7091 /**
7092 * Directly encodes the message to a base64 encoded string.
7093 * @name ProtoBuf.Builder.Message#encode64
7094 * @function
7095 * @return {string} Base64 encoded string
7096 * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
7097 * still returns the encoded base64 string in the `encoded` property on the error.
7098 * @expose
7099 */
7100 MessagePrototype.encode64 = function() {
7101 try {
7102 return this.encode().toBase64();
7103 } catch (e) {
7104 if (e["encoded"]) e["encoded"] = e["encoded"].toBase64();
7105 throw(e);
7106 }
7107 };
7108
7109 /**
7110 * Returns the message as a base64 encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encode64}.
7111 * @name ProtoBuf.Builder.Message#toBase64
7112 * @function
7113 * @return {string} Base64 encoded string
7114 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
7115 * returns the encoded base64 string in the `encoded` property on the error.
7116 * @expose
7117 */
7118 MessagePrototype.toBase64 = MessagePrototype.encode64;
7119
7120 /**
7121 * Directly encodes the message to a hex encoded string.
7122 * @name ProtoBuf.Builder.Message#encodeHex
7123 * @function
7124 * @return {string} Hex encoded string
7125 * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
7126 * still returns the encoded hex string in the `encoded` property on the error.
7127 * @expose
7128 */
7129 MessagePrototype.encodeHex = function() {
7130 try {
7131 return this.encode().toHex();
7132 } catch (e) {
7133 if (e["encoded"]) e["encoded"] = e["encoded"].toHex();
7134 throw(e);
7135 }
7136 };
7137
7138 /**
7139 * Returns the message as a hex encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encodeHex}.
7140 * @name ProtoBuf.Builder.Message#toHex
7141 * @function
7142 * @return {string} Hex encoded string
7143 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
7144 * returns the encoded hex string in the `encoded` property on the error.
7145 * @expose
7146 */
7147 MessagePrototype.toHex = MessagePrototype.encodeHex;
7148
7149 /**
7150 * Clones a message object or field value to a raw object.
7151 * @param {*} obj Object to clone
7152 * @param {boolean} binaryAsBase64 Whether to include binary data as base64 strings or as a buffer otherwise
7153 * @param {boolean} longsAsStrings Whether to encode longs as strings
7154 * @param {!ProtoBuf.Reflect.T=} resolvedType The resolved field type if a field
7155 * @returns {*} Cloned object
7156 * @inner
7157 */
7158 function cloneRaw(obj, binaryAsBase64, longsAsStrings, resolvedType) {
7159 if (obj === null || typeof obj !== 'object') {
7160 // Convert enum values to their respective names
7161 if (resolvedType && resolvedType instanceof ProtoBuf.Reflect.Enum) {
7162 var name = ProtoBuf.Reflect.Enum.getName(resolvedType.object, obj);
7163 if (name !== null)
7164 return name;
7165 }
7166 // Pass-through string, number, boolean, null...
7167 return obj;
7168 }
7169 // Convert ByteBuffers to raw buffer or strings
7170 if (ByteBuffer.isByteBuffer(obj))
7171 return binaryAsBase64 ? obj.toBase64() : obj.toBuffer();
7172 // Convert Longs to proper objects or strings
7173 if (ProtoBuf.Long.isLong(obj))
7174 return longsAsStrings ? obj.toString() : ProtoBuf.Long.fromValue(obj);
7175 var clone;
7176 // Clone arrays
7177 if (Array.isArray(obj)) {
7178 clone = [];
7179 obj.forEach(function(v, k) {
7180 clone[k] = cloneRaw(v, binaryAsBase64, longsAsStrings, resolvedType);
7181 });
7182 return clone;
7183 }
7184 clone = {};
7185 // Convert maps to objects
7186 if (obj instanceof ProtoBuf.Map) {
7187 var it = obj.entries();
7188 for (var e = it.next(); !e.done; e = it.next())
7189 clone[obj.keyElem.valueToString(e.value[0])] = cloneRaw(e.value[1], binaryAsBase64, longsAsStrings, obj.valueElem.resolvedType);
7190 return clone;
7191 }
7192 // Everything else is a non-null object
7193 var type = obj.$type,
7194 field = undefined;
7195 for (var i in obj)
7196 if (obj.hasOwnProperty(i)) {
7197 if (type && (field = type.getChild(i)))
7198 clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings, field.resolvedType);
7199 else
7200 clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings);
7201 }
7202 return clone;
7203 }
7204
7205 /**
7206 * Returns the message's raw payload.
7207 * @param {boolean=} binaryAsBase64 Whether to include binary data as base64 strings instead of Buffers, defaults to `false`
7208 * @param {boolean} longsAsStrings Whether to encode longs as strings
7209 * @returns {Object.<string,*>} Raw payload
7210 * @expose
7211 */
7212 MessagePrototype.toRaw = function(binaryAsBase64, longsAsStrings) {
7213 return cloneRaw(this, !!binaryAsBase64, !!longsAsStrings, this.$type);
7214 };
7215
7216 /**
7217 * Encodes a message to JSON.
7218 * @returns {string} JSON string
7219 * @expose
7220 */
7221 MessagePrototype.encodeJSON = function() {
7222 return JSON.stringify(
7223 cloneRaw(this,
7224 /* binary-as-base64 */ true,
7225 /* longs-as-strings */ true,
7226 this.$type
7227 )
7228 );
7229 };
7230
7231 /**
7232 * Decodes a message from the specified buffer or string.
7233 * @name ProtoBuf.Builder.Message.decode
7234 * @function
7235 * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
7236 * @param {(number|string)=} length Message length. Defaults to decode all the remainig data.
7237 * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
7238 * @return {!ProtoBuf.Builder.Message} Decoded message
7239 * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
7240 * returns the decoded message with missing fields in the `decoded` property on the error.
7241 * @expose
7242 * @see ProtoBuf.Builder.Message.decode64
7243 * @see ProtoBuf.Builder.Message.decodeHex
7244 */
7245 Message.decode = function(buffer, length, enc) {
7246 if (typeof length === 'string')
7247 enc = length,
7248 length = -1;
7249 if (typeof buffer === 'string')
7250 buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
7251 else if (!ByteBuffer.isByteBuffer(buffer))
7252 buffer = ByteBuffer.wrap(buffer); // May throw
7253 var le = buffer.littleEndian;
7254 try {
7255 var msg = T.decode(buffer.LE(), length);
7256 buffer.LE(le);
7257 return msg;
7258 } catch (e) {
7259 buffer.LE(le);
7260 throw(e);
7261 }
7262 };
7263
7264 /**
7265 * Decodes a varint32 length-delimited message from the specified buffer or string.
7266 * @name ProtoBuf.Builder.Message.decodeDelimited
7267 * @function
7268 * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
7269 * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
7270 * @return {ProtoBuf.Builder.Message} Decoded message or `null` if not enough bytes are available yet
7271 * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
7272 * returns the decoded message with missing fields in the `decoded` property on the error.
7273 * @expose
7274 */
7275 Message.decodeDelimited = function(buffer, enc) {
7276 if (typeof buffer === 'string')
7277 buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
7278 else if (!ByteBuffer.isByteBuffer(buffer))
7279 buffer = ByteBuffer.wrap(buffer); // May throw
7280 if (buffer.remaining() < 1)
7281 return null;
7282 var off = buffer.offset,
7283 len = buffer.readVarint32();
7284 if (buffer.remaining() < len) {
7285 buffer.offset = off;
7286 return null;
7287 }
7288 try {
7289 var msg = T.decode(buffer.slice(buffer.offset, buffer.offset + len).LE());
7290 buffer.offset += len;
7291 return msg;
7292 } catch (err) {
7293 buffer.offset += len;
7294 throw err;
7295 }
7296 };
7297
7298 /**
7299 * Decodes the message from the specified base64 encoded string.
7300 * @name ProtoBuf.Builder.Message.decode64
7301 * @function
7302 * @param {string} str String to decode from
7303 * @return {!ProtoBuf.Builder.Message} Decoded message
7304 * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
7305 * returns the decoded message with missing fields in the `decoded` property on the error.
7306 * @expose
7307 */
7308 Message.decode64 = function(str) {
7309 return Message.decode(str, "base64");
7310 };
7311
7312 /**
7313 * Decodes the message from the specified hex encoded string.
7314 * @name ProtoBuf.Builder.Message.decodeHex
7315 * @function
7316 * @param {string} str String to decode from
7317 * @return {!ProtoBuf.Builder.Message} Decoded message
7318 * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
7319 * returns the decoded message with missing fields in the `decoded` property on the error.
7320 * @expose
7321 */
7322 Message.decodeHex = function(str) {
7323 return Message.decode(str, "hex");
7324 };
7325
7326 /**
7327 * Decodes the message from a JSON string.
7328 * @name ProtoBuf.Builder.Message.decodeJSON
7329 * @function
7330 * @param {string} str String to decode from
7331 * @return {!ProtoBuf.Builder.Message} Decoded message
7332 * @throws {Error} If the message cannot be decoded or if required fields are
7333 * missing.
7334 * @expose
7335 */
7336 Message.decodeJSON = function(str) {
7337 return new Message(JSON.parse(str));
7338 };
7339
7340 // Utility
7341
7342 /**
7343 * Returns a string representation of this Message.
7344 * @name ProtoBuf.Builder.Message#toString
7345 * @function
7346 * @return {string} String representation as of ".Fully.Qualified.MessageName"
7347 * @expose
7348 */
7349 MessagePrototype.toString = function() {
7350 return T.toString();
7351 };
7352
7353 if (Object.defineProperty)
7354 Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),
7355 Object.defineProperty(MessagePrototype, "$options", { "value": Message["$options"] }),
7356 Object.defineProperty(Message, "$type", { "value": T }),
7357 Object.defineProperty(MessagePrototype, "$type", { "value": T });
7358
7359 return Message;
7360
7361 })(ProtoBuf, this);
7362
7363 // Static enums and prototyped sub-messages / cached collections
7364 this._fields = [];
7365 this._fieldsById = {};
7366 this._fieldsByName = {};
7367 this._oneofsByName = {};
7368 for (var i=0, k=this.children.length, child; i<k; i++) {
7369 child = this.children[i];
7370 if (child instanceof Enum || child instanceof Message || child instanceof Service) {
7371 if (clazz.hasOwnProperty(child.name))
7372 throw Error("Illegal reflect child of "+this.toString(true)+": "+child.toString(true)+" cannot override static property '"+child.name+"'");
7373 clazz[child.name] = child.build();
7374 } else if (child instanceof Message.Field)
7375 child.build(),
7376 this._fields.push(child),
7377 this._fieldsById[child.id] = child,
7378 this._fieldsByName[child.name] = child;
7379 else if (child instanceof Message.OneOf) {
7380 this._oneofsByName[child.name] = child;
7381 }
7382 else if (!(child instanceof Message.OneOf) && !(child instanceof Extension)) // Not built
7383 throw Error("Illegal reflect child of "+this.toString(true)+": "+this.children[i].toString(true));
7384 }
7385
7386 return this.clazz = clazz;
7387 };
7388
7389 /**
7390 * Encodes a runtime message's contents to the specified buffer.
7391 * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
7392 * @param {ByteBuffer} buffer ByteBuffer to write to
7393 * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
7394 * @return {ByteBuffer} The ByteBuffer for chaining
7395 * @throws {Error} If required fields are missing or the message cannot be encoded for another reason
7396 * @expose
7397 */
7398 MessagePrototype.encode = function(message, buffer, noVerify) {
7399 var fieldMissing = null,
7400 field;
7401 for (var i=0, k=this._fields.length, val; i<k; ++i) {
7402 field = this._fields[i];
7403 val = message[field.name];
7404 if (field.required && val === null) {
7405 if (fieldMissing === null)
7406 fieldMissing = field;
7407 } else
7408 field.encode(noVerify ? val : field.verifyValue(val), buffer, message);
7409 }
7410 if (fieldMissing !== null) {
7411 var err = Error("Missing at least one required field for "+this.toString(true)+": "+fieldMissing);
7412 err["encoded"] = buffer; // Still expose what we got
7413 throw(err);
7414 }
7415 return buffer;
7416 };
7417
7418 /**
7419 * Calculates a runtime message's byte length.
7420 * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
7421 * @returns {number} Byte length
7422 * @throws {Error} If required fields are missing or the message cannot be calculated for another reason
7423 * @expose
7424 */
7425 MessagePrototype.calculate = function(message) {
7426 for (var n=0, i=0, k=this._fields.length, field, val; i<k; ++i) {
7427 field = this._fields[i];
7428 val = message[field.name];
7429 if (field.required && val === null)
7430 throw Error("Missing at least one required field for "+this.toString(true)+": "+field);
7431 else
7432 n += field.calculate(val, message);
7433 }
7434 return n;
7435 };
7436
7437 /**
7438 * Skips all data until the end of the specified group has been reached.
7439 * @param {number} expectedId Expected GROUPEND id
7440 * @param {!ByteBuffer} buf ByteBuffer
7441 * @returns {boolean} `true` if a value as been skipped, `false` if the end has been reached
7442 * @throws {Error} If it wasn't possible to find the end of the group (buffer overrun or end tag mismatch)
7443 * @inner
7444 */
7445 function skipTillGroupEnd(expectedId, buf) {
7446 var tag = buf.readVarint32(), // Throws on OOB
7447 wireType = tag & 0x07,
7448 id = tag >>> 3;
7449 switch (wireType) {
7450 case ProtoBuf.WIRE_TYPES.VARINT:
7451 do tag = buf.readUint8();
7452 while ((tag & 0x80) === 0x80);
7453 break;
7454 case ProtoBuf.WIRE_TYPES.BITS64:
7455 buf.offset += 8;
7456 break;
7457 case ProtoBuf.WIRE_TYPES.LDELIM:
7458 tag = buf.readVarint32(); // reads the varint
7459 buf.offset += tag; // skips n bytes
7460 break;
7461 case ProtoBuf.WIRE_TYPES.STARTGROUP:
7462 skipTillGroupEnd(id, buf);
7463 break;
7464 case ProtoBuf.WIRE_TYPES.ENDGROUP:
7465 if (id === expectedId)
7466 return false;
7467 else
7468 throw Error("Illegal GROUPEND after unknown group: "+id+" ("+expectedId+" expected)");
7469 case ProtoBuf.WIRE_TYPES.BITS32:
7470 buf.offset += 4;
7471 break;
7472 default:
7473 throw Error("Illegal wire type in unknown group "+expectedId+": "+wireType);
7474 }
7475 return true;
7476 }
7477
7478 /**
7479 * Decodes an encoded message and returns the decoded message.
7480 * @param {ByteBuffer} buffer ByteBuffer to decode from
7481 * @param {number=} length Message length. Defaults to decode all remaining data.
7482 * @param {number=} expectedGroupEndId Expected GROUPEND id if this is a legacy group
7483 * @return {ProtoBuf.Builder.Message} Decoded message
7484 * @throws {Error} If the message cannot be decoded
7485 * @expose
7486 */
7487 MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {
7488 if (typeof length !== 'number')
7489 length = -1;
7490 var start = buffer.offset,
7491 msg = new (this.clazz)(),
7492 tag, wireType, id, field;
7493 while (buffer.offset < start+length || (length === -1 && buffer.remaining() > 0)) {
7494 tag = buffer.readVarint32();
7495 wireType = tag & 0x07;
7496 id = tag >>> 3;
7497 if (wireType === ProtoBuf.WIRE_TYPES.ENDGROUP) {
7498 if (id !== expectedGroupEndId)
7499 throw Error("Illegal group end indicator for "+this.toString(true)+": "+id+" ("+(expectedGroupEndId ? expectedGroupEndId+" expected" : "not a group")+")");
7500 break;
7501 }
7502 if (!(field = this._fieldsById[id])) {
7503 // "messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing."
7504 switch (wireType) {
7505 case ProtoBuf.WIRE_TYPES.VARINT:
7506 buffer.readVarint32();
7507 break;
7508 case ProtoBuf.WIRE_TYPES.BITS32:
7509 buffer.offset += 4;
7510 break;
7511 case ProtoBuf.WIRE_TYPES.BITS64:
7512 buffer.offset += 8;
7513 break;
7514 case ProtoBuf.WIRE_TYPES.LDELIM:
7515 var len = buffer.readVarint32();
7516 buffer.offset += len;
7517 break;
7518 case ProtoBuf.WIRE_TYPES.STARTGROUP:
7519 while (skipTillGroupEnd(id, buffer)) {}
7520 break;
7521 default:
7522 throw Error("Illegal wire type for unknown field "+id+" in "+this.toString(true)+"#decode: "+wireType);
7523 }
7524 continue;
7525 }
7526 if (field.repeated && !field.options["packed"]) {
7527 msg[field.name].push(field.decode(wireType, buffer));
7528 } else if (field.map) {
7529 var keyval = field.decode(wireType, buffer);
7530 msg[field.name].set(keyval[0], keyval[1]);
7531 } else {
7532 msg[field.name] = field.decode(wireType, buffer);
7533 if (field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
7534 var currentField = msg[field.oneof.name]; // Virtual field references currently set field
7535 if (currentField !== null && currentField !== field.name)
7536 msg[currentField] = null; // Clear currently set field
7537 msg[field.oneof.name] = field.name; // Point virtual field at this field
7538 }
7539 }
7540 }
7541
7542 // Check if all required fields are present and set default values for optional fields that are not
7543 for (var i=0, k=this._fields.length; i<k; ++i) {
7544 field = this._fields[i];
7545 if (msg[field.name] === null) {
7546 if (this.syntax === "proto3") { // Proto3 sets default values by specification
7547 msg[field.name] = field.defaultValue;
7548 } else if (field.required) {
7549 var err = Error("Missing at least one required field for " + this.toString(true) + ": " + field.name);
7550 err["decoded"] = msg; // Still expose what we got
7551 throw(err);
7552 } else if (ProtoBuf.populateDefaults && field.defaultValue !== null)
7553 msg[field.name] = field.defaultValue;
7554 }
7555 }
7556 return msg;
7557 };
7558
7559 /**
7560 * @alias ProtoBuf.Reflect.Message
7561 * @expose
7562 */
7563 Reflect.Message = Message;
7564
7565 /**
7566 * Constructs a new Message Field.
7567 * @exports ProtoBuf.Reflect.Message.Field
7568 * @param {!ProtoBuf.Builder} builder Builder reference
7569 * @param {!ProtoBuf.Reflect.Message} message Message reference
7570 * @param {string} rule Rule, one of requried, optional, repeated
7571 * @param {string?} keytype Key data type, if any.
7572 * @param {string} type Data type, e.g. int32
7573 * @param {string} name Field name
7574 * @param {number} id Unique field id
7575 * @param {Object.<string,*>=} options Options
7576 * @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf
7577 * @param {string?} syntax The syntax level of this definition (e.g., proto3)
7578 * @constructor
7579 * @extends ProtoBuf.Reflect.T
7580 */
7581 var Field = function(builder, message, rule, keytype, type, name, id, options, oneof, syntax) {
7582 T.call(this, builder, message, name);
7583
7584 /**
7585 * @override
7586 */
7587 this.className = "Message.Field";
7588
7589 /**
7590 * Message field required flag.
7591 * @type {boolean}
7592 * @expose
7593 */
7594 this.required = rule === "required";
7595
7596 /**
7597 * Message field repeated flag.
7598 * @type {boolean}
7599 * @expose
7600 */
7601 this.repeated = rule === "repeated";
7602
7603 /**
7604 * Message field map flag.
7605 * @type {boolean}
7606 * @expose
7607 */
7608 this.map = rule === "map";
7609
7610 /**
7611 * Message field key type. Type reference string if unresolved, protobuf
7612 * type if resolved. Valid only if this.map === true, null otherwise.
7613 * @type {string|{name: string, wireType: number}|null}
7614 * @expose
7615 */
7616 this.keyType = keytype || null;
7617
7618 /**
7619 * Message field type. Type reference string if unresolved, protobuf type if
7620 * resolved. In a map field, this is the value type.
7621 * @type {string|{name: string, wireType: number}}
7622 * @expose
7623 */
7624 this.type = type;
7625
7626 /**
7627 * Resolved type reference inside the global namespace.
7628 * @type {ProtoBuf.Reflect.T|null}
7629 * @expose
7630 */
7631 this.resolvedType = null;
7632
7633 /**
7634 * Unique message field id.
7635 * @type {number}
7636 * @expose
7637 */
7638 this.id = id;
7639
7640 /**
7641 * Message field options.
7642 * @type {!Object.<string,*>}
7643 * @dict
7644 * @expose
7645 */
7646 this.options = options || {};
7647
7648 /**
7649 * Default value.
7650 * @type {*}
7651 * @expose
7652 */
7653 this.defaultValue = null;
7654
7655 /**
7656 * Enclosing OneOf.
7657 * @type {?ProtoBuf.Reflect.Message.OneOf}
7658 * @expose
7659 */
7660 this.oneof = oneof || null;
7661
7662 /**
7663 * Syntax level of this definition (e.g., proto3).
7664 * @type {string}
7665 * @expose
7666 */
7667 this.syntax = syntax || 'proto2';
7668
7669 /**
7670 * Original field name.
7671 * @type {string}
7672 * @expose
7673 */
7674 this.originalName = this.name; // Used to revert camelcase transformation on naming collisions
7675
7676 /**
7677 * Element implementation. Created in build() after types are resolved.
7678 * @type {ProtoBuf.Element}
7679 * @expose
7680 */
7681 this.element = null;
7682
7683 /**
7684 * Key element implementation, for map fields. Created in build() after
7685 * types are resolved.
7686 * @type {ProtoBuf.Element}
7687 * @expose
7688 */
7689 this.keyElement = null;
7690
7691 // Convert field names to camel case notation if the override is set
7692 if (this.builder.options['convertFieldsToCamelCase'] && !(this instanceof Message.ExtensionField))
7693 this.name = ProtoBuf.Util.toCamelCase(this.name);
7694 };
7695
7696 /**
7697 * @alias ProtoBuf.Reflect.Message.Field.prototype
7698 * @inner
7699 */
7700 var FieldPrototype = Field.prototype = Object.create(T.prototype);
7701
7702 /**
7703 * Builds the field.
7704 * @override
7705 * @expose
7706 */
7707 FieldPrototype.build = function() {
7708 this.element = new Element(this.type, this.resolvedType, false, this.syntax, this.name);
7709 if (this.map)
7710 this.keyElement = new Element(this.keyType, undefined, true, this.syntax, this.name);
7711
7712 // In proto3, fields do not have field presence, and every field is set to
7713 // its type's default value ("", 0, 0.0, or false).
7714 if (this.syntax === 'proto3' && !this.repeated && !this.map)
7715 this.defaultValue = Element.defaultFieldValue(this.type);
7716
7717 // Otherwise, default values are present when explicitly specified
7718 else if (typeof this.options['default'] !== 'undefined')
7719 this.defaultValue = this.verifyValue(this.options['default']);
7720 };
7721
7722 /**
7723 * Checks if the given value can be set for this field.
7724 * @param {*} value Value to check
7725 * @param {boolean=} skipRepeated Whether to skip the repeated value check or not. Defaults to false.
7726 * @return {*} Verified, maybe adjusted, value
7727 * @throws {Error} If the value cannot be set for this field
7728 * @expose
7729 */
7730 FieldPrototype.verifyValue = function(value, skipRepeated) {
7731 skipRepeated = skipRepeated || false;
7732 var self = this;
7733 function fail(val, msg) {
7734 throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
7735 }
7736 if (value === null) { // NULL values for optional fields
7737 if (this.required)
7738 fail(typeof value, "required");
7739 if (this.syntax === 'proto3' && this.type !== ProtoBuf.TYPES["message"])
7740 fail(typeof value, "proto3 field without field presence cannot be null");
7741 return null;
7742 }
7743 var i;
7744 if (this.repeated && !skipRepeated) { // Repeated values as arrays
7745 if (!Array.isArray(value))
7746 value = [value];
7747 var res = [];
7748 for (i=0; i<value.length; i++)
7749 res.push(this.element.verifyValue(value[i]));
7750 return res;
7751 }
7752 if (this.map && !skipRepeated) { // Map values as objects
7753 if (!(value instanceof ProtoBuf.Map)) {
7754 // If not already a Map, attempt to convert.
7755 if (!(value instanceof Object)) {
7756 fail(typeof value,
7757 "expected ProtoBuf.Map or raw object for map field");
7758 }
7759 return new ProtoBuf.Map(this, value);
7760 } else {
7761 return value;
7762 }
7763 }
7764 // All non-repeated fields expect no array
7765 if (!this.repeated && Array.isArray(value))
7766 fail(typeof value, "no array expected");
7767
7768 return this.element.verifyValue(value);
7769 };
7770
7771 /**
7772 * Determines whether the field will have a presence on the wire given its
7773 * value.
7774 * @param {*} value Verified field value
7775 * @param {!ProtoBuf.Builder.Message} message Runtime message
7776 * @return {boolean} Whether the field will be present on the wire
7777 */
7778 FieldPrototype.hasWirePresence = function(value, message) {
7779 if (this.syntax !== 'proto3')
7780 return (value !== null);
7781 if (this.oneof && message[this.oneof.name] === this.name)
7782 return true;
7783 switch (this.type) {
7784 case ProtoBuf.TYPES["int32"]:
7785 case ProtoBuf.TYPES["sint32"]:
7786 case ProtoBuf.TYPES["sfixed32"]:
7787 case ProtoBuf.TYPES["uint32"]:
7788 case ProtoBuf.TYPES["fixed32"]:
7789 return value !== 0;
7790
7791 case ProtoBuf.TYPES["int64"]:
7792 case ProtoBuf.TYPES["sint64"]:
7793 case ProtoBuf.TYPES["sfixed64"]:
7794 case ProtoBuf.TYPES["uint64"]:
7795 case ProtoBuf.TYPES["fixed64"]:
7796 return value.low !== 0 || value.high !== 0;
7797
7798 case ProtoBuf.TYPES["bool"]:
7799 return value;
7800
7801 case ProtoBuf.TYPES["float"]:
7802 case ProtoBuf.TYPES["double"]:
7803 return value !== 0.0;
7804
7805 case ProtoBuf.TYPES["string"]:
7806 return value.length > 0;
7807
7808 case ProtoBuf.TYPES["bytes"]:
7809 return value.remaining() > 0;
7810
7811 case ProtoBuf.TYPES["enum"]:
7812 return value !== 0;
7813
7814 case ProtoBuf.TYPES["message"]:
7815 return value !== null;
7816 default:
7817 return true;
7818 }
7819 };
7820
7821 /**
7822 * Encodes the specified field value to the specified buffer.
7823 * @param {*} value Verified field value
7824 * @param {ByteBuffer} buffer ByteBuffer to encode to
7825 * @param {!ProtoBuf.Builder.Message} message Runtime message
7826 * @return {ByteBuffer} The ByteBuffer for chaining
7827 * @throws {Error} If the field cannot be encoded
7828 * @expose
7829 */
7830 FieldPrototype.encode = function(value, buffer, message) {
7831 if (this.type === null || typeof this.type !== 'object')
7832 throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
7833 if (value === null || (this.repeated && value.length == 0))
7834 return buffer; // Optional omitted
7835 try {
7836 if (this.repeated) {
7837 var i;
7838 // "Only repeated fields of primitive numeric types (types which use the varint, 32-bit, or 64-bit wire
7839 // types) can be declared 'packed'."
7840 if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
7841 // "All of the elements of the field are packed into a single key-value pair with wire type 2
7842 // (length-delimited). Each element is encoded the same way it would be normally, except without a
7843 // tag preceding it."
7844 buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
7845 buffer.ensureCapacity(buffer.offset += 1); // We do not know the length yet, so let's assume a varint of length 1
7846 var start = buffer.offset; // Remember where the contents begin
7847 for (i=0; i<value.length; i++)
7848 this.element.encodeValue(this.id, value[i], buffer);
7849 var len = buffer.offset-start,
7850 varintLen = ByteBuffer.calculateVarint32(len);
7851 if (varintLen > 1) { // We need to move the contents
7852 var contents = buffer.slice(start, buffer.offset);
7853 start += varintLen-1;
7854 buffer.offset = start;
7855 buffer.append(contents);
7856 }
7857 buffer.writeVarint32(len, start-varintLen);
7858 } else {
7859 // "If your message definition has repeated elements (without the [packed=true] option), the encoded
7860 // message has zero or more key-value pairs with the same tag number"
7861 for (i=0; i<value.length; i++)
7862 buffer.writeVarint32((this.id << 3) | this.type.wireType),
7863 this.element.encodeValue(this.id, value[i], buffer);
7864 }
7865 } else if (this.map) {
7866 // Write out each map entry as a submessage.
7867 value.forEach(function(val, key, m) {
7868 // Compute the length of the submessage (key, val) pair.
7869 var length =
7870 ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
7871 this.keyElement.calculateLength(1, key) +
7872 ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
7873 this.element.calculateLength(2, val);
7874
7875 // Submessage with wire type of length-delimited.
7876 buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
7877 buffer.writeVarint32(length);
7878
7879 // Write out the key and val.
7880 buffer.writeVarint32((1 << 3) | this.keyType.wireType);
7881 this.keyElement.encodeValue(1, key, buffer);
7882 buffer.writeVarint32((2 << 3) | this.type.wireType);
7883 this.element.encodeValue(2, val, buffer);
7884 }, this);
7885 } else {
7886 if (this.hasWirePresence(value, message)) {
7887 buffer.writeVarint32((this.id << 3) | this.type.wireType);
7888 this.element.encodeValue(this.id, value, buffer);
7889 }
7890 }
7891 } catch (e) {
7892 throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
7893 }
7894 return buffer;
7895 };
7896
7897 /**
7898 * Calculates the length of this field's value on the network level.
7899 * @param {*} value Field value
7900 * @param {!ProtoBuf.Builder.Message} message Runtime message
7901 * @returns {number} Byte length
7902 * @expose
7903 */
7904 FieldPrototype.calculate = function(value, message) {
7905 value = this.verifyValue(value); // May throw
7906 if (this.type === null || typeof this.type !== 'object')
7907 throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
7908 if (value === null || (this.repeated && value.length == 0))
7909 return 0; // Optional omitted
7910 var n = 0;
7911 try {
7912 if (this.repeated) {
7913 var i, ni;
7914 if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
7915 n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
7916 ni = 0;
7917 for (i=0; i<value.length; i++)
7918 ni += this.element.calculateLength(this.id, value[i]);
7919 n += ByteBuffer.calculateVarint32(ni);
7920 n += ni;
7921 } else {
7922 for (i=0; i<value.length; i++)
7923 n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType),
7924 n += this.element.calculateLength(this.id, value[i]);
7925 }
7926 } else if (this.map) {
7927 // Each map entry becomes a submessage.
7928 value.forEach(function(val, key, m) {
7929 // Compute the length of the submessage (key, val) pair.
7930 var length =
7931 ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
7932 this.keyElement.calculateLength(1, key) +
7933 ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
7934 this.element.calculateLength(2, val);
7935
7936 n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
7937 n += ByteBuffer.calculateVarint32(length);
7938 n += length;
7939 }, this);
7940 } else {
7941 if (this.hasWirePresence(value, message)) {
7942 n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType);
7943 n += this.element.calculateLength(this.id, value);
7944 }
7945 }
7946 } catch (e) {
7947 throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
7948 }
7949 return n;
7950 };
7951
7952 /**
7953 * Decode the field value from the specified buffer.
7954 * @param {number} wireType Leading wire type
7955 * @param {ByteBuffer} buffer ByteBuffer to decode from
7956 * @param {boolean=} skipRepeated Whether to skip the repeated check or not. Defaults to false.
7957 * @return {*} Decoded value: array for packed repeated fields, [key, value] for
7958 * map fields, or an individual value otherwise.
7959 * @throws {Error} If the field cannot be decoded
7960 * @expose
7961 */
7962 FieldPrototype.decode = function(wireType, buffer, skipRepeated) {
7963 var value, nBytes;
7964
7965 // We expect wireType to match the underlying type's wireType unless we see
7966 // a packed repeated field, or unless this is a map field.
7967 var wireTypeOK =
7968 (!this.map && wireType == this.type.wireType) ||
7969 (!skipRepeated && this.repeated && this.options["packed"] &&
7970 wireType == ProtoBuf.WIRE_TYPES.LDELIM) ||
7971 (this.map && wireType == ProtoBuf.WIRE_TYPES.LDELIM);
7972 if (!wireTypeOK)
7973 throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");
7974
7975 // Handle packed repeated fields.
7976 if (wireType == ProtoBuf.WIRE_TYPES.LDELIM && this.repeated && this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
7977 if (!skipRepeated) {
7978 nBytes = buffer.readVarint32();
7979 nBytes = buffer.offset + nBytes; // Limit
7980 var values = [];
7981 while (buffer.offset < nBytes)
7982 values.push(this.decode(this.type.wireType, buffer, true));
7983 return values;
7984 }
7985 // Read the next value otherwise...
7986 }
7987
7988 // Handle maps.
7989 if (this.map) {
7990 // Read one (key, value) submessage, and return [key, value]
7991 var key = Element.defaultFieldValue(this.keyType);
7992 value = Element.defaultFieldValue(this.type);
7993
7994 // Read the length
7995 nBytes = buffer.readVarint32();
7996 if (buffer.remaining() < nBytes)
7997 throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
7998
7999 // Get a sub-buffer of this key/value submessage
8000 var msgbuf = buffer.clone();
8001 msgbuf.limit = msgbuf.offset + nBytes;
8002 buffer.offset += nBytes;
8003
8004 while (msgbuf.remaining() > 0) {
8005 var tag = msgbuf.readVarint32();
8006 wireType = tag & 0x07;
8007 var id = tag >>> 3;
8008 if (id === 1) {
8009 key = this.keyElement.decode(msgbuf, wireType, id);
8010 } else if (id === 2) {
8011 value = this.element.decode(msgbuf, wireType, id);
8012 } else {
8013 throw Error("Unexpected tag in map field key/value submessage");
8014 }
8015 }
8016
8017 return [key, value];
8018 }
8019
8020 // Handle singular and non-packed repeated field values.
8021 return this.element.decode(buffer, wireType, this.id);
8022 };
8023
8024 /**
8025 * @alias ProtoBuf.Reflect.Message.Field
8026 * @expose
8027 */
8028 Reflect.Message.Field = Field;
8029
8030 /**
8031 * Constructs a new Message ExtensionField.
8032 * @exports ProtoBuf.Reflect.Message.ExtensionField
8033 * @param {!ProtoBuf.Builder} builder Builder reference
8034 * @param {!ProtoBuf.Reflect.Message} message Message reference
8035 * @param {string} rule Rule, one of requried, optional, repeated
8036 * @param {string} type Data type, e.g. int32
8037 * @param {string} name Field name
8038 * @param {number} id Unique field id
8039 * @param {!Object.<string,*>=} options Options
8040 * @constructor
8041 * @extends ProtoBuf.Reflect.Message.Field
8042 */
8043 var ExtensionField = function(builder, message, rule, type, name, id, options) {
8044 Field.call(this, builder, message, rule, /* keytype = */ null, type, name, id, options);
8045
8046 /**
8047 * Extension reference.
8048 * @type {!ProtoBuf.Reflect.Extension}
8049 * @expose
8050 */
8051 this.extension;
8052 };
8053
8054 // Extends Field
8055 ExtensionField.prototype = Object.create(Field.prototype);
8056
8057 /**
8058 * @alias ProtoBuf.Reflect.Message.ExtensionField
8059 * @expose
8060 */
8061 Reflect.Message.ExtensionField = ExtensionField;
8062
8063 /**
8064 * Constructs a new Message OneOf.
8065 * @exports ProtoBuf.Reflect.Message.OneOf
8066 * @param {!ProtoBuf.Builder} builder Builder reference
8067 * @param {!ProtoBuf.Reflect.Message} message Message reference
8068 * @param {string} name OneOf name
8069 * @constructor
8070 * @extends ProtoBuf.Reflect.T
8071 */
8072 var OneOf = function(builder, message, name) {
8073 T.call(this, builder, message, name);
8074
8075 /**
8076 * Enclosed fields.
8077 * @type {!Array.<!ProtoBuf.Reflect.Message.Field>}
8078 * @expose
8079 */
8080 this.fields = [];
8081 };
8082
8083 /**
8084 * @alias ProtoBuf.Reflect.Message.OneOf
8085 * @expose
8086 */
8087 Reflect.Message.OneOf = OneOf;
8088
8089 /**
8090 * Constructs a new Enum.
8091 * @exports ProtoBuf.Reflect.Enum
8092 * @param {!ProtoBuf.Builder} builder Builder reference
8093 * @param {!ProtoBuf.Reflect.T} parent Parent Reflect object
8094 * @param {string} name Enum name
8095 * @param {Object.<string,*>=} options Enum options
8096 * @param {string?} syntax The syntax level (e.g., proto3)
8097 * @constructor
8098 * @extends ProtoBuf.Reflect.Namespace
8099 */
8100 var Enum = function(builder, parent, name, options, syntax) {
8101 Namespace.call(this, builder, parent, name, options, syntax);
8102
8103 /**
8104 * @override
8105 */
8106 this.className = "Enum";
8107
8108 /**
8109 * Runtime enum object.
8110 * @type {Object.<string,number>|null}
8111 * @expose
8112 */
8113 this.object = null;
8114 };
8115
8116 /**
8117 * Gets the string name of an enum value.
8118 * @param {!ProtoBuf.Builder.Enum} enm Runtime enum
8119 * @param {number} value Enum value
8120 * @returns {?string} Name or `null` if not present
8121 * @expose
8122 */
8123 Enum.getName = function(enm, value) {
8124 var keys = Object.keys(enm);
8125 for (var i=0, key; i<keys.length; ++i)
8126 if (enm[key = keys[i]] === value)
8127 return key;
8128 return null;
8129 };
8130
8131 /**
8132 * @alias ProtoBuf.Reflect.Enum.prototype
8133 * @inner
8134 */
8135 var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);
8136
8137 /**
8138 * Builds this enum and returns the runtime counterpart.
8139 * @param {boolean} rebuild Whether to rebuild or not, defaults to false
8140 * @returns {!Object.<string,number>}
8141 * @expose
8142 */
8143 EnumPrototype.build = function(rebuild) {
8144 if (this.object && !rebuild)
8145 return this.object;
8146 var enm = new ProtoBuf.Builder.Enum(),
8147 values = this.getChildren(Enum.Value);
8148 for (var i=0, k=values.length; i<k; ++i)
8149 enm[values[i]['name']] = values[i]['id'];
8150 if (Object.defineProperty)
8151 Object.defineProperty(enm, '$options', {
8152 "value": this.buildOpt(),
8153 "enumerable": false
8154 });
8155 return this.object = enm;
8156 };
8157
8158 /**
8159 * @alias ProtoBuf.Reflect.Enum
8160 * @expose
8161 */
8162 Reflect.Enum = Enum;
8163
8164 /**
8165 * Constructs a new Enum Value.
8166 * @exports ProtoBuf.Reflect.Enum.Value
8167 * @param {!ProtoBuf.Builder} builder Builder reference
8168 * @param {!ProtoBuf.Reflect.Enum} enm Enum reference
8169 * @param {string} name Field name
8170 * @param {number} id Unique field id
8171 * @constructor
8172 * @extends ProtoBuf.Reflect.T
8173 */
8174 var Value = function(builder, enm, name, id) {
8175 T.call(this, builder, enm, name);
8176
8177 /**
8178 * @override
8179 */
8180 this.className = "Enum.Value";
8181
8182 /**
8183 * Unique enum value id.
8184 * @type {number}
8185 * @expose
8186 */
8187 this.id = id;
8188 };
8189
8190 // Extends T
8191 Value.prototype = Object.create(T.prototype);
8192
8193 /**
8194 * @alias ProtoBuf.Reflect.Enum.Value
8195 * @expose
8196 */
8197 Reflect.Enum.Value = Value;
8198
8199 /**
8200 * An extension (field).
8201 * @exports ProtoBuf.Reflect.Extension
8202 * @constructor
8203 * @param {!ProtoBuf.Builder} builder Builder reference
8204 * @param {!ProtoBuf.Reflect.T} parent Parent object
8205 * @param {string} name Object name
8206 * @param {!ProtoBuf.Reflect.Message.Field} field Extension field
8207 */
8208 var Extension = function(builder, parent, name, field) {
8209 T.call(this, builder, parent, name);
8210
8211 /**
8212 * Extended message field.
8213 * @type {!ProtoBuf.Reflect.Message.Field}
8214 * @expose
8215 */
8216 this.field = field;
8217 };
8218
8219 // Extends T
8220 Extension.prototype = Object.create(T.prototype);
8221
8222 /**
8223 * @alias ProtoBuf.Reflect.Extension
8224 * @expose
8225 */
8226 Reflect.Extension = Extension;
8227
8228 /**
8229 * Constructs a new Service.
8230 * @exports ProtoBuf.Reflect.Service
8231 * @param {!ProtoBuf.Builder} builder Builder reference
8232 * @param {!ProtoBuf.Reflect.Namespace} root Root
8233 * @param {string} name Service name
8234 * @param {Object.<string,*>=} options Options
8235 * @constructor
8236 * @extends ProtoBuf.Reflect.Namespace
8237 */
8238 var Service = function(builder, root, name, options) {
8239 Namespace.call(this, builder, root, name, options);
8240
8241 /**
8242 * @override
8243 */
8244 this.className = "Service";
8245
8246 /**
8247 * Built runtime service class.
8248 * @type {?function(new:ProtoBuf.Builder.Service)}
8249 */
8250 this.clazz = null;
8251 };
8252
8253 /**
8254 * @alias ProtoBuf.Reflect.Service.prototype
8255 * @inner
8256 */
8257 var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);
8258
8259 /**
8260 * Builds the service and returns the runtime counterpart, which is a fully functional class.
8261 * @see ProtoBuf.Builder.Service
8262 * @param {boolean=} rebuild Whether to rebuild or not
8263 * @return {Function} Service class
8264 * @throws {Error} If the message cannot be built
8265 * @expose
8266 */
8267 ServicePrototype.build = function(rebuild) {
8268 if (this.clazz && !rebuild)
8269 return this.clazz;
8270
8271 // Create the runtime Service class in its own scope
8272 return this.clazz = (function(ProtoBuf, T) {
8273
8274 /**
8275 * Constructs a new runtime Service.
8276 * @name ProtoBuf.Builder.Service
8277 * @param {function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))=} rpcImpl RPC implementation receiving the method name and the message
8278 * @class Barebone of all runtime services.
8279 * @constructor
8280 * @throws {Error} If the service cannot be created
8281 */
8282 var Service = function(rpcImpl) {
8283 ProtoBuf.Builder.Service.call(this);
8284
8285 /**
8286 * Service implementation.
8287 * @name ProtoBuf.Builder.Service#rpcImpl
8288 * @type {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))}
8289 * @expose
8290 */
8291 this.rpcImpl = rpcImpl || function(name, msg, callback) {
8292 // This is what a user has to implement: A function receiving the method name, the actual message to
8293 // send (type checked) and the callback that's either provided with the error as its first
8294 // argument or null and the actual response message.
8295 setTimeout(callback.bind(this, Error("Not implemented, see: https://github.com/dcodeIO/ProtoBuf.js/wiki/Services")), 0); // Must be async!
8296 };
8297 };
8298
8299 /**
8300 * @alias ProtoBuf.Builder.Service.prototype
8301 * @inner
8302 */
8303 var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
8304
8305 /**
8306 * Asynchronously performs an RPC call using the given RPC implementation.
8307 * @name ProtoBuf.Builder.Service.[Method]
8308 * @function
8309 * @param {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))} rpcImpl RPC implementation
8310 * @param {ProtoBuf.Builder.Message} req Request
8311 * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
8312 * the error if any and the response either as a pre-parsed message or as its raw bytes
8313 * @abstract
8314 */
8315
8316 /**
8317 * Asynchronously performs an RPC call using the instance's RPC implementation.
8318 * @name ProtoBuf.Builder.Service#[Method]
8319 * @function
8320 * @param {ProtoBuf.Builder.Message} req Request
8321 * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
8322 * the error if any and the response either as a pre-parsed message or as its raw bytes
8323 * @abstract
8324 */
8325
8326 var rpc = T.getChildren(ProtoBuf.Reflect.Service.RPCMethod);
8327 for (var i=0; i<rpc.length; i++) {
8328 (function(method) {
8329
8330 // service#Method(message, callback)
8331 ServicePrototype[method.name] = function(req, callback) {
8332 try {
8333 try {
8334 // If given as a buffer, decode the request. Will throw a TypeError if not a valid buffer.
8335 req = method.resolvedRequestType.clazz.decode(ByteBuffer.wrap(req));
8336 } catch (err) {
8337 if (!(err instanceof TypeError))
8338 throw err;
8339 }
8340 if (req === null || typeof req !== 'object')
8341 throw Error("Illegal arguments");
8342 if (!(req instanceof method.resolvedRequestType.clazz))
8343 req = new method.resolvedRequestType.clazz(req);
8344 this.rpcImpl(method.fqn(), req, function(err, res) { // Assumes that this is properly async
8345 if (err) {
8346 callback(err);
8347 return;
8348 }
8349 // Coalesce to empty string when service response has empty content
8350 if (res === null)
8351 res = '';
8352 try { res = method.resolvedResponseType.clazz.decode(res); } catch (notABuffer) {}
8353 if (!res || !(res instanceof method.resolvedResponseType.clazz)) {
8354 callback(Error("Illegal response type received in service method "+ T.name+"#"+method.name));
8355 return;
8356 }
8357 callback(null, res);
8358 });
8359 } catch (err) {
8360 setTimeout(callback.bind(this, err), 0);
8361 }
8362 };
8363
8364 // Service.Method(rpcImpl, message, callback)
8365 Service[method.name] = function(rpcImpl, req, callback) {
8366 new Service(rpcImpl)[method.name](req, callback);
8367 };
8368
8369 if (Object.defineProperty)
8370 Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),
8371 Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });
8372 })(rpc[i]);
8373 }
8374
8375 if (Object.defineProperty)
8376 Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),
8377 Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] }),
8378 Object.defineProperty(Service, "$type", { "value": T }),
8379 Object.defineProperty(ServicePrototype, "$type", { "value": T });
8380
8381 return Service;
8382
8383 })(ProtoBuf, this);
8384 };
8385
8386 /**
8387 * @alias ProtoBuf.Reflect.Service
8388 * @expose
8389 */
8390 Reflect.Service = Service;
8391
8392 /**
8393 * Abstract service method.
8394 * @exports ProtoBuf.Reflect.Service.Method
8395 * @param {!ProtoBuf.Builder} builder Builder reference
8396 * @param {!ProtoBuf.Reflect.Service} svc Service
8397 * @param {string} name Method name
8398 * @param {Object.<string,*>=} options Options
8399 * @constructor
8400 * @extends ProtoBuf.Reflect.T
8401 */
8402 var Method = function(builder, svc, name, options) {
8403 T.call(this, builder, svc, name);
8404
8405 /**
8406 * @override
8407 */
8408 this.className = "Service.Method";
8409
8410 /**
8411 * Options.
8412 * @type {Object.<string, *>}
8413 * @expose
8414 */
8415 this.options = options || {};
8416 };
8417
8418 /**
8419 * @alias ProtoBuf.Reflect.Service.Method.prototype
8420 * @inner
8421 */
8422 var MethodPrototype = Method.prototype = Object.create(T.prototype);
8423
8424 /**
8425 * Builds the method's '$options' property.
8426 * @name ProtoBuf.Reflect.Service.Method#buildOpt
8427 * @function
8428 * @return {Object.<string,*>}
8429 */
8430 MethodPrototype.buildOpt = NamespacePrototype.buildOpt;
8431
8432 /**
8433 * @alias ProtoBuf.Reflect.Service.Method
8434 * @expose
8435 */
8436 Reflect.Service.Method = Method;
8437
8438 /**
8439 * RPC service method.
8440 * @exports ProtoBuf.Reflect.Service.RPCMethod
8441 * @param {!ProtoBuf.Builder} builder Builder reference
8442 * @param {!ProtoBuf.Reflect.Service} svc Service
8443 * @param {string} name Method name
8444 * @param {string} request Request message name
8445 * @param {string} response Response message name
8446 * @param {boolean} request_stream Whether requests are streamed
8447 * @param {boolean} response_stream Whether responses are streamed
8448 * @param {Object.<string,*>=} options Options
8449 * @constructor
8450 * @extends ProtoBuf.Reflect.Service.Method
8451 */
8452 var RPCMethod = function(builder, svc, name, request, response, request_stream, response_stream, options) {
8453 Method.call(this, builder, svc, name, options);
8454
8455 /**
8456 * @override
8457 */
8458 this.className = "Service.RPCMethod";
8459
8460 /**
8461 * Request message name.
8462 * @type {string}
8463 * @expose
8464 */
8465 this.requestName = request;
8466
8467 /**
8468 * Response message name.
8469 * @type {string}
8470 * @expose
8471 */
8472 this.responseName = response;
8473
8474 /**
8475 * Whether requests are streamed
8476 * @type {bool}
8477 * @expose
8478 */
8479 this.requestStream = request_stream;
8480
8481 /**
8482 * Whether responses are streamed
8483 * @type {bool}
8484 * @expose
8485 */
8486 this.responseStream = response_stream;
8487
8488 /**
8489 * Resolved request message type.
8490 * @type {ProtoBuf.Reflect.Message}
8491 * @expose
8492 */
8493 this.resolvedRequestType = null;
8494
8495 /**
8496 * Resolved response message type.
8497 * @type {ProtoBuf.Reflect.Message}
8498 * @expose
8499 */
8500 this.resolvedResponseType = null;
8501 };
8502
8503 // Extends Method
8504 RPCMethod.prototype = Object.create(Method.prototype);
8505
8506 /**
8507 * @alias ProtoBuf.Reflect.Service.RPCMethod
8508 * @expose
8509 */
8510 Reflect.Service.RPCMethod = RPCMethod;
8511
8512 return Reflect;
8513
8514 })(ProtoBuf);
8515
8516 /**
8517 * @alias ProtoBuf.Builder
8518 * @expose
8519 */
8520 ProtoBuf.Builder = (function(ProtoBuf, Lang, Reflect) {
8521
8522 /**
8523 * Constructs a new Builder.
8524 * @exports ProtoBuf.Builder
8525 * @class Provides the functionality to build protocol messages.
8526 * @param {Object.<string,*>=} options Options
8527 * @constructor
8528 */
8529 var Builder = function(options) {
8530
8531 /**
8532 * Namespace.
8533 * @type {ProtoBuf.Reflect.Namespace}
8534 * @expose
8535 */
8536 this.ns = new Reflect.Namespace(this, null, ""); // Global namespace
8537
8538 /**
8539 * Namespace pointer.
8540 * @type {ProtoBuf.Reflect.T}
8541 * @expose
8542 */
8543 this.ptr = this.ns;
8544
8545 /**
8546 * Resolved flag.
8547 * @type {boolean}
8548 * @expose
8549 */
8550 this.resolved = false;
8551
8552 /**
8553 * The current building result.
8554 * @type {Object.<string,ProtoBuf.Builder.Message|Object>|null}
8555 * @expose
8556 */
8557 this.result = null;
8558
8559 /**
8560 * Imported files.
8561 * @type {Array.<string>}
8562 * @expose
8563 */
8564 this.files = {};
8565
8566 /**
8567 * Import root override.
8568 * @type {?string}
8569 * @expose
8570 */
8571 this.importRoot = null;
8572
8573 /**
8574 * Options.
8575 * @type {!Object.<string, *>}
8576 * @expose
8577 */
8578 this.options = options || {};
8579 };
8580
8581 /**
8582 * @alias ProtoBuf.Builder.prototype
8583 * @inner
8584 */
8585 var BuilderPrototype = Builder.prototype;
8586
8587 // ----- Definition tests -----
8588
8589 /**
8590 * Tests if a definition most likely describes a message.
8591 * @param {!Object} def
8592 * @returns {boolean}
8593 * @expose
8594 */
8595 Builder.isMessage = function(def) {
8596 // Messages require a string name
8597 if (typeof def["name"] !== 'string')
8598 return false;
8599 // Messages do not contain values (enum) or rpc methods (service)
8600 if (typeof def["values"] !== 'undefined' || typeof def["rpc"] !== 'undefined')
8601 return false;
8602 return true;
8603 };
8604
8605 /**
8606 * Tests if a definition most likely describes a message field.
8607 * @param {!Object} def
8608 * @returns {boolean}
8609 * @expose
8610 */
8611 Builder.isMessageField = function(def) {
8612 // Message fields require a string rule, name and type and an id
8613 if (typeof def["rule"] !== 'string' || typeof def["name"] !== 'string' || typeof def["type"] !== 'string' || typeof def["id"] === 'undefined')
8614 return false;
8615 return true;
8616 };
8617
8618 /**
8619 * Tests if a definition most likely describes an enum.
8620 * @param {!Object} def
8621 * @returns {boolean}
8622 * @expose
8623 */
8624 Builder.isEnum = function(def) {
8625 // Enums require a string name
8626 if (typeof def["name"] !== 'string')
8627 return false;
8628 // Enums require at least one value
8629 if (typeof def["values"] === 'undefined' || !Array.isArray(def["values"]) || def["values"].length === 0)
8630 return false;
8631 return true;
8632 };
8633
8634 /**
8635 * Tests if a definition most likely describes a service.
8636 * @param {!Object} def
8637 * @returns {boolean}
8638 * @expose
8639 */
8640 Builder.isService = function(def) {
8641 // Services require a string name and an rpc object
8642 if (typeof def["name"] !== 'string' || typeof def["rpc"] !== 'object' || !def["rpc"])
8643 return false;
8644 return true;
8645 };
8646
8647 /**
8648 * Tests if a definition most likely describes an extended message
8649 * @param {!Object} def
8650 * @returns {boolean}
8651 * @expose
8652 */
8653 Builder.isExtend = function(def) {
8654 // Extends rquire a string ref
8655 if (typeof def["ref"] !== 'string')
8656 return false;
8657 return true;
8658 };
8659
8660 // ----- Building -----
8661
8662 /**
8663 * Resets the pointer to the root namespace.
8664 * @returns {!ProtoBuf.Builder} this
8665 * @expose
8666 */
8667 BuilderPrototype.reset = function() {
8668 this.ptr = this.ns;
8669 return this;
8670 };
8671
8672 /**
8673 * Defines a namespace on top of the current pointer position and places the pointer on it.
8674 * @param {string} namespace
8675 * @return {!ProtoBuf.Builder} this
8676 * @expose
8677 */
8678 BuilderPrototype.define = function(namespace) {
8679 if (typeof namespace !== 'string' || !Lang.TYPEREF.test(namespace))
8680 throw Error("illegal namespace: "+namespace);
8681 namespace.split(".").forEach(function(part) {
8682 var ns = this.ptr.getChild(part);
8683 if (ns === null) // Keep existing
8684 this.ptr.addChild(ns = new Reflect.Namespace(this, this.ptr, part));
8685 this.ptr = ns;
8686 }, this);
8687 return this;
8688 };
8689
8690 /**
8691 * Creates the specified definitions at the current pointer position.
8692 * @param {!Array.<!Object>} defs Messages, enums or services to create
8693 * @returns {!ProtoBuf.Builder} this
8694 * @throws {Error} If a message definition is invalid
8695 * @expose
8696 */
8697 BuilderPrototype.create = function(defs) {
8698 if (!defs)
8699 return this; // Nothing to create
8700 if (!Array.isArray(defs))
8701 defs = [defs];
8702 else {
8703 if (defs.length === 0)
8704 return this;
8705 defs = defs.slice();
8706 }
8707
8708 // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.
8709 var stack = [defs];
8710 while (stack.length > 0) {
8711 defs = stack.pop();
8712
8713 if (!Array.isArray(defs)) // Stack always contains entire namespaces
8714 throw Error("not a valid namespace: "+JSON.stringify(defs));
8715
8716 while (defs.length > 0) {
8717 var def = defs.shift(); // Namespaces always contain an array of messages, enums and services
8718
8719 if (Builder.isMessage(def)) {
8720 var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"], def["syntax"]);
8721
8722 // Create OneOfs
8723 var oneofs = {};
8724 if (def["oneofs"])
8725 Object.keys(def["oneofs"]).forEach(function(name) {
8726 obj.addChild(oneofs[name] = new Reflect.Message.OneOf(this, obj, name));
8727 }, this);
8728
8729 // Create fields
8730 if (def["fields"])
8731 def["fields"].forEach(function(fld) {
8732 if (obj.getChild(fld["id"]|0) !== null)
8733 throw Error("duplicate or invalid field id in "+obj.name+": "+fld['id']);
8734 if (fld["options"] && typeof fld["options"] !== 'object')
8735 throw Error("illegal field options in "+obj.name+"#"+fld["name"]);
8736 var oneof = null;
8737 if (typeof fld["oneof"] === 'string' && !(oneof = oneofs[fld["oneof"]]))
8738 throw Error("illegal oneof in "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);
8739 fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["keytype"], fld["type"], fld["name"], fld["id"], fld["options"], oneof, def["syntax"]);
8740 if (oneof)
8741 oneof.fields.push(fld);
8742 obj.addChild(fld);
8743 }, this);
8744
8745 // Push children to stack
8746 var subObj = [];
8747 if (def["enums"])
8748 def["enums"].forEach(function(enm) {
8749 subObj.push(enm);
8750 });
8751 if (def["messages"])
8752 def["messages"].forEach(function(msg) {
8753 subObj.push(msg);
8754 });
8755 if (def["services"])
8756 def["services"].forEach(function(svc) {
8757 subObj.push(svc);
8758 });
8759
8760 // Set extension ranges
8761 if (def["extensions"]) {
8762 if (typeof def["extensions"][0] === 'number') // pre 5.0.1
8763 obj.extensions = [ def["extensions"] ];
8764 else
8765 obj.extensions = def["extensions"];
8766 }
8767
8768 // Create on top of current namespace
8769 this.ptr.addChild(obj);
8770 if (subObj.length > 0) {
8771 stack.push(defs); // Push the current level back
8772 defs = subObj; // Continue processing sub level
8773 subObj = null;
8774 this.ptr = obj; // And move the pointer to this namespace
8775 obj = null;
8776 continue;
8777 }
8778 subObj = null;
8779
8780 } else if (Builder.isEnum(def)) {
8781
8782 obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"], def["syntax"]);
8783 def["values"].forEach(function(val) {
8784 obj.addChild(new Reflect.Enum.Value(this, obj, val["name"], val["id"]));
8785 }, this);
8786 this.ptr.addChild(obj);
8787
8788 } else if (Builder.isService(def)) {
8789
8790 obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);
8791 Object.keys(def["rpc"]).forEach(function(name) {
8792 var mtd = def["rpc"][name];
8793 obj.addChild(new Reflect.Service.RPCMethod(this, obj, name, mtd["request"], mtd["response"], !!mtd["request_stream"], !!mtd["response_stream"], mtd["options"]));
8794 }, this);
8795 this.ptr.addChild(obj);
8796
8797 } else if (Builder.isExtend(def)) {
8798
8799 obj = this.ptr.resolve(def["ref"], true);
8800 if (obj) {
8801 def["fields"].forEach(function(fld) {
8802 if (obj.getChild(fld['id']|0) !== null)
8803 throw Error("duplicate extended field id in "+obj.name+": "+fld['id']);
8804 // Check if field id is allowed to be extended
8805 if (obj.extensions) {
8806 var valid = false;
8807 obj.extensions.forEach(function(range) {
8808 if (fld["id"] >= range[0] && fld["id"] <= range[1])
8809 valid = true;
8810 });
8811 if (!valid)
8812 throw Error("illegal extended field id in "+obj.name+": "+fld['id']+" (not within valid ranges)");
8813 }
8814 // Convert extension field names to camel case notation if the override is set
8815 var name = fld["name"];
8816 if (this.options['convertFieldsToCamelCase'])
8817 name = ProtoBuf.Util.toCamelCase(name);
8818 // see #161: Extensions use their fully qualified name as their runtime key and...
8819 var field = new Reflect.Message.ExtensionField(this, obj, fld["rule"], fld["type"], this.ptr.fqn()+'.'+name, fld["id"], fld["options"]);
8820 // ...are added on top of the current namespace as an extension which is used for
8821 // resolving their type later on (the extension always keeps the original name to
8822 // prevent naming collisions)
8823 var ext = new Reflect.Extension(this, this.ptr, fld["name"], field);
8824 field.extension = ext;
8825 this.ptr.addChild(ext);
8826 obj.addChild(field);
8827 }, this);
8828
8829 } else if (!/\.?google\.protobuf\./.test(def["ref"])) // Silently skip internal extensions
8830 throw Error("extended message "+def["ref"]+" is not defined");
8831
8832 } else
8833 throw Error("not a valid definition: "+JSON.stringify(def));
8834
8835 def = null;
8836 obj = null;
8837 }
8838 // Break goes here
8839 defs = null;
8840 this.ptr = this.ptr.parent; // Namespace done, continue at parent
8841 }
8842 this.resolved = false; // Require re-resolve
8843 this.result = null; // Require re-build
8844 return this;
8845 };
8846
8847 /**
8848 * Propagates syntax to all children.
8849 * @param {!Object} parent
8850 * @inner
8851 */
8852 function propagateSyntax(parent) {
8853 if (parent['messages']) {
8854 parent['messages'].forEach(function(child) {
8855 child["syntax"] = parent["syntax"];
8856 propagateSyntax(child);
8857 });
8858 }
8859 if (parent['enums']) {
8860 parent['enums'].forEach(function(child) {
8861 child["syntax"] = parent["syntax"];
8862 });
8863 }
8864 }
8865
8866 /**
8867 * Imports another definition into this builder.
8868 * @param {Object.<string,*>} json Parsed import
8869 * @param {(string|{root: string, file: string})=} filename Imported file name
8870 * @returns {!ProtoBuf.Builder} this
8871 * @throws {Error} If the definition or file cannot be imported
8872 * @expose
8873 */
8874 BuilderPrototype["import"] = function(json, filename) {
8875 var delim = '/';
8876
8877 // Make sure to skip duplicate imports
8878
8879 if (typeof filename === 'string') {
8880
8881 if (ProtoBuf.Util.IS_NODE)
8882 filename = require$$2['resolve'](filename);
8883 if (this.files[filename] === true)
8884 return this.reset();
8885 this.files[filename] = true;
8886
8887 } else if (typeof filename === 'object') { // Object with root, file.
8888
8889 var root = filename.root;
8890 if (ProtoBuf.Util.IS_NODE)
8891 root = require$$2['resolve'](root);
8892 if (root.indexOf("\\") >= 0 || filename.file.indexOf("\\") >= 0)
8893 delim = '\\';
8894 var fname;
8895 if (ProtoBuf.Util.IS_NODE)
8896 fname = require$$2['join'](root, filename.file);
8897 else
8898 fname = root + delim + filename.file;
8899 if (this.files[fname] === true)
8900 return this.reset();
8901 this.files[fname] = true;
8902 }
8903
8904 // Import imports
8905
8906 if (json['imports'] && json['imports'].length > 0) {
8907 var importRoot,
8908 resetRoot = false;
8909
8910 if (typeof filename === 'object') { // If an import root is specified, override
8911
8912 this.importRoot = filename["root"]; resetRoot = true; // ... and reset afterwards
8913 importRoot = this.importRoot;
8914 filename = filename["file"];
8915 if (importRoot.indexOf("\\") >= 0 || filename.indexOf("\\") >= 0)
8916 delim = '\\';
8917
8918 } else if (typeof filename === 'string') {
8919
8920 if (this.importRoot) // If import root is overridden, use it
8921 importRoot = this.importRoot;
8922 else { // Otherwise compute from filename
8923 if (filename.indexOf("/") >= 0) { // Unix
8924 importRoot = filename.replace(/\/[^\/]*$/, "");
8925 if (/* /file.proto */ importRoot === "")
8926 importRoot = "/";
8927 } else if (filename.indexOf("\\") >= 0) { // Windows
8928 importRoot = filename.replace(/\\[^\\]*$/, "");
8929 delim = '\\';
8930 } else
8931 importRoot = ".";
8932 }
8933
8934 } else
8935 importRoot = null;
8936
8937 for (var i=0; i<json['imports'].length; i++) {
8938 if (typeof json['imports'][i] === 'string') { // Import file
8939 if (!importRoot)
8940 throw Error("cannot determine import root");
8941 var importFilename = json['imports'][i];
8942 if (importFilename === "google/protobuf/descriptor.proto")
8943 continue; // Not needed and therefore not used
8944 if (ProtoBuf.Util.IS_NODE)
8945 importFilename = require$$2['join'](importRoot, importFilename);
8946 else
8947 importFilename = importRoot + delim + importFilename;
8948 if (this.files[importFilename] === true)
8949 continue; // Already imported
8950 if (/\.proto$/i.test(importFilename) && !ProtoBuf.DotProto) // If this is a light build
8951 importFilename = importFilename.replace(/\.proto$/, ".json"); // always load the JSON file
8952 var contents = ProtoBuf.Util.fetch(importFilename);
8953 if (contents === null)
8954 throw Error("failed to import '"+importFilename+"' in '"+filename+"': file not found");
8955 if (/\.json$/i.test(importFilename)) // Always possible
8956 this["import"](JSON.parse(contents+""), importFilename); // May throw
8957 else
8958 this["import"](ProtoBuf.DotProto.Parser.parse(contents), importFilename); // May throw
8959 } else // Import structure
8960 if (!filename)
8961 this["import"](json['imports'][i]);
8962 else if (/\.(\w+)$/.test(filename)) // With extension: Append _importN to the name portion to make it unique
8963 this["import"](json['imports'][i], filename.replace(/^(.+)\.(\w+)$/, function($0, $1, $2) { return $1+"_import"+i+"."+$2; }));
8964 else // Without extension: Append _importN to make it unique
8965 this["import"](json['imports'][i], filename+"_import"+i);
8966 }
8967 if (resetRoot) // Reset import root override when all imports are done
8968 this.importRoot = null;
8969 }
8970
8971 // Import structures
8972
8973 if (json['package'])
8974 this.define(json['package']);
8975 if (json['syntax'])
8976 propagateSyntax(json);
8977 var base = this.ptr;
8978 if (json['options'])
8979 Object.keys(json['options']).forEach(function(key) {
8980 base.options[key] = json['options'][key];
8981 });
8982 if (json['messages'])
8983 this.create(json['messages']),
8984 this.ptr = base;
8985 if (json['enums'])
8986 this.create(json['enums']),
8987 this.ptr = base;
8988 if (json['services'])
8989 this.create(json['services']),
8990 this.ptr = base;
8991 if (json['extends'])
8992 this.create(json['extends']);
8993
8994 return this.reset();
8995 };
8996
8997 /**
8998 * Resolves all namespace objects.
8999 * @throws {Error} If a type cannot be resolved
9000 * @returns {!ProtoBuf.Builder} this
9001 * @expose
9002 */
9003 BuilderPrototype.resolveAll = function() {
9004 // Resolve all reflected objects
9005 var res;
9006 if (this.ptr == null || typeof this.ptr.type === 'object')
9007 return this; // Done (already resolved)
9008
9009 if (this.ptr instanceof Reflect.Namespace) { // Resolve children
9010
9011 this.ptr.children.forEach(function(child) {
9012 this.ptr = child;
9013 this.resolveAll();
9014 }, this);
9015
9016 } else if (this.ptr instanceof Reflect.Message.Field) { // Resolve type
9017
9018 if (!Lang.TYPE.test(this.ptr.type)) {
9019 if (!Lang.TYPEREF.test(this.ptr.type))
9020 throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
9021 res = (this.ptr instanceof Reflect.Message.ExtensionField ? this.ptr.extension.parent : this.ptr.parent).resolve(this.ptr.type, true);
9022 if (!res)
9023 throw Error("unresolvable type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
9024 this.ptr.resolvedType = res;
9025 if (res instanceof Reflect.Enum) {
9026 this.ptr.type = ProtoBuf.TYPES["enum"];
9027 if (this.ptr.syntax === 'proto3' && res.syntax !== 'proto3')
9028 throw Error("proto3 message cannot reference proto2 enum");
9029 }
9030 else if (res instanceof Reflect.Message)
9031 this.ptr.type = res.isGroup ? ProtoBuf.TYPES["group"] : ProtoBuf.TYPES["message"];
9032 else
9033 throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
9034 } else
9035 this.ptr.type = ProtoBuf.TYPES[this.ptr.type];
9036
9037 // If it's a map field, also resolve the key type. The key type can be only a numeric, string, or bool type
9038 // (i.e., no enums or messages), so we don't need to resolve against the current namespace.
9039 if (this.ptr.map) {
9040 if (!Lang.TYPE.test(this.ptr.keyType))
9041 throw Error("illegal key type for map field in "+this.ptr.toString(true)+": "+this.ptr.keyType);
9042 this.ptr.keyType = ProtoBuf.TYPES[this.ptr.keyType];
9043 }
9044
9045 // If it's a repeated and packable field then proto3 mandates it should be packed by
9046 // default
9047 if (
9048 this.ptr.syntax === 'proto3' &&
9049 this.ptr.repeated && this.ptr.options.packed === undefined &&
9050 ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.ptr.type.wireType) !== -1
9051 ) {
9052 this.ptr.options.packed = true;
9053 }
9054
9055 } else if (this.ptr instanceof ProtoBuf.Reflect.Service.Method) {
9056
9057 if (this.ptr instanceof ProtoBuf.Reflect.Service.RPCMethod) {
9058 res = this.ptr.parent.resolve(this.ptr.requestName, true);
9059 if (!res || !(res instanceof ProtoBuf.Reflect.Message))
9060 throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.requestName);
9061 this.ptr.resolvedRequestType = res;
9062 res = this.ptr.parent.resolve(this.ptr.responseName, true);
9063 if (!res || !(res instanceof ProtoBuf.Reflect.Message))
9064 throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.responseName);
9065 this.ptr.resolvedResponseType = res;
9066 } else // Should not happen as nothing else is implemented
9067 throw Error("illegal service type in "+this.ptr.toString(true));
9068
9069 } else if (
9070 !(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && // Not built
9071 !(this.ptr instanceof ProtoBuf.Reflect.Extension) && // Not built
9072 !(this.ptr instanceof ProtoBuf.Reflect.Enum.Value) // Built in enum
9073 )
9074 throw Error("illegal object in namespace: "+typeof(this.ptr)+": "+this.ptr);
9075
9076 return this.reset();
9077 };
9078
9079 /**
9080 * Builds the protocol. This will first try to resolve all definitions and, if this has been successful,
9081 * return the built package.
9082 * @param {(string|Array.<string>)=} path Specifies what to return. If omitted, the entire namespace will be returned.
9083 * @returns {!ProtoBuf.Builder.Message|!Object.<string,*>}
9084 * @throws {Error} If a type could not be resolved
9085 * @expose
9086 */
9087 BuilderPrototype.build = function(path) {
9088 this.reset();
9089 if (!this.resolved)
9090 this.resolveAll(),
9091 this.resolved = true,
9092 this.result = null; // Require re-build
9093 if (this.result === null) // (Re-)Build
9094 this.result = this.ns.build();
9095 if (!path)
9096 return this.result;
9097 var part = typeof path === 'string' ? path.split(".") : path,
9098 ptr = this.result; // Build namespace pointer (no hasChild etc.)
9099 for (var i=0; i<part.length; i++)
9100 if (ptr[part[i]])
9101 ptr = ptr[part[i]];
9102 else {
9103 ptr = null;
9104 break;
9105 }
9106 return ptr;
9107 };
9108
9109 /**
9110 * Similar to {@link ProtoBuf.Builder#build}, but looks up the internal reflection descriptor.
9111 * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.
9112 * @param {boolean=} excludeNonNamespace Excludes non-namespace types like fields, defaults to `false`
9113 * @returns {?ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found
9114 */
9115 BuilderPrototype.lookup = function(path, excludeNonNamespace) {
9116 return path ? this.ns.resolve(path, excludeNonNamespace) : this.ns;
9117 };
9118
9119 /**
9120 * Returns a string representation of this object.
9121 * @return {string} String representation as of "Builder"
9122 * @expose
9123 */
9124 BuilderPrototype.toString = function() {
9125 return "Builder";
9126 };
9127
9128 // ----- Base classes -----
9129 // Exist for the sole purpose of being able to "... instanceof ProtoBuf.Builder.Message" etc.
9130
9131 /**
9132 * @alias ProtoBuf.Builder.Message
9133 */
9134 Builder.Message = function() {};
9135
9136 /**
9137 * @alias ProtoBuf.Builder.Enum
9138 */
9139 Builder.Enum = function() {};
9140
9141 /**
9142 * @alias ProtoBuf.Builder.Message
9143 */
9144 Builder.Service = function() {};
9145
9146 return Builder;
9147
9148 })(ProtoBuf, ProtoBuf.Lang, ProtoBuf.Reflect);
9149
9150 /**
9151 * @alias ProtoBuf.Map
9152 * @expose
9153 */
9154 ProtoBuf.Map = (function(ProtoBuf, Reflect) {
9155
9156 /**
9157 * Constructs a new Map. A Map is a container that is used to implement map
9158 * fields on message objects. It closely follows the ES6 Map API; however,
9159 * it is distinct because we do not want to depend on external polyfills or
9160 * on ES6 itself.
9161 *
9162 * @exports ProtoBuf.Map
9163 * @param {!ProtoBuf.Reflect.Field} field Map field
9164 * @param {Object.<string,*>=} contents Initial contents
9165 * @constructor
9166 */
9167 var Map = function(field, contents) {
9168 if (!field.map)
9169 throw Error("field is not a map");
9170
9171 /**
9172 * The field corresponding to this map.
9173 * @type {!ProtoBuf.Reflect.Field}
9174 */
9175 this.field = field;
9176
9177 /**
9178 * Element instance corresponding to key type.
9179 * @type {!ProtoBuf.Reflect.Element}
9180 */
9181 this.keyElem = new Reflect.Element(field.keyType, null, true, field.syntax);
9182
9183 /**
9184 * Element instance corresponding to value type.
9185 * @type {!ProtoBuf.Reflect.Element}
9186 */
9187 this.valueElem = new Reflect.Element(field.type, field.resolvedType, false, field.syntax);
9188
9189 /**
9190 * Internal map: stores mapping of (string form of key) -> (key, value)
9191 * pair.
9192 *
9193 * We provide map semantics for arbitrary key types, but we build on top
9194 * of an Object, which has only string keys. In order to avoid the need
9195 * to convert a string key back to its native type in many situations,
9196 * we store the native key value alongside the value. Thus, we only need
9197 * a one-way mapping from a key type to its string form that guarantees
9198 * uniqueness and equality (i.e., str(K1) === str(K2) if and only if K1
9199 * === K2).
9200 *
9201 * @type {!Object<string, {key: *, value: *}>}
9202 */
9203 this.map = {};
9204
9205 /**
9206 * Returns the number of elements in the map.
9207 */
9208 Object.defineProperty(this, "size", {
9209 get: function() { return Object.keys(this.map).length; }
9210 });
9211
9212 // Fill initial contents from a raw object.
9213 if (contents) {
9214 var keys = Object.keys(contents);
9215 for (var i = 0; i < keys.length; i++) {
9216 var key = this.keyElem.valueFromString(keys[i]);
9217 var val = this.valueElem.verifyValue(contents[keys[i]]);
9218 this.map[this.keyElem.valueToString(key)] =
9219 { key: key, value: val };
9220 }
9221 }
9222 };
9223
9224 var MapPrototype = Map.prototype;
9225
9226 /**
9227 * Helper: return an iterator over an array.
9228 * @param {!Array<*>} arr the array
9229 * @returns {!Object} an iterator
9230 * @inner
9231 */
9232 function arrayIterator(arr) {
9233 var idx = 0;
9234 return {
9235 next: function() {
9236 if (idx < arr.length)
9237 return { done: false, value: arr[idx++] };
9238 return { done: true };
9239 }
9240 }
9241 }
9242
9243 /**
9244 * Clears the map.
9245 */
9246 MapPrototype.clear = function() {
9247 this.map = {};
9248 };
9249
9250 /**
9251 * Deletes a particular key from the map.
9252 * @returns {boolean} Whether any entry with this key was deleted.
9253 */
9254 MapPrototype["delete"] = function(key) {
9255 var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
9256 var hadKey = keyValue in this.map;
9257 delete this.map[keyValue];
9258 return hadKey;
9259 };
9260
9261 /**
9262 * Returns an iterator over [key, value] pairs in the map.
9263 * @returns {Object} The iterator
9264 */
9265 MapPrototype.entries = function() {
9266 var entries = [];
9267 var strKeys = Object.keys(this.map);
9268 for (var i = 0, entry; i < strKeys.length; i++)
9269 entries.push([(entry=this.map[strKeys[i]]).key, entry.value]);
9270 return arrayIterator(entries);
9271 };
9272
9273 /**
9274 * Returns an iterator over keys in the map.
9275 * @returns {Object} The iterator
9276 */
9277 MapPrototype.keys = function() {
9278 var keys = [];
9279 var strKeys = Object.keys(this.map);
9280 for (var i = 0; i < strKeys.length; i++)
9281 keys.push(this.map[strKeys[i]].key);
9282 return arrayIterator(keys);
9283 };
9284
9285 /**
9286 * Returns an iterator over values in the map.
9287 * @returns {!Object} The iterator
9288 */
9289 MapPrototype.values = function() {
9290 var values = [];
9291 var strKeys = Object.keys(this.map);
9292 for (var i = 0; i < strKeys.length; i++)
9293 values.push(this.map[strKeys[i]].value);
9294 return arrayIterator(values);
9295 };
9296
9297 /**
9298 * Iterates over entries in the map, calling a function on each.
9299 * @param {function(this:*, *, *, *)} cb The callback to invoke with value, key, and map arguments.
9300 * @param {Object=} thisArg The `this` value for the callback
9301 */
9302 MapPrototype.forEach = function(cb, thisArg) {
9303 var strKeys = Object.keys(this.map);
9304 for (var i = 0, entry; i < strKeys.length; i++)
9305 cb.call(thisArg, (entry=this.map[strKeys[i]]).value, entry.key, this);
9306 };
9307
9308 /**
9309 * Sets a key in the map to the given value.
9310 * @param {*} key The key
9311 * @param {*} value The value
9312 * @returns {!ProtoBuf.Map} The map instance
9313 */
9314 MapPrototype.set = function(key, value) {
9315 var keyValue = this.keyElem.verifyValue(key);
9316 var valValue = this.valueElem.verifyValue(value);
9317 this.map[this.keyElem.valueToString(keyValue)] =
9318 { key: keyValue, value: valValue };
9319 return this;
9320 };
9321
9322 /**
9323 * Gets the value corresponding to a key in the map.
9324 * @param {*} key The key
9325 * @returns {*|undefined} The value, or `undefined` if key not present
9326 */
9327 MapPrototype.get = function(key) {
9328 var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
9329 if (!(keyValue in this.map))
9330 return undefined;
9331 return this.map[keyValue].value;
9332 };
9333
9334 /**
9335 * Determines whether the given key is present in the map.
9336 * @param {*} key The key
9337 * @returns {boolean} `true` if the key is present
9338 */
9339 MapPrototype.has = function(key) {
9340 var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
9341 return (keyValue in this.map);
9342 };
9343
9344 return Map;
9345 })(ProtoBuf, ProtoBuf.Reflect);
9346
9347
9348 /**
9349 * Constructs a new empty Builder.
9350 * @param {Object.<string,*>=} options Builder options, defaults to global options set on ProtoBuf
9351 * @return {!ProtoBuf.Builder} Builder
9352 * @expose
9353 */
9354 ProtoBuf.newBuilder = function(options) {
9355 options = options || {};
9356 if (typeof options['convertFieldsToCamelCase'] === 'undefined')
9357 options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;
9358 if (typeof options['populateAccessors'] === 'undefined')
9359 options['populateAccessors'] = ProtoBuf.populateAccessors;
9360 return new ProtoBuf.Builder(options);
9361 };
9362
9363 /**
9364 * Loads a .json definition and returns the Builder.
9365 * @param {!*|string} json JSON definition
9366 * @param {(ProtoBuf.Builder|string|{root: string, file: string})=} builder Builder to append to. Will create a new one if omitted.
9367 * @param {(string|{root: string, file: string})=} filename The corresponding file name if known. Must be specified for imports.
9368 * @return {ProtoBuf.Builder} Builder to create new messages
9369 * @throws {Error} If the definition cannot be parsed or built
9370 * @expose
9371 */
9372 ProtoBuf.loadJson = function(json, builder, filename) {
9373 if (typeof builder === 'string' || (builder && typeof builder["file"] === 'string' && typeof builder["root"] === 'string'))
9374 filename = builder,
9375 builder = null;
9376 if (!builder || typeof builder !== 'object')
9377 builder = ProtoBuf.newBuilder();
9378 if (typeof json === 'string')
9379 json = JSON.parse(json);
9380 builder["import"](json, filename);
9381 builder.resolveAll();
9382 return builder;
9383 };
9384
9385 /**
9386 * Loads a .json file and returns the Builder.
9387 * @param {string|!{root: string, file: string}} filename Path to json file or an object specifying 'file' with
9388 * an overridden 'root' path for all imported files.
9389 * @param {function(?Error, !ProtoBuf.Builder=)=} callback Callback that will receive `null` as the first and
9390 * the Builder as its second argument on success, otherwise the error as its first argument. If omitted, the
9391 * file will be read synchronously and this function will return the Builder.
9392 * @param {ProtoBuf.Builder=} builder Builder to append to. Will create a new one if omitted.
9393 * @return {?ProtoBuf.Builder|undefined} The Builder if synchronous (no callback specified, will be NULL if the
9394 * request has failed), else undefined
9395 * @expose
9396 */
9397 ProtoBuf.loadJsonFile = function(filename, callback, builder) {
9398 if (callback && typeof callback === 'object')
9399 builder = callback,
9400 callback = null;
9401 else if (!callback || typeof callback !== 'function')
9402 callback = null;
9403 if (callback)
9404 return ProtoBuf.Util.fetch(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(contents) {
9405 if (contents === null) {
9406 callback(Error("Failed to fetch file"));
9407 return;
9408 }
9409 try {
9410 callback(null, ProtoBuf.loadJson(JSON.parse(contents), builder, filename));
9411 } catch (e) {
9412 callback(e);
9413 }
9414 });
9415 var contents = ProtoBuf.Util.fetch(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename);
9416 return contents === null ? null : ProtoBuf.loadJson(JSON.parse(contents), builder, filename);
9417 };
9418
9419 return ProtoBuf;
9420 });
9421 });
9422
9423 var messageCompiled = protobufLight.newBuilder({})['import']({
9424 package: 'push_server.messages2',
9425 syntax: 'proto2',
9426 options: {
9427 objc_class_prefix: 'AVIM'
9428 },
9429 messages: [{
9430 name: 'JsonObjectMessage',
9431 syntax: 'proto2',
9432 fields: [{
9433 rule: 'required',
9434 type: 'string',
9435 name: 'data',
9436 id: 1
9437 }]
9438 }, {
9439 name: 'UnreadTuple',
9440 syntax: 'proto2',
9441 fields: [{
9442 rule: 'required',
9443 type: 'string',
9444 name: 'cid',
9445 id: 1
9446 }, {
9447 rule: 'required',
9448 type: 'int32',
9449 name: 'unread',
9450 id: 2
9451 }, {
9452 rule: 'optional',
9453 type: 'string',
9454 name: 'mid',
9455 id: 3
9456 }, {
9457 rule: 'optional',
9458 type: 'int64',
9459 name: 'timestamp',
9460 id: 4
9461 }, {
9462 rule: 'optional',
9463 type: 'string',
9464 name: 'from',
9465 id: 5
9466 }, {
9467 rule: 'optional',
9468 type: 'string',
9469 name: 'data',
9470 id: 6
9471 }, {
9472 rule: 'optional',
9473 type: 'int64',
9474 name: 'patchTimestamp',
9475 id: 7
9476 }, {
9477 rule: 'optional',
9478 type: 'bool',
9479 name: 'mentioned',
9480 id: 8
9481 }, {
9482 rule: 'optional',
9483 type: 'bytes',
9484 name: 'binaryMsg',
9485 id: 9
9486 }, {
9487 rule: 'optional',
9488 type: 'int32',
9489 name: 'convType',
9490 id: 10
9491 }]
9492 }, {
9493 name: 'LogItem',
9494 syntax: 'proto2',
9495 fields: [{
9496 rule: 'optional',
9497 type: 'string',
9498 name: 'from',
9499 id: 1
9500 }, {
9501 rule: 'optional',
9502 type: 'string',
9503 name: 'data',
9504 id: 2
9505 }, {
9506 rule: 'optional',
9507 type: 'int64',
9508 name: 'timestamp',
9509 id: 3
9510 }, {
9511 rule: 'optional',
9512 type: 'string',
9513 name: 'msgId',
9514 id: 4
9515 }, {
9516 rule: 'optional',
9517 type: 'int64',
9518 name: 'ackAt',
9519 id: 5
9520 }, {
9521 rule: 'optional',
9522 type: 'int64',
9523 name: 'readAt',
9524 id: 6
9525 }, {
9526 rule: 'optional',
9527 type: 'int64',
9528 name: 'patchTimestamp',
9529 id: 7
9530 }, {
9531 rule: 'optional',
9532 type: 'bool',
9533 name: 'mentionAll',
9534 id: 8
9535 }, {
9536 rule: 'repeated',
9537 type: 'string',
9538 name: 'mentionPids',
9539 id: 9
9540 }, {
9541 rule: 'optional',
9542 type: 'bool',
9543 name: 'bin',
9544 id: 10
9545 }, {
9546 rule: 'optional',
9547 type: 'int32',
9548 name: 'convType',
9549 id: 11
9550 }]
9551 }, {
9552 name: 'ConvMemberInfo',
9553 syntax: 'proto2',
9554 fields: [{
9555 rule: 'optional',
9556 type: 'string',
9557 name: 'pid',
9558 id: 1
9559 }, {
9560 rule: 'optional',
9561 type: 'string',
9562 name: 'role',
9563 id: 2
9564 }, {
9565 rule: 'optional',
9566 type: 'string',
9567 name: 'infoId',
9568 id: 3
9569 }]
9570 }, {
9571 name: 'DataCommand',
9572 syntax: 'proto2',
9573 fields: [{
9574 rule: 'repeated',
9575 type: 'string',
9576 name: 'ids',
9577 id: 1
9578 }, {
9579 rule: 'repeated',
9580 type: 'JsonObjectMessage',
9581 name: 'msg',
9582 id: 2
9583 }, {
9584 rule: 'optional',
9585 type: 'bool',
9586 name: 'offline',
9587 id: 3
9588 }]
9589 }, {
9590 name: 'SessionCommand',
9591 syntax: 'proto2',
9592 fields: [{
9593 rule: 'optional',
9594 type: 'int64',
9595 name: 't',
9596 id: 1
9597 }, {
9598 rule: 'optional',
9599 type: 'string',
9600 name: 'n',
9601 id: 2
9602 }, {
9603 rule: 'optional',
9604 type: 'string',
9605 name: 's',
9606 id: 3
9607 }, {
9608 rule: 'optional',
9609 type: 'string',
9610 name: 'ua',
9611 id: 4
9612 }, {
9613 rule: 'optional',
9614 type: 'bool',
9615 name: 'r',
9616 id: 5
9617 }, {
9618 rule: 'optional',
9619 type: 'string',
9620 name: 'tag',
9621 id: 6
9622 }, {
9623 rule: 'optional',
9624 type: 'string',
9625 name: 'deviceId',
9626 id: 7
9627 }, {
9628 rule: 'repeated',
9629 type: 'string',
9630 name: 'sessionPeerIds',
9631 id: 8
9632 }, {
9633 rule: 'repeated',
9634 type: 'string',
9635 name: 'onlineSessionPeerIds',
9636 id: 9
9637 }, {
9638 rule: 'optional',
9639 type: 'string',
9640 name: 'st',
9641 id: 10
9642 }, {
9643 rule: 'optional',
9644 type: 'int32',
9645 name: 'stTtl',
9646 id: 11
9647 }, {
9648 rule: 'optional',
9649 type: 'int32',
9650 name: 'code',
9651 id: 12
9652 }, {
9653 rule: 'optional',
9654 type: 'string',
9655 name: 'reason',
9656 id: 13
9657 }, {
9658 rule: 'optional',
9659 type: 'string',
9660 name: 'deviceToken',
9661 id: 14
9662 }, {
9663 rule: 'optional',
9664 type: 'bool',
9665 name: 'sp',
9666 id: 15
9667 }, {
9668 rule: 'optional',
9669 type: 'string',
9670 name: 'detail',
9671 id: 16
9672 }, {
9673 rule: 'optional',
9674 type: 'int64',
9675 name: 'lastUnreadNotifTime',
9676 id: 17
9677 }, {
9678 rule: 'optional',
9679 type: 'int64',
9680 name: 'lastPatchTime',
9681 id: 18
9682 }, {
9683 rule: 'optional',
9684 type: 'int64',
9685 name: 'configBitmap',
9686 id: 19
9687 }]
9688 }, {
9689 name: 'ErrorCommand',
9690 syntax: 'proto2',
9691 fields: [{
9692 rule: 'required',
9693 type: 'int32',
9694 name: 'code',
9695 id: 1
9696 }, {
9697 rule: 'required',
9698 type: 'string',
9699 name: 'reason',
9700 id: 2
9701 }, {
9702 rule: 'optional',
9703 type: 'int32',
9704 name: 'appCode',
9705 id: 3
9706 }, {
9707 rule: 'optional',
9708 type: 'string',
9709 name: 'detail',
9710 id: 4
9711 }, {
9712 rule: 'repeated',
9713 type: 'string',
9714 name: 'pids',
9715 id: 5
9716 }, {
9717 rule: 'optional',
9718 type: 'string',
9719 name: 'appMsg',
9720 id: 6
9721 }]
9722 }, {
9723 name: 'DirectCommand',
9724 syntax: 'proto2',
9725 fields: [{
9726 rule: 'optional',
9727 type: 'string',
9728 name: 'msg',
9729 id: 1
9730 }, {
9731 rule: 'optional',
9732 type: 'string',
9733 name: 'uid',
9734 id: 2
9735 }, {
9736 rule: 'optional',
9737 type: 'string',
9738 name: 'fromPeerId',
9739 id: 3
9740 }, {
9741 rule: 'optional',
9742 type: 'int64',
9743 name: 'timestamp',
9744 id: 4
9745 }, {
9746 rule: 'optional',
9747 type: 'bool',
9748 name: 'offline',
9749 id: 5
9750 }, {
9751 rule: 'optional',
9752 type: 'bool',
9753 name: 'hasMore',
9754 id: 6
9755 }, {
9756 rule: 'repeated',
9757 type: 'string',
9758 name: 'toPeerIds',
9759 id: 7
9760 }, {
9761 rule: 'optional',
9762 type: 'bool',
9763 name: 'r',
9764 id: 10
9765 }, {
9766 rule: 'optional',
9767 type: 'string',
9768 name: 'cid',
9769 id: 11
9770 }, {
9771 rule: 'optional',
9772 type: 'string',
9773 name: 'id',
9774 id: 12
9775 }, {
9776 rule: 'optional',
9777 type: 'bool',
9778 name: 'transient',
9779 id: 13
9780 }, {
9781 rule: 'optional',
9782 type: 'string',
9783 name: 'dt',
9784 id: 14
9785 }, {
9786 rule: 'optional',
9787 type: 'string',
9788 name: 'roomId',
9789 id: 15
9790 }, {
9791 rule: 'optional',
9792 type: 'string',
9793 name: 'pushData',
9794 id: 16
9795 }, {
9796 rule: 'optional',
9797 type: 'bool',
9798 name: 'will',
9799 id: 17
9800 }, {
9801 rule: 'optional',
9802 type: 'int64',
9803 name: 'patchTimestamp',
9804 id: 18
9805 }, {
9806 rule: 'optional',
9807 type: 'bytes',
9808 name: 'binaryMsg',
9809 id: 19
9810 }, {
9811 rule: 'repeated',
9812 type: 'string',
9813 name: 'mentionPids',
9814 id: 20
9815 }, {
9816 rule: 'optional',
9817 type: 'bool',
9818 name: 'mentionAll',
9819 id: 21
9820 }, {
9821 rule: 'optional',
9822 type: 'int32',
9823 name: 'convType',
9824 id: 22
9825 }]
9826 }, {
9827 name: 'AckCommand',
9828 syntax: 'proto2',
9829 fields: [{
9830 rule: 'optional',
9831 type: 'int32',
9832 name: 'code',
9833 id: 1
9834 }, {
9835 rule: 'optional',
9836 type: 'string',
9837 name: 'reason',
9838 id: 2
9839 }, {
9840 rule: 'optional',
9841 type: 'string',
9842 name: 'mid',
9843 id: 3
9844 }, {
9845 rule: 'optional',
9846 type: 'string',
9847 name: 'cid',
9848 id: 4
9849 }, {
9850 rule: 'optional',
9851 type: 'int64',
9852 name: 't',
9853 id: 5
9854 }, {
9855 rule: 'optional',
9856 type: 'string',
9857 name: 'uid',
9858 id: 6
9859 }, {
9860 rule: 'optional',
9861 type: 'int64',
9862 name: 'fromts',
9863 id: 7
9864 }, {
9865 rule: 'optional',
9866 type: 'int64',
9867 name: 'tots',
9868 id: 8
9869 }, {
9870 rule: 'optional',
9871 type: 'string',
9872 name: 'type',
9873 id: 9
9874 }, {
9875 rule: 'repeated',
9876 type: 'string',
9877 name: 'ids',
9878 id: 10
9879 }, {
9880 rule: 'optional',
9881 type: 'int32',
9882 name: 'appCode',
9883 id: 11
9884 }, {
9885 rule: 'optional',
9886 type: 'string',
9887 name: 'appMsg',
9888 id: 12
9889 }]
9890 }, {
9891 name: 'UnreadCommand',
9892 syntax: 'proto2',
9893 fields: [{
9894 rule: 'repeated',
9895 type: 'UnreadTuple',
9896 name: 'convs',
9897 id: 1
9898 }, {
9899 rule: 'optional',
9900 type: 'int64',
9901 name: 'notifTime',
9902 id: 2
9903 }]
9904 }, {
9905 name: 'ConvCommand',
9906 syntax: 'proto2',
9907 fields: [{
9908 rule: 'repeated',
9909 type: 'string',
9910 name: 'm',
9911 id: 1
9912 }, {
9913 rule: 'optional',
9914 type: 'bool',
9915 name: 'transient',
9916 id: 2
9917 }, {
9918 rule: 'optional',
9919 type: 'bool',
9920 name: 'unique',
9921 id: 3
9922 }, {
9923 rule: 'optional',
9924 type: 'string',
9925 name: 'cid',
9926 id: 4
9927 }, {
9928 rule: 'optional',
9929 type: 'string',
9930 name: 'cdate',
9931 id: 5
9932 }, {
9933 rule: 'optional',
9934 type: 'string',
9935 name: 'initBy',
9936 id: 6
9937 }, {
9938 rule: 'optional',
9939 type: 'string',
9940 name: 'sort',
9941 id: 7
9942 }, {
9943 rule: 'optional',
9944 type: 'int32',
9945 name: 'limit',
9946 id: 8
9947 }, {
9948 rule: 'optional',
9949 type: 'int32',
9950 name: 'skip',
9951 id: 9
9952 }, {
9953 rule: 'optional',
9954 type: 'int32',
9955 name: 'flag',
9956 id: 10
9957 }, {
9958 rule: 'optional',
9959 type: 'int32',
9960 name: 'count',
9961 id: 11
9962 }, {
9963 rule: 'optional',
9964 type: 'string',
9965 name: 'udate',
9966 id: 12
9967 }, {
9968 rule: 'optional',
9969 type: 'int64',
9970 name: 't',
9971 id: 13
9972 }, {
9973 rule: 'optional',
9974 type: 'string',
9975 name: 'n',
9976 id: 14
9977 }, {
9978 rule: 'optional',
9979 type: 'string',
9980 name: 's',
9981 id: 15
9982 }, {
9983 rule: 'optional',
9984 type: 'bool',
9985 name: 'statusSub',
9986 id: 16
9987 }, {
9988 rule: 'optional',
9989 type: 'bool',
9990 name: 'statusPub',
9991 id: 17
9992 }, {
9993 rule: 'optional',
9994 type: 'int32',
9995 name: 'statusTTL',
9996 id: 18
9997 }, {
9998 rule: 'optional',
9999 type: 'string',
10000 name: 'uniqueId',
10001 id: 19
10002 }, {
10003 rule: 'optional',
10004 type: 'string',
10005 name: 'targetClientId',
10006 id: 20
10007 }, {
10008 rule: 'optional',
10009 type: 'int64',
10010 name: 'maxReadTimestamp',
10011 id: 21
10012 }, {
10013 rule: 'optional',
10014 type: 'int64',
10015 name: 'maxAckTimestamp',
10016 id: 22
10017 }, {
10018 rule: 'optional',
10019 type: 'bool',
10020 name: 'queryAllMembers',
10021 id: 23
10022 }, {
10023 rule: 'repeated',
10024 type: 'MaxReadTuple',
10025 name: 'maxReadTuples',
10026 id: 24
10027 }, {
10028 rule: 'repeated',
10029 type: 'string',
10030 name: 'cids',
10031 id: 25
10032 }, {
10033 rule: 'optional',
10034 type: 'ConvMemberInfo',
10035 name: 'info',
10036 id: 26
10037 }, {
10038 rule: 'optional',
10039 type: 'bool',
10040 name: 'tempConv',
10041 id: 27
10042 }, {
10043 rule: 'optional',
10044 type: 'int32',
10045 name: 'tempConvTTL',
10046 id: 28
10047 }, {
10048 rule: 'repeated',
10049 type: 'string',
10050 name: 'tempConvIds',
10051 id: 29
10052 }, {
10053 rule: 'repeated',
10054 type: 'string',
10055 name: 'allowedPids',
10056 id: 30
10057 }, {
10058 rule: 'repeated',
10059 type: 'ErrorCommand',
10060 name: 'failedPids',
10061 id: 31
10062 }, {
10063 rule: 'optional',
10064 type: 'string',
10065 name: 'next',
10066 id: 40
10067 }, {
10068 rule: 'optional',
10069 type: 'JsonObjectMessage',
10070 name: 'results',
10071 id: 100
10072 }, {
10073 rule: 'optional',
10074 type: 'JsonObjectMessage',
10075 name: 'where',
10076 id: 101
10077 }, {
10078 rule: 'optional',
10079 type: 'JsonObjectMessage',
10080 name: 'attr',
10081 id: 103
10082 }, {
10083 rule: 'optional',
10084 type: 'JsonObjectMessage',
10085 name: 'attrModified',
10086 id: 104
10087 }]
10088 }, {
10089 name: 'RoomCommand',
10090 syntax: 'proto2',
10091 fields: [{
10092 rule: 'optional',
10093 type: 'string',
10094 name: 'roomId',
10095 id: 1
10096 }, {
10097 rule: 'optional',
10098 type: 'string',
10099 name: 's',
10100 id: 2
10101 }, {
10102 rule: 'optional',
10103 type: 'int64',
10104 name: 't',
10105 id: 3
10106 }, {
10107 rule: 'optional',
10108 type: 'string',
10109 name: 'n',
10110 id: 4
10111 }, {
10112 rule: 'optional',
10113 type: 'bool',
10114 name: 'transient',
10115 id: 5
10116 }, {
10117 rule: 'repeated',
10118 type: 'string',
10119 name: 'roomPeerIds',
10120 id: 6
10121 }, {
10122 rule: 'optional',
10123 type: 'string',
10124 name: 'byPeerId',
10125 id: 7
10126 }]
10127 }, {
10128 name: 'LogsCommand',
10129 syntax: 'proto2',
10130 fields: [{
10131 rule: 'optional',
10132 type: 'string',
10133 name: 'cid',
10134 id: 1
10135 }, {
10136 rule: 'optional',
10137 type: 'int32',
10138 name: 'l',
10139 id: 2
10140 }, {
10141 rule: 'optional',
10142 type: 'int32',
10143 name: 'limit',
10144 id: 3
10145 }, {
10146 rule: 'optional',
10147 type: 'int64',
10148 name: 't',
10149 id: 4
10150 }, {
10151 rule: 'optional',
10152 type: 'int64',
10153 name: 'tt',
10154 id: 5
10155 }, {
10156 rule: 'optional',
10157 type: 'string',
10158 name: 'tmid',
10159 id: 6
10160 }, {
10161 rule: 'optional',
10162 type: 'string',
10163 name: 'mid',
10164 id: 7
10165 }, {
10166 rule: 'optional',
10167 type: 'string',
10168 name: 'checksum',
10169 id: 8
10170 }, {
10171 rule: 'optional',
10172 type: 'bool',
10173 name: 'stored',
10174 id: 9
10175 }, {
10176 rule: 'optional',
10177 type: 'QueryDirection',
10178 name: 'direction',
10179 id: 10,
10180 options: {
10181 default: 'OLD'
10182 }
10183 }, {
10184 rule: 'optional',
10185 type: 'bool',
10186 name: 'tIncluded',
10187 id: 11
10188 }, {
10189 rule: 'optional',
10190 type: 'bool',
10191 name: 'ttIncluded',
10192 id: 12
10193 }, {
10194 rule: 'optional',
10195 type: 'int32',
10196 name: 'lctype',
10197 id: 13
10198 }, {
10199 rule: 'repeated',
10200 type: 'LogItem',
10201 name: 'logs',
10202 id: 105
10203 }],
10204 enums: [{
10205 name: 'QueryDirection',
10206 syntax: 'proto2',
10207 values: [{
10208 name: 'OLD',
10209 id: 1
10210 }, {
10211 name: 'NEW',
10212 id: 2
10213 }]
10214 }]
10215 }, {
10216 name: 'RcpCommand',
10217 syntax: 'proto2',
10218 fields: [{
10219 rule: 'optional',
10220 type: 'string',
10221 name: 'id',
10222 id: 1
10223 }, {
10224 rule: 'optional',
10225 type: 'string',
10226 name: 'cid',
10227 id: 2
10228 }, {
10229 rule: 'optional',
10230 type: 'int64',
10231 name: 't',
10232 id: 3
10233 }, {
10234 rule: 'optional',
10235 type: 'bool',
10236 name: 'read',
10237 id: 4
10238 }, {
10239 rule: 'optional',
10240 type: 'string',
10241 name: 'from',
10242 id: 5
10243 }]
10244 }, {
10245 name: 'ReadTuple',
10246 syntax: 'proto2',
10247 fields: [{
10248 rule: 'required',
10249 type: 'string',
10250 name: 'cid',
10251 id: 1
10252 }, {
10253 rule: 'optional',
10254 type: 'int64',
10255 name: 'timestamp',
10256 id: 2
10257 }, {
10258 rule: 'optional',
10259 type: 'string',
10260 name: 'mid',
10261 id: 3
10262 }]
10263 }, {
10264 name: 'MaxReadTuple',
10265 syntax: 'proto2',
10266 fields: [{
10267 rule: 'optional',
10268 type: 'string',
10269 name: 'pid',
10270 id: 1
10271 }, {
10272 rule: 'optional',
10273 type: 'int64',
10274 name: 'maxAckTimestamp',
10275 id: 2
10276 }, {
10277 rule: 'optional',
10278 type: 'int64',
10279 name: 'maxReadTimestamp',
10280 id: 3
10281 }]
10282 }, {
10283 name: 'ReadCommand',
10284 syntax: 'proto2',
10285 fields: [{
10286 rule: 'optional',
10287 type: 'string',
10288 name: 'cid',
10289 id: 1
10290 }, {
10291 rule: 'repeated',
10292 type: 'string',
10293 name: 'cids',
10294 id: 2
10295 }, {
10296 rule: 'repeated',
10297 type: 'ReadTuple',
10298 name: 'convs',
10299 id: 3
10300 }]
10301 }, {
10302 name: 'PresenceCommand',
10303 syntax: 'proto2',
10304 fields: [{
10305 rule: 'optional',
10306 type: 'StatusType',
10307 name: 'status',
10308 id: 1
10309 }, {
10310 rule: 'repeated',
10311 type: 'string',
10312 name: 'sessionPeerIds',
10313 id: 2
10314 }, {
10315 rule: 'optional',
10316 type: 'string',
10317 name: 'cid',
10318 id: 3
10319 }]
10320 }, {
10321 name: 'ReportCommand',
10322 syntax: 'proto2',
10323 fields: [{
10324 rule: 'optional',
10325 type: 'bool',
10326 name: 'initiative',
10327 id: 1
10328 }, {
10329 rule: 'optional',
10330 type: 'string',
10331 name: 'type',
10332 id: 2
10333 }, {
10334 rule: 'optional',
10335 type: 'string',
10336 name: 'data',
10337 id: 3
10338 }]
10339 }, {
10340 name: 'PatchItem',
10341 syntax: 'proto2',
10342 fields: [{
10343 rule: 'optional',
10344 type: 'string',
10345 name: 'cid',
10346 id: 1
10347 }, {
10348 rule: 'optional',
10349 type: 'string',
10350 name: 'mid',
10351 id: 2
10352 }, {
10353 rule: 'optional',
10354 type: 'int64',
10355 name: 'timestamp',
10356 id: 3
10357 }, {
10358 rule: 'optional',
10359 type: 'bool',
10360 name: 'recall',
10361 id: 4
10362 }, {
10363 rule: 'optional',
10364 type: 'string',
10365 name: 'data',
10366 id: 5
10367 }, {
10368 rule: 'optional',
10369 type: 'int64',
10370 name: 'patchTimestamp',
10371 id: 6
10372 }, {
10373 rule: 'optional',
10374 type: 'string',
10375 name: 'from',
10376 id: 7
10377 }, {
10378 rule: 'optional',
10379 type: 'bytes',
10380 name: 'binaryMsg',
10381 id: 8
10382 }, {
10383 rule: 'optional',
10384 type: 'bool',
10385 name: 'mentionAll',
10386 id: 9
10387 }, {
10388 rule: 'repeated',
10389 type: 'string',
10390 name: 'mentionPids',
10391 id: 10
10392 }, {
10393 rule: 'optional',
10394 type: 'int64',
10395 name: 'patchCode',
10396 id: 11
10397 }, {
10398 rule: 'optional',
10399 type: 'string',
10400 name: 'patchReason',
10401 id: 12
10402 }]
10403 }, {
10404 name: 'PatchCommand',
10405 syntax: 'proto2',
10406 fields: [{
10407 rule: 'repeated',
10408 type: 'PatchItem',
10409 name: 'patches',
10410 id: 1
10411 }, {
10412 rule: 'optional',
10413 type: 'int64',
10414 name: 'lastPatchTime',
10415 id: 2
10416 }]
10417 }, {
10418 name: 'PubsubCommand',
10419 syntax: 'proto2',
10420 fields: [{
10421 rule: 'optional',
10422 type: 'string',
10423 name: 'cid',
10424 id: 1
10425 }, {
10426 rule: 'repeated',
10427 type: 'string',
10428 name: 'cids',
10429 id: 2
10430 }, {
10431 rule: 'optional',
10432 type: 'string',
10433 name: 'topic',
10434 id: 3
10435 }, {
10436 rule: 'optional',
10437 type: 'string',
10438 name: 'subtopic',
10439 id: 4
10440 }, {
10441 rule: 'repeated',
10442 type: 'string',
10443 name: 'topics',
10444 id: 5
10445 }, {
10446 rule: 'repeated',
10447 type: 'string',
10448 name: 'subtopics',
10449 id: 6
10450 }, {
10451 rule: 'optional',
10452 type: 'JsonObjectMessage',
10453 name: 'results',
10454 id: 7
10455 }]
10456 }, {
10457 name: 'BlacklistCommand',
10458 syntax: 'proto2',
10459 fields: [{
10460 rule: 'optional',
10461 type: 'string',
10462 name: 'srcCid',
10463 id: 1
10464 }, {
10465 rule: 'repeated',
10466 type: 'string',
10467 name: 'toPids',
10468 id: 2
10469 }, {
10470 rule: 'optional',
10471 type: 'string',
10472 name: 'srcPid',
10473 id: 3
10474 }, {
10475 rule: 'repeated',
10476 type: 'string',
10477 name: 'toCids',
10478 id: 4
10479 }, {
10480 rule: 'optional',
10481 type: 'int32',
10482 name: 'limit',
10483 id: 5
10484 }, {
10485 rule: 'optional',
10486 type: 'string',
10487 name: 'next',
10488 id: 6
10489 }, {
10490 rule: 'repeated',
10491 type: 'string',
10492 name: 'blockedPids',
10493 id: 8
10494 }, {
10495 rule: 'repeated',
10496 type: 'string',
10497 name: 'blockedCids',
10498 id: 9
10499 }, {
10500 rule: 'repeated',
10501 type: 'string',
10502 name: 'allowedPids',
10503 id: 10
10504 }, {
10505 rule: 'repeated',
10506 type: 'ErrorCommand',
10507 name: 'failedPids',
10508 id: 11
10509 }, {
10510 rule: 'optional',
10511 type: 'int64',
10512 name: 't',
10513 id: 12
10514 }, {
10515 rule: 'optional',
10516 type: 'string',
10517 name: 'n',
10518 id: 13
10519 }, {
10520 rule: 'optional',
10521 type: 'string',
10522 name: 's',
10523 id: 14
10524 }]
10525 }, {
10526 name: 'GenericCommand',
10527 syntax: 'proto2',
10528 fields: [{
10529 rule: 'optional',
10530 type: 'CommandType',
10531 name: 'cmd',
10532 id: 1
10533 }, {
10534 rule: 'optional',
10535 type: 'OpType',
10536 name: 'op',
10537 id: 2
10538 }, {
10539 rule: 'optional',
10540 type: 'string',
10541 name: 'appId',
10542 id: 3
10543 }, {
10544 rule: 'optional',
10545 type: 'string',
10546 name: 'peerId',
10547 id: 4
10548 }, {
10549 rule: 'optional',
10550 type: 'int32',
10551 name: 'i',
10552 id: 5
10553 }, {
10554 rule: 'optional',
10555 type: 'string',
10556 name: 'installationId',
10557 id: 6
10558 }, {
10559 rule: 'optional',
10560 type: 'int32',
10561 name: 'priority',
10562 id: 7
10563 }, {
10564 rule: 'optional',
10565 type: 'int32',
10566 name: 'service',
10567 id: 8
10568 }, {
10569 rule: 'optional',
10570 type: 'int64',
10571 name: 'serverTs',
10572 id: 9
10573 }, {
10574 rule: 'optional',
10575 type: 'int64',
10576 name: 'clientTs',
10577 id: 10
10578 }, {
10579 rule: 'optional',
10580 type: 'int32',
10581 name: 'notificationType',
10582 id: 11
10583 }, {
10584 rule: 'optional',
10585 type: 'DataCommand',
10586 name: 'dataMessage',
10587 id: 101
10588 }, {
10589 rule: 'optional',
10590 type: 'SessionCommand',
10591 name: 'sessionMessage',
10592 id: 102
10593 }, {
10594 rule: 'optional',
10595 type: 'ErrorCommand',
10596 name: 'errorMessage',
10597 id: 103
10598 }, {
10599 rule: 'optional',
10600 type: 'DirectCommand',
10601 name: 'directMessage',
10602 id: 104
10603 }, {
10604 rule: 'optional',
10605 type: 'AckCommand',
10606 name: 'ackMessage',
10607 id: 105
10608 }, {
10609 rule: 'optional',
10610 type: 'UnreadCommand',
10611 name: 'unreadMessage',
10612 id: 106
10613 }, {
10614 rule: 'optional',
10615 type: 'ReadCommand',
10616 name: 'readMessage',
10617 id: 107
10618 }, {
10619 rule: 'optional',
10620 type: 'RcpCommand',
10621 name: 'rcpMessage',
10622 id: 108
10623 }, {
10624 rule: 'optional',
10625 type: 'LogsCommand',
10626 name: 'logsMessage',
10627 id: 109
10628 }, {
10629 rule: 'optional',
10630 type: 'ConvCommand',
10631 name: 'convMessage',
10632 id: 110
10633 }, {
10634 rule: 'optional',
10635 type: 'RoomCommand',
10636 name: 'roomMessage',
10637 id: 111
10638 }, {
10639 rule: 'optional',
10640 type: 'PresenceCommand',
10641 name: 'presenceMessage',
10642 id: 112
10643 }, {
10644 rule: 'optional',
10645 type: 'ReportCommand',
10646 name: 'reportMessage',
10647 id: 113
10648 }, {
10649 rule: 'optional',
10650 type: 'PatchCommand',
10651 name: 'patchMessage',
10652 id: 114
10653 }, {
10654 rule: 'optional',
10655 type: 'PubsubCommand',
10656 name: 'pubsubMessage',
10657 id: 115
10658 }, {
10659 rule: 'optional',
10660 type: 'BlacklistCommand',
10661 name: 'blacklistMessage',
10662 id: 116
10663 }]
10664 }],
10665 enums: [{
10666 name: 'CommandType',
10667 syntax: 'proto2',
10668 values: [{
10669 name: 'session',
10670 id: 0
10671 }, {
10672 name: 'conv',
10673 id: 1
10674 }, {
10675 name: 'direct',
10676 id: 2
10677 }, {
10678 name: 'ack',
10679 id: 3
10680 }, {
10681 name: 'rcp',
10682 id: 4
10683 }, {
10684 name: 'unread',
10685 id: 5
10686 }, {
10687 name: 'logs',
10688 id: 6
10689 }, {
10690 name: 'error',
10691 id: 7
10692 }, {
10693 name: 'login',
10694 id: 8
10695 }, {
10696 name: 'data',
10697 id: 9
10698 }, {
10699 name: 'room',
10700 id: 10
10701 }, {
10702 name: 'read',
10703 id: 11
10704 }, {
10705 name: 'presence',
10706 id: 12
10707 }, {
10708 name: 'report',
10709 id: 13
10710 }, {
10711 name: 'echo',
10712 id: 14
10713 }, {
10714 name: 'loggedin',
10715 id: 15
10716 }, {
10717 name: 'logout',
10718 id: 16
10719 }, {
10720 name: 'loggedout',
10721 id: 17
10722 }, {
10723 name: 'patch',
10724 id: 18
10725 }, {
10726 name: 'pubsub',
10727 id: 19
10728 }, {
10729 name: 'blacklist',
10730 id: 20
10731 }, {
10732 name: 'goaway',
10733 id: 21
10734 }]
10735 }, {
10736 name: 'OpType',
10737 syntax: 'proto2',
10738 values: [{
10739 name: 'open',
10740 id: 1
10741 }, {
10742 name: 'add',
10743 id: 2
10744 }, {
10745 name: 'remove',
10746 id: 3
10747 }, {
10748 name: 'close',
10749 id: 4
10750 }, {
10751 name: 'opened',
10752 id: 5
10753 }, {
10754 name: 'closed',
10755 id: 6
10756 }, {
10757 name: 'query',
10758 id: 7
10759 }, {
10760 name: 'query_result',
10761 id: 8
10762 }, {
10763 name: 'conflict',
10764 id: 9
10765 }, {
10766 name: 'added',
10767 id: 10
10768 }, {
10769 name: 'removed',
10770 id: 11
10771 }, {
10772 name: 'refresh',
10773 id: 12
10774 }, {
10775 name: 'refreshed',
10776 id: 13
10777 }, {
10778 name: 'start',
10779 id: 30
10780 }, {
10781 name: 'started',
10782 id: 31
10783 }, {
10784 name: 'joined',
10785 id: 32
10786 }, {
10787 name: 'members_joined',
10788 id: 33
10789 }, {
10790 name: 'left',
10791 id: 39
10792 }, {
10793 name: 'members_left',
10794 id: 40
10795 }, {
10796 name: 'results',
10797 id: 42
10798 }, {
10799 name: 'count',
10800 id: 43
10801 }, {
10802 name: 'result',
10803 id: 44
10804 }, {
10805 name: 'update',
10806 id: 45
10807 }, {
10808 name: 'updated',
10809 id: 46
10810 }, {
10811 name: 'mute',
10812 id: 47
10813 }, {
10814 name: 'unmute',
10815 id: 48
10816 }, {
10817 name: 'status',
10818 id: 49
10819 }, {
10820 name: 'members',
10821 id: 50
10822 }, {
10823 name: 'max_read',
10824 id: 51
10825 }, {
10826 name: 'is_member',
10827 id: 52
10828 }, {
10829 name: 'member_info_update',
10830 id: 53
10831 }, {
10832 name: 'member_info_updated',
10833 id: 54
10834 }, {
10835 name: 'member_info_changed',
10836 id: 55
10837 }, {
10838 name: 'join',
10839 id: 80
10840 }, {
10841 name: 'invite',
10842 id: 81
10843 }, {
10844 name: 'leave',
10845 id: 82
10846 }, {
10847 name: 'kick',
10848 id: 83
10849 }, {
10850 name: 'reject',
10851 id: 84
10852 }, {
10853 name: 'invited',
10854 id: 85
10855 }, {
10856 name: 'kicked',
10857 id: 86
10858 }, {
10859 name: 'upload',
10860 id: 100
10861 }, {
10862 name: 'uploaded',
10863 id: 101
10864 }, {
10865 name: 'subscribe',
10866 id: 120
10867 }, {
10868 name: 'subscribed',
10869 id: 121
10870 }, {
10871 name: 'unsubscribe',
10872 id: 122
10873 }, {
10874 name: 'unsubscribed',
10875 id: 123
10876 }, {
10877 name: 'is_subscribed',
10878 id: 124
10879 }, {
10880 name: 'modify',
10881 id: 150
10882 }, {
10883 name: 'modified',
10884 id: 151
10885 }, {
10886 name: 'block',
10887 id: 170
10888 }, {
10889 name: 'unblock',
10890 id: 171
10891 }, {
10892 name: 'blocked',
10893 id: 172
10894 }, {
10895 name: 'unblocked',
10896 id: 173
10897 }, {
10898 name: 'members_blocked',
10899 id: 174
10900 }, {
10901 name: 'members_unblocked',
10902 id: 175
10903 }, {
10904 name: 'check_block',
10905 id: 176
10906 }, {
10907 name: 'check_result',
10908 id: 177
10909 }, {
10910 name: 'add_shutup',
10911 id: 180
10912 }, {
10913 name: 'remove_shutup',
10914 id: 181
10915 }, {
10916 name: 'query_shutup',
10917 id: 182
10918 }, {
10919 name: 'shutup_added',
10920 id: 183
10921 }, {
10922 name: 'shutup_removed',
10923 id: 184
10924 }, {
10925 name: 'shutup_result',
10926 id: 185
10927 }, {
10928 name: 'shutuped',
10929 id: 186
10930 }, {
10931 name: 'unshutuped',
10932 id: 187
10933 }, {
10934 name: 'members_shutuped',
10935 id: 188
10936 }, {
10937 name: 'members_unshutuped',
10938 id: 189
10939 }, {
10940 name: 'check_shutup',
10941 id: 190
10942 }]
10943 }, {
10944 name: 'StatusType',
10945 syntax: 'proto2',
10946 values: [{
10947 name: 'on',
10948 id: 1
10949 }, {
10950 name: 'off',
10951 id: 2
10952 }]
10953 }],
10954 isNamespace: true
10955 }).build();
10956
10957 var _messages$push_server = messageCompiled.push_server.messages2,
10958 JsonObjectMessage = _messages$push_server.JsonObjectMessage,
10959 UnreadTuple = _messages$push_server.UnreadTuple,
10960 LogItem = _messages$push_server.LogItem,
10961 DataCommand = _messages$push_server.DataCommand,
10962 SessionCommand = _messages$push_server.SessionCommand,
10963 ErrorCommand = _messages$push_server.ErrorCommand,
10964 DirectCommand = _messages$push_server.DirectCommand,
10965 AckCommand = _messages$push_server.AckCommand,
10966 UnreadCommand = _messages$push_server.UnreadCommand,
10967 ConvCommand = _messages$push_server.ConvCommand,
10968 RoomCommand = _messages$push_server.RoomCommand,
10969 LogsCommand = _messages$push_server.LogsCommand,
10970 RcpCommand = _messages$push_server.RcpCommand,
10971 ReadTuple = _messages$push_server.ReadTuple,
10972 MaxReadTuple = _messages$push_server.MaxReadTuple,
10973 ReadCommand = _messages$push_server.ReadCommand,
10974 PresenceCommand = _messages$push_server.PresenceCommand,
10975 ReportCommand = _messages$push_server.ReportCommand,
10976 GenericCommand = _messages$push_server.GenericCommand,
10977 BlacklistCommand = _messages$push_server.BlacklistCommand,
10978 PatchCommand = _messages$push_server.PatchCommand,
10979 PatchItem = _messages$push_server.PatchItem,
10980 ConvMemberInfo = _messages$push_server.ConvMemberInfo,
10981 CommandType = _messages$push_server.CommandType,
10982 OpType = _messages$push_server.OpType,
10983 StatusType = _messages$push_server.StatusType;
10984
10985 var message = /*#__PURE__*/Object.freeze({
10986 JsonObjectMessage: JsonObjectMessage,
10987 UnreadTuple: UnreadTuple,
10988 LogItem: LogItem,
10989 DataCommand: DataCommand,
10990 SessionCommand: SessionCommand,
10991 ErrorCommand: ErrorCommand,
10992 DirectCommand: DirectCommand,
10993 AckCommand: AckCommand,
10994 UnreadCommand: UnreadCommand,
10995 ConvCommand: ConvCommand,
10996 RoomCommand: RoomCommand,
10997 LogsCommand: LogsCommand,
10998 RcpCommand: RcpCommand,
10999 ReadTuple: ReadTuple,
11000 MaxReadTuple: MaxReadTuple,
11001 ReadCommand: ReadCommand,
11002 PresenceCommand: PresenceCommand,
11003 ReportCommand: ReportCommand,
11004 GenericCommand: GenericCommand,
11005 BlacklistCommand: BlacklistCommand,
11006 PatchCommand: PatchCommand,
11007 PatchItem: PatchItem,
11008 ConvMemberInfo: ConvMemberInfo,
11009 CommandType: CommandType,
11010 OpType: OpType,
11011 StatusType: StatusType
11012 });
11013
11014 var eventemitter3 = createCommonjsModule(function (module) {
11015
11016 var has = Object.prototype.hasOwnProperty
11017 , prefix = '~';
11018
11019 /**
11020 * Constructor to create a storage for our `EE` objects.
11021 * An `Events` instance is a plain object whose properties are event names.
11022 *
11023 * @constructor
11024 * @private
11025 */
11026 function Events() {}
11027
11028 //
11029 // We try to not inherit from `Object.prototype`. In some engines creating an
11030 // instance in this way is faster than calling `Object.create(null)` directly.
11031 // If `Object.create(null)` is not supported we prefix the event names with a
11032 // character to make sure that the built-in object properties are not
11033 // overridden or used as an attack vector.
11034 //
11035 if (Object.create) {
11036 Events.prototype = Object.create(null);
11037
11038 //
11039 // This hack is needed because the `__proto__` property is still inherited in
11040 // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
11041 //
11042 if (!new Events().__proto__) prefix = false;
11043 }
11044
11045 /**
11046 * Representation of a single event listener.
11047 *
11048 * @param {Function} fn The listener function.
11049 * @param {*} context The context to invoke the listener with.
11050 * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
11051 * @constructor
11052 * @private
11053 */
11054 function EE(fn, context, once) {
11055 this.fn = fn;
11056 this.context = context;
11057 this.once = once || false;
11058 }
11059
11060 /**
11061 * Add a listener for a given event.
11062 *
11063 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
11064 * @param {(String|Symbol)} event The event name.
11065 * @param {Function} fn The listener function.
11066 * @param {*} context The context to invoke the listener with.
11067 * @param {Boolean} once Specify if the listener is a one-time listener.
11068 * @returns {EventEmitter}
11069 * @private
11070 */
11071 function addListener(emitter, event, fn, context, once) {
11072 if (typeof fn !== 'function') {
11073 throw new TypeError('The listener must be a function');
11074 }
11075
11076 var listener = new EE(fn, context || emitter, once)
11077 , evt = prefix ? prefix + event : event;
11078
11079 if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
11080 else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
11081 else emitter._events[evt] = [emitter._events[evt], listener];
11082
11083 return emitter;
11084 }
11085
11086 /**
11087 * Clear event by name.
11088 *
11089 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
11090 * @param {(String|Symbol)} evt The Event name.
11091 * @private
11092 */
11093 function clearEvent(emitter, evt) {
11094 if (--emitter._eventsCount === 0) emitter._events = new Events();
11095 else delete emitter._events[evt];
11096 }
11097
11098 /**
11099 * Minimal `EventEmitter` interface that is molded against the Node.js
11100 * `EventEmitter` interface.
11101 *
11102 * @constructor
11103 * @public
11104 */
11105 function EventEmitter() {
11106 this._events = new Events();
11107 this._eventsCount = 0;
11108 }
11109
11110 /**
11111 * Return an array listing the events for which the emitter has registered
11112 * listeners.
11113 *
11114 * @returns {Array}
11115 * @public
11116 */
11117 EventEmitter.prototype.eventNames = function eventNames() {
11118 var names = []
11119 , events
11120 , name;
11121
11122 if (this._eventsCount === 0) return names;
11123
11124 for (name in (events = this._events)) {
11125 if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
11126 }
11127
11128 if (Object.getOwnPropertySymbols) {
11129 return names.concat(Object.getOwnPropertySymbols(events));
11130 }
11131
11132 return names;
11133 };
11134
11135 /**
11136 * Return the listeners registered for a given event.
11137 *
11138 * @param {(String|Symbol)} event The event name.
11139 * @returns {Array} The registered listeners.
11140 * @public
11141 */
11142 EventEmitter.prototype.listeners = function listeners(event) {
11143 var evt = prefix ? prefix + event : event
11144 , handlers = this._events[evt];
11145
11146 if (!handlers) return [];
11147 if (handlers.fn) return [handlers.fn];
11148
11149 for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
11150 ee[i] = handlers[i].fn;
11151 }
11152
11153 return ee;
11154 };
11155
11156 /**
11157 * Return the number of listeners listening to a given event.
11158 *
11159 * @param {(String|Symbol)} event The event name.
11160 * @returns {Number} The number of listeners.
11161 * @public
11162 */
11163 EventEmitter.prototype.listenerCount = function listenerCount(event) {
11164 var evt = prefix ? prefix + event : event
11165 , listeners = this._events[evt];
11166
11167 if (!listeners) return 0;
11168 if (listeners.fn) return 1;
11169 return listeners.length;
11170 };
11171
11172 /**
11173 * Calls each of the listeners registered for a given event.
11174 *
11175 * @param {(String|Symbol)} event The event name.
11176 * @returns {Boolean} `true` if the event had listeners, else `false`.
11177 * @public
11178 */
11179 EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
11180 var evt = prefix ? prefix + event : event;
11181
11182 if (!this._events[evt]) return false;
11183
11184 var listeners = this._events[evt]
11185 , len = arguments.length
11186 , args
11187 , i;
11188
11189 if (listeners.fn) {
11190 if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
11191
11192 switch (len) {
11193 case 1: return listeners.fn.call(listeners.context), true;
11194 case 2: return listeners.fn.call(listeners.context, a1), true;
11195 case 3: return listeners.fn.call(listeners.context, a1, a2), true;
11196 case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
11197 case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
11198 case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
11199 }
11200
11201 for (i = 1, args = new Array(len -1); i < len; i++) {
11202 args[i - 1] = arguments[i];
11203 }
11204
11205 listeners.fn.apply(listeners.context, args);
11206 } else {
11207 var length = listeners.length
11208 , j;
11209
11210 for (i = 0; i < length; i++) {
11211 if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
11212
11213 switch (len) {
11214 case 1: listeners[i].fn.call(listeners[i].context); break;
11215 case 2: listeners[i].fn.call(listeners[i].context, a1); break;
11216 case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
11217 case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
11218 default:
11219 if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
11220 args[j - 1] = arguments[j];
11221 }
11222
11223 listeners[i].fn.apply(listeners[i].context, args);
11224 }
11225 }
11226 }
11227
11228 return true;
11229 };
11230
11231 /**
11232 * Add a listener for a given event.
11233 *
11234 * @param {(String|Symbol)} event The event name.
11235 * @param {Function} fn The listener function.
11236 * @param {*} [context=this] The context to invoke the listener with.
11237 * @returns {EventEmitter} `this`.
11238 * @public
11239 */
11240 EventEmitter.prototype.on = function on(event, fn, context) {
11241 return addListener(this, event, fn, context, false);
11242 };
11243
11244 /**
11245 * Add a one-time listener for a given event.
11246 *
11247 * @param {(String|Symbol)} event The event name.
11248 * @param {Function} fn The listener function.
11249 * @param {*} [context=this] The context to invoke the listener with.
11250 * @returns {EventEmitter} `this`.
11251 * @public
11252 */
11253 EventEmitter.prototype.once = function once(event, fn, context) {
11254 return addListener(this, event, fn, context, true);
11255 };
11256
11257 /**
11258 * Remove the listeners of a given event.
11259 *
11260 * @param {(String|Symbol)} event The event name.
11261 * @param {Function} fn Only remove the listeners that match this function.
11262 * @param {*} context Only remove the listeners that have this context.
11263 * @param {Boolean} once Only remove one-time listeners.
11264 * @returns {EventEmitter} `this`.
11265 * @public
11266 */
11267 EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
11268 var evt = prefix ? prefix + event : event;
11269
11270 if (!this._events[evt]) return this;
11271 if (!fn) {
11272 clearEvent(this, evt);
11273 return this;
11274 }
11275
11276 var listeners = this._events[evt];
11277
11278 if (listeners.fn) {
11279 if (
11280 listeners.fn === fn &&
11281 (!once || listeners.once) &&
11282 (!context || listeners.context === context)
11283 ) {
11284 clearEvent(this, evt);
11285 }
11286 } else {
11287 for (var i = 0, events = [], length = listeners.length; i < length; i++) {
11288 if (
11289 listeners[i].fn !== fn ||
11290 (once && !listeners[i].once) ||
11291 (context && listeners[i].context !== context)
11292 ) {
11293 events.push(listeners[i]);
11294 }
11295 }
11296
11297 //
11298 // Reset the array, or remove it completely if we have no more listeners.
11299 //
11300 if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
11301 else clearEvent(this, evt);
11302 }
11303
11304 return this;
11305 };
11306
11307 /**
11308 * Remove all listeners, or those of the specified event.
11309 *
11310 * @param {(String|Symbol)} [event] The event name.
11311 * @returns {EventEmitter} `this`.
11312 * @public
11313 */
11314 EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
11315 var evt;
11316
11317 if (event) {
11318 evt = prefix ? prefix + event : event;
11319 if (this._events[evt]) clearEvent(this, evt);
11320 } else {
11321 this._events = new Events();
11322 this._eventsCount = 0;
11323 }
11324
11325 return this;
11326 };
11327
11328 //
11329 // Alias methods names because people roll like that.
11330 //
11331 EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
11332 EventEmitter.prototype.addListener = EventEmitter.prototype.on;
11333
11334 //
11335 // Expose the prefix.
11336 //
11337 EventEmitter.prefixed = prefix;
11338
11339 //
11340 // Allow `EventEmitter` to be imported as module namespace.
11341 //
11342 EventEmitter.EventEmitter = EventEmitter;
11343
11344 //
11345 // Expose the module.
11346 //
11347 {
11348 module.exports = EventEmitter;
11349 }
11350 });
11351
11352 var runtime = createCommonjsModule(function (module) {
11353 /**
11354 * Copyright (c) 2014-present, Facebook, Inc.
11355 *
11356 * This source code is licensed under the MIT license found in the
11357 * LICENSE file in the root directory of this source tree.
11358 */
11359
11360 !(function(global) {
11361
11362 var Op = Object.prototype;
11363 var hasOwn = Op.hasOwnProperty;
11364 var undefined$1; // More compressible than void 0.
11365 var $Symbol = typeof Symbol === "function" ? Symbol : {};
11366 var iteratorSymbol = $Symbol.iterator || "@@iterator";
11367 var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
11368 var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
11369 var runtime = global.regeneratorRuntime;
11370 if (runtime) {
11371 {
11372 // If regeneratorRuntime is defined globally and we're in a module,
11373 // make the exports object identical to regeneratorRuntime.
11374 module.exports = runtime;
11375 }
11376 // Don't bother evaluating the rest of this file if the runtime was
11377 // already defined globally.
11378 return;
11379 }
11380
11381 // Define the runtime globally (as expected by generated code) as either
11382 // module.exports (if we're in a module) or a new, empty object.
11383 runtime = global.regeneratorRuntime = module.exports;
11384
11385 function wrap(innerFn, outerFn, self, tryLocsList) {
11386 // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
11387 var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
11388 var generator = Object.create(protoGenerator.prototype);
11389 var context = new Context(tryLocsList || []);
11390
11391 // The ._invoke method unifies the implementations of the .next,
11392 // .throw, and .return methods.
11393 generator._invoke = makeInvokeMethod(innerFn, self, context);
11394
11395 return generator;
11396 }
11397 runtime.wrap = wrap;
11398
11399 // Try/catch helper to minimize deoptimizations. Returns a completion
11400 // record like context.tryEntries[i].completion. This interface could
11401 // have been (and was previously) designed to take a closure to be
11402 // invoked without arguments, but in all the cases we care about we
11403 // already have an existing method we want to call, so there's no need
11404 // to create a new function object. We can even get away with assuming
11405 // the method takes exactly one argument, since that happens to be true
11406 // in every case, so we don't have to touch the arguments object. The
11407 // only additional allocation required is the completion record, which
11408 // has a stable shape and so hopefully should be cheap to allocate.
11409 function tryCatch(fn, obj, arg) {
11410 try {
11411 return { type: "normal", arg: fn.call(obj, arg) };
11412 } catch (err) {
11413 return { type: "throw", arg: err };
11414 }
11415 }
11416
11417 var GenStateSuspendedStart = "suspendedStart";
11418 var GenStateSuspendedYield = "suspendedYield";
11419 var GenStateExecuting = "executing";
11420 var GenStateCompleted = "completed";
11421
11422 // Returning this object from the innerFn has the same effect as
11423 // breaking out of the dispatch switch statement.
11424 var ContinueSentinel = {};
11425
11426 // Dummy constructor functions that we use as the .constructor and
11427 // .constructor.prototype properties for functions that return Generator
11428 // objects. For full spec compliance, you may wish to configure your
11429 // minifier not to mangle the names of these two functions.
11430 function Generator() {}
11431 function GeneratorFunction() {}
11432 function GeneratorFunctionPrototype() {}
11433
11434 // This is a polyfill for %IteratorPrototype% for environments that
11435 // don't natively support it.
11436 var IteratorPrototype = {};
11437 IteratorPrototype[iteratorSymbol] = function () {
11438 return this;
11439 };
11440
11441 var getProto = Object.getPrototypeOf;
11442 var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
11443 if (NativeIteratorPrototype &&
11444 NativeIteratorPrototype !== Op &&
11445 hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
11446 // This environment has a native %IteratorPrototype%; use it instead
11447 // of the polyfill.
11448 IteratorPrototype = NativeIteratorPrototype;
11449 }
11450
11451 var Gp = GeneratorFunctionPrototype.prototype =
11452 Generator.prototype = Object.create(IteratorPrototype);
11453 GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
11454 GeneratorFunctionPrototype.constructor = GeneratorFunction;
11455 GeneratorFunctionPrototype[toStringTagSymbol] =
11456 GeneratorFunction.displayName = "GeneratorFunction";
11457
11458 // Helper for defining the .next, .throw, and .return methods of the
11459 // Iterator interface in terms of a single ._invoke method.
11460 function defineIteratorMethods(prototype) {
11461 ["next", "throw", "return"].forEach(function(method) {
11462 prototype[method] = function(arg) {
11463 return this._invoke(method, arg);
11464 };
11465 });
11466 }
11467
11468 runtime.isGeneratorFunction = function(genFun) {
11469 var ctor = typeof genFun === "function" && genFun.constructor;
11470 return ctor
11471 ? ctor === GeneratorFunction ||
11472 // For the native GeneratorFunction constructor, the best we can
11473 // do is to check its .name property.
11474 (ctor.displayName || ctor.name) === "GeneratorFunction"
11475 : false;
11476 };
11477
11478 runtime.mark = function(genFun) {
11479 if (Object.setPrototypeOf) {
11480 Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
11481 } else {
11482 genFun.__proto__ = GeneratorFunctionPrototype;
11483 if (!(toStringTagSymbol in genFun)) {
11484 genFun[toStringTagSymbol] = "GeneratorFunction";
11485 }
11486 }
11487 genFun.prototype = Object.create(Gp);
11488 return genFun;
11489 };
11490
11491 // Within the body of any async function, `await x` is transformed to
11492 // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
11493 // `hasOwn.call(value, "__await")` to determine if the yielded value is
11494 // meant to be awaited.
11495 runtime.awrap = function(arg) {
11496 return { __await: arg };
11497 };
11498
11499 function AsyncIterator(generator) {
11500 function invoke(method, arg, resolve, reject) {
11501 var record = tryCatch(generator[method], generator, arg);
11502 if (record.type === "throw") {
11503 reject(record.arg);
11504 } else {
11505 var result = record.arg;
11506 var value = result.value;
11507 if (value &&
11508 typeof value === "object" &&
11509 hasOwn.call(value, "__await")) {
11510 return Promise.resolve(value.__await).then(function(value) {
11511 invoke("next", value, resolve, reject);
11512 }, function(err) {
11513 invoke("throw", err, resolve, reject);
11514 });
11515 }
11516
11517 return Promise.resolve(value).then(function(unwrapped) {
11518 // When a yielded Promise is resolved, its final value becomes
11519 // the .value of the Promise<{value,done}> result for the
11520 // current iteration.
11521 result.value = unwrapped;
11522 resolve(result);
11523 }, function(error) {
11524 // If a rejected Promise was yielded, throw the rejection back
11525 // into the async generator function so it can be handled there.
11526 return invoke("throw", error, resolve, reject);
11527 });
11528 }
11529 }
11530
11531 var previousPromise;
11532
11533 function enqueue(method, arg) {
11534 function callInvokeWithMethodAndArg() {
11535 return new Promise(function(resolve, reject) {
11536 invoke(method, arg, resolve, reject);
11537 });
11538 }
11539
11540 return previousPromise =
11541 // If enqueue has been called before, then we want to wait until
11542 // all previous Promises have been resolved before calling invoke,
11543 // so that results are always delivered in the correct order. If
11544 // enqueue has not been called before, then it is important to
11545 // call invoke immediately, without waiting on a callback to fire,
11546 // so that the async generator function has the opportunity to do
11547 // any necessary setup in a predictable way. This predictability
11548 // is why the Promise constructor synchronously invokes its
11549 // executor callback, and why async functions synchronously
11550 // execute code before the first await. Since we implement simple
11551 // async functions in terms of async generators, it is especially
11552 // important to get this right, even though it requires care.
11553 previousPromise ? previousPromise.then(
11554 callInvokeWithMethodAndArg,
11555 // Avoid propagating failures to Promises returned by later
11556 // invocations of the iterator.
11557 callInvokeWithMethodAndArg
11558 ) : callInvokeWithMethodAndArg();
11559 }
11560
11561 // Define the unified helper method that is used to implement .next,
11562 // .throw, and .return (see defineIteratorMethods).
11563 this._invoke = enqueue;
11564 }
11565
11566 defineIteratorMethods(AsyncIterator.prototype);
11567 AsyncIterator.prototype[asyncIteratorSymbol] = function () {
11568 return this;
11569 };
11570 runtime.AsyncIterator = AsyncIterator;
11571
11572 // Note that simple async functions are implemented on top of
11573 // AsyncIterator objects; they just return a Promise for the value of
11574 // the final result produced by the iterator.
11575 runtime.async = function(innerFn, outerFn, self, tryLocsList) {
11576 var iter = new AsyncIterator(
11577 wrap(innerFn, outerFn, self, tryLocsList)
11578 );
11579
11580 return runtime.isGeneratorFunction(outerFn)
11581 ? iter // If outerFn is a generator, return the full iterator.
11582 : iter.next().then(function(result) {
11583 return result.done ? result.value : iter.next();
11584 });
11585 };
11586
11587 function makeInvokeMethod(innerFn, self, context) {
11588 var state = GenStateSuspendedStart;
11589
11590 return function invoke(method, arg) {
11591 if (state === GenStateExecuting) {
11592 throw new Error("Generator is already running");
11593 }
11594
11595 if (state === GenStateCompleted) {
11596 if (method === "throw") {
11597 throw arg;
11598 }
11599
11600 // Be forgiving, per 25.3.3.3.3 of the spec:
11601 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
11602 return doneResult();
11603 }
11604
11605 context.method = method;
11606 context.arg = arg;
11607
11608 while (true) {
11609 var delegate = context.delegate;
11610 if (delegate) {
11611 var delegateResult = maybeInvokeDelegate(delegate, context);
11612 if (delegateResult) {
11613 if (delegateResult === ContinueSentinel) continue;
11614 return delegateResult;
11615 }
11616 }
11617
11618 if (context.method === "next") {
11619 // Setting context._sent for legacy support of Babel's
11620 // function.sent implementation.
11621 context.sent = context._sent = context.arg;
11622
11623 } else if (context.method === "throw") {
11624 if (state === GenStateSuspendedStart) {
11625 state = GenStateCompleted;
11626 throw context.arg;
11627 }
11628
11629 context.dispatchException(context.arg);
11630
11631 } else if (context.method === "return") {
11632 context.abrupt("return", context.arg);
11633 }
11634
11635 state = GenStateExecuting;
11636
11637 var record = tryCatch(innerFn, self, context);
11638 if (record.type === "normal") {
11639 // If an exception is thrown from innerFn, we leave state ===
11640 // GenStateExecuting and loop back for another invocation.
11641 state = context.done
11642 ? GenStateCompleted
11643 : GenStateSuspendedYield;
11644
11645 if (record.arg === ContinueSentinel) {
11646 continue;
11647 }
11648
11649 return {
11650 value: record.arg,
11651 done: context.done
11652 };
11653
11654 } else if (record.type === "throw") {
11655 state = GenStateCompleted;
11656 // Dispatch the exception by looping back around to the
11657 // context.dispatchException(context.arg) call above.
11658 context.method = "throw";
11659 context.arg = record.arg;
11660 }
11661 }
11662 };
11663 }
11664
11665 // Call delegate.iterator[context.method](context.arg) and handle the
11666 // result, either by returning a { value, done } result from the
11667 // delegate iterator, or by modifying context.method and context.arg,
11668 // setting context.delegate to null, and returning the ContinueSentinel.
11669 function maybeInvokeDelegate(delegate, context) {
11670 var method = delegate.iterator[context.method];
11671 if (method === undefined$1) {
11672 // A .throw or .return when the delegate iterator has no .throw
11673 // method always terminates the yield* loop.
11674 context.delegate = null;
11675
11676 if (context.method === "throw") {
11677 if (delegate.iterator.return) {
11678 // If the delegate iterator has a return method, give it a
11679 // chance to clean up.
11680 context.method = "return";
11681 context.arg = undefined$1;
11682 maybeInvokeDelegate(delegate, context);
11683
11684 if (context.method === "throw") {
11685 // If maybeInvokeDelegate(context) changed context.method from
11686 // "return" to "throw", let that override the TypeError below.
11687 return ContinueSentinel;
11688 }
11689 }
11690
11691 context.method = "throw";
11692 context.arg = new TypeError(
11693 "The iterator does not provide a 'throw' method");
11694 }
11695
11696 return ContinueSentinel;
11697 }
11698
11699 var record = tryCatch(method, delegate.iterator, context.arg);
11700
11701 if (record.type === "throw") {
11702 context.method = "throw";
11703 context.arg = record.arg;
11704 context.delegate = null;
11705 return ContinueSentinel;
11706 }
11707
11708 var info = record.arg;
11709
11710 if (! info) {
11711 context.method = "throw";
11712 context.arg = new TypeError("iterator result is not an object");
11713 context.delegate = null;
11714 return ContinueSentinel;
11715 }
11716
11717 if (info.done) {
11718 // Assign the result of the finished delegate to the temporary
11719 // variable specified by delegate.resultName (see delegateYield).
11720 context[delegate.resultName] = info.value;
11721
11722 // Resume execution at the desired location (see delegateYield).
11723 context.next = delegate.nextLoc;
11724
11725 // If context.method was "throw" but the delegate handled the
11726 // exception, let the outer generator proceed normally. If
11727 // context.method was "next", forget context.arg since it has been
11728 // "consumed" by the delegate iterator. If context.method was
11729 // "return", allow the original .return call to continue in the
11730 // outer generator.
11731 if (context.method !== "return") {
11732 context.method = "next";
11733 context.arg = undefined$1;
11734 }
11735
11736 } else {
11737 // Re-yield the result returned by the delegate method.
11738 return info;
11739 }
11740
11741 // The delegate iterator is finished, so forget it and continue with
11742 // the outer generator.
11743 context.delegate = null;
11744 return ContinueSentinel;
11745 }
11746
11747 // Define Generator.prototype.{next,throw,return} in terms of the
11748 // unified ._invoke helper method.
11749 defineIteratorMethods(Gp);
11750
11751 Gp[toStringTagSymbol] = "Generator";
11752
11753 // A Generator should always return itself as the iterator object when the
11754 // @@iterator function is called on it. Some browsers' implementations of the
11755 // iterator prototype chain incorrectly implement this, causing the Generator
11756 // object to not be returned from this call. This ensures that doesn't happen.
11757 // See https://github.com/facebook/regenerator/issues/274 for more details.
11758 Gp[iteratorSymbol] = function() {
11759 return this;
11760 };
11761
11762 Gp.toString = function() {
11763 return "[object Generator]";
11764 };
11765
11766 function pushTryEntry(locs) {
11767 var entry = { tryLoc: locs[0] };
11768
11769 if (1 in locs) {
11770 entry.catchLoc = locs[1];
11771 }
11772
11773 if (2 in locs) {
11774 entry.finallyLoc = locs[2];
11775 entry.afterLoc = locs[3];
11776 }
11777
11778 this.tryEntries.push(entry);
11779 }
11780
11781 function resetTryEntry(entry) {
11782 var record = entry.completion || {};
11783 record.type = "normal";
11784 delete record.arg;
11785 entry.completion = record;
11786 }
11787
11788 function Context(tryLocsList) {
11789 // The root entry object (effectively a try statement without a catch
11790 // or a finally block) gives us a place to store values thrown from
11791 // locations where there is no enclosing try statement.
11792 this.tryEntries = [{ tryLoc: "root" }];
11793 tryLocsList.forEach(pushTryEntry, this);
11794 this.reset(true);
11795 }
11796
11797 runtime.keys = function(object) {
11798 var keys = [];
11799 for (var key in object) {
11800 keys.push(key);
11801 }
11802 keys.reverse();
11803
11804 // Rather than returning an object with a next method, we keep
11805 // things simple and return the next function itself.
11806 return function next() {
11807 while (keys.length) {
11808 var key = keys.pop();
11809 if (key in object) {
11810 next.value = key;
11811 next.done = false;
11812 return next;
11813 }
11814 }
11815
11816 // To avoid creating an additional object, we just hang the .value
11817 // and .done properties off the next function object itself. This
11818 // also ensures that the minifier will not anonymize the function.
11819 next.done = true;
11820 return next;
11821 };
11822 };
11823
11824 function values(iterable) {
11825 if (iterable) {
11826 var iteratorMethod = iterable[iteratorSymbol];
11827 if (iteratorMethod) {
11828 return iteratorMethod.call(iterable);
11829 }
11830
11831 if (typeof iterable.next === "function") {
11832 return iterable;
11833 }
11834
11835 if (!isNaN(iterable.length)) {
11836 var i = -1, next = function next() {
11837 while (++i < iterable.length) {
11838 if (hasOwn.call(iterable, i)) {
11839 next.value = iterable[i];
11840 next.done = false;
11841 return next;
11842 }
11843 }
11844
11845 next.value = undefined$1;
11846 next.done = true;
11847
11848 return next;
11849 };
11850
11851 return next.next = next;
11852 }
11853 }
11854
11855 // Return an iterator with no values.
11856 return { next: doneResult };
11857 }
11858 runtime.values = values;
11859
11860 function doneResult() {
11861 return { value: undefined$1, done: true };
11862 }
11863
11864 Context.prototype = {
11865 constructor: Context,
11866
11867 reset: function(skipTempReset) {
11868 this.prev = 0;
11869 this.next = 0;
11870 // Resetting context._sent for legacy support of Babel's
11871 // function.sent implementation.
11872 this.sent = this._sent = undefined$1;
11873 this.done = false;
11874 this.delegate = null;
11875
11876 this.method = "next";
11877 this.arg = undefined$1;
11878
11879 this.tryEntries.forEach(resetTryEntry);
11880
11881 if (!skipTempReset) {
11882 for (var name in this) {
11883 // Not sure about the optimal order of these conditions:
11884 if (name.charAt(0) === "t" &&
11885 hasOwn.call(this, name) &&
11886 !isNaN(+name.slice(1))) {
11887 this[name] = undefined$1;
11888 }
11889 }
11890 }
11891 },
11892
11893 stop: function() {
11894 this.done = true;
11895
11896 var rootEntry = this.tryEntries[0];
11897 var rootRecord = rootEntry.completion;
11898 if (rootRecord.type === "throw") {
11899 throw rootRecord.arg;
11900 }
11901
11902 return this.rval;
11903 },
11904
11905 dispatchException: function(exception) {
11906 if (this.done) {
11907 throw exception;
11908 }
11909
11910 var context = this;
11911 function handle(loc, caught) {
11912 record.type = "throw";
11913 record.arg = exception;
11914 context.next = loc;
11915
11916 if (caught) {
11917 // If the dispatched exception was caught by a catch block,
11918 // then let that catch block handle the exception normally.
11919 context.method = "next";
11920 context.arg = undefined$1;
11921 }
11922
11923 return !! caught;
11924 }
11925
11926 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
11927 var entry = this.tryEntries[i];
11928 var record = entry.completion;
11929
11930 if (entry.tryLoc === "root") {
11931 // Exception thrown outside of any try block that could handle
11932 // it, so set the completion value of the entire function to
11933 // throw the exception.
11934 return handle("end");
11935 }
11936
11937 if (entry.tryLoc <= this.prev) {
11938 var hasCatch = hasOwn.call(entry, "catchLoc");
11939 var hasFinally = hasOwn.call(entry, "finallyLoc");
11940
11941 if (hasCatch && hasFinally) {
11942 if (this.prev < entry.catchLoc) {
11943 return handle(entry.catchLoc, true);
11944 } else if (this.prev < entry.finallyLoc) {
11945 return handle(entry.finallyLoc);
11946 }
11947
11948 } else if (hasCatch) {
11949 if (this.prev < entry.catchLoc) {
11950 return handle(entry.catchLoc, true);
11951 }
11952
11953 } else if (hasFinally) {
11954 if (this.prev < entry.finallyLoc) {
11955 return handle(entry.finallyLoc);
11956 }
11957
11958 } else {
11959 throw new Error("try statement without catch or finally");
11960 }
11961 }
11962 }
11963 },
11964
11965 abrupt: function(type, arg) {
11966 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
11967 var entry = this.tryEntries[i];
11968 if (entry.tryLoc <= this.prev &&
11969 hasOwn.call(entry, "finallyLoc") &&
11970 this.prev < entry.finallyLoc) {
11971 var finallyEntry = entry;
11972 break;
11973 }
11974 }
11975
11976 if (finallyEntry &&
11977 (type === "break" ||
11978 type === "continue") &&
11979 finallyEntry.tryLoc <= arg &&
11980 arg <= finallyEntry.finallyLoc) {
11981 // Ignore the finally entry if control is not jumping to a
11982 // location outside the try/catch block.
11983 finallyEntry = null;
11984 }
11985
11986 var record = finallyEntry ? finallyEntry.completion : {};
11987 record.type = type;
11988 record.arg = arg;
11989
11990 if (finallyEntry) {
11991 this.method = "next";
11992 this.next = finallyEntry.finallyLoc;
11993 return ContinueSentinel;
11994 }
11995
11996 return this.complete(record);
11997 },
11998
11999 complete: function(record, afterLoc) {
12000 if (record.type === "throw") {
12001 throw record.arg;
12002 }
12003
12004 if (record.type === "break" ||
12005 record.type === "continue") {
12006 this.next = record.arg;
12007 } else if (record.type === "return") {
12008 this.rval = this.arg = record.arg;
12009 this.method = "return";
12010 this.next = "end";
12011 } else if (record.type === "normal" && afterLoc) {
12012 this.next = afterLoc;
12013 }
12014
12015 return ContinueSentinel;
12016 },
12017
12018 finish: function(finallyLoc) {
12019 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
12020 var entry = this.tryEntries[i];
12021 if (entry.finallyLoc === finallyLoc) {
12022 this.complete(entry.completion, entry.afterLoc);
12023 resetTryEntry(entry);
12024 return ContinueSentinel;
12025 }
12026 }
12027 },
12028
12029 "catch": function(tryLoc) {
12030 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
12031 var entry = this.tryEntries[i];
12032 if (entry.tryLoc === tryLoc) {
12033 var record = entry.completion;
12034 if (record.type === "throw") {
12035 var thrown = record.arg;
12036 resetTryEntry(entry);
12037 }
12038 return thrown;
12039 }
12040 }
12041
12042 // The context.catch method must only be called with a location
12043 // argument that corresponds to a known catch block.
12044 throw new Error("illegal catch attempt");
12045 },
12046
12047 delegateYield: function(iterable, resultName, nextLoc) {
12048 this.delegate = {
12049 iterator: values(iterable),
12050 resultName: resultName,
12051 nextLoc: nextLoc
12052 };
12053
12054 if (this.method === "next") {
12055 // Deliberately forget the last sent value so that we don't
12056 // accidentally pass it on to the delegate.
12057 this.arg = undefined$1;
12058 }
12059
12060 return ContinueSentinel;
12061 }
12062 };
12063 })(
12064 // In sloppy mode, unbound `this` refers to the global object, fallback to
12065 // Function constructor if we're in global strict mode. That is sadly a form
12066 // of indirect eval which violates Content Security Policy.
12067 (function() {
12068 return this || (typeof self === "object" && self);
12069 })() || Function("return this")()
12070 );
12071 });
12072
12073 /**
12074 * Copyright (c) 2014-present, Facebook, Inc.
12075 *
12076 * This source code is licensed under the MIT license found in the
12077 * LICENSE file in the root directory of this source tree.
12078 */
12079
12080 // This method of obtaining a reference to the global object needs to be
12081 // kept identical to the way it is obtained in runtime.js
12082 var g = (function() {
12083 return this || (typeof self === "object" && self);
12084 })() || Function("return this")();
12085
12086 // Use `getOwnPropertyNames` because not all browsers support calling
12087 // `hasOwnProperty` on the global `self` object in a worker. See #183.
12088 var hadRuntime = g.regeneratorRuntime &&
12089 Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0;
12090
12091 // Save the old regeneratorRuntime in case it needs to be restored later.
12092 var oldRuntime = hadRuntime && g.regeneratorRuntime;
12093
12094 // Force reevalutation of runtime.js.
12095 g.regeneratorRuntime = undefined;
12096
12097 var runtimeModule = runtime;
12098
12099 if (hadRuntime) {
12100 // Restore the original runtime.
12101 g.regeneratorRuntime = oldRuntime;
12102 } else {
12103 // Remove the global property added by runtime.js.
12104 try {
12105 delete g.regeneratorRuntime;
12106 } catch(e) {
12107 g.regeneratorRuntime = undefined;
12108 }
12109 }
12110
12111 var regenerator = runtimeModule;
12112
12113 /**
12114 * Helpers.
12115 */
12116
12117 var s = 1000;
12118 var m = s * 60;
12119 var h = m * 60;
12120 var d = h * 24;
12121 var w = d * 7;
12122 var y = d * 365.25;
12123
12124 /**
12125 * Parse or format the given `val`.
12126 *
12127 * Options:
12128 *
12129 * - `long` verbose formatting [false]
12130 *
12131 * @param {String|Number} val
12132 * @param {Object} [options]
12133 * @throws {Error} throw an error if val is not a non-empty string or a number
12134 * @return {String|Number}
12135 * @api public
12136 */
12137
12138 var ms = function(val, options) {
12139 options = options || {};
12140 var type = typeof val;
12141 if (type === 'string' && val.length > 0) {
12142 return parse(val);
12143 } else if (type === 'number' && isNaN(val) === false) {
12144 return options.long ? fmtLong(val) : fmtShort(val);
12145 }
12146 throw new Error(
12147 'val is not a non-empty string or a valid number. val=' +
12148 JSON.stringify(val)
12149 );
12150 };
12151
12152 /**
12153 * Parse the given `str` and return milliseconds.
12154 *
12155 * @param {String} str
12156 * @return {Number}
12157 * @api private
12158 */
12159
12160 function parse(str) {
12161 str = String(str);
12162 if (str.length > 100) {
12163 return;
12164 }
12165 var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
12166 str
12167 );
12168 if (!match) {
12169 return;
12170 }
12171 var n = parseFloat(match[1]);
12172 var type = (match[2] || 'ms').toLowerCase();
12173 switch (type) {
12174 case 'years':
12175 case 'year':
12176 case 'yrs':
12177 case 'yr':
12178 case 'y':
12179 return n * y;
12180 case 'weeks':
12181 case 'week':
12182 case 'w':
12183 return n * w;
12184 case 'days':
12185 case 'day':
12186 case 'd':
12187 return n * d;
12188 case 'hours':
12189 case 'hour':
12190 case 'hrs':
12191 case 'hr':
12192 case 'h':
12193 return n * h;
12194 case 'minutes':
12195 case 'minute':
12196 case 'mins':
12197 case 'min':
12198 case 'm':
12199 return n * m;
12200 case 'seconds':
12201 case 'second':
12202 case 'secs':
12203 case 'sec':
12204 case 's':
12205 return n * s;
12206 case 'milliseconds':
12207 case 'millisecond':
12208 case 'msecs':
12209 case 'msec':
12210 case 'ms':
12211 return n;
12212 default:
12213 return undefined;
12214 }
12215 }
12216
12217 /**
12218 * Short format for `ms`.
12219 *
12220 * @param {Number} ms
12221 * @return {String}
12222 * @api private
12223 */
12224
12225 function fmtShort(ms) {
12226 var msAbs = Math.abs(ms);
12227 if (msAbs >= d) {
12228 return Math.round(ms / d) + 'd';
12229 }
12230 if (msAbs >= h) {
12231 return Math.round(ms / h) + 'h';
12232 }
12233 if (msAbs >= m) {
12234 return Math.round(ms / m) + 'm';
12235 }
12236 if (msAbs >= s) {
12237 return Math.round(ms / s) + 's';
12238 }
12239 return ms + 'ms';
12240 }
12241
12242 /**
12243 * Long format for `ms`.
12244 *
12245 * @param {Number} ms
12246 * @return {String}
12247 * @api private
12248 */
12249
12250 function fmtLong(ms) {
12251 var msAbs = Math.abs(ms);
12252 if (msAbs >= d) {
12253 return plural(ms, msAbs, d, 'day');
12254 }
12255 if (msAbs >= h) {
12256 return plural(ms, msAbs, h, 'hour');
12257 }
12258 if (msAbs >= m) {
12259 return plural(ms, msAbs, m, 'minute');
12260 }
12261 if (msAbs >= s) {
12262 return plural(ms, msAbs, s, 'second');
12263 }
12264 return ms + ' ms';
12265 }
12266
12267 /**
12268 * Pluralization helper.
12269 */
12270
12271 function plural(ms, msAbs, n, name) {
12272 var isPlural = msAbs >= n * 1.5;
12273 return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
12274 }
12275
12276 /**
12277 * This is the common logic for both the Node.js and web browser
12278 * implementations of `debug()`.
12279 */
12280 function setup(env) {
12281 createDebug.debug = createDebug;
12282 createDebug.default = createDebug;
12283 createDebug.coerce = coerce;
12284 createDebug.disable = disable;
12285 createDebug.enable = enable;
12286 createDebug.enabled = enabled;
12287 createDebug.humanize = ms;
12288 Object.keys(env).forEach(function (key) {
12289 createDebug[key] = env[key];
12290 });
12291 /**
12292 * Active `debug` instances.
12293 */
12294
12295 createDebug.instances = [];
12296 /**
12297 * The currently active debug mode names, and names to skip.
12298 */
12299
12300 createDebug.names = [];
12301 createDebug.skips = [];
12302 /**
12303 * Map of special "%n" handling functions, for the debug "format" argument.
12304 *
12305 * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
12306 */
12307
12308 createDebug.formatters = {};
12309 /**
12310 * Selects a color for a debug namespace
12311 * @param {String} namespace The namespace string for the for the debug instance to be colored
12312 * @return {Number|String} An ANSI color code for the given namespace
12313 * @api private
12314 */
12315
12316 function selectColor(namespace) {
12317 var hash = 0;
12318
12319 for (var i = 0; i < namespace.length; i++) {
12320 hash = (hash << 5) - hash + namespace.charCodeAt(i);
12321 hash |= 0; // Convert to 32bit integer
12322 }
12323
12324 return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
12325 }
12326
12327 createDebug.selectColor = selectColor;
12328 /**
12329 * Create a debugger with the given `namespace`.
12330 *
12331 * @param {String} namespace
12332 * @return {Function}
12333 * @api public
12334 */
12335
12336 function createDebug(namespace) {
12337 var prevTime;
12338
12339 function debug() {
12340 // Disabled?
12341 if (!debug.enabled) {
12342 return;
12343 }
12344
12345 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
12346 args[_key] = arguments[_key];
12347 }
12348
12349 var self = debug; // Set `diff` timestamp
12350
12351 var curr = Number(new Date());
12352 var ms = curr - (prevTime || curr);
12353 self.diff = ms;
12354 self.prev = prevTime;
12355 self.curr = curr;
12356 prevTime = curr;
12357 args[0] = createDebug.coerce(args[0]);
12358
12359 if (typeof args[0] !== 'string') {
12360 // Anything else let's inspect with %O
12361 args.unshift('%O');
12362 } // Apply any `formatters` transformations
12363
12364
12365 var index = 0;
12366 args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {
12367 // If we encounter an escaped % then don't increase the array index
12368 if (match === '%%') {
12369 return match;
12370 }
12371
12372 index++;
12373 var formatter = createDebug.formatters[format];
12374
12375 if (typeof formatter === 'function') {
12376 var val = args[index];
12377 match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`
12378
12379 args.splice(index, 1);
12380 index--;
12381 }
12382
12383 return match;
12384 }); // Apply env-specific formatting (colors, etc.)
12385
12386 createDebug.formatArgs.call(self, args);
12387 var logFn = self.log || createDebug.log;
12388 logFn.apply(self, args);
12389 }
12390
12391 debug.namespace = namespace;
12392 debug.enabled = createDebug.enabled(namespace);
12393 debug.useColors = createDebug.useColors();
12394 debug.color = selectColor(namespace);
12395 debug.destroy = destroy;
12396 debug.extend = extend; // Debug.formatArgs = formatArgs;
12397 // debug.rawLog = rawLog;
12398 // env-specific initialization logic for debug instances
12399
12400 if (typeof createDebug.init === 'function') {
12401 createDebug.init(debug);
12402 }
12403
12404 createDebug.instances.push(debug);
12405 return debug;
12406 }
12407
12408 function destroy() {
12409 var index = createDebug.instances.indexOf(this);
12410
12411 if (index !== -1) {
12412 createDebug.instances.splice(index, 1);
12413 return true;
12414 }
12415
12416 return false;
12417 }
12418
12419 function extend(namespace, delimiter) {
12420 return createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
12421 }
12422 /**
12423 * Enables a debug mode by namespaces. This can include modes
12424 * separated by a colon and wildcards.
12425 *
12426 * @param {String} namespaces
12427 * @api public
12428 */
12429
12430
12431 function enable(namespaces) {
12432 createDebug.save(namespaces);
12433 createDebug.names = [];
12434 createDebug.skips = [];
12435 var i;
12436 var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
12437 var len = split.length;
12438
12439 for (i = 0; i < len; i++) {
12440 if (!split[i]) {
12441 // ignore empty strings
12442 continue;
12443 }
12444
12445 namespaces = split[i].replace(/\*/g, '.*?');
12446
12447 if (namespaces[0] === '-') {
12448 createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
12449 } else {
12450 createDebug.names.push(new RegExp('^' + namespaces + '$'));
12451 }
12452 }
12453
12454 for (i = 0; i < createDebug.instances.length; i++) {
12455 var instance = createDebug.instances[i];
12456 instance.enabled = createDebug.enabled(instance.namespace);
12457 }
12458 }
12459 /**
12460 * Disable debug output.
12461 *
12462 * @api public
12463 */
12464
12465
12466 function disable() {
12467 createDebug.enable('');
12468 }
12469 /**
12470 * Returns true if the given mode name is enabled, false otherwise.
12471 *
12472 * @param {String} name
12473 * @return {Boolean}
12474 * @api public
12475 */
12476
12477
12478 function enabled(name) {
12479 if (name[name.length - 1] === '*') {
12480 return true;
12481 }
12482
12483 var i;
12484 var len;
12485
12486 for (i = 0, len = createDebug.skips.length; i < len; i++) {
12487 if (createDebug.skips[i].test(name)) {
12488 return false;
12489 }
12490 }
12491
12492 for (i = 0, len = createDebug.names.length; i < len; i++) {
12493 if (createDebug.names[i].test(name)) {
12494 return true;
12495 }
12496 }
12497
12498 return false;
12499 }
12500 /**
12501 * Coerce `val`.
12502 *
12503 * @param {Mixed} val
12504 * @return {Mixed}
12505 * @api private
12506 */
12507
12508
12509 function coerce(val) {
12510 if (val instanceof Error) {
12511 return val.stack || val.message;
12512 }
12513
12514 return val;
12515 }
12516
12517 createDebug.enable(createDebug.load());
12518 return createDebug;
12519 }
12520
12521 var common = setup;
12522
12523 var browser = createCommonjsModule(function (module, exports) {
12524
12525 function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
12526
12527 /* eslint-env browser */
12528
12529 /**
12530 * This is the web browser implementation of `debug()`.
12531 */
12532 exports.log = log;
12533 exports.formatArgs = formatArgs;
12534 exports.save = save;
12535 exports.load = load;
12536 exports.useColors = useColors;
12537 exports.storage = localstorage();
12538 /**
12539 * Colors.
12540 */
12541
12542 exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];
12543 /**
12544 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
12545 * and the Firebug extension (any Firefox version) are known
12546 * to support "%c" CSS customizations.
12547 *
12548 * TODO: add a `localStorage` variable to explicitly enable/disable colors
12549 */
12550 // eslint-disable-next-line complexity
12551
12552 function useColors() {
12553 // NB: In an Electron preload script, document will be defined but not fully
12554 // initialized. Since we know we're in Chrome, we'll just detect this case
12555 // explicitly
12556 if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
12557 return true;
12558 } // Internet Explorer and Edge do not support colors.
12559
12560
12561 if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
12562 return false;
12563 } // Is webkit? http://stackoverflow.com/a/16459606/376773
12564 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
12565
12566
12567 return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
12568 typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
12569 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
12570 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
12571 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
12572 }
12573 /**
12574 * Colorize log arguments if enabled.
12575 *
12576 * @api public
12577 */
12578
12579
12580 function formatArgs(args) {
12581 args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);
12582
12583 if (!this.useColors) {
12584 return;
12585 }
12586
12587 var c = 'color: ' + this.color;
12588 args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other
12589 // arguments passed either before or after the %c, so we need to
12590 // figure out the correct index to insert the CSS into
12591
12592 var index = 0;
12593 var lastC = 0;
12594 args[0].replace(/%[a-zA-Z%]/g, function (match) {
12595 if (match === '%%') {
12596 return;
12597 }
12598
12599 index++;
12600
12601 if (match === '%c') {
12602 // We only are interested in the *last* %c
12603 // (the user may have provided their own)
12604 lastC = index;
12605 }
12606 });
12607 args.splice(lastC, 0, c);
12608 }
12609 /**
12610 * Invokes `console.log()` when available.
12611 * No-op when `console.log` is not a "function".
12612 *
12613 * @api public
12614 */
12615
12616
12617 function log() {
12618 var _console;
12619
12620 // This hackery is required for IE8/9, where
12621 // the `console.log` function doesn't have 'apply'
12622 return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);
12623 }
12624 /**
12625 * Save `namespaces`.
12626 *
12627 * @param {String} namespaces
12628 * @api private
12629 */
12630
12631
12632 function save(namespaces) {
12633 try {
12634 if (namespaces) {
12635 exports.storage.setItem('debug', namespaces);
12636 } else {
12637 exports.storage.removeItem('debug');
12638 }
12639 } catch (error) {// Swallow
12640 // XXX (@Qix-) should we be logging these?
12641 }
12642 }
12643 /**
12644 * Load `namespaces`.
12645 *
12646 * @return {String} returns the previously persisted debug modes
12647 * @api private
12648 */
12649
12650
12651 function load() {
12652 var r;
12653
12654 try {
12655 r = exports.storage.getItem('debug');
12656 } catch (error) {} // Swallow
12657 // XXX (@Qix-) should we be logging these?
12658 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
12659
12660
12661 if (!r && typeof process !== 'undefined' && 'env' in process) {
12662 r = process.env.DEBUG;
12663 }
12664
12665 return r;
12666 }
12667 /**
12668 * Localstorage attempts to return the localstorage.
12669 *
12670 * This is necessary because safari throws
12671 * when a user disables cookies/localstorage
12672 * and you attempt to access it.
12673 *
12674 * @return {LocalStorage}
12675 * @api private
12676 */
12677
12678
12679 function localstorage() {
12680 try {
12681 // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
12682 // The Browser also has localStorage in the global context.
12683 return localStorage;
12684 } catch (error) {// Swallow
12685 // XXX (@Qix-) should we be logging these?
12686 }
12687 }
12688
12689 module.exports = common(exports);
12690 var formatters = module.exports.formatters;
12691 /**
12692 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
12693 */
12694
12695 formatters.j = function (v) {
12696 try {
12697 return JSON.stringify(v);
12698 } catch (error) {
12699 return '[UnexpectedJSONParseError]: ' + error.message;
12700 }
12701 };
12702 });
12703 var browser_1 = browser.log;
12704 var browser_2 = browser.formatArgs;
12705 var browser_3 = browser.save;
12706 var browser_4 = browser.load;
12707 var browser_5 = browser.useColors;
12708 var browser_6 = browser.storage;
12709 var browser_7 = browser.colors;
12710
12711 var componentEmitter = createCommonjsModule(function (module) {
12712 /**
12713 * Expose `Emitter`.
12714 */
12715 {
12716 module.exports = Emitter;
12717 }
12718 /**
12719 * Initialize a new `Emitter`.
12720 *
12721 * @api public
12722 */
12723
12724
12725 function Emitter(obj) {
12726 if (obj) return mixin(obj);
12727 }
12728 /**
12729 * Mixin the emitter properties.
12730 *
12731 * @param {Object} obj
12732 * @return {Object}
12733 * @api private
12734 */
12735
12736 function mixin(obj) {
12737 for (var key in Emitter.prototype) {
12738 obj[key] = Emitter.prototype[key];
12739 }
12740
12741 return obj;
12742 }
12743 /**
12744 * Listen on the given `event` with `fn`.
12745 *
12746 * @param {String} event
12747 * @param {Function} fn
12748 * @return {Emitter}
12749 * @api public
12750 */
12751
12752
12753 Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {
12754 this._callbacks = this._callbacks || {};
12755 (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn);
12756 return this;
12757 };
12758 /**
12759 * Adds an `event` listener that will be invoked a single
12760 * time then automatically removed.
12761 *
12762 * @param {String} event
12763 * @param {Function} fn
12764 * @return {Emitter}
12765 * @api public
12766 */
12767
12768
12769 Emitter.prototype.once = function (event, fn) {
12770 function on() {
12771 this.off(event, on);
12772 fn.apply(this, arguments);
12773 }
12774
12775 on.fn = fn;
12776 this.on(event, on);
12777 return this;
12778 };
12779 /**
12780 * Remove the given callback for `event` or all
12781 * registered callbacks.
12782 *
12783 * @param {String} event
12784 * @param {Function} fn
12785 * @return {Emitter}
12786 * @api public
12787 */
12788
12789
12790 Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {
12791 this._callbacks = this._callbacks || {}; // all
12792
12793 if (0 == arguments.length) {
12794 this._callbacks = {};
12795 return this;
12796 } // specific event
12797
12798
12799 var callbacks = this._callbacks['$' + event];
12800 if (!callbacks) return this; // remove all handlers
12801
12802 if (1 == arguments.length) {
12803 delete this._callbacks['$' + event];
12804 return this;
12805 } // remove specific handler
12806
12807
12808 var cb;
12809
12810 for (var i = 0; i < callbacks.length; i++) {
12811 cb = callbacks[i];
12812
12813 if (cb === fn || cb.fn === fn) {
12814 callbacks.splice(i, 1);
12815 break;
12816 }
12817 } // Remove event specific arrays for event types that no
12818 // one is subscribed for to avoid memory leak.
12819
12820
12821 if (callbacks.length === 0) {
12822 delete this._callbacks['$' + event];
12823 }
12824
12825 return this;
12826 };
12827 /**
12828 * Emit `event` with the given args.
12829 *
12830 * @param {String} event
12831 * @param {Mixed} ...
12832 * @return {Emitter}
12833 */
12834
12835
12836 Emitter.prototype.emit = function (event) {
12837 this._callbacks = this._callbacks || {};
12838 var args = new Array(arguments.length - 1),
12839 callbacks = this._callbacks['$' + event];
12840
12841 for (var i = 1; i < arguments.length; i++) {
12842 args[i - 1] = arguments[i];
12843 }
12844
12845 if (callbacks) {
12846 callbacks = callbacks.slice(0);
12847
12848 for (var i = 0, len = callbacks.length; i < len; ++i) {
12849 callbacks[i].apply(this, args);
12850 }
12851 }
12852
12853 return this;
12854 };
12855 /**
12856 * Return array of callbacks for `event`.
12857 *
12858 * @param {String} event
12859 * @return {Array}
12860 * @api public
12861 */
12862
12863
12864 Emitter.prototype.listeners = function (event) {
12865 this._callbacks = this._callbacks || {};
12866 return this._callbacks['$' + event] || [];
12867 };
12868 /**
12869 * Check if this emitter has `event` handlers.
12870 *
12871 * @param {String} event
12872 * @return {Boolean}
12873 * @api public
12874 */
12875
12876
12877 Emitter.prototype.hasListeners = function (event) {
12878 return !!this.listeners(event).length;
12879 };
12880 });
12881
12882 var fastSafeStringify = stringify;
12883 stringify.default = stringify;
12884 stringify.stable = deterministicStringify;
12885 stringify.stableStringify = deterministicStringify;
12886
12887 var arr = [];
12888 var replacerStack = [];
12889
12890 // Regular stringify
12891 function stringify (obj, replacer, spacer) {
12892 decirc(obj, '', [], undefined);
12893 var res;
12894 if (replacerStack.length === 0) {
12895 res = JSON.stringify(obj, replacer, spacer);
12896 } else {
12897 res = JSON.stringify(obj, replaceGetterValues(replacer), spacer);
12898 }
12899 while (arr.length !== 0) {
12900 var part = arr.pop();
12901 if (part.length === 4) {
12902 Object.defineProperty(part[0], part[1], part[3]);
12903 } else {
12904 part[0][part[1]] = part[2];
12905 }
12906 }
12907 return res
12908 }
12909 function decirc (val, k, stack, parent) {
12910 var i;
12911 if (typeof val === 'object' && val !== null) {
12912 for (i = 0; i < stack.length; i++) {
12913 if (stack[i] === val) {
12914 var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);
12915 if (propertyDescriptor.get !== undefined) {
12916 if (propertyDescriptor.configurable) {
12917 Object.defineProperty(parent, k, { value: '[Circular]' });
12918 arr.push([parent, k, val, propertyDescriptor]);
12919 } else {
12920 replacerStack.push([val, k]);
12921 }
12922 } else {
12923 parent[k] = '[Circular]';
12924 arr.push([parent, k, val]);
12925 }
12926 return
12927 }
12928 }
12929 stack.push(val);
12930 // Optimize for Arrays. Big arrays could kill the performance otherwise!
12931 if (Array.isArray(val)) {
12932 for (i = 0; i < val.length; i++) {
12933 decirc(val[i], i, stack, val);
12934 }
12935 } else {
12936 var keys = Object.keys(val);
12937 for (i = 0; i < keys.length; i++) {
12938 var key = keys[i];
12939 decirc(val[key], key, stack, val);
12940 }
12941 }
12942 stack.pop();
12943 }
12944 }
12945
12946 // Stable-stringify
12947 function compareFunction (a, b) {
12948 if (a < b) {
12949 return -1
12950 }
12951 if (a > b) {
12952 return 1
12953 }
12954 return 0
12955 }
12956
12957 function deterministicStringify (obj, replacer, spacer) {
12958 var tmp = deterministicDecirc(obj, '', [], undefined) || obj;
12959 var res;
12960 if (replacerStack.length === 0) {
12961 res = JSON.stringify(tmp, replacer, spacer);
12962 } else {
12963 res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer);
12964 }
12965 while (arr.length !== 0) {
12966 var part = arr.pop();
12967 if (part.length === 4) {
12968 Object.defineProperty(part[0], part[1], part[3]);
12969 } else {
12970 part[0][part[1]] = part[2];
12971 }
12972 }
12973 return res
12974 }
12975
12976 function deterministicDecirc (val, k, stack, parent) {
12977 var i;
12978 if (typeof val === 'object' && val !== null) {
12979 for (i = 0; i < stack.length; i++) {
12980 if (stack[i] === val) {
12981 var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);
12982 if (propertyDescriptor.get !== undefined) {
12983 if (propertyDescriptor.configurable) {
12984 Object.defineProperty(parent, k, { value: '[Circular]' });
12985 arr.push([parent, k, val, propertyDescriptor]);
12986 } else {
12987 replacerStack.push([val, k]);
12988 }
12989 } else {
12990 parent[k] = '[Circular]';
12991 arr.push([parent, k, val]);
12992 }
12993 return
12994 }
12995 }
12996 if (typeof val.toJSON === 'function') {
12997 return
12998 }
12999 stack.push(val);
13000 // Optimize for Arrays. Big arrays could kill the performance otherwise!
13001 if (Array.isArray(val)) {
13002 for (i = 0; i < val.length; i++) {
13003 deterministicDecirc(val[i], i, stack, val);
13004 }
13005 } else {
13006 // Create a temporary object in the required way
13007 var tmp = {};
13008 var keys = Object.keys(val).sort(compareFunction);
13009 for (i = 0; i < keys.length; i++) {
13010 var key = keys[i];
13011 deterministicDecirc(val[key], key, stack, val);
13012 tmp[key] = val[key];
13013 }
13014 if (parent !== undefined) {
13015 arr.push([parent, k, val]);
13016 parent[k] = tmp;
13017 } else {
13018 return tmp
13019 }
13020 }
13021 stack.pop();
13022 }
13023 }
13024
13025 // wraps replacer function to handle values we couldn't replace
13026 // and mark them as [Circular]
13027 function replaceGetterValues (replacer) {
13028 replacer = replacer !== undefined ? replacer : function (k, v) { return v };
13029 return function (key, val) {
13030 if (replacerStack.length > 0) {
13031 for (var i = 0; i < replacerStack.length; i++) {
13032 var part = replacerStack[i];
13033 if (part[1] === key && part[0] === val) {
13034 val = '[Circular]';
13035 replacerStack.splice(i, 1);
13036 break
13037 }
13038 }
13039 }
13040 return replacer.call(this, key, val)
13041 }
13042 }
13043
13044 function _typeof$1(obj) {
13045 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
13046 _typeof$1 = function _typeof$1(obj) {
13047 return _typeof(obj);
13048 };
13049 } else {
13050 _typeof$1 = function _typeof$1(obj) {
13051 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
13052 };
13053 }
13054
13055 return _typeof$1(obj);
13056 }
13057 /**
13058 * Check if `obj` is an object.
13059 *
13060 * @param {Object} obj
13061 * @return {Boolean}
13062 * @api private
13063 */
13064
13065
13066 function isObject(obj) {
13067 return obj !== null && _typeof$1(obj) === 'object';
13068 }
13069
13070 var isObject_1 = isObject;
13071
13072 function _typeof$2(obj) {
13073 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
13074 _typeof$2 = function _typeof$1(obj) {
13075 return _typeof(obj);
13076 };
13077 } else {
13078 _typeof$2 = function _typeof$1(obj) {
13079 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
13080 };
13081 }
13082
13083 return _typeof$2(obj);
13084 }
13085 /**
13086 * Module of mixed-in functions shared between node and client code
13087 */
13088
13089 /**
13090 * Expose `RequestBase`.
13091 */
13092
13093
13094 var requestBase = RequestBase;
13095 /**
13096 * Initialize a new `RequestBase`.
13097 *
13098 * @api public
13099 */
13100
13101 function RequestBase(obj) {
13102 if (obj) return mixin(obj);
13103 }
13104 /**
13105 * Mixin the prototype properties.
13106 *
13107 * @param {Object} obj
13108 * @return {Object}
13109 * @api private
13110 */
13111
13112
13113 function mixin(obj) {
13114 for (var key in RequestBase.prototype) {
13115 if (Object.prototype.hasOwnProperty.call(RequestBase.prototype, key)) obj[key] = RequestBase.prototype[key];
13116 }
13117
13118 return obj;
13119 }
13120 /**
13121 * Clear previous timeout.
13122 *
13123 * @return {Request} for chaining
13124 * @api public
13125 */
13126
13127
13128 RequestBase.prototype.clearTimeout = function () {
13129 clearTimeout(this._timer);
13130 clearTimeout(this._responseTimeoutTimer);
13131 clearTimeout(this._uploadTimeoutTimer);
13132 delete this._timer;
13133 delete this._responseTimeoutTimer;
13134 delete this._uploadTimeoutTimer;
13135 return this;
13136 };
13137 /**
13138 * Override default response body parser
13139 *
13140 * This function will be called to convert incoming data into request.body
13141 *
13142 * @param {Function}
13143 * @api public
13144 */
13145
13146
13147 RequestBase.prototype.parse = function (fn) {
13148 this._parser = fn;
13149 return this;
13150 };
13151 /**
13152 * Set format of binary response body.
13153 * In browser valid formats are 'blob' and 'arraybuffer',
13154 * which return Blob and ArrayBuffer, respectively.
13155 *
13156 * In Node all values result in Buffer.
13157 *
13158 * Examples:
13159 *
13160 * req.get('/')
13161 * .responseType('blob')
13162 * .end(callback);
13163 *
13164 * @param {String} val
13165 * @return {Request} for chaining
13166 * @api public
13167 */
13168
13169
13170 RequestBase.prototype.responseType = function (val) {
13171 this._responseType = val;
13172 return this;
13173 };
13174 /**
13175 * Override default request body serializer
13176 *
13177 * This function will be called to convert data set via .send or .attach into payload to send
13178 *
13179 * @param {Function}
13180 * @api public
13181 */
13182
13183
13184 RequestBase.prototype.serialize = function (fn) {
13185 this._serializer = fn;
13186 return this;
13187 };
13188 /**
13189 * Set timeouts.
13190 *
13191 * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time.
13192 * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections.
13193 * - upload is the time since last bit of data was sent or received. This timeout works only if deadline timeout is off
13194 *
13195 * Value of 0 or false means no timeout.
13196 *
13197 * @param {Number|Object} ms or {response, deadline}
13198 * @return {Request} for chaining
13199 * @api public
13200 */
13201
13202
13203 RequestBase.prototype.timeout = function (options) {
13204 if (!options || _typeof$2(options) !== 'object') {
13205 this._timeout = options;
13206 this._responseTimeout = 0;
13207 this._uploadTimeout = 0;
13208 return this;
13209 }
13210
13211 for (var option in options) {
13212 if (Object.prototype.hasOwnProperty.call(options, option)) {
13213 switch (option) {
13214 case 'deadline':
13215 this._timeout = options.deadline;
13216 break;
13217
13218 case 'response':
13219 this._responseTimeout = options.response;
13220 break;
13221
13222 case 'upload':
13223 this._uploadTimeout = options.upload;
13224 break;
13225
13226 default:
13227 console.warn('Unknown timeout option', option);
13228 }
13229 }
13230 }
13231
13232 return this;
13233 };
13234 /**
13235 * Set number of retry attempts on error.
13236 *
13237 * Failed requests will be retried 'count' times if timeout or err.code >= 500.
13238 *
13239 * @param {Number} count
13240 * @param {Function} [fn]
13241 * @return {Request} for chaining
13242 * @api public
13243 */
13244
13245
13246 RequestBase.prototype.retry = function (count, fn) {
13247 // Default to 1 if no count passed or true
13248 if (arguments.length === 0 || count === true) count = 1;
13249 if (count <= 0) count = 0;
13250 this._maxRetries = count;
13251 this._retries = 0;
13252 this._retryCallback = fn;
13253 return this;
13254 };
13255
13256 var ERROR_CODES = ['ECONNRESET', 'ETIMEDOUT', 'EADDRINFO', 'ESOCKETTIMEDOUT'];
13257 /**
13258 * Determine if a request should be retried.
13259 * (Borrowed from segmentio/superagent-retry)
13260 *
13261 * @param {Error} err an error
13262 * @param {Response} [res] response
13263 * @returns {Boolean} if segment should be retried
13264 */
13265
13266 RequestBase.prototype._shouldRetry = function (err, res) {
13267 if (!this._maxRetries || this._retries++ >= this._maxRetries) {
13268 return false;
13269 }
13270
13271 if (this._retryCallback) {
13272 try {
13273 var override = this._retryCallback(err, res);
13274
13275 if (override === true) return true;
13276 if (override === false) return false; // undefined falls back to defaults
13277 } catch (err2) {
13278 console.error(err2);
13279 }
13280 }
13281
13282 if (res && res.status && res.status >= 500 && res.status !== 501) return true;
13283
13284 if (err) {
13285 if (err.code && ERROR_CODES.indexOf(err.code) !== -1) return true; // Superagent timeout
13286
13287 if (err.timeout && err.code === 'ECONNABORTED') return true;
13288 if (err.crossDomain) return true;
13289 }
13290
13291 return false;
13292 };
13293 /**
13294 * Retry request
13295 *
13296 * @return {Request} for chaining
13297 * @api private
13298 */
13299
13300
13301 RequestBase.prototype._retry = function () {
13302 this.clearTimeout(); // node
13303
13304 if (this.req) {
13305 this.req = null;
13306 this.req = this.request();
13307 }
13308
13309 this._aborted = false;
13310 this.timedout = false;
13311 return this._end();
13312 };
13313 /**
13314 * Promise support
13315 *
13316 * @param {Function} resolve
13317 * @param {Function} [reject]
13318 * @return {Request}
13319 */
13320
13321
13322 RequestBase.prototype.then = function (resolve, reject) {
13323 var _this = this;
13324
13325 if (!this._fullfilledPromise) {
13326 var self = this;
13327
13328 if (this._endCalled) {
13329 console.warn('Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises');
13330 }
13331
13332 this._fullfilledPromise = new Promise(function (resolve, reject) {
13333 self.on('abort', function () {
13334 var err = new Error('Aborted');
13335 err.code = 'ABORTED';
13336 err.status = _this.status;
13337 err.method = _this.method;
13338 err.url = _this.url;
13339 reject(err);
13340 });
13341 self.end(function (err, res) {
13342 if (err) reject(err);else resolve(res);
13343 });
13344 });
13345 }
13346
13347 return this._fullfilledPromise.then(resolve, reject);
13348 };
13349
13350 RequestBase.prototype.catch = function (cb) {
13351 return this.then(undefined, cb);
13352 };
13353 /**
13354 * Allow for extension
13355 */
13356
13357
13358 RequestBase.prototype.use = function (fn) {
13359 fn(this);
13360 return this;
13361 };
13362
13363 RequestBase.prototype.ok = function (cb) {
13364 if (typeof cb !== 'function') throw new Error('Callback required');
13365 this._okCallback = cb;
13366 return this;
13367 };
13368
13369 RequestBase.prototype._isResponseOK = function (res) {
13370 if (!res) {
13371 return false;
13372 }
13373
13374 if (this._okCallback) {
13375 return this._okCallback(res);
13376 }
13377
13378 return res.status >= 200 && res.status < 300;
13379 };
13380 /**
13381 * Get request header `field`.
13382 * Case-insensitive.
13383 *
13384 * @param {String} field
13385 * @return {String}
13386 * @api public
13387 */
13388
13389
13390 RequestBase.prototype.get = function (field) {
13391 return this._header[field.toLowerCase()];
13392 };
13393 /**
13394 * Get case-insensitive header `field` value.
13395 * This is a deprecated internal API. Use `.get(field)` instead.
13396 *
13397 * (getHeader is no longer used internally by the superagent code base)
13398 *
13399 * @param {String} field
13400 * @return {String}
13401 * @api private
13402 * @deprecated
13403 */
13404
13405
13406 RequestBase.prototype.getHeader = RequestBase.prototype.get;
13407 /**
13408 * Set header `field` to `val`, or multiple fields with one object.
13409 * Case-insensitive.
13410 *
13411 * Examples:
13412 *
13413 * req.get('/')
13414 * .set('Accept', 'application/json')
13415 * .set('X-API-Key', 'foobar')
13416 * .end(callback);
13417 *
13418 * req.get('/')
13419 * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
13420 * .end(callback);
13421 *
13422 * @param {String|Object} field
13423 * @param {String} val
13424 * @return {Request} for chaining
13425 * @api public
13426 */
13427
13428 RequestBase.prototype.set = function (field, val) {
13429 if (isObject_1(field)) {
13430 for (var key in field) {
13431 if (Object.prototype.hasOwnProperty.call(field, key)) this.set(key, field[key]);
13432 }
13433
13434 return this;
13435 }
13436
13437 this._header[field.toLowerCase()] = val;
13438 this.header[field] = val;
13439 return this;
13440 }; // eslint-disable-next-line valid-jsdoc
13441
13442 /**
13443 * Remove header `field`.
13444 * Case-insensitive.
13445 *
13446 * Example:
13447 *
13448 * req.get('/')
13449 * .unset('User-Agent')
13450 * .end(callback);
13451 *
13452 * @param {String} field field name
13453 */
13454
13455
13456 RequestBase.prototype.unset = function (field) {
13457 delete this._header[field.toLowerCase()];
13458 delete this.header[field];
13459 return this;
13460 };
13461 /**
13462 * Write the field `name` and `val`, or multiple fields with one object
13463 * for "multipart/form-data" request bodies.
13464 *
13465 * ``` js
13466 * request.post('/upload')
13467 * .field('foo', 'bar')
13468 * .end(callback);
13469 *
13470 * request.post('/upload')
13471 * .field({ foo: 'bar', baz: 'qux' })
13472 * .end(callback);
13473 * ```
13474 *
13475 * @param {String|Object} name name of field
13476 * @param {String|Blob|File|Buffer|fs.ReadStream} val value of field
13477 * @return {Request} for chaining
13478 * @api public
13479 */
13480
13481
13482 RequestBase.prototype.field = function (name, val) {
13483 // name should be either a string or an object.
13484 if (name === null || undefined === name) {
13485 throw new Error('.field(name, val) name can not be empty');
13486 }
13487
13488 if (this._data) {
13489 throw new Error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()");
13490 }
13491
13492 if (isObject_1(name)) {
13493 for (var key in name) {
13494 if (Object.prototype.hasOwnProperty.call(name, key)) this.field(key, name[key]);
13495 }
13496
13497 return this;
13498 }
13499
13500 if (Array.isArray(val)) {
13501 for (var i in val) {
13502 if (Object.prototype.hasOwnProperty.call(val, i)) this.field(name, val[i]);
13503 }
13504
13505 return this;
13506 } // val should be defined now
13507
13508
13509 if (val === null || undefined === val) {
13510 throw new Error('.field(name, val) val can not be empty');
13511 }
13512
13513 if (typeof val === 'boolean') {
13514 val = String(val);
13515 }
13516
13517 this._getFormData().append(name, val);
13518
13519 return this;
13520 };
13521 /**
13522 * Abort the request, and clear potential timeout.
13523 *
13524 * @return {Request} request
13525 * @api public
13526 */
13527
13528
13529 RequestBase.prototype.abort = function () {
13530 if (this._aborted) {
13531 return this;
13532 }
13533
13534 this._aborted = true;
13535 if (this.xhr) this.xhr.abort(); // browser
13536
13537 if (this.req) this.req.abort(); // node
13538
13539 this.clearTimeout();
13540 this.emit('abort');
13541 return this;
13542 };
13543
13544 RequestBase.prototype._auth = function (user, pass, options, base64Encoder) {
13545 switch (options.type) {
13546 case 'basic':
13547 this.set('Authorization', "Basic ".concat(base64Encoder("".concat(user, ":").concat(pass))));
13548 break;
13549
13550 case 'auto':
13551 this.username = user;
13552 this.password = pass;
13553 break;
13554
13555 case 'bearer':
13556 // usage would be .auth(accessToken, { type: 'bearer' })
13557 this.set('Authorization', "Bearer ".concat(user));
13558 break;
13559
13560 default:
13561 break;
13562 }
13563
13564 return this;
13565 };
13566 /**
13567 * Enable transmission of cookies with x-domain requests.
13568 *
13569 * Note that for this to work the origin must not be
13570 * using "Access-Control-Allow-Origin" with a wildcard,
13571 * and also must set "Access-Control-Allow-Credentials"
13572 * to "true".
13573 *
13574 * @api public
13575 */
13576
13577
13578 RequestBase.prototype.withCredentials = function (on) {
13579 // This is browser-only functionality. Node side is no-op.
13580 if (on === undefined) on = true;
13581 this._withCredentials = on;
13582 return this;
13583 };
13584 /**
13585 * Set the max redirects to `n`. Does nothing in browser XHR implementation.
13586 *
13587 * @param {Number} n
13588 * @return {Request} for chaining
13589 * @api public
13590 */
13591
13592
13593 RequestBase.prototype.redirects = function (n) {
13594 this._maxRedirects = n;
13595 return this;
13596 };
13597 /**
13598 * Maximum size of buffered response body, in bytes. Counts uncompressed size.
13599 * Default 200MB.
13600 *
13601 * @param {Number} n number of bytes
13602 * @return {Request} for chaining
13603 */
13604
13605
13606 RequestBase.prototype.maxResponseSize = function (n) {
13607 if (typeof n !== 'number') {
13608 throw new TypeError('Invalid argument');
13609 }
13610
13611 this._maxResponseSize = n;
13612 return this;
13613 };
13614 /**
13615 * Convert to a plain javascript object (not JSON string) of scalar properties.
13616 * Note as this method is designed to return a useful non-this value,
13617 * it cannot be chained.
13618 *
13619 * @return {Object} describing method, url, and data of this request
13620 * @api public
13621 */
13622
13623
13624 RequestBase.prototype.toJSON = function () {
13625 return {
13626 method: this.method,
13627 url: this.url,
13628 data: this._data,
13629 headers: this._header
13630 };
13631 };
13632 /**
13633 * Send `data` as the request body, defaulting the `.type()` to "json" when
13634 * an object is given.
13635 *
13636 * Examples:
13637 *
13638 * // manual json
13639 * request.post('/user')
13640 * .type('json')
13641 * .send('{"name":"tj"}')
13642 * .end(callback)
13643 *
13644 * // auto json
13645 * request.post('/user')
13646 * .send({ name: 'tj' })
13647 * .end(callback)
13648 *
13649 * // manual x-www-form-urlencoded
13650 * request.post('/user')
13651 * .type('form')
13652 * .send('name=tj')
13653 * .end(callback)
13654 *
13655 * // auto x-www-form-urlencoded
13656 * request.post('/user')
13657 * .type('form')
13658 * .send({ name: 'tj' })
13659 * .end(callback)
13660 *
13661 * // defaults to x-www-form-urlencoded
13662 * request.post('/user')
13663 * .send('name=tobi')
13664 * .send('species=ferret')
13665 * .end(callback)
13666 *
13667 * @param {String|Object} data
13668 * @return {Request} for chaining
13669 * @api public
13670 */
13671 // eslint-disable-next-line complexity
13672
13673
13674 RequestBase.prototype.send = function (data) {
13675 var isObj = isObject_1(data);
13676 var type = this._header['content-type'];
13677
13678 if (this._formData) {
13679 throw new Error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()");
13680 }
13681
13682 if (isObj && !this._data) {
13683 if (Array.isArray(data)) {
13684 this._data = [];
13685 } else if (!this._isHost(data)) {
13686 this._data = {};
13687 }
13688 } else if (data && this._data && this._isHost(this._data)) {
13689 throw new Error("Can't merge these send calls");
13690 } // merge
13691
13692
13693 if (isObj && isObject_1(this._data)) {
13694 for (var key in data) {
13695 if (Object.prototype.hasOwnProperty.call(data, key)) this._data[key] = data[key];
13696 }
13697 } else if (typeof data === 'string') {
13698 // default to x-www-form-urlencoded
13699 if (!type) this.type('form');
13700 type = this._header['content-type'];
13701
13702 if (type === 'application/x-www-form-urlencoded') {
13703 this._data = this._data ? "".concat(this._data, "&").concat(data) : data;
13704 } else {
13705 this._data = (this._data || '') + data;
13706 }
13707 } else {
13708 this._data = data;
13709 }
13710
13711 if (!isObj || this._isHost(data)) {
13712 return this;
13713 } // default to json
13714
13715
13716 if (!type) this.type('json');
13717 return this;
13718 };
13719 /**
13720 * Sort `querystring` by the sort function
13721 *
13722 *
13723 * Examples:
13724 *
13725 * // default order
13726 * request.get('/user')
13727 * .query('name=Nick')
13728 * .query('search=Manny')
13729 * .sortQuery()
13730 * .end(callback)
13731 *
13732 * // customized sort function
13733 * request.get('/user')
13734 * .query('name=Nick')
13735 * .query('search=Manny')
13736 * .sortQuery(function(a, b){
13737 * return a.length - b.length;
13738 * })
13739 * .end(callback)
13740 *
13741 *
13742 * @param {Function} sort
13743 * @return {Request} for chaining
13744 * @api public
13745 */
13746
13747
13748 RequestBase.prototype.sortQuery = function (sort) {
13749 // _sort default to true but otherwise can be a function or boolean
13750 this._sort = typeof sort === 'undefined' ? true : sort;
13751 return this;
13752 };
13753 /**
13754 * Compose querystring to append to req.url
13755 *
13756 * @api private
13757 */
13758
13759
13760 RequestBase.prototype._finalizeQueryString = function () {
13761 var query = this._query.join('&');
13762
13763 if (query) {
13764 this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query;
13765 }
13766
13767 this._query.length = 0; // Makes the call idempotent
13768
13769 if (this._sort) {
13770 var index = this.url.indexOf('?');
13771
13772 if (index >= 0) {
13773 var queryArr = this.url.substring(index + 1).split('&');
13774
13775 if (typeof this._sort === 'function') {
13776 queryArr.sort(this._sort);
13777 } else {
13778 queryArr.sort();
13779 }
13780
13781 this.url = this.url.substring(0, index) + '?' + queryArr.join('&');
13782 }
13783 }
13784 }; // For backwards compat only
13785
13786
13787 RequestBase.prototype._appendQueryString = function () {
13788 console.warn('Unsupported');
13789 };
13790 /**
13791 * Invoke callback with timeout error.
13792 *
13793 * @api private
13794 */
13795
13796
13797 RequestBase.prototype._timeoutError = function (reason, timeout, errno) {
13798 if (this._aborted) {
13799 return;
13800 }
13801
13802 var err = new Error("".concat(reason + timeout, "ms exceeded"));
13803 err.timeout = timeout;
13804 err.code = 'ECONNABORTED';
13805 err.errno = errno;
13806 this.timedout = true;
13807 this.abort();
13808 this.callback(err);
13809 };
13810
13811 RequestBase.prototype._setTimeouts = function () {
13812 var self = this; // deadline
13813
13814 if (this._timeout && !this._timer) {
13815 this._timer = setTimeout(function () {
13816 self._timeoutError('Timeout of ', self._timeout, 'ETIME');
13817 }, this._timeout);
13818 } // response timeout
13819
13820
13821 if (this._responseTimeout && !this._responseTimeoutTimer) {
13822 this._responseTimeoutTimer = setTimeout(function () {
13823 self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT');
13824 }, this._responseTimeout);
13825 }
13826 };
13827
13828 /**
13829 * Return the mime type for the given `str`.
13830 *
13831 * @param {String} str
13832 * @return {String}
13833 * @api private
13834 */
13835
13836 var type = function type(str) {
13837 return str.split(/ *; */).shift();
13838 };
13839 /**
13840 * Return header field parameters.
13841 *
13842 * @param {String} str
13843 * @return {Object}
13844 * @api private
13845 */
13846
13847
13848 var params = function params(str) {
13849 return str.split(/ *; */).reduce(function (obj, str) {
13850 var parts = str.split(/ *= */);
13851 var key = parts.shift();
13852 var val = parts.shift();
13853 if (key && val) obj[key] = val;
13854 return obj;
13855 }, {});
13856 };
13857 /**
13858 * Parse Link header fields.
13859 *
13860 * @param {String} str
13861 * @return {Object}
13862 * @api private
13863 */
13864
13865
13866 var parseLinks = function parseLinks(str) {
13867 return str.split(/ *, */).reduce(function (obj, str) {
13868 var parts = str.split(/ *; */);
13869 var url = parts[0].slice(1, -1);
13870 var rel = parts[1].split(/ *= */)[1].slice(1, -1);
13871 obj[rel] = url;
13872 return obj;
13873 }, {});
13874 };
13875 /**
13876 * Strip content related fields from `header`.
13877 *
13878 * @param {Object} header
13879 * @return {Object} header
13880 * @api private
13881 */
13882
13883
13884 var cleanHeader = function cleanHeader(header, changesOrigin) {
13885 delete header['content-type'];
13886 delete header['content-length'];
13887 delete header['transfer-encoding'];
13888 delete header.host; // secuirty
13889
13890 if (changesOrigin) {
13891 delete header.authorization;
13892 delete header.cookie;
13893 }
13894
13895 return header;
13896 };
13897
13898 var utils = {
13899 type: type,
13900 params: params,
13901 parseLinks: parseLinks,
13902 cleanHeader: cleanHeader
13903 };
13904
13905 /**
13906 * Module dependencies.
13907 */
13908
13909 /**
13910 * Expose `ResponseBase`.
13911 */
13912
13913
13914 var responseBase = ResponseBase;
13915 /**
13916 * Initialize a new `ResponseBase`.
13917 *
13918 * @api public
13919 */
13920
13921 function ResponseBase(obj) {
13922 if (obj) return mixin$1(obj);
13923 }
13924 /**
13925 * Mixin the prototype properties.
13926 *
13927 * @param {Object} obj
13928 * @return {Object}
13929 * @api private
13930 */
13931
13932
13933 function mixin$1(obj) {
13934 for (var key in ResponseBase.prototype) {
13935 if (Object.prototype.hasOwnProperty.call(ResponseBase.prototype, key)) obj[key] = ResponseBase.prototype[key];
13936 }
13937
13938 return obj;
13939 }
13940 /**
13941 * Get case-insensitive `field` value.
13942 *
13943 * @param {String} field
13944 * @return {String}
13945 * @api public
13946 */
13947
13948
13949 ResponseBase.prototype.get = function (field) {
13950 return this.header[field.toLowerCase()];
13951 };
13952 /**
13953 * Set header related properties:
13954 *
13955 * - `.type` the content type without params
13956 *
13957 * A response of "Content-Type: text/plain; charset=utf-8"
13958 * will provide you with a `.type` of "text/plain".
13959 *
13960 * @param {Object} header
13961 * @api private
13962 */
13963
13964
13965 ResponseBase.prototype._setHeaderProperties = function (header) {
13966 // TODO: moar!
13967 // TODO: make this a util
13968 // content-type
13969 var ct = header['content-type'] || '';
13970 this.type = utils.type(ct); // params
13971
13972 var params = utils.params(ct);
13973
13974 for (var key in params) {
13975 if (Object.prototype.hasOwnProperty.call(params, key)) this[key] = params[key];
13976 }
13977
13978 this.links = {}; // links
13979
13980 try {
13981 if (header.link) {
13982 this.links = utils.parseLinks(header.link);
13983 }
13984 } catch (err) {// ignore
13985 }
13986 };
13987 /**
13988 * Set flags such as `.ok` based on `status`.
13989 *
13990 * For example a 2xx response will give you a `.ok` of __true__
13991 * whereas 5xx will be __false__ and `.error` will be __true__. The
13992 * `.clientError` and `.serverError` are also available to be more
13993 * specific, and `.statusType` is the class of error ranging from 1..5
13994 * sometimes useful for mapping respond colors etc.
13995 *
13996 * "sugar" properties are also defined for common cases. Currently providing:
13997 *
13998 * - .noContent
13999 * - .badRequest
14000 * - .unauthorized
14001 * - .notAcceptable
14002 * - .notFound
14003 *
14004 * @param {Number} status
14005 * @api private
14006 */
14007
14008
14009 ResponseBase.prototype._setStatusProperties = function (status) {
14010 var type = status / 100 | 0; // status / class
14011
14012 this.statusCode = status;
14013 this.status = this.statusCode;
14014 this.statusType = type; // basics
14015
14016 this.info = type === 1;
14017 this.ok = type === 2;
14018 this.redirect = type === 3;
14019 this.clientError = type === 4;
14020 this.serverError = type === 5;
14021 this.error = type === 4 || type === 5 ? this.toError() : false; // sugar
14022
14023 this.created = status === 201;
14024 this.accepted = status === 202;
14025 this.noContent = status === 204;
14026 this.badRequest = status === 400;
14027 this.unauthorized = status === 401;
14028 this.notAcceptable = status === 406;
14029 this.forbidden = status === 403;
14030 this.notFound = status === 404;
14031 this.unprocessableEntity = status === 422;
14032 };
14033
14034 function _toConsumableArray$1(arr) {
14035 return _arrayWithoutHoles$1(arr) || _iterableToArray$1(arr) || _nonIterableSpread$1();
14036 }
14037
14038 function _nonIterableSpread$1() {
14039 throw new TypeError("Invalid attempt to spread non-iterable instance");
14040 }
14041
14042 function _iterableToArray$1(iter) {
14043 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
14044 }
14045
14046 function _arrayWithoutHoles$1(arr) {
14047 if (Array.isArray(arr)) {
14048 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
14049 arr2[i] = arr[i];
14050 }
14051
14052 return arr2;
14053 }
14054 }
14055
14056 function Agent() {
14057 this._defaults = [];
14058 }
14059
14060 ['use', 'on', 'once', 'set', 'query', 'type', 'accept', 'auth', 'withCredentials', 'sortQuery', 'retry', 'ok', 'redirects', 'timeout', 'buffer', 'serialize', 'parse', 'ca', 'key', 'pfx', 'cert'].forEach(function (fn) {
14061 // Default setting for all requests from this agent
14062 Agent.prototype[fn] = function () {
14063 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
14064 args[_key] = arguments[_key];
14065 }
14066
14067 this._defaults.push({
14068 fn: fn,
14069 args: args
14070 });
14071
14072 return this;
14073 };
14074 });
14075
14076 Agent.prototype._setDefaults = function (req) {
14077 this._defaults.forEach(function (def) {
14078 req[def.fn].apply(req, _toConsumableArray$1(def.args));
14079 });
14080 };
14081
14082 var agentBase = Agent;
14083
14084 var client = createCommonjsModule(function (module, exports) {
14085
14086 function _typeof$1(obj) {
14087 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
14088 _typeof$1 = function _typeof$1(obj) {
14089 return _typeof(obj);
14090 };
14091 } else {
14092 _typeof$1 = function _typeof$1(obj) {
14093 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
14094 };
14095 }
14096
14097 return _typeof$1(obj);
14098 }
14099 /**
14100 * Root reference for iframes.
14101 */
14102
14103
14104 var root;
14105
14106 if (typeof window !== 'undefined') {
14107 // Browser window
14108 root = window;
14109 } else if (typeof self === 'undefined') {
14110 // Other environments
14111 console.warn('Using browser-only version of superagent in non-browser environment');
14112 root = void 0;
14113 } else {
14114 // Web Worker
14115 root = self;
14116 }
14117 /**
14118 * Noop.
14119 */
14120
14121
14122 function noop() {}
14123 /**
14124 * Expose `request`.
14125 */
14126
14127
14128 module.exports = function (method, url) {
14129 // callback
14130 if (typeof url === 'function') {
14131 return new exports.Request('GET', method).end(url);
14132 } // url first
14133
14134
14135 if (arguments.length === 1) {
14136 return new exports.Request('GET', method);
14137 }
14138
14139 return new exports.Request(method, url);
14140 };
14141
14142 exports = module.exports;
14143 var request = exports;
14144 exports.Request = Request;
14145 /**
14146 * Determine XHR.
14147 */
14148
14149 request.getXHR = function () {
14150 if (root.XMLHttpRequest && (!root.location || root.location.protocol !== 'file:' || !root.ActiveXObject)) {
14151 return new XMLHttpRequest();
14152 }
14153
14154 try {
14155 return new ActiveXObject('Microsoft.XMLHTTP');
14156 } catch (err) {}
14157
14158 try {
14159 return new ActiveXObject('Msxml2.XMLHTTP.6.0');
14160 } catch (err) {}
14161
14162 try {
14163 return new ActiveXObject('Msxml2.XMLHTTP.3.0');
14164 } catch (err) {}
14165
14166 try {
14167 return new ActiveXObject('Msxml2.XMLHTTP');
14168 } catch (err) {}
14169
14170 throw new Error('Browser-only version of superagent could not find XHR');
14171 };
14172 /**
14173 * Removes leading and trailing whitespace, added to support IE.
14174 *
14175 * @param {String} s
14176 * @return {String}
14177 * @api private
14178 */
14179
14180
14181 var trim = ''.trim ? function (s) {
14182 return s.trim();
14183 } : function (s) {
14184 return s.replace(/(^\s*|\s*$)/g, '');
14185 };
14186 /**
14187 * Serialize the given `obj`.
14188 *
14189 * @param {Object} obj
14190 * @return {String}
14191 * @api private
14192 */
14193
14194 function serialize(obj) {
14195 if (!isObject_1(obj)) return obj;
14196 var pairs = [];
14197
14198 for (var key in obj) {
14199 if (Object.prototype.hasOwnProperty.call(obj, key)) pushEncodedKeyValuePair(pairs, key, obj[key]);
14200 }
14201
14202 return pairs.join('&');
14203 }
14204 /**
14205 * Helps 'serialize' with serializing arrays.
14206 * Mutates the pairs array.
14207 *
14208 * @param {Array} pairs
14209 * @param {String} key
14210 * @param {Mixed} val
14211 */
14212
14213
14214 function pushEncodedKeyValuePair(pairs, key, val) {
14215 if (val === undefined) return;
14216
14217 if (val === null) {
14218 pairs.push(encodeURIComponent(key));
14219 return;
14220 }
14221
14222 if (Array.isArray(val)) {
14223 val.forEach(function (v) {
14224 pushEncodedKeyValuePair(pairs, key, v);
14225 });
14226 } else if (isObject_1(val)) {
14227 for (var subkey in val) {
14228 if (Object.prototype.hasOwnProperty.call(val, subkey)) pushEncodedKeyValuePair(pairs, "".concat(key, "[").concat(subkey, "]"), val[subkey]);
14229 }
14230 } else {
14231 pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
14232 }
14233 }
14234 /**
14235 * Expose serialization method.
14236 */
14237
14238
14239 request.serializeObject = serialize;
14240 /**
14241 * Parse the given x-www-form-urlencoded `str`.
14242 *
14243 * @param {String} str
14244 * @return {Object}
14245 * @api private
14246 */
14247
14248 function parseString(str) {
14249 var obj = {};
14250 var pairs = str.split('&');
14251 var pair;
14252 var pos;
14253
14254 for (var i = 0, len = pairs.length; i < len; ++i) {
14255 pair = pairs[i];
14256 pos = pair.indexOf('=');
14257
14258 if (pos === -1) {
14259 obj[decodeURIComponent(pair)] = '';
14260 } else {
14261 obj[decodeURIComponent(pair.slice(0, pos))] = decodeURIComponent(pair.slice(pos + 1));
14262 }
14263 }
14264
14265 return obj;
14266 }
14267 /**
14268 * Expose parser.
14269 */
14270
14271
14272 request.parseString = parseString;
14273 /**
14274 * Default MIME type map.
14275 *
14276 * superagent.types.xml = 'application/xml';
14277 *
14278 */
14279
14280 request.types = {
14281 html: 'text/html',
14282 json: 'application/json',
14283 xml: 'text/xml',
14284 urlencoded: 'application/x-www-form-urlencoded',
14285 form: 'application/x-www-form-urlencoded',
14286 'form-data': 'application/x-www-form-urlencoded'
14287 };
14288 /**
14289 * Default serialization map.
14290 *
14291 * superagent.serialize['application/xml'] = function(obj){
14292 * return 'generated xml here';
14293 * };
14294 *
14295 */
14296
14297 request.serialize = {
14298 'application/x-www-form-urlencoded': serialize,
14299 'application/json': fastSafeStringify
14300 };
14301 /**
14302 * Default parsers.
14303 *
14304 * superagent.parse['application/xml'] = function(str){
14305 * return { object parsed from str };
14306 * };
14307 *
14308 */
14309
14310 request.parse = {
14311 'application/x-www-form-urlencoded': parseString,
14312 'application/json': JSON.parse
14313 };
14314 /**
14315 * Parse the given header `str` into
14316 * an object containing the mapped fields.
14317 *
14318 * @param {String} str
14319 * @return {Object}
14320 * @api private
14321 */
14322
14323 function parseHeader(str) {
14324 var lines = str.split(/\r?\n/);
14325 var fields = {};
14326 var index;
14327 var line;
14328 var field;
14329 var val;
14330
14331 for (var i = 0, len = lines.length; i < len; ++i) {
14332 line = lines[i];
14333 index = line.indexOf(':');
14334
14335 if (index === -1) {
14336 // could be empty line, just skip it
14337 continue;
14338 }
14339
14340 field = line.slice(0, index).toLowerCase();
14341 val = trim(line.slice(index + 1));
14342 fields[field] = val;
14343 }
14344
14345 return fields;
14346 }
14347 /**
14348 * Check if `mime` is json or has +json structured syntax suffix.
14349 *
14350 * @param {String} mime
14351 * @return {Boolean}
14352 * @api private
14353 */
14354
14355
14356 function isJSON(mime) {
14357 // should match /json or +json
14358 // but not /json-seq
14359 return /[/+]json($|[^-\w])/.test(mime);
14360 }
14361 /**
14362 * Initialize a new `Response` with the given `xhr`.
14363 *
14364 * - set flags (.ok, .error, etc)
14365 * - parse header
14366 *
14367 * Examples:
14368 *
14369 * Aliasing `superagent` as `request` is nice:
14370 *
14371 * request = superagent;
14372 *
14373 * We can use the promise-like API, or pass callbacks:
14374 *
14375 * request.get('/').end(function(res){});
14376 * request.get('/', function(res){});
14377 *
14378 * Sending data can be chained:
14379 *
14380 * request
14381 * .post('/user')
14382 * .send({ name: 'tj' })
14383 * .end(function(res){});
14384 *
14385 * Or passed to `.send()`:
14386 *
14387 * request
14388 * .post('/user')
14389 * .send({ name: 'tj' }, function(res){});
14390 *
14391 * Or passed to `.post()`:
14392 *
14393 * request
14394 * .post('/user', { name: 'tj' })
14395 * .end(function(res){});
14396 *
14397 * Or further reduced to a single call for simple cases:
14398 *
14399 * request
14400 * .post('/user', { name: 'tj' }, function(res){});
14401 *
14402 * @param {XMLHTTPRequest} xhr
14403 * @param {Object} options
14404 * @api private
14405 */
14406
14407
14408 function Response(req) {
14409 this.req = req;
14410 this.xhr = this.req.xhr; // responseText is accessible only if responseType is '' or 'text' and on older browsers
14411
14412 this.text = this.req.method !== 'HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text') || typeof this.xhr.responseType === 'undefined' ? this.xhr.responseText : null;
14413 this.statusText = this.req.xhr.statusText;
14414 var status = this.xhr.status; // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
14415
14416 if (status === 1223) {
14417 status = 204;
14418 }
14419
14420 this._setStatusProperties(status);
14421
14422 this.headers = parseHeader(this.xhr.getAllResponseHeaders());
14423 this.header = this.headers; // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
14424 // getResponseHeader still works. so we get content-type even if getting
14425 // other headers fails.
14426
14427 this.header['content-type'] = this.xhr.getResponseHeader('content-type');
14428
14429 this._setHeaderProperties(this.header);
14430
14431 if (this.text === null && req._responseType) {
14432 this.body = this.xhr.response;
14433 } else {
14434 this.body = this.req.method === 'HEAD' ? null : this._parseBody(this.text ? this.text : this.xhr.response);
14435 }
14436 } // eslint-disable-next-line new-cap
14437
14438
14439 responseBase(Response.prototype);
14440 /**
14441 * Parse the given body `str`.
14442 *
14443 * Used for auto-parsing of bodies. Parsers
14444 * are defined on the `superagent.parse` object.
14445 *
14446 * @param {String} str
14447 * @return {Mixed}
14448 * @api private
14449 */
14450
14451 Response.prototype._parseBody = function (str) {
14452 var parse = request.parse[this.type];
14453
14454 if (this.req._parser) {
14455 return this.req._parser(this, str);
14456 }
14457
14458 if (!parse && isJSON(this.type)) {
14459 parse = request.parse['application/json'];
14460 }
14461
14462 return parse && str && (str.length > 0 || str instanceof Object) ? parse(str) : null;
14463 };
14464 /**
14465 * Return an `Error` representative of this response.
14466 *
14467 * @return {Error}
14468 * @api public
14469 */
14470
14471
14472 Response.prototype.toError = function () {
14473 var req = this.req;
14474 var method = req.method;
14475 var url = req.url;
14476 var msg = "cannot ".concat(method, " ").concat(url, " (").concat(this.status, ")");
14477 var err = new Error(msg);
14478 err.status = this.status;
14479 err.method = method;
14480 err.url = url;
14481 return err;
14482 };
14483 /**
14484 * Expose `Response`.
14485 */
14486
14487
14488 request.Response = Response;
14489 /**
14490 * Initialize a new `Request` with the given `method` and `url`.
14491 *
14492 * @param {String} method
14493 * @param {String} url
14494 * @api public
14495 */
14496
14497 function Request(method, url) {
14498 var self = this;
14499 this._query = this._query || [];
14500 this.method = method;
14501 this.url = url;
14502 this.header = {}; // preserves header name case
14503
14504 this._header = {}; // coerces header names to lowercase
14505
14506 this.on('end', function () {
14507 var err = null;
14508 var res = null;
14509
14510 try {
14511 res = new Response(self);
14512 } catch (err2) {
14513 err = new Error('Parser is unable to parse the response');
14514 err.parse = true;
14515 err.original = err2; // issue #675: return the raw response if the response parsing fails
14516
14517 if (self.xhr) {
14518 // ie9 doesn't have 'response' property
14519 err.rawResponse = typeof self.xhr.responseType === 'undefined' ? self.xhr.responseText : self.xhr.response; // issue #876: return the http status code if the response parsing fails
14520
14521 err.status = self.xhr.status ? self.xhr.status : null;
14522 err.statusCode = err.status; // backwards-compat only
14523 } else {
14524 err.rawResponse = null;
14525 err.status = null;
14526 }
14527
14528 return self.callback(err);
14529 }
14530
14531 self.emit('response', res);
14532 var new_err;
14533
14534 try {
14535 if (!self._isResponseOK(res)) {
14536 new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
14537 }
14538 } catch (err2) {
14539 new_err = err2; // ok() callback can throw
14540 } // #1000 don't catch errors from the callback to avoid double calling it
14541
14542
14543 if (new_err) {
14544 new_err.original = err;
14545 new_err.response = res;
14546 new_err.status = res.status;
14547 self.callback(new_err, res);
14548 } else {
14549 self.callback(null, res);
14550 }
14551 });
14552 }
14553 /**
14554 * Mixin `Emitter` and `RequestBase`.
14555 */
14556 // eslint-disable-next-line new-cap
14557
14558
14559 componentEmitter(Request.prototype); // eslint-disable-next-line new-cap
14560
14561 requestBase(Request.prototype);
14562 /**
14563 * Set Content-Type to `type`, mapping values from `request.types`.
14564 *
14565 * Examples:
14566 *
14567 * superagent.types.xml = 'application/xml';
14568 *
14569 * request.post('/')
14570 * .type('xml')
14571 * .send(xmlstring)
14572 * .end(callback);
14573 *
14574 * request.post('/')
14575 * .type('application/xml')
14576 * .send(xmlstring)
14577 * .end(callback);
14578 *
14579 * @param {String} type
14580 * @return {Request} for chaining
14581 * @api public
14582 */
14583
14584 Request.prototype.type = function (type) {
14585 this.set('Content-Type', request.types[type] || type);
14586 return this;
14587 };
14588 /**
14589 * Set Accept to `type`, mapping values from `request.types`.
14590 *
14591 * Examples:
14592 *
14593 * superagent.types.json = 'application/json';
14594 *
14595 * request.get('/agent')
14596 * .accept('json')
14597 * .end(callback);
14598 *
14599 * request.get('/agent')
14600 * .accept('application/json')
14601 * .end(callback);
14602 *
14603 * @param {String} accept
14604 * @return {Request} for chaining
14605 * @api public
14606 */
14607
14608
14609 Request.prototype.accept = function (type) {
14610 this.set('Accept', request.types[type] || type);
14611 return this;
14612 };
14613 /**
14614 * Set Authorization field value with `user` and `pass`.
14615 *
14616 * @param {String} user
14617 * @param {String} [pass] optional in case of using 'bearer' as type
14618 * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic')
14619 * @return {Request} for chaining
14620 * @api public
14621 */
14622
14623
14624 Request.prototype.auth = function (user, pass, options) {
14625 if (arguments.length === 1) pass = '';
14626
14627 if (_typeof$1(pass) === 'object' && pass !== null) {
14628 // pass is optional and can be replaced with options
14629 options = pass;
14630 pass = '';
14631 }
14632
14633 if (!options) {
14634 options = {
14635 type: typeof btoa === 'function' ? 'basic' : 'auto'
14636 };
14637 }
14638
14639 var encoder = function encoder(string) {
14640 if (typeof btoa === 'function') {
14641 return btoa(string);
14642 }
14643
14644 throw new Error('Cannot use basic auth, btoa is not a function');
14645 };
14646
14647 return this._auth(user, pass, options, encoder);
14648 };
14649 /**
14650 * Add query-string `val`.
14651 *
14652 * Examples:
14653 *
14654 * request.get('/shoes')
14655 * .query('size=10')
14656 * .query({ color: 'blue' })
14657 *
14658 * @param {Object|String} val
14659 * @return {Request} for chaining
14660 * @api public
14661 */
14662
14663
14664 Request.prototype.query = function (val) {
14665 if (typeof val !== 'string') val = serialize(val);
14666 if (val) this._query.push(val);
14667 return this;
14668 };
14669 /**
14670 * Queue the given `file` as an attachment to the specified `field`,
14671 * with optional `options` (or filename).
14672 *
14673 * ``` js
14674 * request.post('/upload')
14675 * .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
14676 * .end(callback);
14677 * ```
14678 *
14679 * @param {String} field
14680 * @param {Blob|File} file
14681 * @param {String|Object} options
14682 * @return {Request} for chaining
14683 * @api public
14684 */
14685
14686
14687 Request.prototype.attach = function (field, file, options) {
14688 if (file) {
14689 if (this._data) {
14690 throw new Error("superagent can't mix .send() and .attach()");
14691 }
14692
14693 this._getFormData().append(field, file, options || file.name);
14694 }
14695
14696 return this;
14697 };
14698
14699 Request.prototype._getFormData = function () {
14700 if (!this._formData) {
14701 this._formData = new root.FormData();
14702 }
14703
14704 return this._formData;
14705 };
14706 /**
14707 * Invoke the callback with `err` and `res`
14708 * and handle arity check.
14709 *
14710 * @param {Error} err
14711 * @param {Response} res
14712 * @api private
14713 */
14714
14715
14716 Request.prototype.callback = function (err, res) {
14717 if (this._shouldRetry(err, res)) {
14718 return this._retry();
14719 }
14720
14721 var fn = this._callback;
14722 this.clearTimeout();
14723
14724 if (err) {
14725 if (this._maxRetries) err.retries = this._retries - 1;
14726 this.emit('error', err);
14727 }
14728
14729 fn(err, res);
14730 };
14731 /**
14732 * Invoke callback with x-domain error.
14733 *
14734 * @api private
14735 */
14736
14737
14738 Request.prototype.crossDomainError = function () {
14739 var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
14740 err.crossDomain = true;
14741 err.status = this.status;
14742 err.method = this.method;
14743 err.url = this.url;
14744 this.callback(err);
14745 }; // This only warns, because the request is still likely to work
14746
14747
14748 Request.prototype.agent = function () {
14749 console.warn('This is not supported in browser version of superagent');
14750 return this;
14751 };
14752
14753 Request.prototype.buffer = Request.prototype.ca;
14754 Request.prototype.ca = Request.prototype.agent; // This throws, because it can't send/receive data as expected
14755
14756 Request.prototype.write = function () {
14757 throw new Error('Streaming is not supported in browser version of superagent');
14758 };
14759
14760 Request.prototype.pipe = Request.prototype.write;
14761 /**
14762 * Check if `obj` is a host object,
14763 * we don't want to serialize these :)
14764 *
14765 * @param {Object} obj host object
14766 * @return {Boolean} is a host object
14767 * @api private
14768 */
14769
14770 Request.prototype._isHost = function (obj) {
14771 // Native objects stringify to [object File], [object Blob], [object FormData], etc.
14772 return obj && _typeof$1(obj) === 'object' && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]';
14773 };
14774 /**
14775 * Initiate request, invoking callback `fn(res)`
14776 * with an instanceof `Response`.
14777 *
14778 * @param {Function} fn
14779 * @return {Request} for chaining
14780 * @api public
14781 */
14782
14783
14784 Request.prototype.end = function (fn) {
14785 if (this._endCalled) {
14786 console.warn('Warning: .end() was called twice. This is not supported in superagent');
14787 }
14788
14789 this._endCalled = true; // store callback
14790
14791 this._callback = fn || noop; // querystring
14792
14793 this._finalizeQueryString();
14794
14795 this._end();
14796 };
14797
14798 Request.prototype._setUploadTimeout = function () {
14799 var self = this; // upload timeout it's wokrs only if deadline timeout is off
14800
14801 if (this._uploadTimeout && !this._uploadTimeoutTimer) {
14802 this._uploadTimeoutTimer = setTimeout(function () {
14803 self._timeoutError('Upload timeout of ', self._uploadTimeout, 'ETIMEDOUT');
14804 }, this._uploadTimeout);
14805 }
14806 }; // eslint-disable-next-line complexity
14807
14808
14809 Request.prototype._end = function () {
14810 if (this._aborted) return this.callback(new Error('The request has been aborted even before .end() was called'));
14811 var self = this;
14812 this.xhr = request.getXHR();
14813 var xhr = this.xhr;
14814 var data = this._formData || this._data;
14815
14816 this._setTimeouts(); // state change
14817
14818
14819 xhr.onreadystatechange = function () {
14820 var readyState = xhr.readyState;
14821
14822 if (readyState >= 2 && self._responseTimeoutTimer) {
14823 clearTimeout(self._responseTimeoutTimer);
14824 }
14825
14826 if (readyState !== 4) {
14827 return;
14828 } // In IE9, reads to any property (e.g. status) off of an aborted XHR will
14829 // result in the error "Could not complete the operation due to error c00c023f"
14830
14831
14832 var status;
14833
14834 try {
14835 status = xhr.status;
14836 } catch (err) {
14837 status = 0;
14838 }
14839
14840 if (!status) {
14841 if (self.timedout || self._aborted) return;
14842 return self.crossDomainError();
14843 }
14844
14845 self.emit('end');
14846 }; // progress
14847
14848
14849 var handleProgress = function handleProgress(direction, e) {
14850 if (e.total > 0) {
14851 e.percent = e.loaded / e.total * 100;
14852
14853 if (e.percent === 100) {
14854 clearTimeout(self._uploadTimeoutTimer);
14855 }
14856 }
14857
14858 e.direction = direction;
14859 self.emit('progress', e);
14860 };
14861
14862 if (this.hasListeners('progress')) {
14863 try {
14864 xhr.addEventListener('progress', handleProgress.bind(null, 'download'));
14865
14866 if (xhr.upload) {
14867 xhr.upload.addEventListener('progress', handleProgress.bind(null, 'upload'));
14868 }
14869 } catch (err) {// Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
14870 // Reported here:
14871 // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
14872 }
14873 }
14874
14875 if (xhr.upload) {
14876 this._setUploadTimeout();
14877 } // initiate request
14878
14879
14880 try {
14881 if (this.username && this.password) {
14882 xhr.open(this.method, this.url, true, this.username, this.password);
14883 } else {
14884 xhr.open(this.method, this.url, true);
14885 }
14886 } catch (err) {
14887 // see #1149
14888 return this.callback(err);
14889 } // CORS
14890
14891
14892 if (this._withCredentials) xhr.withCredentials = true; // body
14893
14894 if (!this._formData && this.method !== 'GET' && this.method !== 'HEAD' && typeof data !== 'string' && !this._isHost(data)) {
14895 // serialize stuff
14896 var contentType = this._header['content-type'];
14897
14898 var _serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
14899
14900 if (!_serialize && isJSON(contentType)) {
14901 _serialize = request.serialize['application/json'];
14902 }
14903
14904 if (_serialize) data = _serialize(data);
14905 } // set header fields
14906
14907
14908 for (var field in this.header) {
14909 if (this.header[field] === null) continue;
14910 if (Object.prototype.hasOwnProperty.call(this.header, field)) xhr.setRequestHeader(field, this.header[field]);
14911 }
14912
14913 if (this._responseType) {
14914 xhr.responseType = this._responseType;
14915 } // send stuff
14916
14917
14918 this.emit('request', this); // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
14919 // We need null here if data is undefined
14920
14921 xhr.send(typeof data === 'undefined' ? null : data);
14922 };
14923
14924 request.agent = function () {
14925 return new agentBase();
14926 };
14927
14928 ['GET', 'POST', 'OPTIONS', 'PATCH', 'PUT', 'DELETE'].forEach(function (method) {
14929 agentBase.prototype[method.toLowerCase()] = function (url, fn) {
14930 var req = new request.Request(method, url);
14931
14932 this._setDefaults(req);
14933
14934 if (fn) {
14935 req.end(fn);
14936 }
14937
14938 return req;
14939 };
14940 });
14941 agentBase.prototype.del = agentBase.prototype.delete;
14942 /**
14943 * GET `url` with optional callback `fn(res)`.
14944 *
14945 * @param {String} url
14946 * @param {Mixed|Function} [data] or fn
14947 * @param {Function} [fn]
14948 * @return {Request}
14949 * @api public
14950 */
14951
14952 request.get = function (url, data, fn) {
14953 var req = request('GET', url);
14954
14955 if (typeof data === 'function') {
14956 fn = data;
14957 data = null;
14958 }
14959
14960 if (data) req.query(data);
14961 if (fn) req.end(fn);
14962 return req;
14963 };
14964 /**
14965 * HEAD `url` with optional callback `fn(res)`.
14966 *
14967 * @param {String} url
14968 * @param {Mixed|Function} [data] or fn
14969 * @param {Function} [fn]
14970 * @return {Request}
14971 * @api public
14972 */
14973
14974
14975 request.head = function (url, data, fn) {
14976 var req = request('HEAD', url);
14977
14978 if (typeof data === 'function') {
14979 fn = data;
14980 data = null;
14981 }
14982
14983 if (data) req.query(data);
14984 if (fn) req.end(fn);
14985 return req;
14986 };
14987 /**
14988 * OPTIONS query to `url` with optional callback `fn(res)`.
14989 *
14990 * @param {String} url
14991 * @param {Mixed|Function} [data] or fn
14992 * @param {Function} [fn]
14993 * @return {Request}
14994 * @api public
14995 */
14996
14997
14998 request.options = function (url, data, fn) {
14999 var req = request('OPTIONS', url);
15000
15001 if (typeof data === 'function') {
15002 fn = data;
15003 data = null;
15004 }
15005
15006 if (data) req.send(data);
15007 if (fn) req.end(fn);
15008 return req;
15009 };
15010 /**
15011 * DELETE `url` with optional `data` and callback `fn(res)`.
15012 *
15013 * @param {String} url
15014 * @param {Mixed} [data]
15015 * @param {Function} [fn]
15016 * @return {Request}
15017 * @api public
15018 */
15019
15020
15021 function del(url, data, fn) {
15022 var req = request('DELETE', url);
15023
15024 if (typeof data === 'function') {
15025 fn = data;
15026 data = null;
15027 }
15028
15029 if (data) req.send(data);
15030 if (fn) req.end(fn);
15031 return req;
15032 }
15033
15034 request.del = del;
15035 request.delete = del;
15036 /**
15037 * PATCH `url` with optional `data` and callback `fn(res)`.
15038 *
15039 * @param {String} url
15040 * @param {Mixed} [data]
15041 * @param {Function} [fn]
15042 * @return {Request}
15043 * @api public
15044 */
15045
15046 request.patch = function (url, data, fn) {
15047 var req = request('PATCH', url);
15048
15049 if (typeof data === 'function') {
15050 fn = data;
15051 data = null;
15052 }
15053
15054 if (data) req.send(data);
15055 if (fn) req.end(fn);
15056 return req;
15057 };
15058 /**
15059 * POST `url` with optional `data` and callback `fn(res)`.
15060 *
15061 * @param {String} url
15062 * @param {Mixed} [data]
15063 * @param {Function} [fn]
15064 * @return {Request}
15065 * @api public
15066 */
15067
15068
15069 request.post = function (url, data, fn) {
15070 var req = request('POST', url);
15071
15072 if (typeof data === 'function') {
15073 fn = data;
15074 data = null;
15075 }
15076
15077 if (data) req.send(data);
15078 if (fn) req.end(fn);
15079 return req;
15080 };
15081 /**
15082 * PUT `url` with optional `data` and callback `fn(res)`.
15083 *
15084 * @param {String} url
15085 * @param {Mixed|Function} [data] or fn
15086 * @param {Function} [fn]
15087 * @return {Request}
15088 * @api public
15089 */
15090
15091
15092 request.put = function (url, data, fn) {
15093 var req = request('PUT', url);
15094
15095 if (typeof data === 'function') {
15096 fn = data;
15097 data = null;
15098 }
15099
15100 if (data) req.send(data);
15101 if (fn) req.end(fn);
15102 return req;
15103 };
15104 });
15105 var client_1 = client.Request;
15106
15107 /**
15108 * Copies the values of `source` to `array`.
15109 *
15110 * @private
15111 * @param {Array} source The array to copy values from.
15112 * @param {Array} [array=[]] The array to copy values to.
15113 * @returns {Array} Returns `array`.
15114 */
15115 function copyArray(source, array) {
15116 var index = -1,
15117 length = source.length;
15118
15119 array || (array = Array(length));
15120 while (++index < length) {
15121 array[index] = source[index];
15122 }
15123 return array;
15124 }
15125
15126 var _copyArray = copyArray;
15127
15128 /* Built-in method references for those with the same name as other `lodash` methods. */
15129 var nativeFloor = Math.floor,
15130 nativeRandom = Math.random;
15131
15132 /**
15133 * The base implementation of `_.random` without support for returning
15134 * floating-point numbers.
15135 *
15136 * @private
15137 * @param {number} lower The lower bound.
15138 * @param {number} upper The upper bound.
15139 * @returns {number} Returns the random number.
15140 */
15141 function baseRandom(lower, upper) {
15142 return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
15143 }
15144
15145 var _baseRandom = baseRandom;
15146
15147 /**
15148 * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
15149 *
15150 * @private
15151 * @param {Array} array The array to shuffle.
15152 * @param {number} [size=array.length] The size of `array`.
15153 * @returns {Array} Returns `array`.
15154 */
15155 function shuffleSelf(array, size) {
15156 var index = -1,
15157 length = array.length,
15158 lastIndex = length - 1;
15159
15160 size = size === undefined ? length : size;
15161 while (++index < size) {
15162 var rand = _baseRandom(index, lastIndex),
15163 value = array[rand];
15164
15165 array[rand] = array[index];
15166 array[index] = value;
15167 }
15168 array.length = size;
15169 return array;
15170 }
15171
15172 var _shuffleSelf = shuffleSelf;
15173
15174 /**
15175 * A specialized version of `_.shuffle` for arrays.
15176 *
15177 * @private
15178 * @param {Array} array The array to shuffle.
15179 * @returns {Array} Returns the new shuffled array.
15180 */
15181 function arrayShuffle(array) {
15182 return _shuffleSelf(_copyArray(array));
15183 }
15184
15185 var _arrayShuffle = arrayShuffle;
15186
15187 /**
15188 * A specialized version of `_.map` for arrays without support for iteratee
15189 * shorthands.
15190 *
15191 * @private
15192 * @param {Array} [array] The array to iterate over.
15193 * @param {Function} iteratee The function invoked per iteration.
15194 * @returns {Array} Returns the new mapped array.
15195 */
15196 function arrayMap(array, iteratee) {
15197 var index = -1,
15198 length = array == null ? 0 : array.length,
15199 result = Array(length);
15200
15201 while (++index < length) {
15202 result[index] = iteratee(array[index], index, array);
15203 }
15204 return result;
15205 }
15206
15207 var _arrayMap = arrayMap;
15208
15209 /**
15210 * The base implementation of `_.values` and `_.valuesIn` which creates an
15211 * array of `object` property values corresponding to the property names
15212 * of `props`.
15213 *
15214 * @private
15215 * @param {Object} object The object to query.
15216 * @param {Array} props The property names to get values for.
15217 * @returns {Object} Returns the array of property values.
15218 */
15219 function baseValues(object, props) {
15220 return _arrayMap(props, function(key) {
15221 return object[key];
15222 });
15223 }
15224
15225 var _baseValues = baseValues;
15226
15227 /**
15228 * The base implementation of `_.times` without support for iteratee shorthands
15229 * or max array length checks.
15230 *
15231 * @private
15232 * @param {number} n The number of times to invoke `iteratee`.
15233 * @param {Function} iteratee The function invoked per iteration.
15234 * @returns {Array} Returns the array of results.
15235 */
15236 function baseTimes(n, iteratee) {
15237 var index = -1,
15238 result = Array(n);
15239
15240 while (++index < n) {
15241 result[index] = iteratee(index);
15242 }
15243 return result;
15244 }
15245
15246 var _baseTimes = baseTimes;
15247
15248 /** Detect free variable `global` from Node.js. */
15249 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
15250
15251 var _freeGlobal = freeGlobal;
15252
15253 /** Detect free variable `self`. */
15254 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
15255
15256 /** Used as a reference to the global object. */
15257 var root = _freeGlobal || freeSelf || Function('return this')();
15258
15259 var _root = root;
15260
15261 /** Built-in value references. */
15262 var Symbol$1 = _root.Symbol;
15263
15264 var _Symbol = Symbol$1;
15265
15266 /** Used for built-in method references. */
15267 var objectProto = Object.prototype;
15268
15269 /** Used to check objects for own properties. */
15270 var hasOwnProperty = objectProto.hasOwnProperty;
15271
15272 /**
15273 * Used to resolve the
15274 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
15275 * of values.
15276 */
15277 var nativeObjectToString = objectProto.toString;
15278
15279 /** Built-in value references. */
15280 var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
15281
15282 /**
15283 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
15284 *
15285 * @private
15286 * @param {*} value The value to query.
15287 * @returns {string} Returns the raw `toStringTag`.
15288 */
15289 function getRawTag(value) {
15290 var isOwn = hasOwnProperty.call(value, symToStringTag),
15291 tag = value[symToStringTag];
15292
15293 try {
15294 value[symToStringTag] = undefined;
15295 var unmasked = true;
15296 } catch (e) {}
15297
15298 var result = nativeObjectToString.call(value);
15299 if (unmasked) {
15300 if (isOwn) {
15301 value[symToStringTag] = tag;
15302 } else {
15303 delete value[symToStringTag];
15304 }
15305 }
15306 return result;
15307 }
15308
15309 var _getRawTag = getRawTag;
15310
15311 /** Used for built-in method references. */
15312 var objectProto$1 = Object.prototype;
15313
15314 /**
15315 * Used to resolve the
15316 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
15317 * of values.
15318 */
15319 var nativeObjectToString$1 = objectProto$1.toString;
15320
15321 /**
15322 * Converts `value` to a string using `Object.prototype.toString`.
15323 *
15324 * @private
15325 * @param {*} value The value to convert.
15326 * @returns {string} Returns the converted string.
15327 */
15328 function objectToString(value) {
15329 return nativeObjectToString$1.call(value);
15330 }
15331
15332 var _objectToString = objectToString;
15333
15334 /** `Object#toString` result references. */
15335 var nullTag = '[object Null]',
15336 undefinedTag = '[object Undefined]';
15337
15338 /** Built-in value references. */
15339 var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;
15340
15341 /**
15342 * The base implementation of `getTag` without fallbacks for buggy environments.
15343 *
15344 * @private
15345 * @param {*} value The value to query.
15346 * @returns {string} Returns the `toStringTag`.
15347 */
15348 function baseGetTag(value) {
15349 if (value == null) {
15350 return value === undefined ? undefinedTag : nullTag;
15351 }
15352 return (symToStringTag$1 && symToStringTag$1 in Object(value))
15353 ? _getRawTag(value)
15354 : _objectToString(value);
15355 }
15356
15357 var _baseGetTag = baseGetTag;
15358
15359 /**
15360 * Checks if `value` is object-like. A value is object-like if it's not `null`
15361 * and has a `typeof` result of "object".
15362 *
15363 * @static
15364 * @memberOf _
15365 * @since 4.0.0
15366 * @category Lang
15367 * @param {*} value The value to check.
15368 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
15369 * @example
15370 *
15371 * _.isObjectLike({});
15372 * // => true
15373 *
15374 * _.isObjectLike([1, 2, 3]);
15375 * // => true
15376 *
15377 * _.isObjectLike(_.noop);
15378 * // => false
15379 *
15380 * _.isObjectLike(null);
15381 * // => false
15382 */
15383 function isObjectLike(value) {
15384 return value != null && typeof value == 'object';
15385 }
15386
15387 var isObjectLike_1 = isObjectLike;
15388
15389 /** `Object#toString` result references. */
15390 var argsTag = '[object Arguments]';
15391
15392 /**
15393 * The base implementation of `_.isArguments`.
15394 *
15395 * @private
15396 * @param {*} value The value to check.
15397 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
15398 */
15399 function baseIsArguments(value) {
15400 return isObjectLike_1(value) && _baseGetTag(value) == argsTag;
15401 }
15402
15403 var _baseIsArguments = baseIsArguments;
15404
15405 /** Used for built-in method references. */
15406 var objectProto$2 = Object.prototype;
15407
15408 /** Used to check objects for own properties. */
15409 var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
15410
15411 /** Built-in value references. */
15412 var propertyIsEnumerable = objectProto$2.propertyIsEnumerable;
15413
15414 /**
15415 * Checks if `value` is likely an `arguments` object.
15416 *
15417 * @static
15418 * @memberOf _
15419 * @since 0.1.0
15420 * @category Lang
15421 * @param {*} value The value to check.
15422 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
15423 * else `false`.
15424 * @example
15425 *
15426 * _.isArguments(function() { return arguments; }());
15427 * // => true
15428 *
15429 * _.isArguments([1, 2, 3]);
15430 * // => false
15431 */
15432 var isArguments = _baseIsArguments(function() { return arguments; }()) ? _baseIsArguments : function(value) {
15433 return isObjectLike_1(value) && hasOwnProperty$1.call(value, 'callee') &&
15434 !propertyIsEnumerable.call(value, 'callee');
15435 };
15436
15437 var isArguments_1 = isArguments;
15438
15439 /**
15440 * Checks if `value` is classified as an `Array` object.
15441 *
15442 * @static
15443 * @memberOf _
15444 * @since 0.1.0
15445 * @category Lang
15446 * @param {*} value The value to check.
15447 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
15448 * @example
15449 *
15450 * _.isArray([1, 2, 3]);
15451 * // => true
15452 *
15453 * _.isArray(document.body.children);
15454 * // => false
15455 *
15456 * _.isArray('abc');
15457 * // => false
15458 *
15459 * _.isArray(_.noop);
15460 * // => false
15461 */
15462 var isArray = Array.isArray;
15463
15464 var isArray_1 = isArray;
15465
15466 /**
15467 * This method returns `false`.
15468 *
15469 * @static
15470 * @memberOf _
15471 * @since 4.13.0
15472 * @category Util
15473 * @returns {boolean} Returns `false`.
15474 * @example
15475 *
15476 * _.times(2, _.stubFalse);
15477 * // => [false, false]
15478 */
15479 function stubFalse() {
15480 return false;
15481 }
15482
15483 var stubFalse_1 = stubFalse;
15484
15485 var isBuffer_1 = createCommonjsModule(function (module, exports) {
15486 /** Detect free variable `exports`. */
15487 var freeExports = exports && !exports.nodeType && exports;
15488
15489 /** Detect free variable `module`. */
15490 var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
15491
15492 /** Detect the popular CommonJS extension `module.exports`. */
15493 var moduleExports = freeModule && freeModule.exports === freeExports;
15494
15495 /** Built-in value references. */
15496 var Buffer = moduleExports ? _root.Buffer : undefined;
15497
15498 /* Built-in method references for those with the same name as other `lodash` methods. */
15499 var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
15500
15501 /**
15502 * Checks if `value` is a buffer.
15503 *
15504 * @static
15505 * @memberOf _
15506 * @since 4.3.0
15507 * @category Lang
15508 * @param {*} value The value to check.
15509 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
15510 * @example
15511 *
15512 * _.isBuffer(new Buffer(2));
15513 * // => true
15514 *
15515 * _.isBuffer(new Uint8Array(2));
15516 * // => false
15517 */
15518 var isBuffer = nativeIsBuffer || stubFalse_1;
15519
15520 module.exports = isBuffer;
15521 });
15522
15523 /** Used as references for various `Number` constants. */
15524 var MAX_SAFE_INTEGER = 9007199254740991;
15525
15526 /** Used to detect unsigned integer values. */
15527 var reIsUint = /^(?:0|[1-9]\d*)$/;
15528
15529 /**
15530 * Checks if `value` is a valid array-like index.
15531 *
15532 * @private
15533 * @param {*} value The value to check.
15534 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
15535 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
15536 */
15537 function isIndex(value, length) {
15538 var type = typeof value;
15539 length = length == null ? MAX_SAFE_INTEGER : length;
15540
15541 return !!length &&
15542 (type == 'number' ||
15543 (type != 'symbol' && reIsUint.test(value))) &&
15544 (value > -1 && value % 1 == 0 && value < length);
15545 }
15546
15547 var _isIndex = isIndex;
15548
15549 /** Used as references for various `Number` constants. */
15550 var MAX_SAFE_INTEGER$1 = 9007199254740991;
15551
15552 /**
15553 * Checks if `value` is a valid array-like length.
15554 *
15555 * **Note:** This method is loosely based on
15556 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
15557 *
15558 * @static
15559 * @memberOf _
15560 * @since 4.0.0
15561 * @category Lang
15562 * @param {*} value The value to check.
15563 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
15564 * @example
15565 *
15566 * _.isLength(3);
15567 * // => true
15568 *
15569 * _.isLength(Number.MIN_VALUE);
15570 * // => false
15571 *
15572 * _.isLength(Infinity);
15573 * // => false
15574 *
15575 * _.isLength('3');
15576 * // => false
15577 */
15578 function isLength(value) {
15579 return typeof value == 'number' &&
15580 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
15581 }
15582
15583 var isLength_1 = isLength;
15584
15585 /** `Object#toString` result references. */
15586 var argsTag$1 = '[object Arguments]',
15587 arrayTag = '[object Array]',
15588 boolTag = '[object Boolean]',
15589 dateTag = '[object Date]',
15590 errorTag = '[object Error]',
15591 funcTag = '[object Function]',
15592 mapTag = '[object Map]',
15593 numberTag = '[object Number]',
15594 objectTag = '[object Object]',
15595 regexpTag = '[object RegExp]',
15596 setTag = '[object Set]',
15597 stringTag = '[object String]',
15598 weakMapTag = '[object WeakMap]';
15599
15600 var arrayBufferTag = '[object ArrayBuffer]',
15601 dataViewTag = '[object DataView]',
15602 float32Tag = '[object Float32Array]',
15603 float64Tag = '[object Float64Array]',
15604 int8Tag = '[object Int8Array]',
15605 int16Tag = '[object Int16Array]',
15606 int32Tag = '[object Int32Array]',
15607 uint8Tag = '[object Uint8Array]',
15608 uint8ClampedTag = '[object Uint8ClampedArray]',
15609 uint16Tag = '[object Uint16Array]',
15610 uint32Tag = '[object Uint32Array]';
15611
15612 /** Used to identify `toStringTag` values of typed arrays. */
15613 var typedArrayTags = {};
15614 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
15615 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
15616 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
15617 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
15618 typedArrayTags[uint32Tag] = true;
15619 typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
15620 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
15621 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
15622 typedArrayTags[errorTag] = typedArrayTags[funcTag] =
15623 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
15624 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
15625 typedArrayTags[setTag] = typedArrayTags[stringTag] =
15626 typedArrayTags[weakMapTag] = false;
15627
15628 /**
15629 * The base implementation of `_.isTypedArray` without Node.js optimizations.
15630 *
15631 * @private
15632 * @param {*} value The value to check.
15633 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
15634 */
15635 function baseIsTypedArray(value) {
15636 return isObjectLike_1(value) &&
15637 isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)];
15638 }
15639
15640 var _baseIsTypedArray = baseIsTypedArray;
15641
15642 /**
15643 * The base implementation of `_.unary` without support for storing metadata.
15644 *
15645 * @private
15646 * @param {Function} func The function to cap arguments for.
15647 * @returns {Function} Returns the new capped function.
15648 */
15649 function baseUnary(func) {
15650 return function(value) {
15651 return func(value);
15652 };
15653 }
15654
15655 var _baseUnary = baseUnary;
15656
15657 var _nodeUtil = createCommonjsModule(function (module, exports) {
15658 /** Detect free variable `exports`. */
15659 var freeExports = exports && !exports.nodeType && exports;
15660
15661 /** Detect free variable `module`. */
15662 var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
15663
15664 /** Detect the popular CommonJS extension `module.exports`. */
15665 var moduleExports = freeModule && freeModule.exports === freeExports;
15666
15667 /** Detect free variable `process` from Node.js. */
15668 var freeProcess = moduleExports && _freeGlobal.process;
15669
15670 /** Used to access faster Node.js helpers. */
15671 var nodeUtil = (function() {
15672 try {
15673 // Use `util.types` for Node.js 10+.
15674 var types = freeModule && freeModule.require && freeModule.require('util').types;
15675
15676 if (types) {
15677 return types;
15678 }
15679
15680 // Legacy `process.binding('util')` for Node.js < 10.
15681 return freeProcess && freeProcess.binding && freeProcess.binding('util');
15682 } catch (e) {}
15683 }());
15684
15685 module.exports = nodeUtil;
15686 });
15687
15688 /* Node.js helper references. */
15689 var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray;
15690
15691 /**
15692 * Checks if `value` is classified as a typed array.
15693 *
15694 * @static
15695 * @memberOf _
15696 * @since 3.0.0
15697 * @category Lang
15698 * @param {*} value The value to check.
15699 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
15700 * @example
15701 *
15702 * _.isTypedArray(new Uint8Array);
15703 * // => true
15704 *
15705 * _.isTypedArray([]);
15706 * // => false
15707 */
15708 var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray;
15709
15710 var isTypedArray_1 = isTypedArray;
15711
15712 /** Used for built-in method references. */
15713 var objectProto$3 = Object.prototype;
15714
15715 /** Used to check objects for own properties. */
15716 var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
15717
15718 /**
15719 * Creates an array of the enumerable property names of the array-like `value`.
15720 *
15721 * @private
15722 * @param {*} value The value to query.
15723 * @param {boolean} inherited Specify returning inherited property names.
15724 * @returns {Array} Returns the array of property names.
15725 */
15726 function arrayLikeKeys(value, inherited) {
15727 var isArr = isArray_1(value),
15728 isArg = !isArr && isArguments_1(value),
15729 isBuff = !isArr && !isArg && isBuffer_1(value),
15730 isType = !isArr && !isArg && !isBuff && isTypedArray_1(value),
15731 skipIndexes = isArr || isArg || isBuff || isType,
15732 result = skipIndexes ? _baseTimes(value.length, String) : [],
15733 length = result.length;
15734
15735 for (var key in value) {
15736 if ((inherited || hasOwnProperty$2.call(value, key)) &&
15737 !(skipIndexes && (
15738 // Safari 9 has enumerable `arguments.length` in strict mode.
15739 key == 'length' ||
15740 // Node.js 0.10 has enumerable non-index properties on buffers.
15741 (isBuff && (key == 'offset' || key == 'parent')) ||
15742 // PhantomJS 2 has enumerable non-index properties on typed arrays.
15743 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
15744 // Skip index properties.
15745 _isIndex(key, length)
15746 ))) {
15747 result.push(key);
15748 }
15749 }
15750 return result;
15751 }
15752
15753 var _arrayLikeKeys = arrayLikeKeys;
15754
15755 /** Used for built-in method references. */
15756 var objectProto$4 = Object.prototype;
15757
15758 /**
15759 * Checks if `value` is likely a prototype object.
15760 *
15761 * @private
15762 * @param {*} value The value to check.
15763 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
15764 */
15765 function isPrototype(value) {
15766 var Ctor = value && value.constructor,
15767 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4;
15768
15769 return value === proto;
15770 }
15771
15772 var _isPrototype = isPrototype;
15773
15774 /**
15775 * Creates a unary function that invokes `func` with its argument transformed.
15776 *
15777 * @private
15778 * @param {Function} func The function to wrap.
15779 * @param {Function} transform The argument transform.
15780 * @returns {Function} Returns the new function.
15781 */
15782 function overArg(func, transform) {
15783 return function(arg) {
15784 return func(transform(arg));
15785 };
15786 }
15787
15788 var _overArg = overArg;
15789
15790 /* Built-in method references for those with the same name as other `lodash` methods. */
15791 var nativeKeys = _overArg(Object.keys, Object);
15792
15793 var _nativeKeys = nativeKeys;
15794
15795 /** Used for built-in method references. */
15796 var objectProto$5 = Object.prototype;
15797
15798 /** Used to check objects for own properties. */
15799 var hasOwnProperty$3 = objectProto$5.hasOwnProperty;
15800
15801 /**
15802 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
15803 *
15804 * @private
15805 * @param {Object} object The object to query.
15806 * @returns {Array} Returns the array of property names.
15807 */
15808 function baseKeys(object) {
15809 if (!_isPrototype(object)) {
15810 return _nativeKeys(object);
15811 }
15812 var result = [];
15813 for (var key in Object(object)) {
15814 if (hasOwnProperty$3.call(object, key) && key != 'constructor') {
15815 result.push(key);
15816 }
15817 }
15818 return result;
15819 }
15820
15821 var _baseKeys = baseKeys;
15822
15823 /**
15824 * Checks if `value` is the
15825 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
15826 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
15827 *
15828 * @static
15829 * @memberOf _
15830 * @since 0.1.0
15831 * @category Lang
15832 * @param {*} value The value to check.
15833 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
15834 * @example
15835 *
15836 * _.isObject({});
15837 * // => true
15838 *
15839 * _.isObject([1, 2, 3]);
15840 * // => true
15841 *
15842 * _.isObject(_.noop);
15843 * // => true
15844 *
15845 * _.isObject(null);
15846 * // => false
15847 */
15848 function isObject$1(value) {
15849 var type = typeof value;
15850 return value != null && (type == 'object' || type == 'function');
15851 }
15852
15853 var isObject_1$1 = isObject$1;
15854
15855 /** `Object#toString` result references. */
15856 var asyncTag = '[object AsyncFunction]',
15857 funcTag$1 = '[object Function]',
15858 genTag = '[object GeneratorFunction]',
15859 proxyTag = '[object Proxy]';
15860
15861 /**
15862 * Checks if `value` is classified as a `Function` object.
15863 *
15864 * @static
15865 * @memberOf _
15866 * @since 0.1.0
15867 * @category Lang
15868 * @param {*} value The value to check.
15869 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
15870 * @example
15871 *
15872 * _.isFunction(_);
15873 * // => true
15874 *
15875 * _.isFunction(/abc/);
15876 * // => false
15877 */
15878 function isFunction(value) {
15879 if (!isObject_1$1(value)) {
15880 return false;
15881 }
15882 // The use of `Object#toString` avoids issues with the `typeof` operator
15883 // in Safari 9 which returns 'object' for typed arrays and other constructors.
15884 var tag = _baseGetTag(value);
15885 return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag;
15886 }
15887
15888 var isFunction_1 = isFunction;
15889
15890 /**
15891 * Checks if `value` is array-like. A value is considered array-like if it's
15892 * not a function and has a `value.length` that's an integer greater than or
15893 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
15894 *
15895 * @static
15896 * @memberOf _
15897 * @since 4.0.0
15898 * @category Lang
15899 * @param {*} value The value to check.
15900 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
15901 * @example
15902 *
15903 * _.isArrayLike([1, 2, 3]);
15904 * // => true
15905 *
15906 * _.isArrayLike(document.body.children);
15907 * // => true
15908 *
15909 * _.isArrayLike('abc');
15910 * // => true
15911 *
15912 * _.isArrayLike(_.noop);
15913 * // => false
15914 */
15915 function isArrayLike(value) {
15916 return value != null && isLength_1(value.length) && !isFunction_1(value);
15917 }
15918
15919 var isArrayLike_1 = isArrayLike;
15920
15921 /**
15922 * Creates an array of the own enumerable property names of `object`.
15923 *
15924 * **Note:** Non-object values are coerced to objects. See the
15925 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
15926 * for more details.
15927 *
15928 * @static
15929 * @since 0.1.0
15930 * @memberOf _
15931 * @category Object
15932 * @param {Object} object The object to query.
15933 * @returns {Array} Returns the array of property names.
15934 * @example
15935 *
15936 * function Foo() {
15937 * this.a = 1;
15938 * this.b = 2;
15939 * }
15940 *
15941 * Foo.prototype.c = 3;
15942 *
15943 * _.keys(new Foo);
15944 * // => ['a', 'b'] (iteration order is not guaranteed)
15945 *
15946 * _.keys('hi');
15947 * // => ['0', '1']
15948 */
15949 function keys(object) {
15950 return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object);
15951 }
15952
15953 var keys_1 = keys;
15954
15955 /**
15956 * Creates an array of the own enumerable string keyed property values of `object`.
15957 *
15958 * **Note:** Non-object values are coerced to objects.
15959 *
15960 * @static
15961 * @since 0.1.0
15962 * @memberOf _
15963 * @category Object
15964 * @param {Object} object The object to query.
15965 * @returns {Array} Returns the array of property values.
15966 * @example
15967 *
15968 * function Foo() {
15969 * this.a = 1;
15970 * this.b = 2;
15971 * }
15972 *
15973 * Foo.prototype.c = 3;
15974 *
15975 * _.values(new Foo);
15976 * // => [1, 2] (iteration order is not guaranteed)
15977 *
15978 * _.values('hi');
15979 * // => ['h', 'i']
15980 */
15981 function values(object) {
15982 return object == null ? [] : _baseValues(object, keys_1(object));
15983 }
15984
15985 var values_1 = values;
15986
15987 /**
15988 * The base implementation of `_.shuffle`.
15989 *
15990 * @private
15991 * @param {Array|Object} collection The collection to shuffle.
15992 * @returns {Array} Returns the new shuffled array.
15993 */
15994 function baseShuffle(collection) {
15995 return _shuffleSelf(values_1(collection));
15996 }
15997
15998 var _baseShuffle = baseShuffle;
15999
16000 /**
16001 * Creates an array of shuffled values, using a version of the
16002 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
16003 *
16004 * @static
16005 * @memberOf _
16006 * @since 0.1.0
16007 * @category Collection
16008 * @param {Array|Object} collection The collection to shuffle.
16009 * @returns {Array} Returns the new shuffled array.
16010 * @example
16011 *
16012 * _.shuffle([1, 2, 3, 4]);
16013 * // => [4, 1, 3, 2]
16014 */
16015 function shuffle(collection) {
16016 var func = isArray_1(collection) ? _arrayShuffle : _baseShuffle;
16017 return func(collection);
16018 }
16019
16020 var shuffle_1 = shuffle;
16021
16022 var stateMachine = createCommonjsModule(function (module, exports) {
16023 /*
16024
16025 Javascript State Machine Library - https://github.com/jakesgordon/javascript-state-machine
16026
16027 Copyright (c) 2012, 2013, 2014, 2015, Jake Gordon and contributors
16028 Released under the MIT license - https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE
16029
16030 */
16031
16032 (function () {
16033
16034 var StateMachine = {
16035
16036 //---------------------------------------------------------------------------
16037
16038 VERSION: "2.4.0",
16039
16040 //---------------------------------------------------------------------------
16041
16042 Result: {
16043 SUCCEEDED: 1, // the event transitioned successfully from one state to another
16044 NOTRANSITION: 2, // the event was successfull but no state transition was necessary
16045 CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback
16046 PENDING: 4 // the event is asynchronous and the caller is in control of when the transition occurs
16047 },
16048
16049 Error: {
16050 INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state
16051 PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending
16052 INVALID_CALLBACK: 300 // caller provided callback function threw an exception
16053 },
16054
16055 WILDCARD: '*',
16056 ASYNC: 'async',
16057
16058 //---------------------------------------------------------------------------
16059
16060 create: function(cfg, target) {
16061
16062 var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false }
16063 var terminal = cfg.terminal || cfg['final'];
16064 var fsm = target || cfg.target || {};
16065 var events = cfg.events || [];
16066 var callbacks = cfg.callbacks || {};
16067 var map = {}; // track state transitions allowed for an event { event: { from: [ to ] } }
16068 var transitions = {}; // track events allowed from a state { state: [ event ] }
16069
16070 var add = function(e) {
16071 var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified
16072 map[e.name] = map[e.name] || {};
16073 for (var n = 0 ; n < from.length ; n++) {
16074 transitions[from[n]] = transitions[from[n]] || [];
16075 transitions[from[n]].push(e.name);
16076
16077 map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified
16078 }
16079 if (e.to)
16080 transitions[e.to] = transitions[e.to] || [];
16081 };
16082
16083 if (initial) {
16084 initial.event = initial.event || 'startup';
16085 add({ name: initial.event, from: 'none', to: initial.state });
16086 }
16087
16088 for(var n = 0 ; n < events.length ; n++)
16089 add(events[n]);
16090
16091 for(var name in map) {
16092 if (map.hasOwnProperty(name))
16093 fsm[name] = StateMachine.buildEvent(name, map[name]);
16094 }
16095
16096 for(var name in callbacks) {
16097 if (callbacks.hasOwnProperty(name))
16098 fsm[name] = callbacks[name];
16099 }
16100
16101 fsm.current = 'none';
16102 fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); };
16103 fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); };
16104 fsm.cannot = function(event) { return !this.can(event); };
16105 fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); };
16106 fsm.isFinished = function() { return this.is(terminal); };
16107 fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17)
16108 fsm.states = function() { return Object.keys(transitions).sort() };
16109
16110 if (initial && !initial.defer)
16111 fsm[initial.event]();
16112
16113 return fsm;
16114
16115 },
16116
16117 //===========================================================================
16118
16119 doCallback: function(fsm, func, name, from, to, args) {
16120 if (func) {
16121 try {
16122 return func.apply(fsm, [name, from, to].concat(args));
16123 }
16124 catch(e) {
16125 return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function", e);
16126 }
16127 }
16128 },
16129
16130 beforeAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbeforeevent'], name, from, to, args); },
16131 afterAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafterevent'] || fsm['onevent'], name, from, to, args); },
16132 leaveAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleavestate'], name, from, to, args); },
16133 enterAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenterstate'] || fsm['onstate'], name, from, to, args); },
16134 changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); },
16135
16136 beforeThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); },
16137 afterThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); },
16138 leaveThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); },
16139 enterThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); },
16140
16141 beforeEvent: function(fsm, name, from, to, args) {
16142 if ((false === StateMachine.beforeThisEvent(fsm, name, from, to, args)) ||
16143 (false === StateMachine.beforeAnyEvent( fsm, name, from, to, args)))
16144 return false;
16145 },
16146
16147 afterEvent: function(fsm, name, from, to, args) {
16148 StateMachine.afterThisEvent(fsm, name, from, to, args);
16149 StateMachine.afterAnyEvent( fsm, name, from, to, args);
16150 },
16151
16152 leaveState: function(fsm, name, from, to, args) {
16153 var specific = StateMachine.leaveThisState(fsm, name, from, to, args),
16154 general = StateMachine.leaveAnyState( fsm, name, from, to, args);
16155 if ((false === specific) || (false === general))
16156 return false;
16157 else if ((StateMachine.ASYNC === specific) || (StateMachine.ASYNC === general))
16158 return StateMachine.ASYNC;
16159 },
16160
16161 enterState: function(fsm, name, from, to, args) {
16162 StateMachine.enterThisState(fsm, name, from, to, args);
16163 StateMachine.enterAnyState( fsm, name, from, to, args);
16164 },
16165
16166 //===========================================================================
16167
16168 buildEvent: function(name, map) {
16169 return function() {
16170
16171 var from = this.current;
16172 var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from;
16173 var args = Array.prototype.slice.call(arguments); // turn arguments into pure array
16174
16175 if (this.transition)
16176 return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, "event " + name + " inappropriate because previous transition did not complete");
16177
16178 if (this.cannot(name))
16179 return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, "event " + name + " inappropriate in current state " + this.current);
16180
16181 if (false === StateMachine.beforeEvent(this, name, from, to, args))
16182 return StateMachine.Result.CANCELLED;
16183
16184 if (from === to) {
16185 StateMachine.afterEvent(this, name, from, to, args);
16186 return StateMachine.Result.NOTRANSITION;
16187 }
16188
16189 // prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState)
16190 var fsm = this;
16191 this.transition = function() {
16192 fsm.transition = null; // this method should only ever be called once
16193 fsm.current = to;
16194 StateMachine.enterState( fsm, name, from, to, args);
16195 StateMachine.changeState(fsm, name, from, to, args);
16196 StateMachine.afterEvent( fsm, name, from, to, args);
16197 return StateMachine.Result.SUCCEEDED;
16198 };
16199 this.transition.cancel = function() { // provide a way for caller to cancel async transition if desired (issue #22)
16200 fsm.transition = null;
16201 StateMachine.afterEvent(fsm, name, from, to, args);
16202 };
16203
16204 var leave = StateMachine.leaveState(this, name, from, to, args);
16205 if (false === leave) {
16206 this.transition = null;
16207 return StateMachine.Result.CANCELLED;
16208 }
16209 else if (StateMachine.ASYNC === leave) {
16210 return StateMachine.Result.PENDING;
16211 }
16212 else {
16213 if (this.transition) // need to check in case user manually called transition() but forgot to return StateMachine.ASYNC
16214 return this.transition();
16215 }
16216
16217 };
16218 }
16219
16220 }; // StateMachine
16221
16222 //===========================================================================
16223
16224 //======
16225 // NODE
16226 //======
16227 {
16228 if (module.exports) {
16229 exports = module.exports = StateMachine;
16230 }
16231 exports.StateMachine = StateMachine;
16232 }
16233
16234 }());
16235 });
16236 var stateMachine_1 = stateMachine.StateMachine;
16237
16238 /** Built-in value references. */
16239 var getPrototype = _overArg(Object.getPrototypeOf, Object);
16240
16241 var _getPrototype = getPrototype;
16242
16243 /** `Object#toString` result references. */
16244 var objectTag$1 = '[object Object]';
16245
16246 /** Used for built-in method references. */
16247 var funcProto = Function.prototype,
16248 objectProto$6 = Object.prototype;
16249
16250 /** Used to resolve the decompiled source of functions. */
16251 var funcToString = funcProto.toString;
16252
16253 /** Used to check objects for own properties. */
16254 var hasOwnProperty$4 = objectProto$6.hasOwnProperty;
16255
16256 /** Used to infer the `Object` constructor. */
16257 var objectCtorString = funcToString.call(Object);
16258
16259 /**
16260 * Checks if `value` is a plain object, that is, an object created by the
16261 * `Object` constructor or one with a `[[Prototype]]` of `null`.
16262 *
16263 * @static
16264 * @memberOf _
16265 * @since 0.8.0
16266 * @category Lang
16267 * @param {*} value The value to check.
16268 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
16269 * @example
16270 *
16271 * function Foo() {
16272 * this.a = 1;
16273 * }
16274 *
16275 * _.isPlainObject(new Foo);
16276 * // => false
16277 *
16278 * _.isPlainObject([1, 2, 3]);
16279 * // => false
16280 *
16281 * _.isPlainObject({ 'x': 0, 'y': 0 });
16282 * // => true
16283 *
16284 * _.isPlainObject(Object.create(null));
16285 * // => true
16286 */
16287 function isPlainObject(value) {
16288 if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag$1) {
16289 return false;
16290 }
16291 var proto = _getPrototype(value);
16292 if (proto === null) {
16293 return true;
16294 }
16295 var Ctor = hasOwnProperty$4.call(proto, 'constructor') && proto.constructor;
16296 return typeof Ctor == 'function' && Ctor instanceof Ctor &&
16297 funcToString.call(Ctor) == objectCtorString;
16298 }
16299
16300 var isPlainObject_1 = isPlainObject;
16301
16302 /* eslint-disable */
16303 var global$1 = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : {};
16304
16305 var EXPIRED = Symbol('expired');
16306 var debug = browser('LC:Expirable');
16307
16308 var Expirable =
16309 /*#__PURE__*/
16310 function () {
16311 function Expirable(value, ttl) {
16312 this.originalValue = value;
16313
16314 if (typeof ttl === 'number') {
16315 this.expiredAt = Date.now() + ttl;
16316 }
16317 }
16318
16319 _createClass(Expirable, [{
16320 key: "value",
16321 get: function get() {
16322 var expired = this.expiredAt && this.expiredAt <= Date.now();
16323 if (expired) debug("expired: ".concat(this.originalValue));
16324 return expired ? EXPIRED : this.originalValue;
16325 }
16326 }]);
16327
16328 return Expirable;
16329 }();
16330 Expirable.EXPIRED = EXPIRED;
16331
16332 var debug$1 = browser('LC:Cache');
16333
16334 var Cache =
16335 /*#__PURE__*/
16336 function () {
16337 function Cache() {
16338 var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'anonymous';
16339 this.name = name;
16340 this._map = {};
16341 }
16342
16343 var _proto = Cache.prototype;
16344
16345 _proto.get = function get(key) {
16346 var cache = this._map[key];
16347
16348 if (cache) {
16349 var value = cache.value;
16350
16351 if (value !== Expirable.EXPIRED) {
16352 debug$1('[%s] hit: %s', this.name, key);
16353 return value;
16354 }
16355
16356 delete this._map[key];
16357 }
16358
16359 debug$1("[".concat(this.name, "] missed: ").concat(key));
16360 return null;
16361 };
16362
16363 _proto.set = function set(key, value, ttl) {
16364 debug$1('[%s] set: %s %d', this.name, key, ttl);
16365 this._map[key] = new Expirable(value, ttl);
16366 };
16367
16368 return Cache;
16369 }();
16370
16371 var debug$2 = {
16372 enable: function enable() {
16373 var namespaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'LC*';
16374 return browser.enable(namespaces);
16375 },
16376 disable: browser.disable
16377 };
16378 var tryAll = function tryAll(promiseConstructors) {
16379 var promise = new Promise(promiseConstructors[0]);
16380
16381 if (promiseConstructors.length === 1) {
16382 return promise;
16383 }
16384
16385 return promise.catch(function () {
16386 return tryAll(promiseConstructors.slice(1));
16387 });
16388 }; // eslint-disable-next-line no-sequences
16389
16390 var tap = function tap(interceptor) {
16391 return function (value) {
16392 return interceptor(value), value;
16393 };
16394 };
16395 var finalize = function finalize(callback) {
16396 return [// eslint-disable-next-line no-sequences
16397 function (value) {
16398 return callback(), value;
16399 }, function (error) {
16400 callback();
16401 throw error;
16402 }];
16403 };
16404 /**
16405 * 将对象转换为 Date,支持 string、number、ProtoBuf Long 以及 LeanCloud 的 Date 类型,
16406 * 其他情况下(包括对象为 falsy)返回原值。
16407 * @private
16408 */
16409
16410 var decodeDate = function decodeDate(date) {
16411 if (!date) return date;
16412
16413 if (typeof date === 'string' || typeof date === 'number') {
16414 return new Date(date);
16415 }
16416
16417 if (date.__type === 'Date' && date.iso) {
16418 return new Date(date.iso);
16419 } // Long
16420
16421
16422 if (typeof date.toNumber === 'function') {
16423 return new Date(date.toNumber());
16424 }
16425
16426 return date;
16427 };
16428 /**
16429 * 获取 Date 的毫秒数,如果不是一个 Date 返回 undefined。
16430 * @private
16431 */
16432
16433 var getTime = function getTime(date) {
16434 return date && date.getTime ? date.getTime() : undefined;
16435 };
16436 /**
16437 * 解码对象中的 LeanCloud 数据结构。
16438 * 目前仅会处理 Date 类型。
16439 * @private
16440 */
16441
16442 var decode = function decode(value) {
16443 if (!value) return value;
16444
16445 if (value.__type === 'Date' && value.iso) {
16446 return new Date(value.iso);
16447 }
16448
16449 if (Array.isArray(value)) {
16450 return value.map(decode);
16451 }
16452
16453 if (isPlainObject_1(value)) {
16454 return Object.keys(value).reduce(function (result, key) {
16455 return _objectSpread({}, result, _defineProperty({}, key, decode(value[key])));
16456 }, {});
16457 }
16458
16459 return value;
16460 };
16461 /**
16462 * 将对象中的特殊类型编码为 LeanCloud 数据结构。
16463 * 目前仅会处理 Date 类型。
16464 * @private
16465 */
16466
16467 var encode = function encode(value) {
16468 if (value instanceof Date) return {
16469 __type: 'Date',
16470 iso: value.toJSON()
16471 };
16472
16473 if (Array.isArray(value)) {
16474 return value.map(encode);
16475 }
16476
16477 if (isPlainObject_1(value)) {
16478 return Object.keys(value).reduce(function (result, key) {
16479 return _objectSpread({}, result, _defineProperty({}, key, encode(value[key])));
16480 }, {});
16481 }
16482
16483 return value;
16484 };
16485 var keyRemap = function keyRemap(keymap, obj) {
16486 return Object.keys(obj).reduce(function (newObj, key) {
16487 var newKey = keymap[key] || key;
16488 return Object.assign(newObj, _defineProperty({}, newKey, obj[key]));
16489 }, {});
16490 };
16491 var isIE10 = global$1.navigator && global$1.navigator.userAgent && global$1.navigator.userAgent.indexOf('MSIE 10.') !== -1;
16492 /* eslint-disable no-proto */
16493
16494 var getStaticProperty = function getStaticProperty(klass, property) {
16495 return klass[property] || (klass.__proto__ ? getStaticProperty(klass.__proto__, property) : undefined);
16496 };
16497 /* eslint-enable no-proto */
16498
16499 var union = function union(a, b) {
16500 return Array.from(new Set([].concat(_toConsumableArray(a), _toConsumableArray(b))));
16501 };
16502 var difference = function difference(a, b) {
16503 return Array.from(function (bSet) {
16504 return new Set(a.filter(function (x) {
16505 return !bSet.has(x);
16506 }));
16507 }(new Set(b)));
16508 };
16509 var map = new WeakMap(); // protected property helper
16510
16511 var internal = function internal(object) {
16512 if (!map.has(object)) {
16513 map.set(object, {});
16514 }
16515
16516 return map.get(object);
16517 };
16518 var compact = function compact(obj, filter) {
16519 if (!isPlainObject_1(obj)) return obj;
16520 var object = Object.assign({}, obj); // eslint-disable-next-line no-restricted-syntax
16521
16522 for (var prop in object) {
16523 if ({}.hasOwnProperty.call(object, prop)) {
16524 var value = object[prop];
16525
16526 if (value === filter) {
16527 delete object[prop];
16528 } else {
16529 object[prop] = compact(value, filter);
16530 }
16531 }
16532 }
16533
16534 return object;
16535 }; // debug utility
16536
16537 var removeNull = function removeNull(obj) {
16538 return compact(obj, null);
16539 };
16540
16541 var trim = function trim(message) {
16542 return removeNull(JSON.parse(JSON.stringify(message)));
16543 };
16544 var ensureArray = function ensureArray(target) {
16545 if (Array.isArray(target)) {
16546 return target;
16547 }
16548
16549 if (target === undefined || target === null) {
16550 return [];
16551 }
16552
16553 return [target];
16554 };
16555 var setValue = function setValue(target, key, value) {
16556 // '.' is not allowed in Class keys, escaping is not in concern now.
16557 var segs = key.split('.');
16558 var lastSeg = segs.pop();
16559 var currentTarget = target;
16560 segs.forEach(function (seg) {
16561 if (currentTarget[seg] === undefined) currentTarget[seg] = {};
16562 currentTarget = currentTarget[seg];
16563 });
16564 currentTarget[lastSeg] = value;
16565 return target;
16566 };
16567 var isWeapp = // eslint-disable-next-line no-undef
16568 (typeof wx === "undefined" ? "undefined" : _typeof(wx)) === 'object' && typeof wx.connectSocket === 'function'; // throttle decorator
16569
16570 var throttle = function throttle(wait) {
16571 return function (target, property, descriptor) {
16572 var callback = descriptor.value; // very naive, internal use only
16573
16574 if (callback.length) {
16575 throw new Error('throttled function should not accept any arguments');
16576 }
16577
16578 return _objectSpread({}, descriptor, {
16579 value: function value() {
16580 var _this = this;
16581
16582 var _internal = internal(this),
16583 throttleMeta = _internal.throttleMeta;
16584
16585 if (!throttleMeta) {
16586 throttleMeta = {};
16587 internal(this).throttleMeta = throttleMeta;
16588 }
16589
16590 var _throttleMeta = throttleMeta,
16591 propertyMeta = _throttleMeta[property];
16592
16593 if (!propertyMeta) {
16594 propertyMeta = {};
16595 throttleMeta[property] = propertyMeta;
16596 }
16597
16598 var _propertyMeta = propertyMeta,
16599 _propertyMeta$previou = _propertyMeta.previouseTimestamp,
16600 previouseTimestamp = _propertyMeta$previou === void 0 ? 0 : _propertyMeta$previou,
16601 timeout = _propertyMeta.timeout;
16602 var now = Date.now();
16603 var remainingTime = wait - (now - previouseTimestamp);
16604
16605 if (remainingTime <= 0) {
16606 throttleMeta[property].previouseTimestamp = now;
16607 callback.apply(this);
16608 } else if (!timeout) {
16609 propertyMeta.timeout = setTimeout(function () {
16610 propertyMeta.previouseTimestamp = Date.now();
16611 delete propertyMeta.timeout;
16612 callback.apply(_this);
16613 }, remainingTime);
16614 }
16615 }
16616 });
16617 };
16618 };
16619 var isCNApp = function isCNApp(appId) {
16620 return appId.slice(-9) !== '-MdYXbMMI';
16621 };
16622
16623 var WebSocket = global$1.WebSocket || global$1.MozWebSocket;
16624
16625 var _class;
16626 var debug$3 = browser('LC:WebSocketPlus');
16627 var OPEN = 'open';
16628 var DISCONNECT = 'disconnect';
16629 var RECONNECT = 'reconnect';
16630 var RETRY = 'retry';
16631 var SCHEDULE = 'schedule';
16632 var OFFLINE = 'offline';
16633 var ONLINE = 'online';
16634 var ERROR = 'error';
16635 var MESSAGE = 'message';
16636 var HEARTBEAT_TIME = 180000;
16637 var TIMEOUT_TIME = 380000;
16638
16639 var DEFAULT_RETRY_STRATEGY = function DEFAULT_RETRY_STRATEGY(attempt) {
16640 return Math.min(1000 * Math.pow(2, attempt), 300000);
16641 };
16642
16643 var requireConnected = function requireConnected(target, name, descriptor) {
16644 return Object.assign({}, descriptor, {
16645 value: function requireConnectedWrapper() {
16646 var _descriptor$value;
16647
16648 this.checkConnectionAvailability(name);
16649
16650 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
16651 args[_key] = arguments[_key];
16652 }
16653
16654 return (_descriptor$value = descriptor.value).call.apply(_descriptor$value, [this].concat(args));
16655 }
16656 });
16657 };
16658
16659 var WebSocketPlus = (_class =
16660 /*#__PURE__*/
16661 function (_EventEmitter) {
16662 _inheritsLoose(WebSocketPlus, _EventEmitter);
16663
16664 _createClass(WebSocketPlus, [{
16665 key: "urls",
16666 get: function get() {
16667 return this._urls;
16668 },
16669 set: function set(urls) {
16670 this._urls = ensureArray(urls);
16671 }
16672 }]);
16673
16674 function WebSocketPlus(getUrls, protocol) {
16675 var _this;
16676
16677 if (typeof WebSocket === 'undefined') {
16678 throw new Error('WebSocket is undefined. Polyfill is required in this runtime.');
16679 }
16680
16681 _this = _EventEmitter.call(this) || this;
16682
16683 _this.init();
16684
16685 _this._protocol = protocol;
16686 Promise.resolve(typeof getUrls === 'function' ? getUrls() : getUrls).then(ensureArray).then(function (urls) {
16687 _this._urls = urls;
16688 return _this._open();
16689 }).then(function () {
16690 _this.__postponeTimeoutTimer = _this._postponeTimeoutTimer.bind(_assertThisInitialized(_this));
16691
16692 if (global$1.addEventListener) {
16693 _this.__pause = function () {
16694 if (_this.can('pause')) _this.pause();
16695 };
16696
16697 _this.__resume = function () {
16698 if (_this.can('resume')) _this.resume();
16699 };
16700
16701 global$1.addEventListener('offline', _this.__pause);
16702 global$1.addEventListener('online', _this.__resume);
16703 }
16704
16705 _this.open();
16706 }).catch(_this.throw.bind(_assertThisInitialized(_this)));
16707 return _this;
16708 }
16709
16710 var _proto = WebSocketPlus.prototype;
16711
16712 _proto._open = function _open() {
16713 var _this2 = this;
16714
16715 return this._createWs(this._urls, this._protocol).then(function (ws) {
16716 var _this2$_urls = _toArray(_this2._urls),
16717 first = _this2$_urls[0],
16718 reset = _this2$_urls.slice(1);
16719
16720 _this2._urls = [].concat(_toConsumableArray(reset), [first]);
16721 return ws;
16722 });
16723 };
16724
16725 _proto._createWs = function _createWs(urls, protocol) {
16726 var _this3 = this;
16727
16728 return tryAll(urls.map(function (url) {
16729 return function (resolve, reject) {
16730 debug$3("connect [".concat(url, "] ").concat(protocol));
16731 var ws = protocol ? new WebSocket(url, protocol) : new WebSocket(url);
16732 ws.binaryType = _this3.binaryType || 'arraybuffer';
16733
16734 ws.onopen = function () {
16735 return resolve(ws);
16736 };
16737
16738 ws.onclose = function (error) {
16739 if (error instanceof Error) {
16740 return reject(error);
16741 } // in browser, error event is useless
16742
16743
16744 return reject(new Error("Failed to connect [".concat(url, "]")));
16745 };
16746
16747 ws.onerror = ws.onclose;
16748 };
16749 })).then(function (ws) {
16750 _this3._ws = ws;
16751 _this3._ws.onclose = _this3._handleClose.bind(_this3);
16752 _this3._ws.onmessage = _this3._handleMessage.bind(_this3);
16753 return ws;
16754 });
16755 };
16756
16757 _proto._destroyWs = function _destroyWs() {
16758 var ws = this._ws;
16759 if (!ws) return;
16760 ws.onopen = null;
16761 ws.onclose = null;
16762 ws.onerror = null;
16763 ws.onmessage = null;
16764 this._ws = null;
16765 ws.close();
16766 } // eslint-disable-next-line class-methods-use-this
16767 ;
16768
16769 _proto.onbeforeevent = function onbeforeevent(event, from, to) {
16770 for (var _len2 = arguments.length, payload = new Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {
16771 payload[_key2 - 3] = arguments[_key2];
16772 }
16773
16774 debug$3("".concat(event, ": ").concat(from, " -> ").concat(to, " %o"), payload);
16775 };
16776
16777 _proto.onopen = function onopen() {
16778 this.emit(OPEN);
16779 };
16780
16781 _proto.onconnected = function onconnected() {
16782 this._startConnectionKeeper();
16783 };
16784
16785 _proto.onleaveconnected = function onleaveconnected(event, from, to) {
16786 this._stopConnectionKeeper();
16787
16788 this._destroyWs();
16789
16790 if (to === 'offline' || to === 'disconnected') {
16791 this.emit(DISCONNECT);
16792 }
16793 };
16794
16795 _proto.onpause = function onpause() {
16796 this.emit(OFFLINE);
16797 };
16798
16799 _proto.onbeforeresume = function onbeforeresume() {
16800 this.emit(ONLINE);
16801 };
16802
16803 _proto.onreconnect = function onreconnect() {
16804 this.emit(RECONNECT);
16805 };
16806
16807 _proto.ondisconnected = function ondisconnected(event, from, to) {
16808 var _this4 = this;
16809
16810 var attempt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
16811 var delay = DEFAULT_RETRY_STRATEGY.call(null, attempt);
16812 debug$3("schedule attempt=".concat(attempt, " delay=").concat(delay));
16813 this.emit(SCHEDULE, attempt, delay);
16814
16815 if (this.__scheduledRetry) {
16816 clearTimeout(this.__scheduledRetry);
16817 }
16818
16819 this.__scheduledRetry = setTimeout(function () {
16820 if (_this4.is('disconnected')) {
16821 _this4.retry(attempt);
16822 }
16823 }, delay);
16824 };
16825
16826 _proto.onretry = function onretry(event, from, to) {
16827 var _this5 = this;
16828
16829 var attempt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
16830 this.emit(RETRY, attempt);
16831
16832 this._open().then(function () {
16833 return _this5.can('reconnect') ? _this5.reconnect() : _this5._destroyWs();
16834 }, function () {
16835 return _this5.can('fail') && _this5.fail(attempt + 1);
16836 });
16837 };
16838
16839 _proto.onerror = function onerror(event, from, to, error) {
16840 this.emit(ERROR, error);
16841 };
16842
16843 _proto.onclose = function onclose() {
16844 if (global$1.removeEventListener) {
16845 if (this.__pause) global$1.removeEventListener('offline', this.__pause);
16846 if (this.__resume) global$1.removeEventListener('online', this.__resume);
16847 }
16848 };
16849
16850 _proto.checkConnectionAvailability = function checkConnectionAvailability() {
16851 var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'API';
16852
16853 if (!this.is('connected')) {
16854 var currentState = this.current;
16855 console.warn("".concat(name, " should not be called when the connection is ").concat(currentState));
16856
16857 if (this.is('disconnected') || this.is('reconnecting')) {
16858 console.warn('disconnect and reconnect event should be handled to avoid such calls.');
16859 }
16860
16861 throw new Error('Connection unavailable');
16862 }
16863 } // jsdoc-ignore-start
16864 ;
16865
16866 _proto. // jsdoc-ignore-end
16867 _ping = function _ping() {
16868 debug$3('ping');
16869
16870 try {
16871 this.ping();
16872 } catch (error) {
16873 console.warn("websocket ping error: ".concat(error.message));
16874 }
16875 };
16876
16877 _proto.ping = function ping() {
16878 if (this._ws.ping) {
16879 this._ws.ping();
16880 } else {
16881 console.warn("The WebSocket implement does not support sending ping frame.\n Override ping method to use application defined ping/pong mechanism.");
16882 }
16883 };
16884
16885 _proto._postponeTimeoutTimer = function _postponeTimeoutTimer() {
16886 var _this6 = this;
16887
16888 debug$3('_postponeTimeoutTimer');
16889
16890 this._clearTimeoutTimers();
16891
16892 this._timeoutTimer = setTimeout(function () {
16893 debug$3('timeout');
16894
16895 _this6.disconnect();
16896 }, TIMEOUT_TIME);
16897 };
16898
16899 _proto._clearTimeoutTimers = function _clearTimeoutTimers() {
16900 if (this._timeoutTimer) {
16901 clearTimeout(this._timeoutTimer);
16902 }
16903 };
16904
16905 _proto._startConnectionKeeper = function _startConnectionKeeper() {
16906 debug$3('start connection keeper');
16907 this._heartbeatTimer = setInterval(this._ping.bind(this), HEARTBEAT_TIME);
16908 var addListener = this._ws.addListener || this._ws.addEventListener;
16909
16910 if (!addListener) {
16911 debug$3('connection keeper disabled due to the lack of #addEventListener.');
16912 return;
16913 }
16914
16915 addListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
16916 addListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
16917
16918 this._postponeTimeoutTimer();
16919 };
16920
16921 _proto._stopConnectionKeeper = function _stopConnectionKeeper() {
16922 debug$3('stop connection keeper'); // websockets/ws#489
16923
16924 var removeListener = this._ws.removeListener || this._ws.removeEventListener;
16925
16926 if (removeListener) {
16927 removeListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
16928 removeListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
16929
16930 this._clearTimeoutTimers();
16931 }
16932
16933 if (this._heartbeatTimer) {
16934 clearInterval(this._heartbeatTimer);
16935 }
16936 };
16937
16938 _proto._handleClose = function _handleClose(event) {
16939 debug$3("ws closed [".concat(event.code, "] ").concat(event.reason)); // socket closed manually, ignore close event.
16940
16941 if (this.isFinished()) return;
16942 this.handleClose(event);
16943 };
16944
16945 _proto.handleClose = function handleClose() {
16946 // reconnect
16947 this.disconnect();
16948 } // jsdoc-ignore-start
16949 ;
16950
16951 _proto. // jsdoc-ignore-end
16952 send = function send(data) {
16953 debug$3('send', data);
16954
16955 this._ws.send(data);
16956 };
16957
16958 _proto._handleMessage = function _handleMessage(event) {
16959 debug$3('message', event.data);
16960 this.handleMessage(event.data);
16961 };
16962
16963 _proto.handleMessage = function handleMessage(message) {
16964 this.emit(MESSAGE, message);
16965 };
16966
16967 return WebSocketPlus;
16968 }(eventemitter3), (_applyDecoratedDescriptor(_class.prototype, "_ping", [requireConnected], Object.getOwnPropertyDescriptor(_class.prototype, "_ping"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "send", [requireConnected], Object.getOwnPropertyDescriptor(_class.prototype, "send"), _class.prototype)), _class);
16969 stateMachine.create({
16970 target: WebSocketPlus.prototype,
16971 initial: {
16972 state: 'initialized',
16973 event: 'init',
16974 defer: true
16975 },
16976 terminal: 'closed',
16977 events: [{
16978 name: 'open',
16979 from: 'initialized',
16980 to: 'connected'
16981 }, {
16982 name: 'disconnect',
16983 from: 'connected',
16984 to: 'disconnected'
16985 }, {
16986 name: 'retry',
16987 from: 'disconnected',
16988 to: 'reconnecting'
16989 }, {
16990 name: 'fail',
16991 from: 'reconnecting',
16992 to: 'disconnected'
16993 }, {
16994 name: 'reconnect',
16995 from: 'reconnecting',
16996 to: 'connected'
16997 }, {
16998 name: 'pause',
16999 from: ['connected', 'disconnected', 'reconnecting'],
17000 to: 'offline'
17001 }, {}, {
17002 name: 'resume',
17003 from: 'offline',
17004 to: 'disconnected'
17005 }, {
17006 name: 'close',
17007 from: ['connected', 'disconnected', 'reconnecting', 'offline'],
17008 to: 'closed'
17009 }, {
17010 name: 'throw',
17011 from: '*',
17012 to: 'error'
17013 }]
17014 });
17015
17016 var error = Object.freeze({
17017 1000: {
17018 name: 'CLOSE_NORMAL'
17019 },
17020 1006: {
17021 name: 'CLOSE_ABNORMAL'
17022 },
17023 4100: {
17024 name: 'APP_NOT_AVAILABLE',
17025 message: 'App not exists or realtime message service is disabled.'
17026 },
17027 4102: {
17028 name: 'SIGNATURE_FAILED',
17029 message: 'Login signature mismatch.'
17030 },
17031 4103: {
17032 name: 'INVALID_LOGIN',
17033 message: 'Malformed clientId.'
17034 },
17035 4105: {
17036 name: 'SESSION_REQUIRED',
17037 message: 'Message sent before session opened.'
17038 },
17039 4107: {
17040 name: 'READ_TIMEOUT'
17041 },
17042 4108: {
17043 name: 'LOGIN_TIMEOUT'
17044 },
17045 4109: {
17046 name: 'FRAME_TOO_LONG'
17047 },
17048 4110: {
17049 name: 'INVALID_ORIGIN',
17050 message: 'Access denied by domain whitelist.'
17051 },
17052 4111: {
17053 name: 'SESSION_CONFLICT'
17054 },
17055 4112: {
17056 name: 'SESSION_TOKEN_EXPIRED'
17057 },
17058 4113: {
17059 name: 'APP_QUOTA_EXCEEDED',
17060 message: 'The daily active users limit exceeded.'
17061 },
17062 4116: {
17063 name: 'MESSAGE_SENT_QUOTA_EXCEEDED',
17064 message: 'Command sent too fast.'
17065 },
17066 4200: {
17067 name: 'INTERNAL_ERROR',
17068 message: 'Internal error, please contact LeanCloud for support.'
17069 },
17070 4301: {
17071 name: 'CONVERSATION_API_FAILED',
17072 message: 'Upstream Conversatoin API failed, see error.detail for details.'
17073 },
17074 4302: {
17075 name: 'CONVERSATION_SIGNATURE_FAILED',
17076 message: 'Conversation action signature mismatch.'
17077 },
17078 4303: {
17079 name: 'CONVERSATION_NOT_FOUND'
17080 },
17081 4304: {
17082 name: 'CONVERSATION_FULL'
17083 },
17084 4305: {
17085 name: 'CONVERSATION_REJECTED_BY_APP',
17086 message: 'Conversation action rejected by hook.'
17087 },
17088 4306: {
17089 name: 'CONVERSATION_UPDATE_FAILED'
17090 },
17091 4307: {
17092 name: 'CONVERSATION_READ_ONLY'
17093 },
17094 4308: {
17095 name: 'CONVERSATION_NOT_ALLOWED'
17096 },
17097 4309: {
17098 name: 'CONVERSATION_UPDATE_REJECTED',
17099 message: 'Conversation update rejected because the client is not a member.'
17100 },
17101 4310: {
17102 name: 'CONVERSATION_QUERY_FAILED',
17103 message: 'Conversation query failed because it is too expansive.'
17104 },
17105 4311: {
17106 name: 'CONVERSATION_LOG_FAILED'
17107 },
17108 4312: {
17109 name: 'CONVERSATION_LOG_REJECTED',
17110 message: 'Message query rejected because the client is not a member of the conversation.'
17111 },
17112 4313: {
17113 name: 'SYSTEM_CONVERSATION_REQUIRED'
17114 },
17115 4314: {
17116 name: 'NORMAL_CONVERSATION_REQUIRED'
17117 },
17118 4315: {
17119 name: 'CONVERSATION_BLACKLISTED',
17120 message: 'Blacklisted in the conversation.'
17121 },
17122 4316: {
17123 name: 'TRANSIENT_CONVERSATION_REQUIRED'
17124 },
17125 4317: {
17126 name: 'CONVERSATION_MEMBERSHIP_REQUIRED'
17127 },
17128 4318: {
17129 name: 'CONVERSATION_API_QUOTA_EXCEEDED',
17130 message: 'LeanCloud API quota exceeded. You may upgrade your plan.'
17131 },
17132 4323: {
17133 name: 'TEMPORARY_CONVERSATION_EXPIRED',
17134 message: 'Temporary conversation expired or does not exist.'
17135 },
17136 4401: {
17137 name: 'INVALID_MESSAGING_TARGET',
17138 message: 'Conversation does not exist or client is not a member.'
17139 },
17140 4402: {
17141 name: 'MESSAGE_REJECTED_BY_APP',
17142 message: 'Message rejected by hook.'
17143 },
17144 4403: {
17145 name: 'MESSAGE_OWNERSHIP_REQUIRED'
17146 },
17147 4404: {
17148 name: 'MESSAGE_NOT_FOUND'
17149 },
17150 4405: {
17151 name: 'MESSAGE_UPDATE_REJECTED_BY_APP',
17152 message: 'Message update rejected by hook.'
17153 },
17154 4406: {
17155 name: 'MESSAGE_EDIT_DISABLED'
17156 },
17157 4407: {
17158 name: 'MESSAGE_RECALL_DISABLED'
17159 },
17160 5130: {
17161 name: 'OWNER_PROMOTION_NOT_ALLOWED',
17162 message: "Updating a member's role to owner is not allowed."
17163 }
17164 });
17165 var ErrorCode = Object.freeze(Object.keys(error).reduce(function (result, code) {
17166 return Object.assign(result, _defineProperty({}, error[code].name, Number(code)));
17167 }, {}));
17168 var createError = function createError(_ref) {
17169 var code = _ref.code,
17170 reason = _ref.reason,
17171 appCode = _ref.appCode,
17172 detail = _ref.detail,
17173 errorMessage = _ref.error;
17174 var message = reason || detail || errorMessage;
17175 var name = reason;
17176
17177 if (!message && error[code]) {
17178 name = error[code].name;
17179 message = error[code].message || name;
17180 }
17181
17182 if (!message) {
17183 message = "Unknow Error: ".concat(code);
17184 }
17185
17186 var err = new Error(message);
17187 return Object.assign(err, {
17188 code: code,
17189 appCode: appCode,
17190 detail: detail,
17191 name: name
17192 });
17193 };
17194
17195 var debug$4 = browser('LC:Connection');
17196 var COMMAND_TIMEOUT = 20000;
17197 var EXPIRE = Symbol('expire');
17198
17199 var Connection =
17200 /*#__PURE__*/
17201 function (_WebSocketPlus) {
17202 _inheritsLoose(Connection, _WebSocketPlus);
17203
17204 function Connection(getUrl, _ref) {
17205 var _this;
17206
17207 var format = _ref.format,
17208 version = _ref.version;
17209 debug$4('initializing Connection');
17210 var protocolString = "lc.".concat(format, ".").concat(version);
17211
17212 if (!isWeapp) {
17213 _this = _WebSocketPlus.call(this, getUrl, protocolString) || this;
17214 } else {
17215 _this = _WebSocketPlus.call(this, getUrl().then(function (urls) {
17216 return urls.map(function (url) {
17217 return "".concat(url).concat(url.indexOf('?') === -1 ? '?' : '&', "subprotocol=").concat(encodeURIComponent(protocolString));
17218 });
17219 })) || this;
17220 }
17221
17222 _this._protocalFormat = format;
17223 _this._commands = {};
17224 _this._serialId = 0;
17225 return _assertThisInitialized(_this);
17226 }
17227
17228 var _proto = Connection.prototype;
17229
17230 _proto.send =
17231 /*#__PURE__*/
17232 function () {
17233 var _send = _asyncToGenerator(
17234 /*#__PURE__*/
17235 regenerator.mark(function _callee(command) {
17236 var _this2 = this;
17237
17238 var waitingForRespond,
17239 serialId,
17240 message,
17241 _args = arguments;
17242 return regenerator.wrap(function _callee$(_context) {
17243 while (1) {
17244 switch (_context.prev = _context.next) {
17245 case 0:
17246 waitingForRespond = _args.length > 1 && _args[1] !== undefined ? _args[1] : true;
17247
17248 if (waitingForRespond) {
17249 this._serialId += 1;
17250 serialId = this._serialId;
17251 command.i = serialId; // eslint-disable-line no-param-reassign
17252 }
17253
17254 if (debug$4.enabled) debug$4('↑ %O sent', trim(command));
17255
17256 if (this._protocalFormat === 'proto2base64') {
17257 message = command.toBase64();
17258 } else if (command.toArrayBuffer) {
17259 message = command.toArrayBuffer();
17260 }
17261
17262 if (message) {
17263 _context.next = 6;
17264 break;
17265 }
17266
17267 throw new TypeError("".concat(command, " is not a GenericCommand"));
17268
17269 case 6:
17270 _WebSocketPlus.prototype.send.call(this, message);
17271
17272 if (waitingForRespond) {
17273 _context.next = 9;
17274 break;
17275 }
17276
17277 return _context.abrupt("return", undefined);
17278
17279 case 9:
17280 return _context.abrupt("return", new Promise(function (resolve, reject) {
17281 _this2._commands[serialId] = {
17282 resolve: resolve,
17283 reject: reject,
17284 timeout: setTimeout(function () {
17285 if (_this2._commands[serialId]) {
17286 if (debug$4.enabled) debug$4('✗ %O timeout', trim(command));
17287 reject(createError({
17288 error: "Command Timeout [cmd:".concat(command.cmd, " op:").concat(command.op, "]"),
17289 name: 'COMMAND_TIMEOUT'
17290 }));
17291 delete _this2._commands[serialId];
17292 }
17293 }, COMMAND_TIMEOUT)
17294 };
17295 }));
17296
17297 case 10:
17298 case "end":
17299 return _context.stop();
17300 }
17301 }
17302 }, _callee, this);
17303 }));
17304
17305 function send(_x) {
17306 return _send.apply(this, arguments);
17307 }
17308
17309 return send;
17310 }();
17311
17312 _proto.handleMessage = function handleMessage(msg) {
17313 var message;
17314
17315 try {
17316 message = GenericCommand.decode(msg);
17317 if (debug$4.enabled) debug$4('↓ %O received', trim(message));
17318 } catch (e) {
17319 console.warn('Decode message failed:', e.message, msg);
17320 return;
17321 }
17322
17323 var serialId = message.i;
17324
17325 if (serialId) {
17326 if (this._commands[serialId]) {
17327 clearTimeout(this._commands[serialId].timeout);
17328
17329 if (message.cmd === CommandType.error) {
17330 this._commands[serialId].reject(createError(message.errorMessage));
17331 } else {
17332 this._commands[serialId].resolve(message);
17333 }
17334
17335 delete this._commands[serialId];
17336 } else {
17337 console.warn("Unexpected command received with serialId [".concat(serialId, "],\n which have timed out or never been requested."));
17338 }
17339 } else {
17340 switch (message.cmd) {
17341 case CommandType.error:
17342 {
17343 this.emit(ERROR, createError(message.errorMessage));
17344 return;
17345 }
17346
17347 case CommandType.goaway:
17348 {
17349 this.emit(EXPIRE);
17350 return;
17351 }
17352
17353 default:
17354 {
17355 this.emit(MESSAGE, message);
17356 }
17357 }
17358 }
17359 };
17360
17361 _proto.ping = function ping() {
17362 return this.send(new GenericCommand({
17363 cmd: CommandType.echo
17364 })).catch(function (error) {
17365 return debug$4('ping failed:', error);
17366 });
17367 };
17368
17369 return Connection;
17370 }(WebSocketPlus);
17371
17372 var checkType = function checkType(middleware) {
17373 return function (param) {
17374 var constructor = param.constructor;
17375 return Promise.resolve(param).then(middleware).then(tap(function (result) {
17376 if (result === undefined || result === null) {
17377 // eslint-disable-next-line max-len
17378 return console.warn("Middleware[".concat(middleware._pluginName || 'anonymous plugin', ":").concat(middleware.name || 'anonymous middleware', "] param/return types not match. It returns ").concat(result, " while a ").concat(param.constructor.name, " expected."));
17379 }
17380
17381 if (!(result instanceof constructor)) {
17382 // eslint-disable-next-line max-len
17383 return console.warn("Middleware[".concat(middleware._pluginName || 'anonymous plugin', ":").concat(middleware.name || 'anonymous middleware', "] param/return types not match. It returns a ").concat(result.constructor.name, " while a ").concat(param.constructor.name, " expected."));
17384 }
17385
17386 return 0;
17387 }));
17388 };
17389 };
17390
17391 var applyDecorators = function applyDecorators(decorators, target) {
17392 if (decorators) {
17393 decorators.forEach(function (decorator) {
17394 try {
17395 decorator(target);
17396 } catch (error) {
17397 if (decorator._pluginName) {
17398 error.message += "[".concat(decorator._pluginName, "]");
17399 }
17400
17401 throw error;
17402 }
17403 });
17404 }
17405 };
17406 var applyMiddlewares = function applyMiddlewares(middlewares) {
17407 return function (target) {
17408 return ensureArray(middlewares).reduce(function (previousPromise, middleware) {
17409 return previousPromise.then(checkType(middleware)).catch(function (error) {
17410 if (middleware._pluginName) {
17411 // eslint-disable-next-line no-param-reassign
17412 error.message += "[".concat(middleware._pluginName, "]");
17413 }
17414
17415 throw error;
17416 });
17417 }, Promise.resolve(target));
17418 };
17419 };
17420 var applyDispatcher = function applyDispatcher(dispatchers, payload) {
17421 return ensureArray(dispatchers).reduce(function (resultPromise, dispatcher) {
17422 return resultPromise.then(function (shouldDispatch) {
17423 return shouldDispatch === false ? false : dispatcher.apply(void 0, _toConsumableArray(payload));
17424 }).catch(function (error) {
17425 if (dispatcher._pluginName) {
17426 // eslint-disable-next-line no-param-reassign
17427 error.message += "[".concat(dispatcher._pluginName, "]");
17428 }
17429
17430 throw error;
17431 });
17432 }, Promise.resolve(true));
17433 };
17434
17435 var version = "5.0.0-beta.0";
17436
17437 var debug$5 = browser('LC:Realtime');
17438 var debugRequest = browser('LC:request');
17439 var routerCache = new Cache('push-router');
17440
17441 var Realtime =
17442 /*#__PURE__*/
17443 function (_EventEmitter) {
17444 _inheritsLoose(Realtime, _EventEmitter);
17445
17446 /**
17447 * @extends EventEmitter
17448 * @param {Object} options
17449 * @param {String} options.appId
17450 * @param {String} options.appKey (since 4.0.0)
17451 * @param {String|Object} [options.server] 指定服务器域名,中国节点应用此参数必填(since 4.0.0)
17452 * @param {Boolean} [options.pushOfflineMessages=false] 启用推送离线消息模式(默认为发送未读消息通知模式)
17453 * @param {Boolean} [options.noBinary=false] 设置 WebSocket 使用字符串格式收发消息(默认为二进制格式)。
17454 * 适用于 WebSocket 实现不支持二进制数据格式的情况
17455 * @param {Boolean} [options.ssl=true] 使用 wss 进行连接
17456 * @param {String|String[]} [options.RTMServers] 指定私有部署的 RTM 服务器地址(since 4.0.0)
17457 * @param {Plugin[]} [options.plugins] 加载插件(since 3.1.0)
17458 */
17459 function Realtime(_ref) {
17460 var _this2;
17461
17462 var plugins = _ref.plugins,
17463 options = _objectWithoutProperties(_ref, ["plugins"]);
17464
17465 debug$5('initializing Realtime %s %O', version, options);
17466 _this2 = _EventEmitter.call(this) || this;
17467
17468 if (typeof options.appId !== 'string') {
17469 throw new TypeError("appId [".concat(options.appId, "] is not a string"));
17470 }
17471
17472 if (typeof options.appKey !== 'string') {
17473 throw new TypeError("appKey [".concat(options.appKey, "] is not a string"));
17474 }
17475
17476 if (isCNApp(options.appId)) {
17477 if (!options.server) {
17478 throw new TypeError("server option is required for apps from CN region");
17479 }
17480 }
17481
17482 _this2._options = Object.assign({
17483 appId: undefined,
17484 appKey: undefined,
17485 pushOfflineMessages: false,
17486 noBinary: false,
17487 ssl: true,
17488 RTMServerName: process.env.RTM_SERVER_NAME // undocumented on purpose, internal use only
17489
17490 }, options);
17491 _this2._cache = new Cache('endpoints');
17492
17493 var _this = internal(_assertThisInitialized(_this2));
17494
17495 _this.clients = new Set();
17496 _this.pendingClients = new Set();
17497 var mergedPlugins = [].concat(_toConsumableArray(ensureArray(Realtime.__preRegisteredPlugins)), _toConsumableArray(ensureArray(plugins)));
17498 debug$5('Using plugins %o', mergedPlugins.map(function (plugin) {
17499 return plugin.name;
17500 }));
17501 _this2._plugins = mergedPlugins.reduce(function (result, plugin) {
17502 // eslint-disable-next-line no-restricted-syntax
17503 for (var hook in plugin) {
17504 if ({}.hasOwnProperty.call(plugin, hook) && hook !== 'name') {
17505 if (plugin.name) {
17506 ensureArray(plugin[hook]).forEach(function (value) {
17507 // eslint-disable-next-line no-param-reassign
17508 value._pluginName = plugin.name;
17509 });
17510 } // eslint-disable-next-line no-param-reassign
17511
17512
17513 result[hook] = ensureArray(result[hook]).concat(plugin[hook]);
17514 }
17515 }
17516
17517 return result;
17518 }, {}); // onRealtimeCreate hook
17519
17520 applyDecorators(_this2._plugins.onRealtimeCreate, _assertThisInitialized(_this2));
17521 return _this2;
17522 }
17523
17524 var _proto = Realtime.prototype;
17525
17526 _proto._request =
17527 /*#__PURE__*/
17528 function () {
17529 var _request2 = _asyncToGenerator(
17530 /*#__PURE__*/
17531 regenerator.mark(function _callee(_ref2) {
17532 var method, _ref2$version, version, path, query, headers, _ref2$data, data, _this$_options, appId, server, _ref3, api, url;
17533
17534 return regenerator.wrap(function _callee$(_context) {
17535 while (1) {
17536 switch (_context.prev = _context.next) {
17537 case 0:
17538 method = _ref2.method, _ref2$version = _ref2.version, version = _ref2$version === void 0 ? '1.1' : _ref2$version, path = _ref2.path, query = _ref2.query, headers = _ref2.headers, _ref2$data = _ref2.data, data = _ref2$data === void 0 ? {} : _ref2$data;
17539 _this$_options = this._options, appId = _this$_options.appId, server = _this$_options.server;
17540 _context.next = 4;
17541 return this.constructor._getServerUrls({
17542 appId: appId,
17543 server: server
17544 });
17545
17546 case 4:
17547 _ref3 = _context.sent;
17548 api = _ref3.api;
17549 url = "".concat(api, "/").concat(version).concat(path);
17550 debugRequest('Req: %O %O %O', method, url, {
17551 query: query,
17552 headers: headers,
17553 data: data
17554 });
17555 return _context.abrupt("return", client(method, url).set(_objectSpread({
17556 'X-LC-Id': this._options.appId,
17557 'X-LC-Key': this._options.appKey
17558 }, headers)).query(query).send(data).then(function (response) {
17559 debugRequest('Res: %O %O %O', url, response.status, response.body);
17560 return response.body;
17561 }, function (error) {
17562 debugRequest('Error: %O %O %O', url, error.response.status, error.response.body);
17563
17564 if (error.response && error.response.body && error.response.body.code) {
17565 throw createError(error.response.body);
17566 }
17567
17568 throw error;
17569 }));
17570
17571 case 9:
17572 case "end":
17573 return _context.stop();
17574 }
17575 }
17576 }, _callee, this);
17577 }));
17578
17579 function _request(_x) {
17580 return _request2.apply(this, arguments);
17581 }
17582
17583 return _request;
17584 }();
17585
17586 _proto._open = function _open() {
17587 var _this3 = this;
17588
17589 if (this._openPromise) return this._openPromise;
17590 var format = 'protobuf2';
17591
17592 if (this._options.noBinary) {
17593 // 不发送 binary data,fallback to base64 string
17594 format = 'proto2base64';
17595 }
17596
17597 var version = 3;
17598
17599 if (this._options.pushOfflineMessages) {
17600 // 不推送离线消息,而是发送对话的未读通知
17601 version = 1;
17602 }
17603
17604 var protocol = {
17605 format: format,
17606 version: version
17607 };
17608 this._openPromise = new Promise(function (resolve, reject) {
17609 debug$5('No connection established, create a new one.');
17610 var connection = new Connection(function () {
17611 return _this3._getRTMServers(_this3._options);
17612 }, protocol);
17613 connection.on(OPEN, function () {
17614 return resolve(connection);
17615 }).on(ERROR, reject).on(EXPIRE,
17616 /*#__PURE__*/
17617 _asyncToGenerator(
17618 /*#__PURE__*/
17619 regenerator.mark(function _callee2() {
17620 return regenerator.wrap(function _callee2$(_context2) {
17621 while (1) {
17622 switch (_context2.prev = _context2.next) {
17623 case 0:
17624 debug$5('Connection expired. Refresh endpoints.');
17625
17626 _this3._cache.set('endpoints', null, 0);
17627
17628 _context2.next = 4;
17629 return _this3._getRTMServers(_this3._options);
17630
17631 case 4:
17632 connection.urls = _context2.sent;
17633 connection.disconnect();
17634
17635 case 6:
17636 case "end":
17637 return _context2.stop();
17638 }
17639 }
17640 }, _callee2, this);
17641 }))).on(MESSAGE, _this3._dispatchCommand.bind(_this3));
17642 /**
17643 * 连接断开。
17644 * 连接断开可能是因为 SDK 进入了离线状态(see {@link Realtime#event:OFFLINE}),或长时间没有收到服务器心跳。
17645 * 连接断开后所有的网络操作都会失败,请在连接断开后禁用相关的 UI 元素。
17646 * @event Realtime#DISCONNECT
17647 */
17648
17649 /**
17650 * 计划在一段时间后尝试重新连接
17651 * @event Realtime#SCHEDULE
17652 * @param {Number} attempt 尝试重连的次数
17653 * @param {Number} delay 延迟的毫秒数
17654 */
17655
17656 /**
17657 * 正在尝试重新连接
17658 * @event Realtime#RETRY
17659 * @param {Number} attempt 尝试重连的次数
17660 */
17661
17662 /**
17663 * 连接恢复正常。
17664 * 请重新启用在 {@link Realtime#event:DISCONNECT} 事件中禁用的相关 UI 元素
17665 * @event Realtime#RECONNECT
17666 */
17667
17668 /**
17669 * 客户端连接断开
17670 * @event IMClient#DISCONNECT
17671 * @see Realtime#event:DISCONNECT
17672 * @since 3.2.0
17673 */
17674
17675 /**
17676 * 计划在一段时间后尝试重新连接
17677 * @event IMClient#SCHEDULE
17678 * @param {Number} attempt 尝试重连的次数
17679 * @param {Number} delay 延迟的毫秒数
17680 * @since 3.2.0
17681 */
17682
17683 /**
17684 * 正在尝试重新连接
17685 * @event IMClient#RETRY
17686 * @param {Number} attempt 尝试重连的次数
17687 * @since 3.2.0
17688 */
17689
17690 /**
17691 * 客户端进入离线状态。
17692 * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
17693 * @event Realtime#OFFLINE
17694 * @since 3.4.0
17695 */
17696
17697 /**
17698 * 客户端恢复在线状态
17699 * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
17700 * @event Realtime#ONLINE
17701 * @since 3.4.0
17702 */
17703
17704 /**
17705 * 进入离线状态。
17706 * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
17707 * @event IMClient#OFFLINE
17708 * @since 3.4.0
17709 */
17710
17711 /**
17712 * 恢复在线状态
17713 * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
17714 * @event IMClient#ONLINE
17715 * @since 3.4.0
17716 */
17717 // event proxy
17718
17719 [DISCONNECT, RECONNECT, RETRY, SCHEDULE, OFFLINE, ONLINE].forEach(function (event) {
17720 return connection.on(event, function () {
17721 for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) {
17722 payload[_key] = arguments[_key];
17723 }
17724
17725 debug$5("".concat(event, " event emitted. %o"), payload);
17726
17727 _this3.emit.apply(_this3, [event].concat(payload));
17728
17729 if (event !== RECONNECT) {
17730 internal(_this3).clients.forEach(function (client) {
17731 client.emit.apply(client, [event].concat(payload));
17732 });
17733 }
17734 });
17735 }); // override handleClose
17736
17737 connection.handleClose = function handleClose(event) {
17738 var isFatal = [ErrorCode.APP_NOT_AVAILABLE, ErrorCode.INVALID_LOGIN, ErrorCode.INVALID_ORIGIN].some(function (errorCode) {
17739 return errorCode === event.code;
17740 });
17741
17742 if (isFatal) {
17743 // in these cases, SDK should throw.
17744 this.throw(createError(event));
17745 } else {
17746 // reconnect
17747 this.disconnect();
17748 }
17749 };
17750
17751 internal(_this3).connection = connection;
17752 });
17753 return this._openPromise;
17754 };
17755
17756 _proto._getRTMServers =
17757 /*#__PURE__*/
17758 function () {
17759 var _getRTMServers2 = _asyncToGenerator(
17760 /*#__PURE__*/
17761 regenerator.mark(function _callee3(options) {
17762 var info, cachedEndPoints;
17763 return regenerator.wrap(function _callee3$(_context3) {
17764 while (1) {
17765 switch (_context3.prev = _context3.next) {
17766 case 0:
17767 if (!options.RTMServers) {
17768 _context3.next = 2;
17769 break;
17770 }
17771
17772 return _context3.abrupt("return", shuffle_1(ensureArray(options.RTMServers)));
17773
17774 case 2:
17775 cachedEndPoints = this._cache.get('endpoints');
17776
17777 if (!cachedEndPoints) {
17778 _context3.next = 9;
17779 break;
17780 }
17781
17782 _context3.next = 6;
17783 return cachedEndPoints;
17784
17785 case 6:
17786 info = _context3.sent;
17787 _context3.next = 13;
17788 break;
17789
17790 case 9:
17791 _context3.next = 11;
17792 return this.constructor._fetchRTMServers(options);
17793
17794 case 11:
17795 info = _context3.sent;
17796
17797 this._cache.set('endpoints', info, info.ttl * 1000);
17798
17799 case 13:
17800 debug$5('endpoint info: %O', info);
17801 return _context3.abrupt("return", [info.server, info.secondary]);
17802
17803 case 15:
17804 case "end":
17805 return _context3.stop();
17806 }
17807 }
17808 }, _callee3, this);
17809 }));
17810
17811 function _getRTMServers(_x2) {
17812 return _getRTMServers2.apply(this, arguments);
17813 }
17814
17815 return _getRTMServers;
17816 }();
17817
17818 Realtime._getServerUrls =
17819 /*#__PURE__*/
17820 function () {
17821 var _getServerUrls2 = _asyncToGenerator(
17822 /*#__PURE__*/
17823 regenerator.mark(function _callee4(_ref5) {
17824 var appId, server, cachedRouter, defaultProtocol;
17825 return regenerator.wrap(function _callee4$(_context4) {
17826 while (1) {
17827 switch (_context4.prev = _context4.next) {
17828 case 0:
17829 appId = _ref5.appId, server = _ref5.server;
17830 debug$5('fetch server urls');
17831
17832 if (!server) {
17833 _context4.next = 6;
17834 break;
17835 }
17836
17837 if (!(typeof server !== 'string')) {
17838 _context4.next = 5;
17839 break;
17840 }
17841
17842 return _context4.abrupt("return", server);
17843
17844 case 5:
17845 return _context4.abrupt("return", {
17846 RTMRouter: server,
17847 api: server
17848 });
17849
17850 case 6:
17851 cachedRouter = routerCache.get(appId);
17852
17853 if (!cachedRouter) {
17854 _context4.next = 9;
17855 break;
17856 }
17857
17858 return _context4.abrupt("return", cachedRouter);
17859
17860 case 9:
17861 defaultProtocol = 'https://';
17862 return _context4.abrupt("return", client.get('https://app-router.com/2/route').query({
17863 appId: appId
17864 }).timeout(20000).then(function (res) {
17865 return res.body;
17866 }).then(tap(debug$5)).then(function (_ref6) {
17867 var RTMRouterServer = _ref6.rtm_router_server,
17868 APIServer = _ref6.api_server,
17869 _ref6$ttl = _ref6.ttl,
17870 ttl = _ref6$ttl === void 0 ? 3600 : _ref6$ttl;
17871
17872 if (!RTMRouterServer) {
17873 throw new Error('rtm router not exists');
17874 }
17875
17876 var serverUrls = {
17877 RTMRouter: "".concat(defaultProtocol).concat(RTMRouterServer),
17878 api: "".concat(defaultProtocol).concat(APIServer)
17879 };
17880 routerCache.set(appId, serverUrls, ttl * 1000);
17881 return serverUrls;
17882 }).catch(function () {
17883 var id = appId.slice(0, 8).toLowerCase();
17884 var domain = 'lncldglobal.com';
17885 return {
17886 RTMRouter: "".concat(defaultProtocol).concat(id, ".rtm.").concat(domain),
17887 api: "".concat(defaultProtocol).concat(id, ".api.").concat(domain)
17888 };
17889 }));
17890
17891 case 11:
17892 case "end":
17893 return _context4.stop();
17894 }
17895 }
17896 }, _callee4, this);
17897 }));
17898
17899 function _getServerUrls(_x3) {
17900 return _getServerUrls2.apply(this, arguments);
17901 }
17902
17903 return _getServerUrls;
17904 }();
17905
17906 Realtime._fetchRTMServers = function _fetchRTMServers(_ref7) {
17907 var appId = _ref7.appId,
17908 ssl = _ref7.ssl,
17909 server = _ref7.server,
17910 RTMServerName = _ref7.RTMServerName;
17911 debug$5('fetch endpoint info');
17912 return this._getServerUrls({
17913 appId: appId,
17914 server: server
17915 }).then(tap(debug$5)).then(function (_ref8) {
17916 var RTMRouter = _ref8.RTMRouter;
17917 return client.get("".concat(RTMRouter, "/v1/route")).query({
17918 appId: appId,
17919 secure: ssl,
17920 features: isWeapp ? 'wechat' : undefined,
17921 server: RTMServerName,
17922 _t: Date.now()
17923 }).timeout(20000).then(function (res) {
17924 return res.body;
17925 }).then(tap(debug$5));
17926 });
17927 };
17928
17929 _proto._close = function _close() {
17930 if (this._openPromise) {
17931 this._openPromise.then(function (connection) {
17932 return connection.close();
17933 });
17934 }
17935
17936 delete this._openPromise;
17937 }
17938 /**
17939 * 手动进行重连。
17940 * SDK 在网络出现异常时会自动按照一定的时间间隔尝试重连,调用该方法会立即尝试重连并重置重连尝试计数器。
17941 * 只能在 `SCHEDULE` 事件之后,`RETRY` 事件之前调用,如果当前网络正常或者正在进行重连,调用该方法会抛异常。
17942 */
17943 ;
17944
17945 _proto.retry = function retry() {
17946 var _internal = internal(this),
17947 connection = _internal.connection;
17948
17949 if (!connection) {
17950 throw new Error('no connection established');
17951 }
17952
17953 if (connection.cannot('retry')) {
17954 throw new Error("retrying not allowed when not disconnected. the connection is now ".concat(connection.current));
17955 }
17956
17957 return connection.retry();
17958 }
17959 /**
17960 * 暂停,使 SDK 进入离线状态。
17961 * 你可以在网络断开、应用进入后台等时刻调用该方法让 SDK 进入离线状态,离线状态下不会尝试重连。
17962 * 在浏览器中 SDK 会自动监听网络变化,因此无需手动调用该方法。
17963 *
17964 * @since 3.4.0
17965 * @see Realtime#event:OFFLINE
17966 */
17967 ;
17968
17969 _proto.pause = function pause() {
17970 // 这个方法常常在网络断开、进入后台时被调用,此时 connection 可能没有建立或者已经 close。
17971 // 因此不像 retry,这个方法应该尽可能 loose
17972 var _internal2 = internal(this),
17973 connection = _internal2.connection;
17974
17975 if (!connection) return;
17976 if (connection.can('pause')) connection.pause();
17977 }
17978 /**
17979 * 恢复在线状态。
17980 * 你可以在网络恢复、应用回到前台等时刻调用该方法让 SDK 恢复在线状态,恢复在线状态后 SDK 会开始尝试重连。
17981 *
17982 * @since 3.4.0
17983 * @see Realtime#event:ONLINE
17984 */
17985 ;
17986
17987 _proto.resume = function resume() {
17988 // 与 pause 一样,这个方法应该尽可能 loose
17989 var _internal3 = internal(this),
17990 connection = _internal3.connection;
17991
17992 if (!connection) return;
17993 if (connection.can('resume')) connection.resume();
17994 };
17995
17996 _proto._registerPending = function _registerPending(value) {
17997 internal(this).pendingClients.add(value);
17998 };
17999
18000 _proto._deregisterPending = function _deregisterPending(client) {
18001 internal(this).pendingClients.delete(client);
18002 };
18003
18004 _proto._register = function _register(client) {
18005 internal(this).clients.add(client);
18006 };
18007
18008 _proto._deregister = function _deregister(client) {
18009 var _this = internal(this);
18010
18011 _this.clients.delete(client);
18012
18013 if (_this.clients.size + _this.pendingClients.size === 0) {
18014 this._close();
18015 }
18016 };
18017
18018 _proto._dispatchCommand = function _dispatchCommand(command) {
18019 return applyDispatcher(this._plugins.beforeCommandDispatch, [command, this]).then(function (shouldDispatch) {
18020 // no plugin handled this command
18021 if (shouldDispatch) return debug$5('[WARN] Unexpected message received: %O', trim(command));
18022 return false;
18023 });
18024 };
18025
18026 return Realtime;
18027 }(eventemitter3);
18028
18029 var polyfilledPromise = Promise;
18030
18031 var rngBrowser = createCommonjsModule(function (module) {
18032 // Unique ID creation requires a high quality random # generator. In the
18033 // browser this is a little complicated due to unknown quality of Math.random()
18034 // and inconsistent support for the `crypto` API. We do the best we can via
18035 // feature-detection
18036
18037 // getRandomValues needs to be invoked in a context where "this" is a Crypto
18038 // implementation. Also, find the complete implementation of crypto on IE11.
18039 var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
18040 (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));
18041
18042 if (getRandomValues) {
18043 // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
18044 var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
18045
18046 module.exports = function whatwgRNG() {
18047 getRandomValues(rnds8);
18048 return rnds8;
18049 };
18050 } else {
18051 // Math.random()-based (RNG)
18052 //
18053 // If all else fails, use Math.random(). It's fast, but is of unspecified
18054 // quality.
18055 var rnds = new Array(16);
18056
18057 module.exports = function mathRNG() {
18058 for (var i = 0, r; i < 16; i++) {
18059 if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
18060 rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
18061 }
18062
18063 return rnds;
18064 };
18065 }
18066 });
18067
18068 /**
18069 * Convert array of 16 byte values to UUID string format of the form:
18070 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
18071 */
18072 var byteToHex = [];
18073 for (var i = 0; i < 256; ++i) {
18074 byteToHex[i] = (i + 0x100).toString(16).substr(1);
18075 }
18076
18077 function bytesToUuid(buf, offset) {
18078 var i = offset || 0;
18079 var bth = byteToHex;
18080 // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
18081 return ([bth[buf[i++]], bth[buf[i++]],
18082 bth[buf[i++]], bth[buf[i++]], '-',
18083 bth[buf[i++]], bth[buf[i++]], '-',
18084 bth[buf[i++]], bth[buf[i++]], '-',
18085 bth[buf[i++]], bth[buf[i++]], '-',
18086 bth[buf[i++]], bth[buf[i++]],
18087 bth[buf[i++]], bth[buf[i++]],
18088 bth[buf[i++]], bth[buf[i++]]]).join('');
18089 }
18090
18091 var bytesToUuid_1 = bytesToUuid;
18092
18093 function v4(options, buf, offset) {
18094 var i = buf && offset || 0;
18095
18096 if (typeof(options) == 'string') {
18097 buf = options === 'binary' ? new Array(16) : null;
18098 options = null;
18099 }
18100 options = options || {};
18101
18102 var rnds = options.random || (options.rng || rngBrowser)();
18103
18104 // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
18105 rnds[6] = (rnds[6] & 0x0f) | 0x40;
18106 rnds[8] = (rnds[8] & 0x3f) | 0x80;
18107
18108 // Copy bytes to buffer, if provided
18109 if (buf) {
18110 for (var ii = 0; ii < 16; ++ii) {
18111 buf[i + ii] = rnds[ii];
18112 }
18113 }
18114
18115 return buf || bytesToUuid_1(rnds);
18116 }
18117
18118 var v4_1 = v4;
18119
18120 var base64Arraybuffer = createCommonjsModule(function (module, exports) {
18121 /*
18122 * base64-arraybuffer
18123 * https://github.com/niklasvh/base64-arraybuffer
18124 *
18125 * Copyright (c) 2012 Niklas von Hertzen
18126 * Licensed under the MIT license.
18127 */
18128 (function(){
18129
18130 var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
18131
18132 // Use a lookup table to find the index.
18133 var lookup = new Uint8Array(256);
18134 for (var i = 0; i < chars.length; i++) {
18135 lookup[chars.charCodeAt(i)] = i;
18136 }
18137
18138 exports.encode = function(arraybuffer) {
18139 var bytes = new Uint8Array(arraybuffer),
18140 i, len = bytes.length, base64 = "";
18141
18142 for (i = 0; i < len; i+=3) {
18143 base64 += chars[bytes[i] >> 2];
18144 base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
18145 base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
18146 base64 += chars[bytes[i + 2] & 63];
18147 }
18148
18149 if ((len % 3) === 2) {
18150 base64 = base64.substring(0, base64.length - 1) + "=";
18151 } else if (len % 3 === 1) {
18152 base64 = base64.substring(0, base64.length - 2) + "==";
18153 }
18154
18155 return base64;
18156 };
18157
18158 exports.decode = function(base64) {
18159 var bufferLength = base64.length * 0.75,
18160 len = base64.length, i, p = 0,
18161 encoded1, encoded2, encoded3, encoded4;
18162
18163 if (base64[base64.length - 1] === "=") {
18164 bufferLength--;
18165 if (base64[base64.length - 2] === "=") {
18166 bufferLength--;
18167 }
18168 }
18169
18170 var arraybuffer = new ArrayBuffer(bufferLength),
18171 bytes = new Uint8Array(arraybuffer);
18172
18173 for (i = 0; i < len; i+=4) {
18174 encoded1 = lookup[base64.charCodeAt(i)];
18175 encoded2 = lookup[base64.charCodeAt(i+1)];
18176 encoded3 = lookup[base64.charCodeAt(i+2)];
18177 encoded4 = lookup[base64.charCodeAt(i+3)];
18178
18179 bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
18180 bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
18181 bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
18182 }
18183
18184 return arraybuffer;
18185 };
18186 })();
18187 });
18188 var base64Arraybuffer_1 = base64Arraybuffer.encode;
18189 var base64Arraybuffer_2 = base64Arraybuffer.decode;
18190
18191 /**
18192 * Removes all key-value entries from the list cache.
18193 *
18194 * @private
18195 * @name clear
18196 * @memberOf ListCache
18197 */
18198 function listCacheClear() {
18199 this.__data__ = [];
18200 this.size = 0;
18201 }
18202
18203 var _listCacheClear = listCacheClear;
18204
18205 /**
18206 * Performs a
18207 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
18208 * comparison between two values to determine if they are equivalent.
18209 *
18210 * @static
18211 * @memberOf _
18212 * @since 4.0.0
18213 * @category Lang
18214 * @param {*} value The value to compare.
18215 * @param {*} other The other value to compare.
18216 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
18217 * @example
18218 *
18219 * var object = { 'a': 1 };
18220 * var other = { 'a': 1 };
18221 *
18222 * _.eq(object, object);
18223 * // => true
18224 *
18225 * _.eq(object, other);
18226 * // => false
18227 *
18228 * _.eq('a', 'a');
18229 * // => true
18230 *
18231 * _.eq('a', Object('a'));
18232 * // => false
18233 *
18234 * _.eq(NaN, NaN);
18235 * // => true
18236 */
18237 function eq(value, other) {
18238 return value === other || (value !== value && other !== other);
18239 }
18240
18241 var eq_1 = eq;
18242
18243 /**
18244 * Gets the index at which the `key` is found in `array` of key-value pairs.
18245 *
18246 * @private
18247 * @param {Array} array The array to inspect.
18248 * @param {*} key The key to search for.
18249 * @returns {number} Returns the index of the matched value, else `-1`.
18250 */
18251 function assocIndexOf(array, key) {
18252 var length = array.length;
18253 while (length--) {
18254 if (eq_1(array[length][0], key)) {
18255 return length;
18256 }
18257 }
18258 return -1;
18259 }
18260
18261 var _assocIndexOf = assocIndexOf;
18262
18263 /** Used for built-in method references. */
18264 var arrayProto = Array.prototype;
18265
18266 /** Built-in value references. */
18267 var splice = arrayProto.splice;
18268
18269 /**
18270 * Removes `key` and its value from the list cache.
18271 *
18272 * @private
18273 * @name delete
18274 * @memberOf ListCache
18275 * @param {string} key The key of the value to remove.
18276 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
18277 */
18278 function listCacheDelete(key) {
18279 var data = this.__data__,
18280 index = _assocIndexOf(data, key);
18281
18282 if (index < 0) {
18283 return false;
18284 }
18285 var lastIndex = data.length - 1;
18286 if (index == lastIndex) {
18287 data.pop();
18288 } else {
18289 splice.call(data, index, 1);
18290 }
18291 --this.size;
18292 return true;
18293 }
18294
18295 var _listCacheDelete = listCacheDelete;
18296
18297 /**
18298 * Gets the list cache value for `key`.
18299 *
18300 * @private
18301 * @name get
18302 * @memberOf ListCache
18303 * @param {string} key The key of the value to get.
18304 * @returns {*} Returns the entry value.
18305 */
18306 function listCacheGet(key) {
18307 var data = this.__data__,
18308 index = _assocIndexOf(data, key);
18309
18310 return index < 0 ? undefined : data[index][1];
18311 }
18312
18313 var _listCacheGet = listCacheGet;
18314
18315 /**
18316 * Checks if a list cache value for `key` exists.
18317 *
18318 * @private
18319 * @name has
18320 * @memberOf ListCache
18321 * @param {string} key The key of the entry to check.
18322 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18323 */
18324 function listCacheHas(key) {
18325 return _assocIndexOf(this.__data__, key) > -1;
18326 }
18327
18328 var _listCacheHas = listCacheHas;
18329
18330 /**
18331 * Sets the list cache `key` to `value`.
18332 *
18333 * @private
18334 * @name set
18335 * @memberOf ListCache
18336 * @param {string} key The key of the value to set.
18337 * @param {*} value The value to set.
18338 * @returns {Object} Returns the list cache instance.
18339 */
18340 function listCacheSet(key, value) {
18341 var data = this.__data__,
18342 index = _assocIndexOf(data, key);
18343
18344 if (index < 0) {
18345 ++this.size;
18346 data.push([key, value]);
18347 } else {
18348 data[index][1] = value;
18349 }
18350 return this;
18351 }
18352
18353 var _listCacheSet = listCacheSet;
18354
18355 /**
18356 * Creates an list cache object.
18357 *
18358 * @private
18359 * @constructor
18360 * @param {Array} [entries] The key-value pairs to cache.
18361 */
18362 function ListCache(entries) {
18363 var index = -1,
18364 length = entries == null ? 0 : entries.length;
18365
18366 this.clear();
18367 while (++index < length) {
18368 var entry = entries[index];
18369 this.set(entry[0], entry[1]);
18370 }
18371 }
18372
18373 // Add methods to `ListCache`.
18374 ListCache.prototype.clear = _listCacheClear;
18375 ListCache.prototype['delete'] = _listCacheDelete;
18376 ListCache.prototype.get = _listCacheGet;
18377 ListCache.prototype.has = _listCacheHas;
18378 ListCache.prototype.set = _listCacheSet;
18379
18380 var _ListCache = ListCache;
18381
18382 /**
18383 * Removes all key-value entries from the stack.
18384 *
18385 * @private
18386 * @name clear
18387 * @memberOf Stack
18388 */
18389 function stackClear() {
18390 this.__data__ = new _ListCache;
18391 this.size = 0;
18392 }
18393
18394 var _stackClear = stackClear;
18395
18396 /**
18397 * Removes `key` and its value from the stack.
18398 *
18399 * @private
18400 * @name delete
18401 * @memberOf Stack
18402 * @param {string} key The key of the value to remove.
18403 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
18404 */
18405 function stackDelete(key) {
18406 var data = this.__data__,
18407 result = data['delete'](key);
18408
18409 this.size = data.size;
18410 return result;
18411 }
18412
18413 var _stackDelete = stackDelete;
18414
18415 /**
18416 * Gets the stack value for `key`.
18417 *
18418 * @private
18419 * @name get
18420 * @memberOf Stack
18421 * @param {string} key The key of the value to get.
18422 * @returns {*} Returns the entry value.
18423 */
18424 function stackGet(key) {
18425 return this.__data__.get(key);
18426 }
18427
18428 var _stackGet = stackGet;
18429
18430 /**
18431 * Checks if a stack value for `key` exists.
18432 *
18433 * @private
18434 * @name has
18435 * @memberOf Stack
18436 * @param {string} key The key of the entry to check.
18437 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18438 */
18439 function stackHas(key) {
18440 return this.__data__.has(key);
18441 }
18442
18443 var _stackHas = stackHas;
18444
18445 /** Used to detect overreaching core-js shims. */
18446 var coreJsData = _root['__core-js_shared__'];
18447
18448 var _coreJsData = coreJsData;
18449
18450 /** Used to detect methods masquerading as native. */
18451 var maskSrcKey = (function() {
18452 var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');
18453 return uid ? ('Symbol(src)_1.' + uid) : '';
18454 }());
18455
18456 /**
18457 * Checks if `func` has its source masked.
18458 *
18459 * @private
18460 * @param {Function} func The function to check.
18461 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
18462 */
18463 function isMasked(func) {
18464 return !!maskSrcKey && (maskSrcKey in func);
18465 }
18466
18467 var _isMasked = isMasked;
18468
18469 /** Used for built-in method references. */
18470 var funcProto$1 = Function.prototype;
18471
18472 /** Used to resolve the decompiled source of functions. */
18473 var funcToString$1 = funcProto$1.toString;
18474
18475 /**
18476 * Converts `func` to its source code.
18477 *
18478 * @private
18479 * @param {Function} func The function to convert.
18480 * @returns {string} Returns the source code.
18481 */
18482 function toSource(func) {
18483 if (func != null) {
18484 try {
18485 return funcToString$1.call(func);
18486 } catch (e) {}
18487 try {
18488 return (func + '');
18489 } catch (e) {}
18490 }
18491 return '';
18492 }
18493
18494 var _toSource = toSource;
18495
18496 /**
18497 * Used to match `RegExp`
18498 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
18499 */
18500 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
18501
18502 /** Used to detect host constructors (Safari). */
18503 var reIsHostCtor = /^\[object .+?Constructor\]$/;
18504
18505 /** Used for built-in method references. */
18506 var funcProto$2 = Function.prototype,
18507 objectProto$7 = Object.prototype;
18508
18509 /** Used to resolve the decompiled source of functions. */
18510 var funcToString$2 = funcProto$2.toString;
18511
18512 /** Used to check objects for own properties. */
18513 var hasOwnProperty$5 = objectProto$7.hasOwnProperty;
18514
18515 /** Used to detect if a method is native. */
18516 var reIsNative = RegExp('^' +
18517 funcToString$2.call(hasOwnProperty$5).replace(reRegExpChar, '\\$&')
18518 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
18519 );
18520
18521 /**
18522 * The base implementation of `_.isNative` without bad shim checks.
18523 *
18524 * @private
18525 * @param {*} value The value to check.
18526 * @returns {boolean} Returns `true` if `value` is a native function,
18527 * else `false`.
18528 */
18529 function baseIsNative(value) {
18530 if (!isObject_1$1(value) || _isMasked(value)) {
18531 return false;
18532 }
18533 var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;
18534 return pattern.test(_toSource(value));
18535 }
18536
18537 var _baseIsNative = baseIsNative;
18538
18539 /**
18540 * Gets the value at `key` of `object`.
18541 *
18542 * @private
18543 * @param {Object} [object] The object to query.
18544 * @param {string} key The key of the property to get.
18545 * @returns {*} Returns the property value.
18546 */
18547 function getValue(object, key) {
18548 return object == null ? undefined : object[key];
18549 }
18550
18551 var _getValue = getValue;
18552
18553 /**
18554 * Gets the native function at `key` of `object`.
18555 *
18556 * @private
18557 * @param {Object} object The object to query.
18558 * @param {string} key The key of the method to get.
18559 * @returns {*} Returns the function if it's native, else `undefined`.
18560 */
18561 function getNative(object, key) {
18562 var value = _getValue(object, key);
18563 return _baseIsNative(value) ? value : undefined;
18564 }
18565
18566 var _getNative = getNative;
18567
18568 /* Built-in method references that are verified to be native. */
18569 var Map = _getNative(_root, 'Map');
18570
18571 var _Map = Map;
18572
18573 /* Built-in method references that are verified to be native. */
18574 var nativeCreate = _getNative(Object, 'create');
18575
18576 var _nativeCreate = nativeCreate;
18577
18578 /**
18579 * Removes all key-value entries from the hash.
18580 *
18581 * @private
18582 * @name clear
18583 * @memberOf Hash
18584 */
18585 function hashClear() {
18586 this.__data__ = _nativeCreate ? _nativeCreate(null) : {};
18587 this.size = 0;
18588 }
18589
18590 var _hashClear = hashClear;
18591
18592 /**
18593 * Removes `key` and its value from the hash.
18594 *
18595 * @private
18596 * @name delete
18597 * @memberOf Hash
18598 * @param {Object} hash The hash to modify.
18599 * @param {string} key The key of the value to remove.
18600 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
18601 */
18602 function hashDelete(key) {
18603 var result = this.has(key) && delete this.__data__[key];
18604 this.size -= result ? 1 : 0;
18605 return result;
18606 }
18607
18608 var _hashDelete = hashDelete;
18609
18610 /** Used to stand-in for `undefined` hash values. */
18611 var HASH_UNDEFINED = '__lodash_hash_undefined__';
18612
18613 /** Used for built-in method references. */
18614 var objectProto$8 = Object.prototype;
18615
18616 /** Used to check objects for own properties. */
18617 var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
18618
18619 /**
18620 * Gets the hash value for `key`.
18621 *
18622 * @private
18623 * @name get
18624 * @memberOf Hash
18625 * @param {string} key The key of the value to get.
18626 * @returns {*} Returns the entry value.
18627 */
18628 function hashGet(key) {
18629 var data = this.__data__;
18630 if (_nativeCreate) {
18631 var result = data[key];
18632 return result === HASH_UNDEFINED ? undefined : result;
18633 }
18634 return hasOwnProperty$6.call(data, key) ? data[key] : undefined;
18635 }
18636
18637 var _hashGet = hashGet;
18638
18639 /** Used for built-in method references. */
18640 var objectProto$9 = Object.prototype;
18641
18642 /** Used to check objects for own properties. */
18643 var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
18644
18645 /**
18646 * Checks if a hash value for `key` exists.
18647 *
18648 * @private
18649 * @name has
18650 * @memberOf Hash
18651 * @param {string} key The key of the entry to check.
18652 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18653 */
18654 function hashHas(key) {
18655 var data = this.__data__;
18656 return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$7.call(data, key);
18657 }
18658
18659 var _hashHas = hashHas;
18660
18661 /** Used to stand-in for `undefined` hash values. */
18662 var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
18663
18664 /**
18665 * Sets the hash `key` to `value`.
18666 *
18667 * @private
18668 * @name set
18669 * @memberOf Hash
18670 * @param {string} key The key of the value to set.
18671 * @param {*} value The value to set.
18672 * @returns {Object} Returns the hash instance.
18673 */
18674 function hashSet(key, value) {
18675 var data = this.__data__;
18676 this.size += this.has(key) ? 0 : 1;
18677 data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
18678 return this;
18679 }
18680
18681 var _hashSet = hashSet;
18682
18683 /**
18684 * Creates a hash object.
18685 *
18686 * @private
18687 * @constructor
18688 * @param {Array} [entries] The key-value pairs to cache.
18689 */
18690 function Hash(entries) {
18691 var index = -1,
18692 length = entries == null ? 0 : entries.length;
18693
18694 this.clear();
18695 while (++index < length) {
18696 var entry = entries[index];
18697 this.set(entry[0], entry[1]);
18698 }
18699 }
18700
18701 // Add methods to `Hash`.
18702 Hash.prototype.clear = _hashClear;
18703 Hash.prototype['delete'] = _hashDelete;
18704 Hash.prototype.get = _hashGet;
18705 Hash.prototype.has = _hashHas;
18706 Hash.prototype.set = _hashSet;
18707
18708 var _Hash = Hash;
18709
18710 /**
18711 * Removes all key-value entries from the map.
18712 *
18713 * @private
18714 * @name clear
18715 * @memberOf MapCache
18716 */
18717 function mapCacheClear() {
18718 this.size = 0;
18719 this.__data__ = {
18720 'hash': new _Hash,
18721 'map': new (_Map || _ListCache),
18722 'string': new _Hash
18723 };
18724 }
18725
18726 var _mapCacheClear = mapCacheClear;
18727
18728 /**
18729 * Checks if `value` is suitable for use as unique object key.
18730 *
18731 * @private
18732 * @param {*} value The value to check.
18733 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
18734 */
18735 function isKeyable(value) {
18736 var type = typeof value;
18737 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
18738 ? (value !== '__proto__')
18739 : (value === null);
18740 }
18741
18742 var _isKeyable = isKeyable;
18743
18744 /**
18745 * Gets the data for `map`.
18746 *
18747 * @private
18748 * @param {Object} map The map to query.
18749 * @param {string} key The reference key.
18750 * @returns {*} Returns the map data.
18751 */
18752 function getMapData(map, key) {
18753 var data = map.__data__;
18754 return _isKeyable(key)
18755 ? data[typeof key == 'string' ? 'string' : 'hash']
18756 : data.map;
18757 }
18758
18759 var _getMapData = getMapData;
18760
18761 /**
18762 * Removes `key` and its value from the map.
18763 *
18764 * @private
18765 * @name delete
18766 * @memberOf MapCache
18767 * @param {string} key The key of the value to remove.
18768 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
18769 */
18770 function mapCacheDelete(key) {
18771 var result = _getMapData(this, key)['delete'](key);
18772 this.size -= result ? 1 : 0;
18773 return result;
18774 }
18775
18776 var _mapCacheDelete = mapCacheDelete;
18777
18778 /**
18779 * Gets the map value for `key`.
18780 *
18781 * @private
18782 * @name get
18783 * @memberOf MapCache
18784 * @param {string} key The key of the value to get.
18785 * @returns {*} Returns the entry value.
18786 */
18787 function mapCacheGet(key) {
18788 return _getMapData(this, key).get(key);
18789 }
18790
18791 var _mapCacheGet = mapCacheGet;
18792
18793 /**
18794 * Checks if a map value for `key` exists.
18795 *
18796 * @private
18797 * @name has
18798 * @memberOf MapCache
18799 * @param {string} key The key of the entry to check.
18800 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18801 */
18802 function mapCacheHas(key) {
18803 return _getMapData(this, key).has(key);
18804 }
18805
18806 var _mapCacheHas = mapCacheHas;
18807
18808 /**
18809 * Sets the map `key` to `value`.
18810 *
18811 * @private
18812 * @name set
18813 * @memberOf MapCache
18814 * @param {string} key The key of the value to set.
18815 * @param {*} value The value to set.
18816 * @returns {Object} Returns the map cache instance.
18817 */
18818 function mapCacheSet(key, value) {
18819 var data = _getMapData(this, key),
18820 size = data.size;
18821
18822 data.set(key, value);
18823 this.size += data.size == size ? 0 : 1;
18824 return this;
18825 }
18826
18827 var _mapCacheSet = mapCacheSet;
18828
18829 /**
18830 * Creates a map cache object to store key-value pairs.
18831 *
18832 * @private
18833 * @constructor
18834 * @param {Array} [entries] The key-value pairs to cache.
18835 */
18836 function MapCache(entries) {
18837 var index = -1,
18838 length = entries == null ? 0 : entries.length;
18839
18840 this.clear();
18841 while (++index < length) {
18842 var entry = entries[index];
18843 this.set(entry[0], entry[1]);
18844 }
18845 }
18846
18847 // Add methods to `MapCache`.
18848 MapCache.prototype.clear = _mapCacheClear;
18849 MapCache.prototype['delete'] = _mapCacheDelete;
18850 MapCache.prototype.get = _mapCacheGet;
18851 MapCache.prototype.has = _mapCacheHas;
18852 MapCache.prototype.set = _mapCacheSet;
18853
18854 var _MapCache = MapCache;
18855
18856 /** Used as the size to enable large array optimizations. */
18857 var LARGE_ARRAY_SIZE = 200;
18858
18859 /**
18860 * Sets the stack `key` to `value`.
18861 *
18862 * @private
18863 * @name set
18864 * @memberOf Stack
18865 * @param {string} key The key of the value to set.
18866 * @param {*} value The value to set.
18867 * @returns {Object} Returns the stack cache instance.
18868 */
18869 function stackSet(key, value) {
18870 var data = this.__data__;
18871 if (data instanceof _ListCache) {
18872 var pairs = data.__data__;
18873 if (!_Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
18874 pairs.push([key, value]);
18875 this.size = ++data.size;
18876 return this;
18877 }
18878 data = this.__data__ = new _MapCache(pairs);
18879 }
18880 data.set(key, value);
18881 this.size = data.size;
18882 return this;
18883 }
18884
18885 var _stackSet = stackSet;
18886
18887 /**
18888 * Creates a stack cache object to store key-value pairs.
18889 *
18890 * @private
18891 * @constructor
18892 * @param {Array} [entries] The key-value pairs to cache.
18893 */
18894 function Stack(entries) {
18895 var data = this.__data__ = new _ListCache(entries);
18896 this.size = data.size;
18897 }
18898
18899 // Add methods to `Stack`.
18900 Stack.prototype.clear = _stackClear;
18901 Stack.prototype['delete'] = _stackDelete;
18902 Stack.prototype.get = _stackGet;
18903 Stack.prototype.has = _stackHas;
18904 Stack.prototype.set = _stackSet;
18905
18906 var _Stack = Stack;
18907
18908 /** Used to stand-in for `undefined` hash values. */
18909 var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
18910
18911 /**
18912 * Adds `value` to the array cache.
18913 *
18914 * @private
18915 * @name add
18916 * @memberOf SetCache
18917 * @alias push
18918 * @param {*} value The value to cache.
18919 * @returns {Object} Returns the cache instance.
18920 */
18921 function setCacheAdd(value) {
18922 this.__data__.set(value, HASH_UNDEFINED$2);
18923 return this;
18924 }
18925
18926 var _setCacheAdd = setCacheAdd;
18927
18928 /**
18929 * Checks if `value` is in the array cache.
18930 *
18931 * @private
18932 * @name has
18933 * @memberOf SetCache
18934 * @param {*} value The value to search for.
18935 * @returns {number} Returns `true` if `value` is found, else `false`.
18936 */
18937 function setCacheHas(value) {
18938 return this.__data__.has(value);
18939 }
18940
18941 var _setCacheHas = setCacheHas;
18942
18943 /**
18944 *
18945 * Creates an array cache object to store unique values.
18946 *
18947 * @private
18948 * @constructor
18949 * @param {Array} [values] The values to cache.
18950 */
18951 function SetCache(values) {
18952 var index = -1,
18953 length = values == null ? 0 : values.length;
18954
18955 this.__data__ = new _MapCache;
18956 while (++index < length) {
18957 this.add(values[index]);
18958 }
18959 }
18960
18961 // Add methods to `SetCache`.
18962 SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd;
18963 SetCache.prototype.has = _setCacheHas;
18964
18965 var _SetCache = SetCache;
18966
18967 /**
18968 * A specialized version of `_.some` for arrays without support for iteratee
18969 * shorthands.
18970 *
18971 * @private
18972 * @param {Array} [array] The array to iterate over.
18973 * @param {Function} predicate The function invoked per iteration.
18974 * @returns {boolean} Returns `true` if any element passes the predicate check,
18975 * else `false`.
18976 */
18977 function arraySome(array, predicate) {
18978 var index = -1,
18979 length = array == null ? 0 : array.length;
18980
18981 while (++index < length) {
18982 if (predicate(array[index], index, array)) {
18983 return true;
18984 }
18985 }
18986 return false;
18987 }
18988
18989 var _arraySome = arraySome;
18990
18991 /**
18992 * Checks if a `cache` value for `key` exists.
18993 *
18994 * @private
18995 * @param {Object} cache The cache to query.
18996 * @param {string} key The key of the entry to check.
18997 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18998 */
18999 function cacheHas(cache, key) {
19000 return cache.has(key);
19001 }
19002
19003 var _cacheHas = cacheHas;
19004
19005 /** Used to compose bitmasks for value comparisons. */
19006 var COMPARE_PARTIAL_FLAG = 1,
19007 COMPARE_UNORDERED_FLAG = 2;
19008
19009 /**
19010 * A specialized version of `baseIsEqualDeep` for arrays with support for
19011 * partial deep comparisons.
19012 *
19013 * @private
19014 * @param {Array} array The array to compare.
19015 * @param {Array} other The other array to compare.
19016 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19017 * @param {Function} customizer The function to customize comparisons.
19018 * @param {Function} equalFunc The function to determine equivalents of values.
19019 * @param {Object} stack Tracks traversed `array` and `other` objects.
19020 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
19021 */
19022 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
19023 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
19024 arrLength = array.length,
19025 othLength = other.length;
19026
19027 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
19028 return false;
19029 }
19030 // Assume cyclic values are equal.
19031 var stacked = stack.get(array);
19032 if (stacked && stack.get(other)) {
19033 return stacked == other;
19034 }
19035 var index = -1,
19036 result = true,
19037 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache : undefined;
19038
19039 stack.set(array, other);
19040 stack.set(other, array);
19041
19042 // Ignore non-index properties.
19043 while (++index < arrLength) {
19044 var arrValue = array[index],
19045 othValue = other[index];
19046
19047 if (customizer) {
19048 var compared = isPartial
19049 ? customizer(othValue, arrValue, index, other, array, stack)
19050 : customizer(arrValue, othValue, index, array, other, stack);
19051 }
19052 if (compared !== undefined) {
19053 if (compared) {
19054 continue;
19055 }
19056 result = false;
19057 break;
19058 }
19059 // Recursively compare arrays (susceptible to call stack limits).
19060 if (seen) {
19061 if (!_arraySome(other, function(othValue, othIndex) {
19062 if (!_cacheHas(seen, othIndex) &&
19063 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
19064 return seen.push(othIndex);
19065 }
19066 })) {
19067 result = false;
19068 break;
19069 }
19070 } else if (!(
19071 arrValue === othValue ||
19072 equalFunc(arrValue, othValue, bitmask, customizer, stack)
19073 )) {
19074 result = false;
19075 break;
19076 }
19077 }
19078 stack['delete'](array);
19079 stack['delete'](other);
19080 return result;
19081 }
19082
19083 var _equalArrays = equalArrays;
19084
19085 /** Built-in value references. */
19086 var Uint8Array$1 = _root.Uint8Array;
19087
19088 var _Uint8Array = Uint8Array$1;
19089
19090 /**
19091 * Converts `map` to its key-value pairs.
19092 *
19093 * @private
19094 * @param {Object} map The map to convert.
19095 * @returns {Array} Returns the key-value pairs.
19096 */
19097 function mapToArray(map) {
19098 var index = -1,
19099 result = Array(map.size);
19100
19101 map.forEach(function(value, key) {
19102 result[++index] = [key, value];
19103 });
19104 return result;
19105 }
19106
19107 var _mapToArray = mapToArray;
19108
19109 /**
19110 * Converts `set` to an array of its values.
19111 *
19112 * @private
19113 * @param {Object} set The set to convert.
19114 * @returns {Array} Returns the values.
19115 */
19116 function setToArray(set) {
19117 var index = -1,
19118 result = Array(set.size);
19119
19120 set.forEach(function(value) {
19121 result[++index] = value;
19122 });
19123 return result;
19124 }
19125
19126 var _setToArray = setToArray;
19127
19128 /** Used to compose bitmasks for value comparisons. */
19129 var COMPARE_PARTIAL_FLAG$1 = 1,
19130 COMPARE_UNORDERED_FLAG$1 = 2;
19131
19132 /** `Object#toString` result references. */
19133 var boolTag$1 = '[object Boolean]',
19134 dateTag$1 = '[object Date]',
19135 errorTag$1 = '[object Error]',
19136 mapTag$1 = '[object Map]',
19137 numberTag$1 = '[object Number]',
19138 regexpTag$1 = '[object RegExp]',
19139 setTag$1 = '[object Set]',
19140 stringTag$1 = '[object String]',
19141 symbolTag = '[object Symbol]';
19142
19143 var arrayBufferTag$1 = '[object ArrayBuffer]',
19144 dataViewTag$1 = '[object DataView]';
19145
19146 /** Used to convert symbols to primitives and strings. */
19147 var symbolProto = _Symbol ? _Symbol.prototype : undefined,
19148 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
19149
19150 /**
19151 * A specialized version of `baseIsEqualDeep` for comparing objects of
19152 * the same `toStringTag`.
19153 *
19154 * **Note:** This function only supports comparing values with tags of
19155 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
19156 *
19157 * @private
19158 * @param {Object} object The object to compare.
19159 * @param {Object} other The other object to compare.
19160 * @param {string} tag The `toStringTag` of the objects to compare.
19161 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19162 * @param {Function} customizer The function to customize comparisons.
19163 * @param {Function} equalFunc The function to determine equivalents of values.
19164 * @param {Object} stack Tracks traversed `object` and `other` objects.
19165 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19166 */
19167 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
19168 switch (tag) {
19169 case dataViewTag$1:
19170 if ((object.byteLength != other.byteLength) ||
19171 (object.byteOffset != other.byteOffset)) {
19172 return false;
19173 }
19174 object = object.buffer;
19175 other = other.buffer;
19176
19177 case arrayBufferTag$1:
19178 if ((object.byteLength != other.byteLength) ||
19179 !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) {
19180 return false;
19181 }
19182 return true;
19183
19184 case boolTag$1:
19185 case dateTag$1:
19186 case numberTag$1:
19187 // Coerce booleans to `1` or `0` and dates to milliseconds.
19188 // Invalid dates are coerced to `NaN`.
19189 return eq_1(+object, +other);
19190
19191 case errorTag$1:
19192 return object.name == other.name && object.message == other.message;
19193
19194 case regexpTag$1:
19195 case stringTag$1:
19196 // Coerce regexes to strings and treat strings, primitives and objects,
19197 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
19198 // for more details.
19199 return object == (other + '');
19200
19201 case mapTag$1:
19202 var convert = _mapToArray;
19203
19204 case setTag$1:
19205 var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1;
19206 convert || (convert = _setToArray);
19207
19208 if (object.size != other.size && !isPartial) {
19209 return false;
19210 }
19211 // Assume cyclic values are equal.
19212 var stacked = stack.get(object);
19213 if (stacked) {
19214 return stacked == other;
19215 }
19216 bitmask |= COMPARE_UNORDERED_FLAG$1;
19217
19218 // Recursively compare objects (susceptible to call stack limits).
19219 stack.set(object, other);
19220 var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
19221 stack['delete'](object);
19222 return result;
19223
19224 case symbolTag:
19225 if (symbolValueOf) {
19226 return symbolValueOf.call(object) == symbolValueOf.call(other);
19227 }
19228 }
19229 return false;
19230 }
19231
19232 var _equalByTag = equalByTag;
19233
19234 /**
19235 * Appends the elements of `values` to `array`.
19236 *
19237 * @private
19238 * @param {Array} array The array to modify.
19239 * @param {Array} values The values to append.
19240 * @returns {Array} Returns `array`.
19241 */
19242 function arrayPush(array, values) {
19243 var index = -1,
19244 length = values.length,
19245 offset = array.length;
19246
19247 while (++index < length) {
19248 array[offset + index] = values[index];
19249 }
19250 return array;
19251 }
19252
19253 var _arrayPush = arrayPush;
19254
19255 /**
19256 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
19257 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
19258 * symbols of `object`.
19259 *
19260 * @private
19261 * @param {Object} object The object to query.
19262 * @param {Function} keysFunc The function to get the keys of `object`.
19263 * @param {Function} symbolsFunc The function to get the symbols of `object`.
19264 * @returns {Array} Returns the array of property names and symbols.
19265 */
19266 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
19267 var result = keysFunc(object);
19268 return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object));
19269 }
19270
19271 var _baseGetAllKeys = baseGetAllKeys;
19272
19273 /**
19274 * A specialized version of `_.filter` for arrays without support for
19275 * iteratee shorthands.
19276 *
19277 * @private
19278 * @param {Array} [array] The array to iterate over.
19279 * @param {Function} predicate The function invoked per iteration.
19280 * @returns {Array} Returns the new filtered array.
19281 */
19282 function arrayFilter(array, predicate) {
19283 var index = -1,
19284 length = array == null ? 0 : array.length,
19285 resIndex = 0,
19286 result = [];
19287
19288 while (++index < length) {
19289 var value = array[index];
19290 if (predicate(value, index, array)) {
19291 result[resIndex++] = value;
19292 }
19293 }
19294 return result;
19295 }
19296
19297 var _arrayFilter = arrayFilter;
19298
19299 /**
19300 * This method returns a new empty array.
19301 *
19302 * @static
19303 * @memberOf _
19304 * @since 4.13.0
19305 * @category Util
19306 * @returns {Array} Returns the new empty array.
19307 * @example
19308 *
19309 * var arrays = _.times(2, _.stubArray);
19310 *
19311 * console.log(arrays);
19312 * // => [[], []]
19313 *
19314 * console.log(arrays[0] === arrays[1]);
19315 * // => false
19316 */
19317 function stubArray() {
19318 return [];
19319 }
19320
19321 var stubArray_1 = stubArray;
19322
19323 /** Used for built-in method references. */
19324 var objectProto$a = Object.prototype;
19325
19326 /** Built-in value references. */
19327 var propertyIsEnumerable$1 = objectProto$a.propertyIsEnumerable;
19328
19329 /* Built-in method references for those with the same name as other `lodash` methods. */
19330 var nativeGetSymbols = Object.getOwnPropertySymbols;
19331
19332 /**
19333 * Creates an array of the own enumerable symbols of `object`.
19334 *
19335 * @private
19336 * @param {Object} object The object to query.
19337 * @returns {Array} Returns the array of symbols.
19338 */
19339 var getSymbols = !nativeGetSymbols ? stubArray_1 : function(object) {
19340 if (object == null) {
19341 return [];
19342 }
19343 object = Object(object);
19344 return _arrayFilter(nativeGetSymbols(object), function(symbol) {
19345 return propertyIsEnumerable$1.call(object, symbol);
19346 });
19347 };
19348
19349 var _getSymbols = getSymbols;
19350
19351 /**
19352 * Creates an array of own enumerable property names and symbols of `object`.
19353 *
19354 * @private
19355 * @param {Object} object The object to query.
19356 * @returns {Array} Returns the array of property names and symbols.
19357 */
19358 function getAllKeys(object) {
19359 return _baseGetAllKeys(object, keys_1, _getSymbols);
19360 }
19361
19362 var _getAllKeys = getAllKeys;
19363
19364 /** Used to compose bitmasks for value comparisons. */
19365 var COMPARE_PARTIAL_FLAG$2 = 1;
19366
19367 /** Used for built-in method references. */
19368 var objectProto$b = Object.prototype;
19369
19370 /** Used to check objects for own properties. */
19371 var hasOwnProperty$8 = objectProto$b.hasOwnProperty;
19372
19373 /**
19374 * A specialized version of `baseIsEqualDeep` for objects with support for
19375 * partial deep comparisons.
19376 *
19377 * @private
19378 * @param {Object} object The object to compare.
19379 * @param {Object} other The other object to compare.
19380 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19381 * @param {Function} customizer The function to customize comparisons.
19382 * @param {Function} equalFunc The function to determine equivalents of values.
19383 * @param {Object} stack Tracks traversed `object` and `other` objects.
19384 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19385 */
19386 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
19387 var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2,
19388 objProps = _getAllKeys(object),
19389 objLength = objProps.length,
19390 othProps = _getAllKeys(other),
19391 othLength = othProps.length;
19392
19393 if (objLength != othLength && !isPartial) {
19394 return false;
19395 }
19396 var index = objLength;
19397 while (index--) {
19398 var key = objProps[index];
19399 if (!(isPartial ? key in other : hasOwnProperty$8.call(other, key))) {
19400 return false;
19401 }
19402 }
19403 // Assume cyclic values are equal.
19404 var stacked = stack.get(object);
19405 if (stacked && stack.get(other)) {
19406 return stacked == other;
19407 }
19408 var result = true;
19409 stack.set(object, other);
19410 stack.set(other, object);
19411
19412 var skipCtor = isPartial;
19413 while (++index < objLength) {
19414 key = objProps[index];
19415 var objValue = object[key],
19416 othValue = other[key];
19417
19418 if (customizer) {
19419 var compared = isPartial
19420 ? customizer(othValue, objValue, key, other, object, stack)
19421 : customizer(objValue, othValue, key, object, other, stack);
19422 }
19423 // Recursively compare objects (susceptible to call stack limits).
19424 if (!(compared === undefined
19425 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
19426 : compared
19427 )) {
19428 result = false;
19429 break;
19430 }
19431 skipCtor || (skipCtor = key == 'constructor');
19432 }
19433 if (result && !skipCtor) {
19434 var objCtor = object.constructor,
19435 othCtor = other.constructor;
19436
19437 // Non `Object` object instances with different constructors are not equal.
19438 if (objCtor != othCtor &&
19439 ('constructor' in object && 'constructor' in other) &&
19440 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
19441 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
19442 result = false;
19443 }
19444 }
19445 stack['delete'](object);
19446 stack['delete'](other);
19447 return result;
19448 }
19449
19450 var _equalObjects = equalObjects;
19451
19452 /* Built-in method references that are verified to be native. */
19453 var DataView = _getNative(_root, 'DataView');
19454
19455 var _DataView = DataView;
19456
19457 /* Built-in method references that are verified to be native. */
19458 var Promise$1 = _getNative(_root, 'Promise');
19459
19460 var _Promise = Promise$1;
19461
19462 /* Built-in method references that are verified to be native. */
19463 var Set$1 = _getNative(_root, 'Set');
19464
19465 var _Set = Set$1;
19466
19467 /* Built-in method references that are verified to be native. */
19468 var WeakMap$1 = _getNative(_root, 'WeakMap');
19469
19470 var _WeakMap = WeakMap$1;
19471
19472 /** `Object#toString` result references. */
19473 var mapTag$2 = '[object Map]',
19474 objectTag$2 = '[object Object]',
19475 promiseTag = '[object Promise]',
19476 setTag$2 = '[object Set]',
19477 weakMapTag$1 = '[object WeakMap]';
19478
19479 var dataViewTag$2 = '[object DataView]';
19480
19481 /** Used to detect maps, sets, and weakmaps. */
19482 var dataViewCtorString = _toSource(_DataView),
19483 mapCtorString = _toSource(_Map),
19484 promiseCtorString = _toSource(_Promise),
19485 setCtorString = _toSource(_Set),
19486 weakMapCtorString = _toSource(_WeakMap);
19487
19488 /**
19489 * Gets the `toStringTag` of `value`.
19490 *
19491 * @private
19492 * @param {*} value The value to query.
19493 * @returns {string} Returns the `toStringTag`.
19494 */
19495 var getTag = _baseGetTag;
19496
19497 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
19498 if ((_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$2) ||
19499 (_Map && getTag(new _Map) != mapTag$2) ||
19500 (_Promise && getTag(_Promise.resolve()) != promiseTag) ||
19501 (_Set && getTag(new _Set) != setTag$2) ||
19502 (_WeakMap && getTag(new _WeakMap) != weakMapTag$1)) {
19503 getTag = function(value) {
19504 var result = _baseGetTag(value),
19505 Ctor = result == objectTag$2 ? value.constructor : undefined,
19506 ctorString = Ctor ? _toSource(Ctor) : '';
19507
19508 if (ctorString) {
19509 switch (ctorString) {
19510 case dataViewCtorString: return dataViewTag$2;
19511 case mapCtorString: return mapTag$2;
19512 case promiseCtorString: return promiseTag;
19513 case setCtorString: return setTag$2;
19514 case weakMapCtorString: return weakMapTag$1;
19515 }
19516 }
19517 return result;
19518 };
19519 }
19520
19521 var _getTag = getTag;
19522
19523 /** Used to compose bitmasks for value comparisons. */
19524 var COMPARE_PARTIAL_FLAG$3 = 1;
19525
19526 /** `Object#toString` result references. */
19527 var argsTag$2 = '[object Arguments]',
19528 arrayTag$1 = '[object Array]',
19529 objectTag$3 = '[object Object]';
19530
19531 /** Used for built-in method references. */
19532 var objectProto$c = Object.prototype;
19533
19534 /** Used to check objects for own properties. */
19535 var hasOwnProperty$9 = objectProto$c.hasOwnProperty;
19536
19537 /**
19538 * A specialized version of `baseIsEqual` for arrays and objects which performs
19539 * deep comparisons and tracks traversed objects enabling objects with circular
19540 * references to be compared.
19541 *
19542 * @private
19543 * @param {Object} object The object to compare.
19544 * @param {Object} other The other object to compare.
19545 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19546 * @param {Function} customizer The function to customize comparisons.
19547 * @param {Function} equalFunc The function to determine equivalents of values.
19548 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
19549 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19550 */
19551 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
19552 var objIsArr = isArray_1(object),
19553 othIsArr = isArray_1(other),
19554 objTag = objIsArr ? arrayTag$1 : _getTag(object),
19555 othTag = othIsArr ? arrayTag$1 : _getTag(other);
19556
19557 objTag = objTag == argsTag$2 ? objectTag$3 : objTag;
19558 othTag = othTag == argsTag$2 ? objectTag$3 : othTag;
19559
19560 var objIsObj = objTag == objectTag$3,
19561 othIsObj = othTag == objectTag$3,
19562 isSameTag = objTag == othTag;
19563
19564 if (isSameTag && isBuffer_1(object)) {
19565 if (!isBuffer_1(other)) {
19566 return false;
19567 }
19568 objIsArr = true;
19569 objIsObj = false;
19570 }
19571 if (isSameTag && !objIsObj) {
19572 stack || (stack = new _Stack);
19573 return (objIsArr || isTypedArray_1(object))
19574 ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack)
19575 : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
19576 }
19577 if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) {
19578 var objIsWrapped = objIsObj && hasOwnProperty$9.call(object, '__wrapped__'),
19579 othIsWrapped = othIsObj && hasOwnProperty$9.call(other, '__wrapped__');
19580
19581 if (objIsWrapped || othIsWrapped) {
19582 var objUnwrapped = objIsWrapped ? object.value() : object,
19583 othUnwrapped = othIsWrapped ? other.value() : other;
19584
19585 stack || (stack = new _Stack);
19586 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
19587 }
19588 }
19589 if (!isSameTag) {
19590 return false;
19591 }
19592 stack || (stack = new _Stack);
19593 return _equalObjects(object, other, bitmask, customizer, equalFunc, stack);
19594 }
19595
19596 var _baseIsEqualDeep = baseIsEqualDeep;
19597
19598 /**
19599 * The base implementation of `_.isEqual` which supports partial comparisons
19600 * and tracks traversed objects.
19601 *
19602 * @private
19603 * @param {*} value The value to compare.
19604 * @param {*} other The other value to compare.
19605 * @param {boolean} bitmask The bitmask flags.
19606 * 1 - Unordered comparison
19607 * 2 - Partial comparison
19608 * @param {Function} [customizer] The function to customize comparisons.
19609 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
19610 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
19611 */
19612 function baseIsEqual(value, other, bitmask, customizer, stack) {
19613 if (value === other) {
19614 return true;
19615 }
19616 if (value == null || other == null || (!isObjectLike_1(value) && !isObjectLike_1(other))) {
19617 return value !== value && other !== other;
19618 }
19619 return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
19620 }
19621
19622 var _baseIsEqual = baseIsEqual;
19623
19624 /** Used to compose bitmasks for value comparisons. */
19625 var COMPARE_PARTIAL_FLAG$4 = 1,
19626 COMPARE_UNORDERED_FLAG$2 = 2;
19627
19628 /**
19629 * The base implementation of `_.isMatch` without support for iteratee shorthands.
19630 *
19631 * @private
19632 * @param {Object} object The object to inspect.
19633 * @param {Object} source The object of property values to match.
19634 * @param {Array} matchData The property names, values, and compare flags to match.
19635 * @param {Function} [customizer] The function to customize comparisons.
19636 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
19637 */
19638 function baseIsMatch(object, source, matchData, customizer) {
19639 var index = matchData.length,
19640 length = index,
19641 noCustomizer = !customizer;
19642
19643 if (object == null) {
19644 return !length;
19645 }
19646 object = Object(object);
19647 while (index--) {
19648 var data = matchData[index];
19649 if ((noCustomizer && data[2])
19650 ? data[1] !== object[data[0]]
19651 : !(data[0] in object)
19652 ) {
19653 return false;
19654 }
19655 }
19656 while (++index < length) {
19657 data = matchData[index];
19658 var key = data[0],
19659 objValue = object[key],
19660 srcValue = data[1];
19661
19662 if (noCustomizer && data[2]) {
19663 if (objValue === undefined && !(key in object)) {
19664 return false;
19665 }
19666 } else {
19667 var stack = new _Stack;
19668 if (customizer) {
19669 var result = customizer(objValue, srcValue, key, object, source, stack);
19670 }
19671 if (!(result === undefined
19672 ? _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack)
19673 : result
19674 )) {
19675 return false;
19676 }
19677 }
19678 }
19679 return true;
19680 }
19681
19682 var _baseIsMatch = baseIsMatch;
19683
19684 /**
19685 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
19686 *
19687 * @private
19688 * @param {*} value The value to check.
19689 * @returns {boolean} Returns `true` if `value` if suitable for strict
19690 * equality comparisons, else `false`.
19691 */
19692 function isStrictComparable(value) {
19693 return value === value && !isObject_1$1(value);
19694 }
19695
19696 var _isStrictComparable = isStrictComparable;
19697
19698 /**
19699 * Gets the property names, values, and compare flags of `object`.
19700 *
19701 * @private
19702 * @param {Object} object The object to query.
19703 * @returns {Array} Returns the match data of `object`.
19704 */
19705 function getMatchData(object) {
19706 var result = keys_1(object),
19707 length = result.length;
19708
19709 while (length--) {
19710 var key = result[length],
19711 value = object[key];
19712
19713 result[length] = [key, value, _isStrictComparable(value)];
19714 }
19715 return result;
19716 }
19717
19718 var _getMatchData = getMatchData;
19719
19720 /**
19721 * A specialized version of `matchesProperty` for source values suitable
19722 * for strict equality comparisons, i.e. `===`.
19723 *
19724 * @private
19725 * @param {string} key The key of the property to get.
19726 * @param {*} srcValue The value to match.
19727 * @returns {Function} Returns the new spec function.
19728 */
19729 function matchesStrictComparable(key, srcValue) {
19730 return function(object) {
19731 if (object == null) {
19732 return false;
19733 }
19734 return object[key] === srcValue &&
19735 (srcValue !== undefined || (key in Object(object)));
19736 };
19737 }
19738
19739 var _matchesStrictComparable = matchesStrictComparable;
19740
19741 /**
19742 * The base implementation of `_.matches` which doesn't clone `source`.
19743 *
19744 * @private
19745 * @param {Object} source The object of property values to match.
19746 * @returns {Function} Returns the new spec function.
19747 */
19748 function baseMatches(source) {
19749 var matchData = _getMatchData(source);
19750 if (matchData.length == 1 && matchData[0][2]) {
19751 return _matchesStrictComparable(matchData[0][0], matchData[0][1]);
19752 }
19753 return function(object) {
19754 return object === source || _baseIsMatch(object, source, matchData);
19755 };
19756 }
19757
19758 var _baseMatches = baseMatches;
19759
19760 /** `Object#toString` result references. */
19761 var symbolTag$1 = '[object Symbol]';
19762
19763 /**
19764 * Checks if `value` is classified as a `Symbol` primitive or object.
19765 *
19766 * @static
19767 * @memberOf _
19768 * @since 4.0.0
19769 * @category Lang
19770 * @param {*} value The value to check.
19771 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
19772 * @example
19773 *
19774 * _.isSymbol(Symbol.iterator);
19775 * // => true
19776 *
19777 * _.isSymbol('abc');
19778 * // => false
19779 */
19780 function isSymbol(value) {
19781 return typeof value == 'symbol' ||
19782 (isObjectLike_1(value) && _baseGetTag(value) == symbolTag$1);
19783 }
19784
19785 var isSymbol_1 = isSymbol;
19786
19787 /** Used to match property names within property paths. */
19788 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
19789 reIsPlainProp = /^\w*$/;
19790
19791 /**
19792 * Checks if `value` is a property name and not a property path.
19793 *
19794 * @private
19795 * @param {*} value The value to check.
19796 * @param {Object} [object] The object to query keys on.
19797 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
19798 */
19799 function isKey(value, object) {
19800 if (isArray_1(value)) {
19801 return false;
19802 }
19803 var type = typeof value;
19804 if (type == 'number' || type == 'symbol' || type == 'boolean' ||
19805 value == null || isSymbol_1(value)) {
19806 return true;
19807 }
19808 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
19809 (object != null && value in Object(object));
19810 }
19811
19812 var _isKey = isKey;
19813
19814 /** Error message constants. */
19815 var FUNC_ERROR_TEXT = 'Expected a function';
19816
19817 /**
19818 * Creates a function that memoizes the result of `func`. If `resolver` is
19819 * provided, it determines the cache key for storing the result based on the
19820 * arguments provided to the memoized function. By default, the first argument
19821 * provided to the memoized function is used as the map cache key. The `func`
19822 * is invoked with the `this` binding of the memoized function.
19823 *
19824 * **Note:** The cache is exposed as the `cache` property on the memoized
19825 * function. Its creation may be customized by replacing the `_.memoize.Cache`
19826 * constructor with one whose instances implement the
19827 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
19828 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
19829 *
19830 * @static
19831 * @memberOf _
19832 * @since 0.1.0
19833 * @category Function
19834 * @param {Function} func The function to have its output memoized.
19835 * @param {Function} [resolver] The function to resolve the cache key.
19836 * @returns {Function} Returns the new memoized function.
19837 * @example
19838 *
19839 * var object = { 'a': 1, 'b': 2 };
19840 * var other = { 'c': 3, 'd': 4 };
19841 *
19842 * var values = _.memoize(_.values);
19843 * values(object);
19844 * // => [1, 2]
19845 *
19846 * values(other);
19847 * // => [3, 4]
19848 *
19849 * object.a = 2;
19850 * values(object);
19851 * // => [1, 2]
19852 *
19853 * // Modify the result cache.
19854 * values.cache.set(object, ['a', 'b']);
19855 * values(object);
19856 * // => ['a', 'b']
19857 *
19858 * // Replace `_.memoize.Cache`.
19859 * _.memoize.Cache = WeakMap;
19860 */
19861 function memoize(func, resolver) {
19862 if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
19863 throw new TypeError(FUNC_ERROR_TEXT);
19864 }
19865 var memoized = function() {
19866 var args = arguments,
19867 key = resolver ? resolver.apply(this, args) : args[0],
19868 cache = memoized.cache;
19869
19870 if (cache.has(key)) {
19871 return cache.get(key);
19872 }
19873 var result = func.apply(this, args);
19874 memoized.cache = cache.set(key, result) || cache;
19875 return result;
19876 };
19877 memoized.cache = new (memoize.Cache || _MapCache);
19878 return memoized;
19879 }
19880
19881 // Expose `MapCache`.
19882 memoize.Cache = _MapCache;
19883
19884 var memoize_1 = memoize;
19885
19886 /** Used as the maximum memoize cache size. */
19887 var MAX_MEMOIZE_SIZE = 500;
19888
19889 /**
19890 * A specialized version of `_.memoize` which clears the memoized function's
19891 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
19892 *
19893 * @private
19894 * @param {Function} func The function to have its output memoized.
19895 * @returns {Function} Returns the new memoized function.
19896 */
19897 function memoizeCapped(func) {
19898 var result = memoize_1(func, function(key) {
19899 if (cache.size === MAX_MEMOIZE_SIZE) {
19900 cache.clear();
19901 }
19902 return key;
19903 });
19904
19905 var cache = result.cache;
19906 return result;
19907 }
19908
19909 var _memoizeCapped = memoizeCapped;
19910
19911 /** Used to match property names within property paths. */
19912 var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
19913
19914 /** Used to match backslashes in property paths. */
19915 var reEscapeChar = /\\(\\)?/g;
19916
19917 /**
19918 * Converts `string` to a property path array.
19919 *
19920 * @private
19921 * @param {string} string The string to convert.
19922 * @returns {Array} Returns the property path array.
19923 */
19924 var stringToPath = _memoizeCapped(function(string) {
19925 var result = [];
19926 if (string.charCodeAt(0) === 46 /* . */) {
19927 result.push('');
19928 }
19929 string.replace(rePropName, function(match, number, quote, subString) {
19930 result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
19931 });
19932 return result;
19933 });
19934
19935 var _stringToPath = stringToPath;
19936
19937 /** Used as references for various `Number` constants. */
19938 var INFINITY = 1 / 0;
19939
19940 /** Used to convert symbols to primitives and strings. */
19941 var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined,
19942 symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined;
19943
19944 /**
19945 * The base implementation of `_.toString` which doesn't convert nullish
19946 * values to empty strings.
19947 *
19948 * @private
19949 * @param {*} value The value to process.
19950 * @returns {string} Returns the string.
19951 */
19952 function baseToString(value) {
19953 // Exit early for strings to avoid a performance hit in some environments.
19954 if (typeof value == 'string') {
19955 return value;
19956 }
19957 if (isArray_1(value)) {
19958 // Recursively convert values (susceptible to call stack limits).
19959 return _arrayMap(value, baseToString) + '';
19960 }
19961 if (isSymbol_1(value)) {
19962 return symbolToString ? symbolToString.call(value) : '';
19963 }
19964 var result = (value + '');
19965 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
19966 }
19967
19968 var _baseToString = baseToString;
19969
19970 /**
19971 * Converts `value` to a string. An empty string is returned for `null`
19972 * and `undefined` values. The sign of `-0` is preserved.
19973 *
19974 * @static
19975 * @memberOf _
19976 * @since 4.0.0
19977 * @category Lang
19978 * @param {*} value The value to convert.
19979 * @returns {string} Returns the converted string.
19980 * @example
19981 *
19982 * _.toString(null);
19983 * // => ''
19984 *
19985 * _.toString(-0);
19986 * // => '-0'
19987 *
19988 * _.toString([1, 2, 3]);
19989 * // => '1,2,3'
19990 */
19991 function toString(value) {
19992 return value == null ? '' : _baseToString(value);
19993 }
19994
19995 var toString_1 = toString;
19996
19997 /**
19998 * Casts `value` to a path array if it's not one.
19999 *
20000 * @private
20001 * @param {*} value The value to inspect.
20002 * @param {Object} [object] The object to query keys on.
20003 * @returns {Array} Returns the cast property path array.
20004 */
20005 function castPath(value, object) {
20006 if (isArray_1(value)) {
20007 return value;
20008 }
20009 return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));
20010 }
20011
20012 var _castPath = castPath;
20013
20014 /** Used as references for various `Number` constants. */
20015 var INFINITY$1 = 1 / 0;
20016
20017 /**
20018 * Converts `value` to a string key if it's not a string or symbol.
20019 *
20020 * @private
20021 * @param {*} value The value to inspect.
20022 * @returns {string|symbol} Returns the key.
20023 */
20024 function toKey(value) {
20025 if (typeof value == 'string' || isSymbol_1(value)) {
20026 return value;
20027 }
20028 var result = (value + '');
20029 return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
20030 }
20031
20032 var _toKey = toKey;
20033
20034 /**
20035 * The base implementation of `_.get` without support for default values.
20036 *
20037 * @private
20038 * @param {Object} object The object to query.
20039 * @param {Array|string} path The path of the property to get.
20040 * @returns {*} Returns the resolved value.
20041 */
20042 function baseGet(object, path) {
20043 path = _castPath(path, object);
20044
20045 var index = 0,
20046 length = path.length;
20047
20048 while (object != null && index < length) {
20049 object = object[_toKey(path[index++])];
20050 }
20051 return (index && index == length) ? object : undefined;
20052 }
20053
20054 var _baseGet = baseGet;
20055
20056 /**
20057 * Gets the value at `path` of `object`. If the resolved value is
20058 * `undefined`, the `defaultValue` is returned in its place.
20059 *
20060 * @static
20061 * @memberOf _
20062 * @since 3.7.0
20063 * @category Object
20064 * @param {Object} object The object to query.
20065 * @param {Array|string} path The path of the property to get.
20066 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
20067 * @returns {*} Returns the resolved value.
20068 * @example
20069 *
20070 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
20071 *
20072 * _.get(object, 'a[0].b.c');
20073 * // => 3
20074 *
20075 * _.get(object, ['a', '0', 'b', 'c']);
20076 * // => 3
20077 *
20078 * _.get(object, 'a.b.c', 'default');
20079 * // => 'default'
20080 */
20081 function get(object, path, defaultValue) {
20082 var result = object == null ? undefined : _baseGet(object, path);
20083 return result === undefined ? defaultValue : result;
20084 }
20085
20086 var get_1 = get;
20087
20088 /**
20089 * The base implementation of `_.hasIn` without support for deep paths.
20090 *
20091 * @private
20092 * @param {Object} [object] The object to query.
20093 * @param {Array|string} key The key to check.
20094 * @returns {boolean} Returns `true` if `key` exists, else `false`.
20095 */
20096 function baseHasIn(object, key) {
20097 return object != null && key in Object(object);
20098 }
20099
20100 var _baseHasIn = baseHasIn;
20101
20102 /**
20103 * Checks if `path` exists on `object`.
20104 *
20105 * @private
20106 * @param {Object} object The object to query.
20107 * @param {Array|string} path The path to check.
20108 * @param {Function} hasFunc The function to check properties.
20109 * @returns {boolean} Returns `true` if `path` exists, else `false`.
20110 */
20111 function hasPath(object, path, hasFunc) {
20112 path = _castPath(path, object);
20113
20114 var index = -1,
20115 length = path.length,
20116 result = false;
20117
20118 while (++index < length) {
20119 var key = _toKey(path[index]);
20120 if (!(result = object != null && hasFunc(object, key))) {
20121 break;
20122 }
20123 object = object[key];
20124 }
20125 if (result || ++index != length) {
20126 return result;
20127 }
20128 length = object == null ? 0 : object.length;
20129 return !!length && isLength_1(length) && _isIndex(key, length) &&
20130 (isArray_1(object) || isArguments_1(object));
20131 }
20132
20133 var _hasPath = hasPath;
20134
20135 /**
20136 * Checks if `path` is a direct or inherited property of `object`.
20137 *
20138 * @static
20139 * @memberOf _
20140 * @since 4.0.0
20141 * @category Object
20142 * @param {Object} object The object to query.
20143 * @param {Array|string} path The path to check.
20144 * @returns {boolean} Returns `true` if `path` exists, else `false`.
20145 * @example
20146 *
20147 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
20148 *
20149 * _.hasIn(object, 'a');
20150 * // => true
20151 *
20152 * _.hasIn(object, 'a.b');
20153 * // => true
20154 *
20155 * _.hasIn(object, ['a', 'b']);
20156 * // => true
20157 *
20158 * _.hasIn(object, 'b');
20159 * // => false
20160 */
20161 function hasIn(object, path) {
20162 return object != null && _hasPath(object, path, _baseHasIn);
20163 }
20164
20165 var hasIn_1 = hasIn;
20166
20167 /** Used to compose bitmasks for value comparisons. */
20168 var COMPARE_PARTIAL_FLAG$5 = 1,
20169 COMPARE_UNORDERED_FLAG$3 = 2;
20170
20171 /**
20172 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
20173 *
20174 * @private
20175 * @param {string} path The path of the property to get.
20176 * @param {*} srcValue The value to match.
20177 * @returns {Function} Returns the new spec function.
20178 */
20179 function baseMatchesProperty(path, srcValue) {
20180 if (_isKey(path) && _isStrictComparable(srcValue)) {
20181 return _matchesStrictComparable(_toKey(path), srcValue);
20182 }
20183 return function(object) {
20184 var objValue = get_1(object, path);
20185 return (objValue === undefined && objValue === srcValue)
20186 ? hasIn_1(object, path)
20187 : _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3);
20188 };
20189 }
20190
20191 var _baseMatchesProperty = baseMatchesProperty;
20192
20193 /**
20194 * This method returns the first argument it receives.
20195 *
20196 * @static
20197 * @since 0.1.0
20198 * @memberOf _
20199 * @category Util
20200 * @param {*} value Any value.
20201 * @returns {*} Returns `value`.
20202 * @example
20203 *
20204 * var object = { 'a': 1 };
20205 *
20206 * console.log(_.identity(object) === object);
20207 * // => true
20208 */
20209 function identity(value) {
20210 return value;
20211 }
20212
20213 var identity_1 = identity;
20214
20215 /**
20216 * The base implementation of `_.property` without support for deep paths.
20217 *
20218 * @private
20219 * @param {string} key The key of the property to get.
20220 * @returns {Function} Returns the new accessor function.
20221 */
20222 function baseProperty(key) {
20223 return function(object) {
20224 return object == null ? undefined : object[key];
20225 };
20226 }
20227
20228 var _baseProperty = baseProperty;
20229
20230 /**
20231 * A specialized version of `baseProperty` which supports deep paths.
20232 *
20233 * @private
20234 * @param {Array|string} path The path of the property to get.
20235 * @returns {Function} Returns the new accessor function.
20236 */
20237 function basePropertyDeep(path) {
20238 return function(object) {
20239 return _baseGet(object, path);
20240 };
20241 }
20242
20243 var _basePropertyDeep = basePropertyDeep;
20244
20245 /**
20246 * Creates a function that returns the value at `path` of a given object.
20247 *
20248 * @static
20249 * @memberOf _
20250 * @since 2.4.0
20251 * @category Util
20252 * @param {Array|string} path The path of the property to get.
20253 * @returns {Function} Returns the new accessor function.
20254 * @example
20255 *
20256 * var objects = [
20257 * { 'a': { 'b': 2 } },
20258 * { 'a': { 'b': 1 } }
20259 * ];
20260 *
20261 * _.map(objects, _.property('a.b'));
20262 * // => [2, 1]
20263 *
20264 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
20265 * // => [1, 2]
20266 */
20267 function property(path) {
20268 return _isKey(path) ? _baseProperty(_toKey(path)) : _basePropertyDeep(path);
20269 }
20270
20271 var property_1 = property;
20272
20273 /**
20274 * The base implementation of `_.iteratee`.
20275 *
20276 * @private
20277 * @param {*} [value=_.identity] The value to convert to an iteratee.
20278 * @returns {Function} Returns the iteratee.
20279 */
20280 function baseIteratee(value) {
20281 // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
20282 // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
20283 if (typeof value == 'function') {
20284 return value;
20285 }
20286 if (value == null) {
20287 return identity_1;
20288 }
20289 if (typeof value == 'object') {
20290 return isArray_1(value)
20291 ? _baseMatchesProperty(value[0], value[1])
20292 : _baseMatches(value);
20293 }
20294 return property_1(value);
20295 }
20296
20297 var _baseIteratee = baseIteratee;
20298
20299 /**
20300 * Gets the last element of `array`.
20301 *
20302 * @static
20303 * @memberOf _
20304 * @since 0.1.0
20305 * @category Array
20306 * @param {Array} array The array to query.
20307 * @returns {*} Returns the last element of `array`.
20308 * @example
20309 *
20310 * _.last([1, 2, 3]);
20311 * // => 3
20312 */
20313 function last(array) {
20314 var length = array == null ? 0 : array.length;
20315 return length ? array[length - 1] : undefined;
20316 }
20317
20318 var last_1 = last;
20319
20320 /**
20321 * The base implementation of `_.slice` without an iteratee call guard.
20322 *
20323 * @private
20324 * @param {Array} array The array to slice.
20325 * @param {number} [start=0] The start position.
20326 * @param {number} [end=array.length] The end position.
20327 * @returns {Array} Returns the slice of `array`.
20328 */
20329 function baseSlice(array, start, end) {
20330 var index = -1,
20331 length = array.length;
20332
20333 if (start < 0) {
20334 start = -start > length ? 0 : (length + start);
20335 }
20336 end = end > length ? length : end;
20337 if (end < 0) {
20338 end += length;
20339 }
20340 length = start > end ? 0 : ((end - start) >>> 0);
20341 start >>>= 0;
20342
20343 var result = Array(length);
20344 while (++index < length) {
20345 result[index] = array[index + start];
20346 }
20347 return result;
20348 }
20349
20350 var _baseSlice = baseSlice;
20351
20352 /**
20353 * Gets the parent value at `path` of `object`.
20354 *
20355 * @private
20356 * @param {Object} object The object to query.
20357 * @param {Array} path The path to get the parent value of.
20358 * @returns {*} Returns the parent value.
20359 */
20360 function parent(object, path) {
20361 return path.length < 2 ? object : _baseGet(object, _baseSlice(path, 0, -1));
20362 }
20363
20364 var _parent = parent;
20365
20366 /**
20367 * The base implementation of `_.unset`.
20368 *
20369 * @private
20370 * @param {Object} object The object to modify.
20371 * @param {Array|string} path The property path to unset.
20372 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
20373 */
20374 function baseUnset(object, path) {
20375 path = _castPath(path, object);
20376 object = _parent(object, path);
20377 return object == null || delete object[_toKey(last_1(path))];
20378 }
20379
20380 var _baseUnset = baseUnset;
20381
20382 /** Used for built-in method references. */
20383 var arrayProto$1 = Array.prototype;
20384
20385 /** Built-in value references. */
20386 var splice$1 = arrayProto$1.splice;
20387
20388 /**
20389 * The base implementation of `_.pullAt` without support for individual
20390 * indexes or capturing the removed elements.
20391 *
20392 * @private
20393 * @param {Array} array The array to modify.
20394 * @param {number[]} indexes The indexes of elements to remove.
20395 * @returns {Array} Returns `array`.
20396 */
20397 function basePullAt(array, indexes) {
20398 var length = array ? indexes.length : 0,
20399 lastIndex = length - 1;
20400
20401 while (length--) {
20402 var index = indexes[length];
20403 if (length == lastIndex || index !== previous) {
20404 var previous = index;
20405 if (_isIndex(index)) {
20406 splice$1.call(array, index, 1);
20407 } else {
20408 _baseUnset(array, index);
20409 }
20410 }
20411 }
20412 return array;
20413 }
20414
20415 var _basePullAt = basePullAt;
20416
20417 /**
20418 * Removes all elements from `array` that `predicate` returns truthy for
20419 * and returns an array of the removed elements. The predicate is invoked
20420 * with three arguments: (value, index, array).
20421 *
20422 * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
20423 * to pull elements from an array by value.
20424 *
20425 * @static
20426 * @memberOf _
20427 * @since 2.0.0
20428 * @category Array
20429 * @param {Array} array The array to modify.
20430 * @param {Function} [predicate=_.identity] The function invoked per iteration.
20431 * @returns {Array} Returns the new array of removed elements.
20432 * @example
20433 *
20434 * var array = [1, 2, 3, 4];
20435 * var evens = _.remove(array, function(n) {
20436 * return n % 2 == 0;
20437 * });
20438 *
20439 * console.log(array);
20440 * // => [1, 3]
20441 *
20442 * console.log(evens);
20443 * // => [2, 4]
20444 */
20445 function remove(array, predicate) {
20446 var result = [];
20447 if (!(array && array.length)) {
20448 return result;
20449 }
20450 var index = -1,
20451 indexes = [],
20452 length = array.length;
20453
20454 predicate = _baseIteratee(predicate, 3);
20455 while (++index < length) {
20456 var value = array[index];
20457 if (predicate(value, index, array)) {
20458 result.push(value);
20459 indexes.push(index);
20460 }
20461 }
20462 _basePullAt(array, indexes);
20463 return result;
20464 }
20465
20466 var remove_1 = remove;
20467
20468 /** `Object#toString` result references. */
20469 var mapTag$3 = '[object Map]',
20470 setTag$3 = '[object Set]';
20471
20472 /** Used for built-in method references. */
20473 var objectProto$d = Object.prototype;
20474
20475 /** Used to check objects for own properties. */
20476 var hasOwnProperty$a = objectProto$d.hasOwnProperty;
20477
20478 /**
20479 * Checks if `value` is an empty object, collection, map, or set.
20480 *
20481 * Objects are considered empty if they have no own enumerable string keyed
20482 * properties.
20483 *
20484 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
20485 * jQuery-like collections are considered empty if they have a `length` of `0`.
20486 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
20487 *
20488 * @static
20489 * @memberOf _
20490 * @since 0.1.0
20491 * @category Lang
20492 * @param {*} value The value to check.
20493 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
20494 * @example
20495 *
20496 * _.isEmpty(null);
20497 * // => true
20498 *
20499 * _.isEmpty(true);
20500 * // => true
20501 *
20502 * _.isEmpty(1);
20503 * // => true
20504 *
20505 * _.isEmpty([1, 2, 3]);
20506 * // => false
20507 *
20508 * _.isEmpty({ 'a': 1 });
20509 * // => false
20510 */
20511 function isEmpty(value) {
20512 if (value == null) {
20513 return true;
20514 }
20515 if (isArrayLike_1(value) &&
20516 (isArray_1(value) || typeof value == 'string' || typeof value.splice == 'function' ||
20517 isBuffer_1(value) || isTypedArray_1(value) || isArguments_1(value))) {
20518 return !value.length;
20519 }
20520 var tag = _getTag(value);
20521 if (tag == mapTag$3 || tag == setTag$3) {
20522 return !value.size;
20523 }
20524 if (_isPrototype(value)) {
20525 return !_baseKeys(value).length;
20526 }
20527 for (var key in value) {
20528 if (hasOwnProperty$a.call(value, key)) {
20529 return false;
20530 }
20531 }
20532 return true;
20533 }
20534
20535 var isEmpty_1 = isEmpty;
20536
20537 /**
20538 * A specialized version of `_.forEach` for arrays without support for
20539 * iteratee shorthands.
20540 *
20541 * @private
20542 * @param {Array} [array] The array to iterate over.
20543 * @param {Function} iteratee The function invoked per iteration.
20544 * @returns {Array} Returns `array`.
20545 */
20546 function arrayEach(array, iteratee) {
20547 var index = -1,
20548 length = array == null ? 0 : array.length;
20549
20550 while (++index < length) {
20551 if (iteratee(array[index], index, array) === false) {
20552 break;
20553 }
20554 }
20555 return array;
20556 }
20557
20558 var _arrayEach = arrayEach;
20559
20560 var defineProperty = (function() {
20561 try {
20562 var func = _getNative(Object, 'defineProperty');
20563 func({}, '', {});
20564 return func;
20565 } catch (e) {}
20566 }());
20567
20568 var _defineProperty$1 = defineProperty;
20569
20570 /**
20571 * The base implementation of `assignValue` and `assignMergeValue` without
20572 * value checks.
20573 *
20574 * @private
20575 * @param {Object} object The object to modify.
20576 * @param {string} key The key of the property to assign.
20577 * @param {*} value The value to assign.
20578 */
20579 function baseAssignValue(object, key, value) {
20580 if (key == '__proto__' && _defineProperty$1) {
20581 _defineProperty$1(object, key, {
20582 'configurable': true,
20583 'enumerable': true,
20584 'value': value,
20585 'writable': true
20586 });
20587 } else {
20588 object[key] = value;
20589 }
20590 }
20591
20592 var _baseAssignValue = baseAssignValue;
20593
20594 /** Used for built-in method references. */
20595 var objectProto$e = Object.prototype;
20596
20597 /** Used to check objects for own properties. */
20598 var hasOwnProperty$b = objectProto$e.hasOwnProperty;
20599
20600 /**
20601 * Assigns `value` to `key` of `object` if the existing value is not equivalent
20602 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
20603 * for equality comparisons.
20604 *
20605 * @private
20606 * @param {Object} object The object to modify.
20607 * @param {string} key The key of the property to assign.
20608 * @param {*} value The value to assign.
20609 */
20610 function assignValue(object, key, value) {
20611 var objValue = object[key];
20612 if (!(hasOwnProperty$b.call(object, key) && eq_1(objValue, value)) ||
20613 (value === undefined && !(key in object))) {
20614 _baseAssignValue(object, key, value);
20615 }
20616 }
20617
20618 var _assignValue = assignValue;
20619
20620 /**
20621 * Copies properties of `source` to `object`.
20622 *
20623 * @private
20624 * @param {Object} source The object to copy properties from.
20625 * @param {Array} props The property identifiers to copy.
20626 * @param {Object} [object={}] The object to copy properties to.
20627 * @param {Function} [customizer] The function to customize copied values.
20628 * @returns {Object} Returns `object`.
20629 */
20630 function copyObject(source, props, object, customizer) {
20631 var isNew = !object;
20632 object || (object = {});
20633
20634 var index = -1,
20635 length = props.length;
20636
20637 while (++index < length) {
20638 var key = props[index];
20639
20640 var newValue = customizer
20641 ? customizer(object[key], source[key], key, object, source)
20642 : undefined;
20643
20644 if (newValue === undefined) {
20645 newValue = source[key];
20646 }
20647 if (isNew) {
20648 _baseAssignValue(object, key, newValue);
20649 } else {
20650 _assignValue(object, key, newValue);
20651 }
20652 }
20653 return object;
20654 }
20655
20656 var _copyObject = copyObject;
20657
20658 /**
20659 * The base implementation of `_.assign` without support for multiple sources
20660 * or `customizer` functions.
20661 *
20662 * @private
20663 * @param {Object} object The destination object.
20664 * @param {Object} source The source object.
20665 * @returns {Object} Returns `object`.
20666 */
20667 function baseAssign(object, source) {
20668 return object && _copyObject(source, keys_1(source), object);
20669 }
20670
20671 var _baseAssign = baseAssign;
20672
20673 /**
20674 * This function is like
20675 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
20676 * except that it includes inherited enumerable properties.
20677 *
20678 * @private
20679 * @param {Object} object The object to query.
20680 * @returns {Array} Returns the array of property names.
20681 */
20682 function nativeKeysIn(object) {
20683 var result = [];
20684 if (object != null) {
20685 for (var key in Object(object)) {
20686 result.push(key);
20687 }
20688 }
20689 return result;
20690 }
20691
20692 var _nativeKeysIn = nativeKeysIn;
20693
20694 /** Used for built-in method references. */
20695 var objectProto$f = Object.prototype;
20696
20697 /** Used to check objects for own properties. */
20698 var hasOwnProperty$c = objectProto$f.hasOwnProperty;
20699
20700 /**
20701 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
20702 *
20703 * @private
20704 * @param {Object} object The object to query.
20705 * @returns {Array} Returns the array of property names.
20706 */
20707 function baseKeysIn(object) {
20708 if (!isObject_1$1(object)) {
20709 return _nativeKeysIn(object);
20710 }
20711 var isProto = _isPrototype(object),
20712 result = [];
20713
20714 for (var key in object) {
20715 if (!(key == 'constructor' && (isProto || !hasOwnProperty$c.call(object, key)))) {
20716 result.push(key);
20717 }
20718 }
20719 return result;
20720 }
20721
20722 var _baseKeysIn = baseKeysIn;
20723
20724 /**
20725 * Creates an array of the own and inherited enumerable property names of `object`.
20726 *
20727 * **Note:** Non-object values are coerced to objects.
20728 *
20729 * @static
20730 * @memberOf _
20731 * @since 3.0.0
20732 * @category Object
20733 * @param {Object} object The object to query.
20734 * @returns {Array} Returns the array of property names.
20735 * @example
20736 *
20737 * function Foo() {
20738 * this.a = 1;
20739 * this.b = 2;
20740 * }
20741 *
20742 * Foo.prototype.c = 3;
20743 *
20744 * _.keysIn(new Foo);
20745 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
20746 */
20747 function keysIn$1(object) {
20748 return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object);
20749 }
20750
20751 var keysIn_1 = keysIn$1;
20752
20753 /**
20754 * The base implementation of `_.assignIn` without support for multiple sources
20755 * or `customizer` functions.
20756 *
20757 * @private
20758 * @param {Object} object The destination object.
20759 * @param {Object} source The source object.
20760 * @returns {Object} Returns `object`.
20761 */
20762 function baseAssignIn(object, source) {
20763 return object && _copyObject(source, keysIn_1(source), object);
20764 }
20765
20766 var _baseAssignIn = baseAssignIn;
20767
20768 var _cloneBuffer = createCommonjsModule(function (module, exports) {
20769 /** Detect free variable `exports`. */
20770 var freeExports = exports && !exports.nodeType && exports;
20771
20772 /** Detect free variable `module`. */
20773 var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
20774
20775 /** Detect the popular CommonJS extension `module.exports`. */
20776 var moduleExports = freeModule && freeModule.exports === freeExports;
20777
20778 /** Built-in value references. */
20779 var Buffer = moduleExports ? _root.Buffer : undefined,
20780 allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
20781
20782 /**
20783 * Creates a clone of `buffer`.
20784 *
20785 * @private
20786 * @param {Buffer} buffer The buffer to clone.
20787 * @param {boolean} [isDeep] Specify a deep clone.
20788 * @returns {Buffer} Returns the cloned buffer.
20789 */
20790 function cloneBuffer(buffer, isDeep) {
20791 if (isDeep) {
20792 return buffer.slice();
20793 }
20794 var length = buffer.length,
20795 result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
20796
20797 buffer.copy(result);
20798 return result;
20799 }
20800
20801 module.exports = cloneBuffer;
20802 });
20803
20804 /**
20805 * Copies own symbols of `source` to `object`.
20806 *
20807 * @private
20808 * @param {Object} source The object to copy symbols from.
20809 * @param {Object} [object={}] The object to copy symbols to.
20810 * @returns {Object} Returns `object`.
20811 */
20812 function copySymbols(source, object) {
20813 return _copyObject(source, _getSymbols(source), object);
20814 }
20815
20816 var _copySymbols = copySymbols;
20817
20818 /* Built-in method references for those with the same name as other `lodash` methods. */
20819 var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
20820
20821 /**
20822 * Creates an array of the own and inherited enumerable symbols of `object`.
20823 *
20824 * @private
20825 * @param {Object} object The object to query.
20826 * @returns {Array} Returns the array of symbols.
20827 */
20828 var getSymbolsIn = !nativeGetSymbols$1 ? stubArray_1 : function(object) {
20829 var result = [];
20830 while (object) {
20831 _arrayPush(result, _getSymbols(object));
20832 object = _getPrototype(object);
20833 }
20834 return result;
20835 };
20836
20837 var _getSymbolsIn = getSymbolsIn;
20838
20839 /**
20840 * Copies own and inherited symbols of `source` to `object`.
20841 *
20842 * @private
20843 * @param {Object} source The object to copy symbols from.
20844 * @param {Object} [object={}] The object to copy symbols to.
20845 * @returns {Object} Returns `object`.
20846 */
20847 function copySymbolsIn(source, object) {
20848 return _copyObject(source, _getSymbolsIn(source), object);
20849 }
20850
20851 var _copySymbolsIn = copySymbolsIn;
20852
20853 /**
20854 * Creates an array of own and inherited enumerable property names and
20855 * symbols of `object`.
20856 *
20857 * @private
20858 * @param {Object} object The object to query.
20859 * @returns {Array} Returns the array of property names and symbols.
20860 */
20861 function getAllKeysIn(object) {
20862 return _baseGetAllKeys(object, keysIn_1, _getSymbolsIn);
20863 }
20864
20865 var _getAllKeysIn = getAllKeysIn;
20866
20867 /** Used for built-in method references. */
20868 var objectProto$g = Object.prototype;
20869
20870 /** Used to check objects for own properties. */
20871 var hasOwnProperty$d = objectProto$g.hasOwnProperty;
20872
20873 /**
20874 * Initializes an array clone.
20875 *
20876 * @private
20877 * @param {Array} array The array to clone.
20878 * @returns {Array} Returns the initialized clone.
20879 */
20880 function initCloneArray(array) {
20881 var length = array.length,
20882 result = new array.constructor(length);
20883
20884 // Add properties assigned by `RegExp#exec`.
20885 if (length && typeof array[0] == 'string' && hasOwnProperty$d.call(array, 'index')) {
20886 result.index = array.index;
20887 result.input = array.input;
20888 }
20889 return result;
20890 }
20891
20892 var _initCloneArray = initCloneArray;
20893
20894 /**
20895 * Creates a clone of `arrayBuffer`.
20896 *
20897 * @private
20898 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
20899 * @returns {ArrayBuffer} Returns the cloned array buffer.
20900 */
20901 function cloneArrayBuffer(arrayBuffer) {
20902 var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
20903 new _Uint8Array(result).set(new _Uint8Array(arrayBuffer));
20904 return result;
20905 }
20906
20907 var _cloneArrayBuffer = cloneArrayBuffer;
20908
20909 /**
20910 * Creates a clone of `dataView`.
20911 *
20912 * @private
20913 * @param {Object} dataView The data view to clone.
20914 * @param {boolean} [isDeep] Specify a deep clone.
20915 * @returns {Object} Returns the cloned data view.
20916 */
20917 function cloneDataView(dataView, isDeep) {
20918 var buffer = isDeep ? _cloneArrayBuffer(dataView.buffer) : dataView.buffer;
20919 return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
20920 }
20921
20922 var _cloneDataView = cloneDataView;
20923
20924 /** Used to match `RegExp` flags from their coerced string values. */
20925 var reFlags = /\w*$/;
20926
20927 /**
20928 * Creates a clone of `regexp`.
20929 *
20930 * @private
20931 * @param {Object} regexp The regexp to clone.
20932 * @returns {Object} Returns the cloned regexp.
20933 */
20934 function cloneRegExp(regexp) {
20935 var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
20936 result.lastIndex = regexp.lastIndex;
20937 return result;
20938 }
20939
20940 var _cloneRegExp = cloneRegExp;
20941
20942 /** Used to convert symbols to primitives and strings. */
20943 var symbolProto$2 = _Symbol ? _Symbol.prototype : undefined,
20944 symbolValueOf$1 = symbolProto$2 ? symbolProto$2.valueOf : undefined;
20945
20946 /**
20947 * Creates a clone of the `symbol` object.
20948 *
20949 * @private
20950 * @param {Object} symbol The symbol object to clone.
20951 * @returns {Object} Returns the cloned symbol object.
20952 */
20953 function cloneSymbol(symbol) {
20954 return symbolValueOf$1 ? Object(symbolValueOf$1.call(symbol)) : {};
20955 }
20956
20957 var _cloneSymbol = cloneSymbol;
20958
20959 /**
20960 * Creates a clone of `typedArray`.
20961 *
20962 * @private
20963 * @param {Object} typedArray The typed array to clone.
20964 * @param {boolean} [isDeep] Specify a deep clone.
20965 * @returns {Object} Returns the cloned typed array.
20966 */
20967 function cloneTypedArray(typedArray, isDeep) {
20968 var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
20969 return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
20970 }
20971
20972 var _cloneTypedArray = cloneTypedArray;
20973
20974 /** `Object#toString` result references. */
20975 var boolTag$2 = '[object Boolean]',
20976 dateTag$2 = '[object Date]',
20977 mapTag$4 = '[object Map]',
20978 numberTag$2 = '[object Number]',
20979 regexpTag$2 = '[object RegExp]',
20980 setTag$4 = '[object Set]',
20981 stringTag$2 = '[object String]',
20982 symbolTag$2 = '[object Symbol]';
20983
20984 var arrayBufferTag$2 = '[object ArrayBuffer]',
20985 dataViewTag$3 = '[object DataView]',
20986 float32Tag$1 = '[object Float32Array]',
20987 float64Tag$1 = '[object Float64Array]',
20988 int8Tag$1 = '[object Int8Array]',
20989 int16Tag$1 = '[object Int16Array]',
20990 int32Tag$1 = '[object Int32Array]',
20991 uint8Tag$1 = '[object Uint8Array]',
20992 uint8ClampedTag$1 = '[object Uint8ClampedArray]',
20993 uint16Tag$1 = '[object Uint16Array]',
20994 uint32Tag$1 = '[object Uint32Array]';
20995
20996 /**
20997 * Initializes an object clone based on its `toStringTag`.
20998 *
20999 * **Note:** This function only supports cloning values with tags of
21000 * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
21001 *
21002 * @private
21003 * @param {Object} object The object to clone.
21004 * @param {string} tag The `toStringTag` of the object to clone.
21005 * @param {boolean} [isDeep] Specify a deep clone.
21006 * @returns {Object} Returns the initialized clone.
21007 */
21008 function initCloneByTag(object, tag, isDeep) {
21009 var Ctor = object.constructor;
21010 switch (tag) {
21011 case arrayBufferTag$2:
21012 return _cloneArrayBuffer(object);
21013
21014 case boolTag$2:
21015 case dateTag$2:
21016 return new Ctor(+object);
21017
21018 case dataViewTag$3:
21019 return _cloneDataView(object, isDeep);
21020
21021 case float32Tag$1: case float64Tag$1:
21022 case int8Tag$1: case int16Tag$1: case int32Tag$1:
21023 case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
21024 return _cloneTypedArray(object, isDeep);
21025
21026 case mapTag$4:
21027 return new Ctor;
21028
21029 case numberTag$2:
21030 case stringTag$2:
21031 return new Ctor(object);
21032
21033 case regexpTag$2:
21034 return _cloneRegExp(object);
21035
21036 case setTag$4:
21037 return new Ctor;
21038
21039 case symbolTag$2:
21040 return _cloneSymbol(object);
21041 }
21042 }
21043
21044 var _initCloneByTag = initCloneByTag;
21045
21046 /** Built-in value references. */
21047 var objectCreate = Object.create;
21048
21049 /**
21050 * The base implementation of `_.create` without support for assigning
21051 * properties to the created object.
21052 *
21053 * @private
21054 * @param {Object} proto The object to inherit from.
21055 * @returns {Object} Returns the new object.
21056 */
21057 var baseCreate = (function() {
21058 function object() {}
21059 return function(proto) {
21060 if (!isObject_1$1(proto)) {
21061 return {};
21062 }
21063 if (objectCreate) {
21064 return objectCreate(proto);
21065 }
21066 object.prototype = proto;
21067 var result = new object;
21068 object.prototype = undefined;
21069 return result;
21070 };
21071 }());
21072
21073 var _baseCreate = baseCreate;
21074
21075 /**
21076 * Initializes an object clone.
21077 *
21078 * @private
21079 * @param {Object} object The object to clone.
21080 * @returns {Object} Returns the initialized clone.
21081 */
21082 function initCloneObject(object) {
21083 return (typeof object.constructor == 'function' && !_isPrototype(object))
21084 ? _baseCreate(_getPrototype(object))
21085 : {};
21086 }
21087
21088 var _initCloneObject = initCloneObject;
21089
21090 /** `Object#toString` result references. */
21091 var mapTag$5 = '[object Map]';
21092
21093 /**
21094 * The base implementation of `_.isMap` without Node.js optimizations.
21095 *
21096 * @private
21097 * @param {*} value The value to check.
21098 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
21099 */
21100 function baseIsMap(value) {
21101 return isObjectLike_1(value) && _getTag(value) == mapTag$5;
21102 }
21103
21104 var _baseIsMap = baseIsMap;
21105
21106 /* Node.js helper references. */
21107 var nodeIsMap = _nodeUtil && _nodeUtil.isMap;
21108
21109 /**
21110 * Checks if `value` is classified as a `Map` object.
21111 *
21112 * @static
21113 * @memberOf _
21114 * @since 4.3.0
21115 * @category Lang
21116 * @param {*} value The value to check.
21117 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
21118 * @example
21119 *
21120 * _.isMap(new Map);
21121 * // => true
21122 *
21123 * _.isMap(new WeakMap);
21124 * // => false
21125 */
21126 var isMap = nodeIsMap ? _baseUnary(nodeIsMap) : _baseIsMap;
21127
21128 var isMap_1 = isMap;
21129
21130 /** `Object#toString` result references. */
21131 var setTag$5 = '[object Set]';
21132
21133 /**
21134 * The base implementation of `_.isSet` without Node.js optimizations.
21135 *
21136 * @private
21137 * @param {*} value The value to check.
21138 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
21139 */
21140 function baseIsSet(value) {
21141 return isObjectLike_1(value) && _getTag(value) == setTag$5;
21142 }
21143
21144 var _baseIsSet = baseIsSet;
21145
21146 /* Node.js helper references. */
21147 var nodeIsSet = _nodeUtil && _nodeUtil.isSet;
21148
21149 /**
21150 * Checks if `value` is classified as a `Set` object.
21151 *
21152 * @static
21153 * @memberOf _
21154 * @since 4.3.0
21155 * @category Lang
21156 * @param {*} value The value to check.
21157 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
21158 * @example
21159 *
21160 * _.isSet(new Set);
21161 * // => true
21162 *
21163 * _.isSet(new WeakSet);
21164 * // => false
21165 */
21166 var isSet = nodeIsSet ? _baseUnary(nodeIsSet) : _baseIsSet;
21167
21168 var isSet_1 = isSet;
21169
21170 /** Used to compose bitmasks for cloning. */
21171 var CLONE_DEEP_FLAG = 1,
21172 CLONE_FLAT_FLAG = 2,
21173 CLONE_SYMBOLS_FLAG = 4;
21174
21175 /** `Object#toString` result references. */
21176 var argsTag$3 = '[object Arguments]',
21177 arrayTag$2 = '[object Array]',
21178 boolTag$3 = '[object Boolean]',
21179 dateTag$3 = '[object Date]',
21180 errorTag$2 = '[object Error]',
21181 funcTag$2 = '[object Function]',
21182 genTag$1 = '[object GeneratorFunction]',
21183 mapTag$6 = '[object Map]',
21184 numberTag$3 = '[object Number]',
21185 objectTag$4 = '[object Object]',
21186 regexpTag$3 = '[object RegExp]',
21187 setTag$6 = '[object Set]',
21188 stringTag$3 = '[object String]',
21189 symbolTag$3 = '[object Symbol]',
21190 weakMapTag$2 = '[object WeakMap]';
21191
21192 var arrayBufferTag$3 = '[object ArrayBuffer]',
21193 dataViewTag$4 = '[object DataView]',
21194 float32Tag$2 = '[object Float32Array]',
21195 float64Tag$2 = '[object Float64Array]',
21196 int8Tag$2 = '[object Int8Array]',
21197 int16Tag$2 = '[object Int16Array]',
21198 int32Tag$2 = '[object Int32Array]',
21199 uint8Tag$2 = '[object Uint8Array]',
21200 uint8ClampedTag$2 = '[object Uint8ClampedArray]',
21201 uint16Tag$2 = '[object Uint16Array]',
21202 uint32Tag$2 = '[object Uint32Array]';
21203
21204 /** Used to identify `toStringTag` values supported by `_.clone`. */
21205 var cloneableTags = {};
21206 cloneableTags[argsTag$3] = cloneableTags[arrayTag$2] =
21207 cloneableTags[arrayBufferTag$3] = cloneableTags[dataViewTag$4] =
21208 cloneableTags[boolTag$3] = cloneableTags[dateTag$3] =
21209 cloneableTags[float32Tag$2] = cloneableTags[float64Tag$2] =
21210 cloneableTags[int8Tag$2] = cloneableTags[int16Tag$2] =
21211 cloneableTags[int32Tag$2] = cloneableTags[mapTag$6] =
21212 cloneableTags[numberTag$3] = cloneableTags[objectTag$4] =
21213 cloneableTags[regexpTag$3] = cloneableTags[setTag$6] =
21214 cloneableTags[stringTag$3] = cloneableTags[symbolTag$3] =
21215 cloneableTags[uint8Tag$2] = cloneableTags[uint8ClampedTag$2] =
21216 cloneableTags[uint16Tag$2] = cloneableTags[uint32Tag$2] = true;
21217 cloneableTags[errorTag$2] = cloneableTags[funcTag$2] =
21218 cloneableTags[weakMapTag$2] = false;
21219
21220 /**
21221 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
21222 * traversed objects.
21223 *
21224 * @private
21225 * @param {*} value The value to clone.
21226 * @param {boolean} bitmask The bitmask flags.
21227 * 1 - Deep clone
21228 * 2 - Flatten inherited properties
21229 * 4 - Clone symbols
21230 * @param {Function} [customizer] The function to customize cloning.
21231 * @param {string} [key] The key of `value`.
21232 * @param {Object} [object] The parent object of `value`.
21233 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
21234 * @returns {*} Returns the cloned value.
21235 */
21236 function baseClone(value, bitmask, customizer, key, object, stack) {
21237 var result,
21238 isDeep = bitmask & CLONE_DEEP_FLAG,
21239 isFlat = bitmask & CLONE_FLAT_FLAG,
21240 isFull = bitmask & CLONE_SYMBOLS_FLAG;
21241
21242 if (customizer) {
21243 result = object ? customizer(value, key, object, stack) : customizer(value);
21244 }
21245 if (result !== undefined) {
21246 return result;
21247 }
21248 if (!isObject_1$1(value)) {
21249 return value;
21250 }
21251 var isArr = isArray_1(value);
21252 if (isArr) {
21253 result = _initCloneArray(value);
21254 if (!isDeep) {
21255 return _copyArray(value, result);
21256 }
21257 } else {
21258 var tag = _getTag(value),
21259 isFunc = tag == funcTag$2 || tag == genTag$1;
21260
21261 if (isBuffer_1(value)) {
21262 return _cloneBuffer(value, isDeep);
21263 }
21264 if (tag == objectTag$4 || tag == argsTag$3 || (isFunc && !object)) {
21265 result = (isFlat || isFunc) ? {} : _initCloneObject(value);
21266 if (!isDeep) {
21267 return isFlat
21268 ? _copySymbolsIn(value, _baseAssignIn(result, value))
21269 : _copySymbols(value, _baseAssign(result, value));
21270 }
21271 } else {
21272 if (!cloneableTags[tag]) {
21273 return object ? value : {};
21274 }
21275 result = _initCloneByTag(value, tag, isDeep);
21276 }
21277 }
21278 // Check for circular references and return its corresponding clone.
21279 stack || (stack = new _Stack);
21280 var stacked = stack.get(value);
21281 if (stacked) {
21282 return stacked;
21283 }
21284 stack.set(value, result);
21285
21286 if (isSet_1(value)) {
21287 value.forEach(function(subValue) {
21288 result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
21289 });
21290
21291 return result;
21292 }
21293
21294 if (isMap_1(value)) {
21295 value.forEach(function(subValue, key) {
21296 result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
21297 });
21298
21299 return result;
21300 }
21301
21302 var keysFunc = isFull
21303 ? (isFlat ? _getAllKeysIn : _getAllKeys)
21304 : (isFlat ? keysIn : keys_1);
21305
21306 var props = isArr ? undefined : keysFunc(value);
21307 _arrayEach(props || value, function(subValue, key) {
21308 if (props) {
21309 key = subValue;
21310 subValue = value[key];
21311 }
21312 // Recursively populate clone (susceptible to call stack limits).
21313 _assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
21314 });
21315 return result;
21316 }
21317
21318 var _baseClone = baseClone;
21319
21320 /** Used to compose bitmasks for cloning. */
21321 var CLONE_DEEP_FLAG$1 = 1,
21322 CLONE_SYMBOLS_FLAG$1 = 4;
21323
21324 /**
21325 * This method is like `_.clone` except that it recursively clones `value`.
21326 *
21327 * @static
21328 * @memberOf _
21329 * @since 1.0.0
21330 * @category Lang
21331 * @param {*} value The value to recursively clone.
21332 * @returns {*} Returns the deep cloned value.
21333 * @see _.clone
21334 * @example
21335 *
21336 * var objects = [{ 'a': 1 }, { 'b': 2 }];
21337 *
21338 * var deep = _.cloneDeep(objects);
21339 * console.log(deep[0] === objects[0]);
21340 * // => false
21341 */
21342 function cloneDeep(value) {
21343 return _baseClone(value, CLONE_DEEP_FLAG$1 | CLONE_SYMBOLS_FLAG$1);
21344 }
21345
21346 var cloneDeep_1 = cloneDeep;
21347
21348 /**
21349 * Creates a `_.find` or `_.findLast` function.
21350 *
21351 * @private
21352 * @param {Function} findIndexFunc The function to find the collection index.
21353 * @returns {Function} Returns the new find function.
21354 */
21355 function createFind(findIndexFunc) {
21356 return function(collection, predicate, fromIndex) {
21357 var iterable = Object(collection);
21358 if (!isArrayLike_1(collection)) {
21359 var iteratee = _baseIteratee(predicate, 3);
21360 collection = keys_1(collection);
21361 predicate = function(key) { return iteratee(iterable[key], key, iterable); };
21362 }
21363 var index = findIndexFunc(collection, predicate, fromIndex);
21364 return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
21365 };
21366 }
21367
21368 var _createFind = createFind;
21369
21370 /**
21371 * The base implementation of `_.findIndex` and `_.findLastIndex` without
21372 * support for iteratee shorthands.
21373 *
21374 * @private
21375 * @param {Array} array The array to inspect.
21376 * @param {Function} predicate The function invoked per iteration.
21377 * @param {number} fromIndex The index to search from.
21378 * @param {boolean} [fromRight] Specify iterating from right to left.
21379 * @returns {number} Returns the index of the matched value, else `-1`.
21380 */
21381 function baseFindIndex(array, predicate, fromIndex, fromRight) {
21382 var length = array.length,
21383 index = fromIndex + (fromRight ? 1 : -1);
21384
21385 while ((fromRight ? index-- : ++index < length)) {
21386 if (predicate(array[index], index, array)) {
21387 return index;
21388 }
21389 }
21390 return -1;
21391 }
21392
21393 var _baseFindIndex = baseFindIndex;
21394
21395 /** Used as references for various `Number` constants. */
21396 var NAN = 0 / 0;
21397
21398 /** Used to match leading and trailing whitespace. */
21399 var reTrim = /^\s+|\s+$/g;
21400
21401 /** Used to detect bad signed hexadecimal string values. */
21402 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
21403
21404 /** Used to detect binary string values. */
21405 var reIsBinary = /^0b[01]+$/i;
21406
21407 /** Used to detect octal string values. */
21408 var reIsOctal = /^0o[0-7]+$/i;
21409
21410 /** Built-in method references without a dependency on `root`. */
21411 var freeParseInt = parseInt;
21412
21413 /**
21414 * Converts `value` to a number.
21415 *
21416 * @static
21417 * @memberOf _
21418 * @since 4.0.0
21419 * @category Lang
21420 * @param {*} value The value to process.
21421 * @returns {number} Returns the number.
21422 * @example
21423 *
21424 * _.toNumber(3.2);
21425 * // => 3.2
21426 *
21427 * _.toNumber(Number.MIN_VALUE);
21428 * // => 5e-324
21429 *
21430 * _.toNumber(Infinity);
21431 * // => Infinity
21432 *
21433 * _.toNumber('3.2');
21434 * // => 3.2
21435 */
21436 function toNumber(value) {
21437 if (typeof value == 'number') {
21438 return value;
21439 }
21440 if (isSymbol_1(value)) {
21441 return NAN;
21442 }
21443 if (isObject_1$1(value)) {
21444 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
21445 value = isObject_1$1(other) ? (other + '') : other;
21446 }
21447 if (typeof value != 'string') {
21448 return value === 0 ? value : +value;
21449 }
21450 value = value.replace(reTrim, '');
21451 var isBinary = reIsBinary.test(value);
21452 return (isBinary || reIsOctal.test(value))
21453 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
21454 : (reIsBadHex.test(value) ? NAN : +value);
21455 }
21456
21457 var toNumber_1 = toNumber;
21458
21459 /** Used as references for various `Number` constants. */
21460 var INFINITY$2 = 1 / 0,
21461 MAX_INTEGER = 1.7976931348623157e+308;
21462
21463 /**
21464 * Converts `value` to a finite number.
21465 *
21466 * @static
21467 * @memberOf _
21468 * @since 4.12.0
21469 * @category Lang
21470 * @param {*} value The value to convert.
21471 * @returns {number} Returns the converted number.
21472 * @example
21473 *
21474 * _.toFinite(3.2);
21475 * // => 3.2
21476 *
21477 * _.toFinite(Number.MIN_VALUE);
21478 * // => 5e-324
21479 *
21480 * _.toFinite(Infinity);
21481 * // => 1.7976931348623157e+308
21482 *
21483 * _.toFinite('3.2');
21484 * // => 3.2
21485 */
21486 function toFinite(value) {
21487 if (!value) {
21488 return value === 0 ? value : 0;
21489 }
21490 value = toNumber_1(value);
21491 if (value === INFINITY$2 || value === -INFINITY$2) {
21492 var sign = (value < 0 ? -1 : 1);
21493 return sign * MAX_INTEGER;
21494 }
21495 return value === value ? value : 0;
21496 }
21497
21498 var toFinite_1 = toFinite;
21499
21500 /**
21501 * Converts `value` to an integer.
21502 *
21503 * **Note:** This method is loosely based on
21504 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
21505 *
21506 * @static
21507 * @memberOf _
21508 * @since 4.0.0
21509 * @category Lang
21510 * @param {*} value The value to convert.
21511 * @returns {number} Returns the converted integer.
21512 * @example
21513 *
21514 * _.toInteger(3.2);
21515 * // => 3
21516 *
21517 * _.toInteger(Number.MIN_VALUE);
21518 * // => 0
21519 *
21520 * _.toInteger(Infinity);
21521 * // => 1.7976931348623157e+308
21522 *
21523 * _.toInteger('3.2');
21524 * // => 3
21525 */
21526 function toInteger(value) {
21527 var result = toFinite_1(value),
21528 remainder = result % 1;
21529
21530 return result === result ? (remainder ? result - remainder : result) : 0;
21531 }
21532
21533 var toInteger_1 = toInteger;
21534
21535 /* Built-in method references for those with the same name as other `lodash` methods. */
21536 var nativeMax = Math.max;
21537
21538 /**
21539 * This method is like `_.find` except that it returns the index of the first
21540 * element `predicate` returns truthy for instead of the element itself.
21541 *
21542 * @static
21543 * @memberOf _
21544 * @since 1.1.0
21545 * @category Array
21546 * @param {Array} array The array to inspect.
21547 * @param {Function} [predicate=_.identity] The function invoked per iteration.
21548 * @param {number} [fromIndex=0] The index to search from.
21549 * @returns {number} Returns the index of the found element, else `-1`.
21550 * @example
21551 *
21552 * var users = [
21553 * { 'user': 'barney', 'active': false },
21554 * { 'user': 'fred', 'active': false },
21555 * { 'user': 'pebbles', 'active': true }
21556 * ];
21557 *
21558 * _.findIndex(users, function(o) { return o.user == 'barney'; });
21559 * // => 0
21560 *
21561 * // The `_.matches` iteratee shorthand.
21562 * _.findIndex(users, { 'user': 'fred', 'active': false });
21563 * // => 1
21564 *
21565 * // The `_.matchesProperty` iteratee shorthand.
21566 * _.findIndex(users, ['active', false]);
21567 * // => 0
21568 *
21569 * // The `_.property` iteratee shorthand.
21570 * _.findIndex(users, 'active');
21571 * // => 2
21572 */
21573 function findIndex(array, predicate, fromIndex) {
21574 var length = array == null ? 0 : array.length;
21575 if (!length) {
21576 return -1;
21577 }
21578 var index = fromIndex == null ? 0 : toInteger_1(fromIndex);
21579 if (index < 0) {
21580 index = nativeMax(length + index, 0);
21581 }
21582 return _baseFindIndex(array, _baseIteratee(predicate, 3), index);
21583 }
21584
21585 var findIndex_1 = findIndex;
21586
21587 /**
21588 * Iterates over elements of `collection`, returning the first element
21589 * `predicate` returns truthy for. The predicate is invoked with three
21590 * arguments: (value, index|key, collection).
21591 *
21592 * @static
21593 * @memberOf _
21594 * @since 0.1.0
21595 * @category Collection
21596 * @param {Array|Object} collection The collection to inspect.
21597 * @param {Function} [predicate=_.identity] The function invoked per iteration.
21598 * @param {number} [fromIndex=0] The index to search from.
21599 * @returns {*} Returns the matched element, else `undefined`.
21600 * @example
21601 *
21602 * var users = [
21603 * { 'user': 'barney', 'age': 36, 'active': true },
21604 * { 'user': 'fred', 'age': 40, 'active': false },
21605 * { 'user': 'pebbles', 'age': 1, 'active': true }
21606 * ];
21607 *
21608 * _.find(users, function(o) { return o.age < 40; });
21609 * // => object for 'barney'
21610 *
21611 * // The `_.matches` iteratee shorthand.
21612 * _.find(users, { 'age': 1, 'active': true });
21613 * // => object for 'pebbles'
21614 *
21615 * // The `_.matchesProperty` iteratee shorthand.
21616 * _.find(users, ['active', false]);
21617 * // => object for 'fred'
21618 *
21619 * // The `_.property` iteratee shorthand.
21620 * _.find(users, 'active');
21621 * // => object for 'barney'
21622 */
21623 var find = _createFind(findIndex_1);
21624
21625 var find_1 = find;
21626
21627 // IMClient
21628 var UNREAD_MESSAGES_COUNT_UPDATE = 'unreadmessagescountupdate';
21629 var CLOSE = 'close';
21630 var CONFLICT = 'conflict';
21631 var CONVERSATION_INFO_UPDATED = 'conversationinfoupdated';
21632 var UNHANDLED_MESSAGE = 'unhandledmessage'; // shared
21633
21634 var INVITED = 'invited';
21635 var KICKED = 'kicked';
21636 var MEMBERS_JOINED = 'membersjoined';
21637 var MEMBERS_LEFT = 'membersleft';
21638 var MEMBER_INFO_UPDATED = 'memberinfoupdated';
21639 var BLOCKED = 'blocked';
21640 var UNBLOCKED = 'unblocked';
21641 var MEMBERS_BLOCKED = 'membersblocked';
21642 var MEMBERS_UNBLOCKED = 'membersunblocked';
21643 var MUTED = 'muted';
21644 var UNMUTED = 'unmuted';
21645 var MEMBERS_MUTED = 'membersmuted';
21646 var MEMBERS_UNMUTED = 'membersunmuted';
21647 var MESSAGE$1 = 'message';
21648 var MESSAGE_RECALL = 'messagerecall';
21649 var MESSAGE_UPDATE = 'messageupdate'; // Conversation
21650
21651 var LAST_DELIVERED_AT_UPDATE = 'lastdeliveredatupdate';
21652 var LAST_READ_AT_UPDATE = 'lastreadatupdate';
21653 var INFO_UPDATED = 'infoupdated';
21654
21655 var Event = /*#__PURE__*/Object.freeze({
21656 UNREAD_MESSAGES_COUNT_UPDATE: UNREAD_MESSAGES_COUNT_UPDATE,
21657 CLOSE: CLOSE,
21658 CONFLICT: CONFLICT,
21659 CONVERSATION_INFO_UPDATED: CONVERSATION_INFO_UPDATED,
21660 UNHANDLED_MESSAGE: UNHANDLED_MESSAGE,
21661 INVITED: INVITED,
21662 KICKED: KICKED,
21663 MEMBERS_JOINED: MEMBERS_JOINED,
21664 MEMBERS_LEFT: MEMBERS_LEFT,
21665 MEMBER_INFO_UPDATED: MEMBER_INFO_UPDATED,
21666 BLOCKED: BLOCKED,
21667 UNBLOCKED: UNBLOCKED,
21668 MEMBERS_BLOCKED: MEMBERS_BLOCKED,
21669 MEMBERS_UNBLOCKED: MEMBERS_UNBLOCKED,
21670 MUTED: MUTED,
21671 UNMUTED: UNMUTED,
21672 MEMBERS_MUTED: MEMBERS_MUTED,
21673 MEMBERS_UNMUTED: MEMBERS_UNMUTED,
21674 MESSAGE: MESSAGE$1,
21675 MESSAGE_RECALL: MESSAGE_RECALL,
21676 MESSAGE_UPDATE: MESSAGE_UPDATE,
21677 LAST_DELIVERED_AT_UPDATE: LAST_DELIVERED_AT_UPDATE,
21678 LAST_READ_AT_UPDATE: LAST_READ_AT_UPDATE,
21679 INFO_UPDATED: INFO_UPDATED
21680 });
21681
21682 var _rMessageStatus;
21683 /**
21684 * 消息状态枚举
21685 * @enum {Symbol}
21686 * @since 3.2.0
21687 * @memberof module:leancloud-realtime
21688 */
21689
21690 var MessageStatus = {
21691 /** 初始状态、未知状态 */
21692 NONE: Symbol('none'),
21693
21694 /** 正在发送 */
21695 SENDING: Symbol('sending'),
21696
21697 /** 已发送 */
21698 SENT: Symbol('sent'),
21699
21700 /** 已送达 */
21701 DELIVERED: Symbol('delivered'),
21702
21703 /** 发送失败 */
21704 FAILED: Symbol('failed')
21705 };
21706 Object.freeze(MessageStatus);
21707 var rMessageStatus = (_rMessageStatus = {}, _defineProperty(_rMessageStatus, MessageStatus.NONE, true), _defineProperty(_rMessageStatus, MessageStatus.SENDING, true), _defineProperty(_rMessageStatus, MessageStatus.SENT, true), _defineProperty(_rMessageStatus, MessageStatus.DELIVERED, true), _defineProperty(_rMessageStatus, MessageStatus.READ, true), _defineProperty(_rMessageStatus, MessageStatus.FAILED, true), _rMessageStatus);
21708
21709 var Message =
21710 /*#__PURE__*/
21711 function () {
21712 /**
21713 * @implements AVMessage
21714 * @param {Object|String|ArrayBuffer} content 消息内容
21715 */
21716 function Message(content) {
21717 Object.assign(this, {
21718 content: content
21719 }, {
21720 /**
21721 * @type {String}
21722 * @memberof Message#
21723 */
21724 id: v4_1(),
21725
21726 /**
21727 * 消息所在的 conversation id
21728 * @memberof Message#
21729 * @type {String?}
21730 */
21731 cid: null,
21732
21733 /**
21734 * 消息发送时间
21735 * @memberof Message#
21736 * @type {Date}
21737 */
21738 timestamp: new Date(),
21739
21740 /**
21741 * 消息发送者
21742 * @memberof Message#
21743 * @type {String}
21744 */
21745 from: undefined,
21746
21747 /**
21748 * 消息提及的用户
21749 * @since 4.0.0
21750 * @memberof Message#
21751 * @type {String[]}
21752 */
21753 mentionList: [],
21754
21755 /**
21756 * 消息是否提及了所有人
21757 * @since 4.0.0
21758 * @memberof Message#
21759 * @type {Boolean}
21760 */
21761 mentionedAll: false,
21762 _mentioned: false
21763 });
21764
21765 this._setStatus(MessageStatus.NONE);
21766 }
21767 /**
21768 * 将当前消息的内容序列化为 JSON 对象
21769 * @private
21770 * @return {Object}
21771 */
21772
21773
21774 var _proto = Message.prototype;
21775
21776 _proto.getPayload = function getPayload() {
21777 return this.content;
21778 };
21779
21780 _proto._toJSON = function _toJSON() {
21781 var id = this.id,
21782 cid = this.cid,
21783 from = this.from,
21784 timestamp = this.timestamp,
21785 deliveredAt = this.deliveredAt,
21786 updatedAt = this.updatedAt,
21787 mentionList = this.mentionList,
21788 mentionedAll = this.mentionedAll,
21789 mentioned = this.mentioned;
21790 return {
21791 id: id,
21792 cid: cid,
21793 from: from,
21794 timestamp: timestamp,
21795 deliveredAt: deliveredAt,
21796 updatedAt: updatedAt,
21797 mentionList: mentionList,
21798 mentionedAll: mentionedAll,
21799 mentioned: mentioned
21800 };
21801 }
21802 /**
21803 * 返回 JSON 格式的消息
21804 * @return {Object} 返回值是一个 plain Object
21805 */
21806 ;
21807
21808 _proto.toJSON = function toJSON() {
21809 return _objectSpread({}, this._toJSON(), {
21810 data: this.content
21811 });
21812 }
21813 /**
21814 * 返回 JSON 格式的消息,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseMessage} 反序列化。
21815 * @return {Object} 返回值是一个 plain Object
21816 * @since 4.0.0
21817 */
21818 ;
21819
21820 _proto.toFullJSON = function toFullJSON() {
21821 var content = this.content,
21822 id = this.id,
21823 cid = this.cid,
21824 from = this.from,
21825 timestamp = this.timestamp,
21826 deliveredAt = this.deliveredAt,
21827 _updatedAt = this._updatedAt,
21828 mentionList = this.mentionList,
21829 mentionedAll = this.mentionedAll;
21830 return {
21831 data: content,
21832 id: id,
21833 cid: cid,
21834 from: from,
21835 timestamp: getTime(timestamp),
21836 deliveredAt: getTime(deliveredAt),
21837 updatedAt: getTime(_updatedAt),
21838 mentionList: mentionList,
21839 mentionedAll: mentionedAll
21840 };
21841 }
21842 /**
21843 * 消息状态,值为 {@link module:leancloud-realtime.MessageStatus} 之一
21844 * @type {Symbol}
21845 * @readonly
21846 * @since 3.2.0
21847 */
21848 ;
21849
21850 _proto._setStatus = function _setStatus(status) {
21851 if (!rMessageStatus[status]) {
21852 throw new Error('Invalid message status');
21853 }
21854
21855 this._status = status;
21856 };
21857
21858 _proto._updateMentioned = function _updateMentioned(client) {
21859 this._mentioned = this.from !== client && (this.mentionedAll || this.mentionList.indexOf(client) > -1);
21860 }
21861 /**
21862 * 获取提及用户列表
21863 * @since 4.0.0
21864 * @return {String[]} 提及用户的 id 列表
21865 */
21866 ;
21867
21868 _proto.getMentionList = function getMentionList() {
21869 return this.mentionList;
21870 }
21871 /**
21872 * 设置提及用户列表
21873 * @since 4.0.0
21874 * @param {String[]} clients 提及用户的 id 列表
21875 * @return {this} self
21876 */
21877 ;
21878
21879 _proto.setMentionList = function setMentionList(clients) {
21880 this.mentionList = ensureArray(clients);
21881 return this;
21882 }
21883 /**
21884 * 设置是否提及所有人
21885 * @since 4.0.0
21886 * @param {Boolean} [value=true]
21887 * @return {this} self
21888 */
21889 ;
21890
21891 _proto.mentionAll = function mentionAll() {
21892 var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
21893 this.mentionedAll = Boolean(value);
21894 return this;
21895 }
21896 /**
21897 * 判断给定的内容是否是有效的 Message,
21898 * 该方法始终返回 true
21899 * @private
21900 * @returns {Boolean}
21901 * @implements AVMessage.validate
21902 */
21903 ;
21904
21905 Message.validate = function validate() {
21906 return true;
21907 }
21908 /**
21909 * 解析处理消息内容
21910 * <pre>
21911 * 如果子类提供了 message,返回该 message
21912 * 如果没有提供,将 json 作为 content 实例化一个 Message
21913 * @private
21914 * @param {Object} json json 格式的消息内容
21915 * @param {Message} message 子类提供的 message
21916 * @return {Message}
21917 * @implements AVMessage.parse
21918 */
21919 ;
21920
21921 Message.parse = function parse(json, message) {
21922 return message || new this(json);
21923 };
21924
21925 _createClass(Message, [{
21926 key: "status",
21927 get: function get() {
21928 return this._status;
21929 }
21930 }, {
21931 key: "timestamp",
21932 get: function get() {
21933 return this._timestamp;
21934 },
21935 set: function set(value) {
21936 this._timestamp = decodeDate(value);
21937 }
21938 /**
21939 * 消息送达时间
21940 * @type {?Date}
21941 */
21942
21943 }, {
21944 key: "deliveredAt",
21945 get: function get() {
21946 return this._deliveredAt;
21947 },
21948 set: function set(value) {
21949 this._deliveredAt = decodeDate(value);
21950 }
21951 /**
21952 * 消息修改或撤回时间,可以通过比较其与消息的 timestamp 是否相等判断消息是否被修改过或撤回过。
21953 * @type {Date}
21954 * @since 3.5.0
21955 */
21956
21957 }, {
21958 key: "updatedAt",
21959 get: function get() {
21960 return this._updatedAt || this.timestamp;
21961 },
21962 set: function set(value) {
21963 this._updatedAt = decodeDate(value);
21964 }
21965 /**
21966 * 当前用户是否在该消息中被提及
21967 * @type {Boolean}
21968 * @readonly
21969 * @since 4.0.0
21970 */
21971
21972 }, {
21973 key: "mentioned",
21974 get: function get() {
21975 return this._mentioned;
21976 }
21977 }]);
21978
21979 return Message;
21980 }();
21981
21982 /* eslint-disable no-param-reassign */
21983
21984 var messageType = function messageType(type) {
21985 if (typeof type !== 'number') {
21986 throw new TypeError("".concat(type, " is not a Number"));
21987 }
21988
21989 return function (target) {
21990 target.TYPE = type;
21991
21992 target.validate = function (json) {
21993 return json._lctype === type;
21994 };
21995
21996 target.prototype._getType = function () {
21997 return {
21998 _lctype: type
21999 };
22000 };
22001 };
22002 }; // documented in ../index.js
22003
22004 var messageField = function messageField(fields) {
22005 if (typeof fields !== 'string') {
22006 if (!Array.isArray(fields)) {
22007 throw new TypeError("".concat(fields, " is not an Array"));
22008 } else if (fields.some(function (value) {
22009 return typeof value !== 'string';
22010 })) {
22011 throw new TypeError('fields contains non-string typed member');
22012 }
22013 }
22014
22015 return function (target) {
22016 // IE10 Hack:
22017 // static properties in IE10 will not be inherited from super
22018 // search for parse method and assign it manually
22019 var originalCustomFields = isIE10 ? getStaticProperty(target, '_customFields') : target._customFields;
22020 originalCustomFields = Array.isArray(originalCustomFields) ? originalCustomFields : [];
22021 target._customFields = originalCustomFields.concat(fields);
22022 };
22023 }; // IE10 Hack:
22024 // static properties in IE10 will not be inherited from super
22025 // search for parse method and assign it manually
22026
22027 var IE10Compatible = function IE10Compatible(target) {
22028 if (isIE10) {
22029 target.parse = getStaticProperty(target, 'parse');
22030 }
22031 };
22032
22033 var _dec, _class$1;
22034
22035 var // jsdoc-ignore-end
22036
22037 /**
22038 * 所有内置的富媒体消息均继承自本类
22039 * @extends Message
22040 */
22041 TypedMessage = (_dec = messageField(['_lctext', '_lcattrs']), _dec(_class$1 =
22042 /*#__PURE__*/
22043 function (_Message) {
22044 _inheritsLoose(TypedMessage, _Message);
22045
22046 function TypedMessage() {
22047 return _Message.apply(this, arguments) || this;
22048 }
22049
22050 var _proto = TypedMessage.prototype;
22051
22052 /**
22053 * @param {String} text
22054 * @return {this} self
22055 */
22056 _proto.setText = function setText(text) {
22057 this._lctext = text;
22058 return this;
22059 }
22060 /**
22061 * @return {String}
22062 */
22063 ;
22064
22065 _proto.getText = function getText() {
22066 return this._lctext;
22067 }
22068 /**
22069 * @param {Object} attributes
22070 * @return {this} self
22071 */
22072 ;
22073
22074 _proto.setAttributes = function setAttributes(attributes) {
22075 this._lcattrs = attributes;
22076 return this;
22077 }
22078 /**
22079 * @return {Object}
22080 */
22081 ;
22082
22083 _proto.getAttributes = function getAttributes() {
22084 return this._lcattrs;
22085 };
22086
22087 _proto._getCustomFields = function _getCustomFields() {
22088 var _this = this;
22089
22090 var fields = Array.isArray(this.constructor._customFields) ? this.constructor._customFields : [];
22091 return fields.reduce(function (result, field) {
22092 if (typeof field !== 'string') return result;
22093 result[field] = _this[field]; // eslint-disable-line no-param-reassign
22094
22095 return result;
22096 }, {});
22097 }
22098 /* eslint-disable class-methods-use-this */
22099 ;
22100
22101 _proto._getType = function _getType() {
22102 throw new Error('not implemented');
22103 }
22104 /* eslint-enable class-methods-use-this */
22105 ;
22106
22107 _proto.getPayload = function getPayload() {
22108 return compact(Object.assign({
22109 _lctext: this.getText(),
22110 _lcattrs: this.getAttributes()
22111 }, this._getCustomFields(), this._getType()));
22112 };
22113
22114 _proto.toJSON = function toJSON() {
22115 var type = this.type,
22116 text = this.text,
22117 attributes = this.attributes,
22118 summary = this.summary;
22119 return _objectSpread({}, _Message.prototype._toJSON.call(this), {
22120 type: type,
22121 text: text,
22122 attributes: attributes,
22123 summary: summary
22124 });
22125 };
22126
22127 _proto.toFullJSON = function toFullJSON() {
22128 return _objectSpread({}, _Message.prototype.toFullJSON.call(this), {
22129 data: this.getPayload()
22130 });
22131 }
22132 /**
22133 * 解析处理消息内容
22134 * <pre>
22135 * 为给定的 message 设置 text 与 attributes 属性,返回该 message
22136 * 如果子类没有提供 message,new this()
22137 * @protected
22138 * @param {Object} json json 格式的消息内容
22139 * @param {TypedMessage} message 子类提供的 message
22140 * @return {TypedMessage}
22141 * @implements AVMessage.parse
22142 */
22143 ;
22144
22145 TypedMessage.parse = function parse(json) {
22146 var message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new this();
22147 message.content = json; // eslint-disable-line no-param-reassign
22148
22149 var customFields = isIE10 ? getStaticProperty(message.constructor, '_customFields') : message.constructor._customFields;
22150 var fields = Array.isArray(customFields) ? customFields : [];
22151 fields = fields.reduce(function (result, field) {
22152 if (typeof field !== 'string') return result;
22153 result[field] = json[field]; // eslint-disable-line no-param-reassign
22154
22155 return result;
22156 }, {});
22157 Object.assign(message, fields);
22158 return _Message.parse.call(this, json, message);
22159 };
22160
22161 _createClass(TypedMessage, [{
22162 key: "type",
22163
22164 /**
22165 * @type {Number}
22166 * @readonly
22167 */
22168 get: function get() {
22169 return this.constructor.TYPE;
22170 }
22171 /** @type {String} */
22172
22173 }, {
22174 key: "text",
22175 set: function set(text) {
22176 return this.setText(text);
22177 },
22178 get: function get() {
22179 return this.getText();
22180 }
22181 /** @type {Object} */
22182
22183 }, {
22184 key: "attributes",
22185 set: function set(attributes) {
22186 return this.setAttributes(attributes);
22187 },
22188 get: function get() {
22189 return this.getAttributes();
22190 }
22191 /**
22192 * 在客户端需要以文本形式展示该消息时显示的文案,
22193 * 如 <code>[红包] 新春快乐</code>。
22194 * 默认值为消息的 text。
22195 * @type {String}
22196 * @readonly
22197 */
22198
22199 }, {
22200 key: "summary",
22201 get: function get() {
22202 return this.text;
22203 }
22204 }]);
22205
22206 return TypedMessage;
22207 }(Message)) || _class$1);
22208
22209 var _dec$1, _class$2;
22210
22211 var // jsdoc-ignore-end
22212
22213 /**
22214 * 已撤回类型消息,当消息被撤回时,SDK 会使用该类型的消息替代原始消息
22215 * @extends TypedMessage
22216 */
22217 RecalledMessage = (_dec$1 = messageType(-127), _dec$1(_class$2 = IE10Compatible(_class$2 =
22218 /*#__PURE__*/
22219 function (_TypedMessage) {
22220 _inheritsLoose(RecalledMessage, _TypedMessage);
22221
22222 function RecalledMessage() {
22223 return _TypedMessage.apply(this, arguments) || this;
22224 }
22225
22226 _createClass(RecalledMessage, [{
22227 key: "summary",
22228
22229 /**
22230 * 在客户端需要以文本形式展示该消息时显示的文案,值为 <code>[该消息已撤回]</code>
22231 * @type {String}
22232 * @readonly
22233 */
22234 // eslint-disable-next-line class-methods-use-this
22235 get: function get() {
22236 return '[该消息已撤回]';
22237 }
22238 }]);
22239
22240 return RecalledMessage;
22241 }(TypedMessage)) || _class$2) || _class$2);
22242
22243 var debug$6 = browser('LC:Conversation');
22244
22245 var serializeMessage = function serializeMessage(message) {
22246 var content = message.getPayload();
22247 var msg;
22248 var binaryMsg;
22249
22250 if (content instanceof ArrayBuffer) {
22251 binaryMsg = content;
22252 } else if (typeof content !== 'string') {
22253 msg = JSON.stringify(content);
22254 } else {
22255 msg = content;
22256 }
22257
22258 return {
22259 msg: msg,
22260 binaryMsg: binaryMsg
22261 };
22262 };
22263
22264 var _LogsCommand$QueryDir = LogsCommand.QueryDirection,
22265 NEW = _LogsCommand$QueryDir.NEW,
22266 OLD = _LogsCommand$QueryDir.OLD;
22267 /**
22268 * 历史消息查询方向枚举
22269 * @enum {Number}
22270 * @since 4.0.0
22271 * @memberof module:leancloud-realtime
22272 */
22273
22274 var MessageQueryDirection = {
22275 /** 从后向前 */
22276 NEW_TO_OLD: OLD,
22277
22278 /** 从前向后 */
22279 OLD_TO_NEW: NEW
22280 };
22281 Object.freeze(MessageQueryDirection);
22282
22283 var ConversationBase =
22284 /*#__PURE__*/
22285 function (_EventEmitter) {
22286 _inheritsLoose(ConversationBase, _EventEmitter);
22287
22288 /**
22289 * @extends EventEmitter
22290 * @private
22291 * @abstract
22292 */
22293 function ConversationBase(_ref, client) {
22294 var _this;
22295
22296 var id = _ref.id,
22297 lastMessageAt = _ref.lastMessageAt,
22298 lastMessage = _ref.lastMessage,
22299 lastDeliveredAt = _ref.lastDeliveredAt,
22300 lastReadAt = _ref.lastReadAt,
22301 _ref$unreadMessagesCo = _ref.unreadMessagesCount,
22302 unreadMessagesCount = _ref$unreadMessagesCo === void 0 ? 0 : _ref$unreadMessagesCo,
22303 _ref$members = _ref.members,
22304 members = _ref$members === void 0 ? [] : _ref$members,
22305 _ref$mentioned = _ref.mentioned,
22306 mentioned = _ref$mentioned === void 0 ? false : _ref$mentioned,
22307 properties = _objectWithoutProperties(_ref, ["id", "lastMessageAt", "lastMessage", "lastDeliveredAt", "lastReadAt", "unreadMessagesCount", "members", "mentioned"]);
22308
22309 _this = _EventEmitter.call(this) || this;
22310 Object.assign(_assertThisInitialized(_this), _objectSpread({
22311 /**
22312 * 对话 id,对应 _Conversation 表中的 objectId
22313 * @memberof ConversationBase#
22314 * @type {String}
22315 */
22316 id: id,
22317
22318 /**
22319 * 最后一条消息时间
22320 * @memberof ConversationBase#
22321 * @type {?Date}
22322 */
22323 lastMessageAt: lastMessageAt,
22324
22325 /**
22326 * 最后一条消息
22327 * @memberof ConversationBase#
22328 * @type {?Message}
22329 */
22330 lastMessage: lastMessage,
22331
22332 /**
22333 * 参与该对话的用户列表
22334 * @memberof ConversationBase#
22335 * @type {String[]}
22336 */
22337 members: members
22338 }, properties));
22339 _this.members = Array.from(new Set(_this.members));
22340 Object.assign(internal(_assertThisInitialized(_this)), {
22341 messagesWaitingForReceipt: {},
22342 lastDeliveredAt: lastDeliveredAt,
22343 lastReadAt: lastReadAt,
22344 unreadMessagesCount: unreadMessagesCount,
22345 mentioned: mentioned
22346 });
22347 _this._client = client;
22348
22349 if (debug$6.enabled) {
22350 values_1(Event).forEach(function (event) {
22351 return _this.on(event, function () {
22352 for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) {
22353 payload[_key] = arguments[_key];
22354 }
22355
22356 return _this._debug("".concat(event, " event emitted. %o"), payload);
22357 });
22358 });
22359 } // onConversationCreate hook
22360
22361
22362 applyDecorators(_this._client._plugins.onConversationCreate, _assertThisInitialized(_this));
22363 return _this;
22364 }
22365 /**
22366 * 当前用户是否在该对话的未读消息中被提及
22367 * @type {Boolean}
22368 * @since 4.0.0
22369 */
22370
22371
22372 var _proto = ConversationBase.prototype;
22373
22374 _proto._setUnreadMessagesMentioned = function _setUnreadMessagesMentioned(value) {
22375 internal(this).unreadMessagesMentioned = Boolean(value);
22376 };
22377
22378 _proto._setLastDeliveredAt = function _setLastDeliveredAt(value) {
22379 var date = decodeDate(value);
22380
22381 if (!(date < internal(this).lastDeliveredAt)) {
22382 internal(this).lastDeliveredAt = date;
22383 /**
22384 * 最后消息送达时间更新
22385 * @event ConversationBase#LAST_DELIVERED_AT_UPDATE
22386 * @since 3.4.0
22387 */
22388
22389 this.emit(LAST_DELIVERED_AT_UPDATE);
22390 }
22391 }
22392 /**
22393 * 最后消息被阅读时间,常用来实现发送消息的「已读」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
22394 * @type {?Date}
22395 * @since 3.4.0
22396 */
22397 ;
22398
22399 _proto._setLastReadAt = function _setLastReadAt(value) {
22400 var date = decodeDate(value);
22401
22402 if (!(date < internal(this).lastReadAt)) {
22403 internal(this).lastReadAt = date;
22404 /**
22405 * 最后消息被阅读时间更新
22406 * @event ConversationBase#LAST_READ_AT_UPDATE
22407 * @since 3.4.0
22408 */
22409
22410 this.emit(LAST_READ_AT_UPDATE);
22411 }
22412 }
22413 /**
22414 * 返回 JSON 格式的对话,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseConversation} 反序列化。
22415 * @return {Object} 返回值是一个 plain Object
22416 * @since 4.0.0
22417 */
22418 ;
22419
22420 _proto.toFullJSON = function toFullJSON() {
22421 var id = this.id,
22422 members = this.members,
22423 lastMessageAt = this.lastMessageAt,
22424 lastDeliveredAt = this.lastDeliveredAt,
22425 lastReadAt = this.lastReadAt,
22426 lastMessage = this.lastMessage,
22427 unreadMessagesCount = this.unreadMessagesCount;
22428 return {
22429 id: id,
22430 members: members,
22431 lastMessageAt: getTime(lastMessageAt),
22432 lastDeliveredAt: getTime(lastDeliveredAt),
22433 lastReadAt: getTime(lastReadAt),
22434 lastMessage: lastMessage ? lastMessage.toFullJSON() : undefined,
22435 unreadMessagesCount: unreadMessagesCount
22436 };
22437 }
22438 /**
22439 * 返回 JSON 格式的对话
22440 * @return {Object} 返回值是一个 plain Object
22441 * @since 4.0.0
22442 */
22443 ;
22444
22445 _proto.toJSON = function toJSON() {
22446 var id = this.id,
22447 members = this.members,
22448 lastMessageAt = this.lastMessageAt,
22449 lastDeliveredAt = this.lastDeliveredAt,
22450 lastReadAt = this.lastReadAt,
22451 lastMessage = this.lastMessage,
22452 unreadMessagesCount = this.unreadMessagesCount,
22453 unreadMessagesMentioned = this.unreadMessagesMentioned;
22454 return {
22455 id: id,
22456 members: members,
22457 lastMessageAt: lastMessageAt,
22458 lastDeliveredAt: lastDeliveredAt,
22459 lastReadAt: lastReadAt,
22460 lastMessage: lastMessage ? lastMessage.toJSON() : undefined,
22461 unreadMessagesCount: unreadMessagesCount,
22462 unreadMessagesMentioned: unreadMessagesMentioned
22463 };
22464 };
22465
22466 _proto._debug = function _debug() {
22467 for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22468 params[_key2] = arguments[_key2];
22469 }
22470
22471 debug$6.apply(void 0, params.concat(["[".concat(this.id, "]")]));
22472 };
22473
22474 _proto._send = function _send(command) {
22475 var _this$_client;
22476
22477 /* eslint-disable no-param-reassign */
22478 if (command.cmd === null) {
22479 command.cmd = 'conv';
22480 }
22481
22482 if (command.cmd === 'conv' && command.convMessage === null) {
22483 command.convMessage = new ConvCommand();
22484 }
22485
22486 if (command.convMessage && command.convMessage.cid === null) {
22487 command.convMessage.cid = this.id;
22488 }
22489 /* eslint-enable no-param-reassign */
22490
22491
22492 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
22493 args[_key3 - 1] = arguments[_key3];
22494 }
22495
22496 return (_this$_client = this._client)._send.apply(_this$_client, [command].concat(args));
22497 }
22498 /**
22499 * 发送消息
22500 * @param {Message} message 消息,Message 及其子类的实例
22501 * @param {Object} [options] since v3.3.0,发送选项
22502 * @param {Boolean} [options.transient] since v3.3.1,是否作为暂态消息发送
22503 * @param {Boolean} [options.receipt] 是否需要回执,仅在普通对话中有效
22504 * @param {Boolean} [options.will] since v3.4.0,是否指定该消息作为「掉线消息」发送,
22505 * 「掉线消息」会延迟到当前用户掉线后发送,常用来实现「下线通知」功能
22506 * @param {MessagePriority} [options.priority] 消息优先级,仅在暂态对话中有效,
22507 * see: {@link module:leancloud-realtime.MessagePriority MessagePriority}
22508 * @param {Object} [options.pushData] 消息对应的离线推送内容,如果消息接收方不在线,会推送指定的内容。其结构说明参见: {@link https://url.leanapp.cn/pushData 推送消息内容}
22509 * @return {Promise.<Message>} 发送的消息
22510 */
22511 ;
22512
22513 _proto.send =
22514 /*#__PURE__*/
22515 function () {
22516 var _send2 = _asyncToGenerator(
22517 /*#__PURE__*/
22518 regenerator.mark(function _callee(message, options) {
22519 var _Object$assign, transient, receipt, priority, pushData, will, _serializeMessage, msg, binaryMsg, command, resCommand, _resCommand$ackMessag, uid, t, code, reason, appCode;
22520
22521 return regenerator.wrap(function _callee$(_context) {
22522 while (1) {
22523 switch (_context.prev = _context.next) {
22524 case 0:
22525 this._debug(message, 'send');
22526
22527 if (message instanceof Message) {
22528 _context.next = 3;
22529 break;
22530 }
22531
22532 throw new TypeError("".concat(message, " is not a Message"));
22533
22534 case 3:
22535 _Object$assign = Object.assign({}, // support Message static property: sendOptions
22536 message.constructor.sendOptions, // support Message static property: getSendOptions
22537 typeof message.constructor.getSendOptions === 'function' ? message.constructor.getSendOptions(message) : {}, options), transient = _Object$assign.transient, receipt = _Object$assign.receipt, priority = _Object$assign.priority, pushData = _Object$assign.pushData, will = _Object$assign.will;
22538
22539 if (receipt) {
22540 if (this.transient) {
22541 console.warn('receipt option is ignored as the conversation is transient.');
22542 } else if (transient) {
22543 console.warn('receipt option is ignored as the message is sent transiently.');
22544 } else if (this.members.length > 2) {
22545 console.warn('receipt option is recommended to be used in one-on-one conversation.'); // eslint-disable-line max-len
22546 }
22547 }
22548
22549 if (priority && !this.transient) {
22550 console.warn('priority option is ignored as the conversation is not transient.');
22551 }
22552
22553 Object.assign(message, {
22554 cid: this.id,
22555 from: this._client.id
22556 });
22557
22558 message._setStatus(MessageStatus.SENDING);
22559
22560 _serializeMessage = serializeMessage(message), msg = _serializeMessage.msg, binaryMsg = _serializeMessage.binaryMsg;
22561 command = new GenericCommand({
22562 cmd: 'direct',
22563 directMessage: new DirectCommand({
22564 msg: msg,
22565 binaryMsg: binaryMsg,
22566 cid: this.id,
22567 r: receipt,
22568 transient: transient,
22569 dt: message.id,
22570 pushData: JSON.stringify(pushData),
22571 will: will,
22572 mentionPids: message.mentionList,
22573 mentionAll: message.mentionedAll
22574 }),
22575 priority: priority
22576 });
22577 _context.prev = 10;
22578 _context.next = 13;
22579 return this._send(command);
22580
22581 case 13:
22582 resCommand = _context.sent;
22583 _resCommand$ackMessag = resCommand.ackMessage, uid = _resCommand$ackMessag.uid, t = _resCommand$ackMessag.t, code = _resCommand$ackMessag.code, reason = _resCommand$ackMessag.reason, appCode = _resCommand$ackMessag.appCode;
22584
22585 if (!(code !== null)) {
22586 _context.next = 17;
22587 break;
22588 }
22589
22590 throw createError({
22591 code: code,
22592 reason: reason,
22593 appCode: appCode
22594 });
22595
22596 case 17:
22597 Object.assign(message, {
22598 id: uid,
22599 timestamp: t
22600 });
22601
22602 if (!transient) {
22603 this.lastMessage = message;
22604 this.lastMessageAt = message.timestamp;
22605 }
22606
22607 message._setStatus(MessageStatus.SENT);
22608
22609 if (receipt) {
22610 internal(this).messagesWaitingForReceipt[message.id] = message;
22611 }
22612
22613 return _context.abrupt("return", message);
22614
22615 case 24:
22616 _context.prev = 24;
22617 _context.t0 = _context["catch"](10);
22618
22619 message._setStatus(MessageStatus.FAILED);
22620
22621 throw _context.t0;
22622
22623 case 28:
22624 case "end":
22625 return _context.stop();
22626 }
22627 }
22628 }, _callee, this, [[10, 24]]);
22629 }));
22630
22631 function send(_x, _x2) {
22632 return _send2.apply(this, arguments);
22633 }
22634
22635 return send;
22636 }();
22637
22638 _proto._update =
22639 /*#__PURE__*/
22640 function () {
22641 var _update2 = _asyncToGenerator(
22642 /*#__PURE__*/
22643 regenerator.mark(function _callee2(message, newMessage, recall) {
22644 var msg, binaryMsg, content, id, cid, timestamp, from, _status;
22645
22646 return regenerator.wrap(function _callee2$(_context2) {
22647 while (1) {
22648 switch (_context2.prev = _context2.next) {
22649 case 0:
22650 this._debug('patch %O %O %O', message, newMessage, recall);
22651
22652 if (!(message instanceof Message)) {
22653 _context2.next = 8;
22654 break;
22655 }
22656
22657 if (!(message.from !== this._client.id)) {
22658 _context2.next = 4;
22659 break;
22660 }
22661
22662 throw new Error('Updating message from others is not allowed');
22663
22664 case 4:
22665 if (!(message.status !== MessageStatus.SENT && message.status !== MessageStatus.DELIVERED)) {
22666 _context2.next = 6;
22667 break;
22668 }
22669
22670 throw new Error('Message is not sent');
22671
22672 case 6:
22673 _context2.next = 10;
22674 break;
22675
22676 case 8:
22677 if (message.id && message.timestamp) {
22678 _context2.next = 10;
22679 break;
22680 }
22681
22682 throw new TypeError("".concat(message, " is not a Message"));
22683
22684 case 10:
22685 if (!recall) {
22686 content = serializeMessage(newMessage);
22687 msg = content.msg;
22688 binaryMsg = content.binaryMsg;
22689 }
22690
22691 _context2.next = 13;
22692 return this._send(new GenericCommand({
22693 cmd: CommandType.patch,
22694 op: OpType.modify,
22695 patchMessage: new PatchCommand({
22696 patches: [new PatchItem({
22697 cid: this.id,
22698 mid: message.id,
22699 timestamp: Number(message.timestamp),
22700 recall: recall,
22701 data: msg,
22702 binaryMsg: binaryMsg,
22703 mentionPids: newMessage.mentionList,
22704 mentionAll: newMessage.mentionedAll
22705 })],
22706 lastPatchTime: this._client._lastPatchTime
22707 })
22708 }));
22709
22710 case 13:
22711 id = message.id, cid = message.cid, timestamp = message.timestamp, from = message.from, _status = message._status;
22712 Object.assign(newMessage, {
22713 id: id,
22714 cid: cid,
22715 timestamp: timestamp,
22716 from: from,
22717 _status: _status
22718 });
22719
22720 if (this.lastMessage.id === newMessage.id) {
22721 this.lastMessage = newMessage;
22722 }
22723
22724 return _context2.abrupt("return", newMessage);
22725
22726 case 17:
22727 case "end":
22728 return _context2.stop();
22729 }
22730 }
22731 }, _callee2, this);
22732 }));
22733
22734 function _update(_x3, _x4, _x5) {
22735 return _update2.apply(this, arguments);
22736 }
22737
22738 return _update;
22739 }()
22740 /**
22741 * 获取对话人数,或暂态对话的在线人数
22742 * @return {Promise.<Number>}
22743 */
22744 ;
22745
22746 _proto.count =
22747 /*#__PURE__*/
22748 function () {
22749 var _count = _asyncToGenerator(
22750 /*#__PURE__*/
22751 regenerator.mark(function _callee3() {
22752 var resCommand;
22753 return regenerator.wrap(function _callee3$(_context3) {
22754 while (1) {
22755 switch (_context3.prev = _context3.next) {
22756 case 0:
22757 this._debug('count');
22758
22759 _context3.next = 3;
22760 return this._send(new GenericCommand({
22761 op: 'count'
22762 }));
22763
22764 case 3:
22765 resCommand = _context3.sent;
22766 return _context3.abrupt("return", resCommand.convMessage.count);
22767
22768 case 5:
22769 case "end":
22770 return _context3.stop();
22771 }
22772 }
22773 }, _callee3, this);
22774 }));
22775
22776 function count() {
22777 return _count.apply(this, arguments);
22778 }
22779
22780 return count;
22781 }()
22782 /**
22783 * 应用增加成员的操作,产生副作用
22784 * @param {string[]} members
22785 * @abstract
22786 * @private
22787 */
22788 ;
22789
22790 _proto._addMembers = function _addMembers() {}
22791 /**
22792 * 应用减少成员的操作,产生副作用
22793 * @param {string[]} members
22794 * @abstract
22795 * @private
22796 */
22797 ;
22798
22799 _proto._removeMembers = function _removeMembers() {}
22800 /**
22801 * 修改已发送的消息
22802 * @param {AVMessage} message 要修改的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
22803 * @param {AVMessage} newMessage 新的消息
22804 * @return {Promise.<AVMessage>} 更新后的消息
22805 */
22806 ;
22807
22808 _proto.update =
22809 /*#__PURE__*/
22810 function () {
22811 var _update3 = _asyncToGenerator(
22812 /*#__PURE__*/
22813 regenerator.mark(function _callee4(message, newMessage) {
22814 return regenerator.wrap(function _callee4$(_context4) {
22815 while (1) {
22816 switch (_context4.prev = _context4.next) {
22817 case 0:
22818 if (newMessage instanceof Message) {
22819 _context4.next = 2;
22820 break;
22821 }
22822
22823 throw new TypeError("".concat(newMessage, " is not a Message"));
22824
22825 case 2:
22826 return _context4.abrupt("return", this._update(message, newMessage, false));
22827
22828 case 3:
22829 case "end":
22830 return _context4.stop();
22831 }
22832 }
22833 }, _callee4, this);
22834 }));
22835
22836 function update(_x6, _x7) {
22837 return _update3.apply(this, arguments);
22838 }
22839
22840 return update;
22841 }()
22842 /**
22843 * 撤回已发送的消息
22844 * @param {AVMessage} message 要撤回的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
22845 * @return {Promise.<RecalledMessage>} 一条已撤回的消息
22846 */
22847 ;
22848
22849 _proto.recall =
22850 /*#__PURE__*/
22851 function () {
22852 var _recall = _asyncToGenerator(
22853 /*#__PURE__*/
22854 regenerator.mark(function _callee5(message) {
22855 return regenerator.wrap(function _callee5$(_context5) {
22856 while (1) {
22857 switch (_context5.prev = _context5.next) {
22858 case 0:
22859 return _context5.abrupt("return", this._update(message, new RecalledMessage(), true));
22860
22861 case 1:
22862 case "end":
22863 return _context5.stop();
22864 }
22865 }
22866 }, _callee5, this);
22867 }));
22868
22869 function recall(_x8) {
22870 return _recall.apply(this, arguments);
22871 }
22872
22873 return recall;
22874 }()
22875 /**
22876 * 查询消息记录
22877 * 如果仅需实现消息向前记录翻页查询需求,建议使用 {@link Conversation#createMessagesIterator}。
22878 * 不论何种方向,获得的消息都是按照时间升序排列的。
22879 * startClosed 与 endClosed 用于指定查询区间的开闭。
22880 *
22881 * @param {Object} [options]
22882 * @param {Number} [options.limit] 限制查询结果的数量,目前服务端默认为 20
22883 * @param {Number} [options.type] 指定查询的富媒体消息类型,不指定则查询所有消息。
22884 * @param {MessageQueryDirection} [options.direction] 查询的方向。
22885 * 在不指定的情况下如果 startTime 大于 endTime,则为从新到旧查询,可以实现加载聊天记录等场景。
22886 * 如果 startTime 小于 endTime,则为从旧到新查询,可以实现弹幕等场景。
22887 * @param {Date} [options.startTime] 从该时间开始查询,不传则从当前时间开始查询
22888 * @param {String} [options.startMessageId] 从该消息之前开始查询,需要与 startTime 同时使用,为防止某时刻有重复消息
22889 * @param {Boolean}[options.startClosed] 指定查询范围是否包括开始的时间点,默认不包括
22890 * @param {Date} [options.endTime] 查询到该时间为止,不传则查询最早消息为止
22891 * @param {String} [options.endMessageId] 查询到该消息为止,需要与 endTime 同时使用,为防止某时刻有重复消息
22892 * @param {Boolean}[options.endClosed] 指定查询范围是否包括结束的时间点,默认不包括
22893 *
22894 * @param {Date} [options.beforeTime] DEPRECATED: 使用 startTime 代替。限制查询结果为小于该时间之前的消息,不传则为当前时间
22895 * @param {String} [options.beforeMessageId] DEPRECATED: 使用 startMessageId 代替。
22896 * 限制查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
22897 * @param {Date} [options.afterTime] DEPRECATED: 使用 endTime 代替。限制查询结果为大于该时间之前的消息
22898 * @param {String} [options.afterMessageId] DEPRECATED: 使用 endMessageId 代替。
22899 * 限制查询结果为该消息之后的消息,需要与 afterTime 同时使用,为防止某时刻有重复消息
22900 * @return {Promise.<Message[]>} 消息列表
22901 */
22902 ;
22903
22904 _proto.queryMessages =
22905 /*#__PURE__*/
22906 function () {
22907 var _queryMessages = _asyncToGenerator(
22908 /*#__PURE__*/
22909 regenerator.mark(function _callee7() {
22910 var _this2 = this;
22911
22912 var options,
22913 beforeTime,
22914 beforeMessageId,
22915 afterTime,
22916 afterMessageId,
22917 limit,
22918 direction,
22919 type,
22920 startTime,
22921 startMessageId,
22922 startClosed,
22923 endTime,
22924 endMessageId,
22925 endClosed,
22926 conditions,
22927 resCommand,
22928 _args7 = arguments;
22929 return regenerator.wrap(function _callee7$(_context7) {
22930 while (1) {
22931 switch (_context7.prev = _context7.next) {
22932 case 0:
22933 options = _args7.length > 0 && _args7[0] !== undefined ? _args7[0] : {};
22934
22935 this._debug('query messages %O', options);
22936
22937 beforeTime = options.beforeTime, beforeMessageId = options.beforeMessageId, afterTime = options.afterTime, afterMessageId = options.afterMessageId, limit = options.limit, direction = options.direction, type = options.type, startTime = options.startTime, startMessageId = options.startMessageId, startClosed = options.startClosed, endTime = options.endTime, endMessageId = options.endMessageId, endClosed = options.endClosed;
22938
22939 if (!(beforeMessageId || beforeTime || afterMessageId || afterTime)) {
22940 _context7.next = 6;
22941 break;
22942 }
22943
22944 console.warn('DEPRECATION: queryMessages options beforeTime, beforeMessageId, afterTime and afterMessageId are deprecated in favor of startTime, startMessageId, endTime and endMessageId.');
22945 return _context7.abrupt("return", this.queryMessages({
22946 startTime: beforeTime,
22947 startMessageId: beforeMessageId,
22948 endTime: afterTime,
22949 endMessageId: afterMessageId,
22950 limit: limit
22951 }));
22952
22953 case 6:
22954 if (!(startMessageId && !startTime)) {
22955 _context7.next = 8;
22956 break;
22957 }
22958
22959 throw new Error('query option startMessageId must be used with option startTime');
22960
22961 case 8:
22962 if (!(endMessageId && !endTime)) {
22963 _context7.next = 10;
22964 break;
22965 }
22966
22967 throw new Error('query option endMessageId must be used with option endTime');
22968
22969 case 10:
22970 conditions = {
22971 t: startTime,
22972 mid: startMessageId,
22973 tIncluded: startClosed,
22974 tt: endTime,
22975 tmid: endMessageId,
22976 ttIncluded: endClosed,
22977 l: limit,
22978 lctype: type
22979 };
22980
22981 if (conditions.t instanceof Date) {
22982 conditions.t = conditions.t.getTime();
22983 }
22984
22985 if (conditions.tt instanceof Date) {
22986 conditions.tt = conditions.tt.getTime();
22987 }
22988
22989 if (direction !== undefined) {
22990 conditions.direction = direction;
22991 } else if (conditions.tt > conditions.t) {
22992 conditions.direction = MessageQueryDirection.OLD_TO_NEW;
22993 }
22994
22995 _context7.next = 16;
22996 return this._send(new GenericCommand({
22997 cmd: 'logs',
22998 logsMessage: new LogsCommand(Object.assign(conditions, {
22999 cid: this.id
23000 }))
23001 }));
23002
23003 case 16:
23004 resCommand = _context7.sent;
23005 return _context7.abrupt("return", Promise.all(resCommand.logsMessage.logs.map(
23006 /*#__PURE__*/
23007 function () {
23008 var _ref3 = _asyncToGenerator(
23009 /*#__PURE__*/
23010 regenerator.mark(function _callee6(_ref2) {
23011 var msgId, timestamp, patchTimestamp, from, ackAt, readAt, data, mentionAll, mentionPids, bin, messageData, message, status;
23012 return regenerator.wrap(function _callee6$(_context6) {
23013 while (1) {
23014 switch (_context6.prev = _context6.next) {
23015 case 0:
23016 msgId = _ref2.msgId, timestamp = _ref2.timestamp, patchTimestamp = _ref2.patchTimestamp, from = _ref2.from, ackAt = _ref2.ackAt, readAt = _ref2.readAt, data = _ref2.data, mentionAll = _ref2.mentionAll, mentionPids = _ref2.mentionPids, bin = _ref2.bin;
23017 messageData = {
23018 data: data,
23019 bin: bin,
23020 id: msgId,
23021 cid: _this2.id,
23022 timestamp: timestamp,
23023 from: from,
23024 deliveredAt: ackAt,
23025 updatedAt: patchTimestamp,
23026 mentionList: mentionPids,
23027 mentionedAll: mentionAll
23028 };
23029 _context6.next = 4;
23030 return _this2._client.parseMessage(messageData);
23031
23032 case 4:
23033 message = _context6.sent;
23034 status = MessageStatus.SENT;
23035
23036 if (_this2.members.length === 2) {
23037 if (ackAt) status = MessageStatus.DELIVERED;
23038 if (ackAt) _this2._setLastDeliveredAt(ackAt);
23039 if (readAt) _this2._setLastReadAt(readAt);
23040 }
23041
23042 message._setStatus(status);
23043
23044 return _context6.abrupt("return", message);
23045
23046 case 9:
23047 case "end":
23048 return _context6.stop();
23049 }
23050 }
23051 }, _callee6, this);
23052 }));
23053
23054 return function (_x9) {
23055 return _ref3.apply(this, arguments);
23056 };
23057 }())));
23058
23059 case 18:
23060 case "end":
23061 return _context7.stop();
23062 }
23063 }
23064 }, _callee7, this);
23065 }));
23066
23067 function queryMessages() {
23068 return _queryMessages.apply(this, arguments);
23069 }
23070
23071 return queryMessages;
23072 }()
23073 /**
23074 * 获取消息翻页迭代器
23075 * @param {Object} [options]
23076 * @param {Date} [options.beforeTime] 限制起始查询结果为小于该时间之前的消息,不传则为当前时间
23077 * @param {String} [options.beforeMessageId] 限制起始查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
23078 * @param {Number} [options.limit] 限制每页查询结果的数量,目前服务端默认为 20
23079 * @return {AsyncIterater.<Promise.<IteratorResult<Message[]>>>} [AsyncIterator]{@link https://github.com/tc39/proposal-async-iteration},调用其 next 方法返回获取下一页消息的 Promise
23080 * @example
23081 * var messageIterator = conversation.createMessagesIterator({ limit: 10 });
23082 * messageIterator.next().then(function(result) {
23083 * // result: {
23084 * // value: [message1, ..., message10],
23085 * // done: false,
23086 * // }
23087 * });
23088 * messageIterator.next().then(function(result) {
23089 * // result: {
23090 * // value: [message11, ..., message20],
23091 * // done: false,
23092 * // }
23093 * });
23094 * messageIterator.next().then(function(result) {
23095 * // No more messages
23096 * // result: { value: [], done: true }
23097 * });
23098 */
23099 ;
23100
23101 _proto.createMessagesIterator = function createMessagesIterator() {
23102 var _this3 = this;
23103
23104 var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
23105 beforeTime = _ref4.beforeTime,
23106 beforeMessageId = _ref4.beforeMessageId,
23107 limit = _ref4.limit;
23108
23109 var promise;
23110 return {
23111 next: function next() {
23112 if (promise === undefined) {
23113 // first call
23114 promise = _this3.queryMessages({
23115 limit: limit,
23116 startTime: beforeTime,
23117 startMessageId: beforeMessageId
23118 });
23119 } else {
23120 promise = promise.then(function (prevMessages) {
23121 if (prevMessages.length === 0 || prevMessages.length < limit) {
23122 // no more messages
23123 return [];
23124 }
23125
23126 return _this3.queryMessages({
23127 startTime: prevMessages[0].timestamp,
23128 startMessageId: prevMessages[0].id,
23129 limit: limit
23130 });
23131 });
23132 }
23133
23134 return promise.then(function (value) {
23135 return {
23136 value: Array.from(value),
23137 done: value.length === 0 || value.length < limit
23138 };
23139 });
23140 }
23141 };
23142 }
23143 /**
23144 * 将该会话标记为已读
23145 * @return {Promise.<this>} self
23146 */
23147 ;
23148
23149 _proto.read =
23150 /*#__PURE__*/
23151 function () {
23152 var _read = _asyncToGenerator(
23153 /*#__PURE__*/
23154 regenerator.mark(function _callee8() {
23155 var client;
23156 return regenerator.wrap(function _callee8$(_context8) {
23157 while (1) {
23158 switch (_context8.prev = _context8.next) {
23159 case 0:
23160 this.unreadMessagesCount = 0;
23161
23162 this._setUnreadMessagesMentioned(false); // 跳过暂态会话
23163
23164
23165 if (!this.transient) {
23166 _context8.next = 4;
23167 break;
23168 }
23169
23170 return _context8.abrupt("return", this);
23171
23172 case 4:
23173 client = this._client;
23174
23175 if (!internal(client).readConversationsBuffer) {
23176 internal(client).readConversationsBuffer = new Set();
23177 }
23178
23179 internal(client).readConversationsBuffer.add(this);
23180
23181 client._doSendRead();
23182
23183 return _context8.abrupt("return", this);
23184
23185 case 9:
23186 case "end":
23187 return _context8.stop();
23188 }
23189 }
23190 }, _callee8, this);
23191 }));
23192
23193 function read() {
23194 return _read.apply(this, arguments);
23195 }
23196
23197 return read;
23198 }();
23199
23200 _proto._handleReceipt = function _handleReceipt(_ref5) {
23201 var messageId = _ref5.messageId,
23202 timestamp = _ref5.timestamp,
23203 read = _ref5.read;
23204
23205 if (read) {
23206 this._setLastReadAt(timestamp);
23207 } else {
23208 this._setLastDeliveredAt(timestamp);
23209 }
23210
23211 var _internal = internal(this),
23212 messagesWaitingForReceipt = _internal.messagesWaitingForReceipt;
23213
23214 var message = messagesWaitingForReceipt[messageId];
23215 if (!message) return;
23216
23217 message._setStatus(MessageStatus.DELIVERED);
23218
23219 message.deliveredAt = timestamp;
23220 delete messagesWaitingForReceipt[messageId];
23221 }
23222 /**
23223 * 更新对话的最新回执时间戳(lastDeliveredAt、lastReadAt)
23224 * @since 3.4.0
23225 * @return {Promise.<this>} this
23226 */
23227 ;
23228
23229 _proto.fetchReceiptTimestamps =
23230 /*#__PURE__*/
23231 function () {
23232 var _fetchReceiptTimestamps = _asyncToGenerator(
23233 /*#__PURE__*/
23234 regenerator.mark(function _callee9() {
23235 var _ref6, _ref6$convMessage, maxReadTimestamp, maxAckTimestamp;
23236
23237 return regenerator.wrap(function _callee9$(_context9) {
23238 while (1) {
23239 switch (_context9.prev = _context9.next) {
23240 case 0:
23241 _context9.next = 2;
23242 return this._send(new GenericCommand({
23243 op: 'max_read'
23244 }));
23245
23246 case 2:
23247 _ref6 = _context9.sent;
23248 _ref6$convMessage = _ref6.convMessage;
23249 maxReadTimestamp = _ref6$convMessage.maxReadTimestamp;
23250 maxAckTimestamp = _ref6$convMessage.maxAckTimestamp;
23251
23252 this._setLastDeliveredAt(maxAckTimestamp);
23253
23254 this._setLastReadAt(maxReadTimestamp);
23255
23256 return _context9.abrupt("return", this);
23257
23258 case 9:
23259 case "end":
23260 return _context9.stop();
23261 }
23262 }
23263 }, _callee9, this);
23264 }));
23265
23266 function fetchReceiptTimestamps() {
23267 return _fetchReceiptTimestamps.apply(this, arguments);
23268 }
23269
23270 return fetchReceiptTimestamps;
23271 }();
23272
23273 _proto._fetchAllReceiptTimestamps = function _fetchAllReceiptTimestamps() {
23274 var convMessage = new ConvCommand({
23275 queryAllMembers: true
23276 });
23277 return this._send(new GenericCommand({
23278 op: 'max_read',
23279 convMessage: convMessage
23280 })).then(function (_ref7) {
23281 var maxReadTuples = _ref7.convMessage.maxReadTuples;
23282 return maxReadTuples.filter(function (maxReadTuple) {
23283 return maxReadTuple.maxAckTimestamp || maxReadTuple.maxReadTimestamp;
23284 }).map(function (_ref8) {
23285 var pid = _ref8.pid,
23286 maxAckTimestamp = _ref8.maxAckTimestamp,
23287 maxReadTimestamp = _ref8.maxReadTimestamp;
23288 return {
23289 pid: pid,
23290 lastDeliveredAt: decodeDate(maxAckTimestamp),
23291 lastReadAt: decodeDate(maxReadTimestamp)
23292 };
23293 });
23294 });
23295 };
23296
23297 _createClass(ConversationBase, [{
23298 key: "unreadMessagesMentioned",
23299 get: function get() {
23300 return internal(this).unreadMessagesMentioned;
23301 }
23302 }, {
23303 key: "unreadMessagesCount",
23304 set: function set(value) {
23305 if (value !== this.unreadMessagesCount) {
23306 internal(this).unreadMessagesCount = value;
23307
23308 this._client.emit(UNREAD_MESSAGES_COUNT_UPDATE, [this]);
23309 }
23310 }
23311 /**
23312 * 当前用户在该对话的未读消息数
23313 * @type {Number}
23314 */
23315 ,
23316 get: function get() {
23317 return internal(this).unreadMessagesCount;
23318 }
23319 }, {
23320 key: "lastMessageAt",
23321 set: function set(value) {
23322 var time = decodeDate(value);
23323 if (time <= this._lastMessageAt) return;
23324 this._lastMessageAt = time;
23325 },
23326 get: function get() {
23327 return this._lastMessageAt;
23328 }
23329 /**
23330 * 最后消息送达时间,常用来实现消息的「已送达」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
23331 * @type {?Date}
23332 * @since 3.4.0
23333 */
23334
23335 }, {
23336 key: "lastDeliveredAt",
23337 get: function get() {
23338 if (this.members.length !== 2) return null;
23339 return internal(this).lastDeliveredAt;
23340 }
23341 }, {
23342 key: "lastReadAt",
23343 get: function get() {
23344 if (this.members.length !== 2) return null;
23345 return internal(this).lastReadAt;
23346 }
23347 }]);
23348
23349 return ConversationBase;
23350 }(eventemitter3);
23351
23352 var debug$7 = browser('LC:SignatureFactoryRunner');
23353
23354 function _validateSignature() {
23355 var signatureResult = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
23356 var signature = signatureResult.signature,
23357 timestamp = signatureResult.timestamp,
23358 nonce = signatureResult.nonce;
23359
23360 if (typeof signature !== 'string' || typeof timestamp !== 'number' || typeof nonce !== 'string') {
23361 throw new Error('malformed signature');
23362 }
23363
23364 return {
23365 signature: signature,
23366 timestamp: timestamp,
23367 nonce: nonce
23368 };
23369 }
23370
23371 var runSignatureFactory = (function (signatureFactory, params) {
23372 return Promise.resolve().then(function () {
23373 debug$7('call signatureFactory with %O', params);
23374 return signatureFactory.apply(void 0, _toConsumableArray(params));
23375 }).then(tap(function (signatureResult) {
23376 return debug$7('sign result %O', signatureResult);
23377 }), function (error) {
23378 // eslint-disable-next-line no-param-reassign
23379 error.message = "sign error: ".concat(error.message);
23380 debug$7(error);
23381 throw error;
23382 }).then(_validateSignature);
23383 });
23384
23385 /**
23386 * 部分失败异常
23387 * @typedef OperationFailureError
23388 * @type {Error}
23389 * @property {string} message 异常信息
23390 * @property {string[]} clientIds 因为该原因失败的 client id 列表
23391 * @property {number} [code] 错误码
23392 * @property {string} [detail] 详细信息
23393 */
23394
23395 /**
23396 * 部分成功的结果
23397 * @typedef PartiallySuccess
23398 * @type {Object}
23399 * @property {string[]} successfulClientIds 成功的 client id 列表
23400 * @property {OperationFailureError[]} failures 失败的异常列表
23401 */
23402
23403 /**
23404 * 分页查询结果
23405 * @typedef PagedResults
23406 * @type {Object}
23407 * @property {T[]} results 查询结果
23408 * @property {string} [next] 存在表示还有更多结果,在下次查询中带上可实现翻页。
23409 */
23410
23411 var createPartiallySuccess = function createPartiallySuccess(_ref) {
23412 var allowedPids = _ref.allowedPids,
23413 failedPids = _ref.failedPids;
23414 return {
23415 successfulClientIds: allowedPids,
23416 failures: failedPids.map(function (_ref2) {
23417 var pids = _ref2.pids,
23418 error = _objectWithoutProperties(_ref2, ["pids"]);
23419
23420 return Object.assign(createError(error), {
23421 clientIds: pids
23422 });
23423 })
23424 };
23425 };
23426 /**
23427 * @extends ConversationBase
23428 * @private
23429 * @abstract
23430 */
23431
23432
23433 var PersistentConversation =
23434 /*#__PURE__*/
23435 function (_ConversationBase) {
23436 _inheritsLoose(PersistentConversation, _ConversationBase);
23437
23438 function PersistentConversation(data, _ref3, client) {
23439 var _this;
23440
23441 var creator = _ref3.creator,
23442 createdAt = _ref3.createdAt,
23443 updatedAt = _ref3.updatedAt,
23444 _ref3$transient = _ref3.transient,
23445 transient = _ref3$transient === void 0 ? false : _ref3$transient,
23446 _ref3$system = _ref3.system,
23447 system = _ref3$system === void 0 ? false : _ref3$system,
23448 _ref3$muted = _ref3.muted,
23449 muted = _ref3$muted === void 0 ? false : _ref3$muted,
23450 _ref3$mutedMembers = _ref3.mutedMembers,
23451 mutedMembers = _ref3$mutedMembers === void 0 ? [] : _ref3$mutedMembers,
23452 attributes = _objectWithoutProperties(_ref3, ["creator", "createdAt", "updatedAt", "transient", "system", "muted", "mutedMembers"]);
23453
23454 _this = _ConversationBase.call(this, _objectSpread({}, data, {
23455 /**
23456 * 对话创建者
23457 * @memberof PersistentConversation#
23458 * @type {String}
23459 */
23460 creator: creator,
23461
23462 /**
23463 * 对话创建时间
23464 * @memberof PersistentConversation#
23465 * @type {Date}
23466 */
23467 createdAt: createdAt,
23468
23469 /**
23470 * 对话更新时间
23471 * @memberof PersistentConversation#
23472 * @type {Date}
23473 */
23474 updatedAt: updatedAt,
23475
23476 /**
23477 * 对该对话设置了静音的用户列表
23478 * @memberof PersistentConversation#
23479 * @type {?String[]}
23480 */
23481 mutedMembers: mutedMembers,
23482
23483 /**
23484 * 暂态对话标记
23485 * @memberof PersistentConversation#
23486 * @type {Boolean}
23487 */
23488 transient: transient,
23489
23490 /**
23491 * 系统对话标记
23492 * @memberof PersistentConversation#
23493 * @type {Boolean}
23494 * @since 3.3.0
23495 */
23496 system: system,
23497
23498 /**
23499 * 当前用户静音该对话标记
23500 * @memberof PersistentConversation#
23501 * @type {Boolean}
23502 */
23503 muted: muted,
23504 _attributes: attributes
23505 }), client) || this;
23506
23507 _this._reset();
23508
23509 return _this;
23510 }
23511
23512 var _proto = PersistentConversation.prototype;
23513
23514 /**
23515 * 获取对话的自定义属性
23516 * @since 3.2.0
23517 * @param {String} key key 属性的键名,'x' 对应 Conversation 表中的 x 列
23518 * @return {Any} 属性的值
23519 */
23520 _proto.get = function get(key) {
23521 return internal(this).currentAttributes[key];
23522 }
23523 /**
23524 * 设置对话的自定义属性
23525 * @since 3.2.0
23526 * @param {String} key 属性的键名,'x' 对应 Conversation 表中的 x 列,支持使用 'x.y.z' 来修改对象的部分字段。
23527 * @param {Any} value 属性的值
23528 * @return {this} self
23529 * @example
23530 *
23531 * // 设置对话的 color 属性
23532 * conversation.set('color', {
23533 * text: '#000',
23534 * background: '#DDD',
23535 * });
23536 * // 设置对话的 color.text 属性
23537 * conversation.set('color.text', '#333');
23538 */
23539 ;
23540
23541 _proto.set = function set(key, value) {
23542 this._debug("set [".concat(key, "]: ").concat(value));
23543
23544 var _internal = internal(this),
23545 pendingAttributes = _internal.pendingAttributes;
23546
23547 var pendingKeys = Object.keys(pendingAttributes); // suppose pendingAttributes = { 'a.b': {} }
23548 // set 'a' or 'a.b': delete 'a.b'
23549
23550 var re = new RegExp("^".concat(key));
23551 var childKeys = pendingKeys.filter(re.test.bind(re));
23552 childKeys.forEach(function (k) {
23553 delete pendingAttributes[k];
23554 });
23555
23556 if (childKeys.length) {
23557 pendingAttributes[key] = value;
23558 } else {
23559 // set 'a.c': nothing to do
23560 // set 'a.b.c.d': assign c: { d: {} } to 'a.b'
23561 var parentKey = find_1(pendingKeys, function (k) {
23562 return key.indexOf(k) === 0;
23563 }); // 'a.b'
23564
23565 if (parentKey) {
23566 setValue(pendingAttributes[parentKey], key.slice(parentKey.length + 1), value);
23567 } else {
23568 pendingAttributes[key] = value;
23569 }
23570 }
23571
23572 this._buildCurrentAttributes();
23573
23574 return this;
23575 };
23576
23577 _proto._buildCurrentAttributes = function _buildCurrentAttributes() {
23578 var _internal2 = internal(this),
23579 pendingAttributes = _internal2.pendingAttributes;
23580
23581 internal(this).currentAttributes = Object.keys(pendingAttributes).reduce(function (target, k) {
23582 return setValue(target, k, pendingAttributes[k]);
23583 }, cloneDeep_1(this._attributes));
23584 };
23585
23586 _proto._updateServerAttributes = function _updateServerAttributes(attributes) {
23587 var _this2 = this;
23588
23589 Object.keys(attributes).forEach(function (key) {
23590 return setValue(_this2._attributes, key, attributes[key]);
23591 });
23592
23593 this._buildCurrentAttributes();
23594 };
23595
23596 _proto._reset = function _reset() {
23597 Object.assign(internal(this), {
23598 pendingAttributes: {},
23599 currentAttributes: this._attributes
23600 });
23601 }
23602 /**
23603 * 保存当前对话的属性至服务器
23604 * @return {Promise.<this>} self
23605 */
23606 ;
23607
23608 _proto.save =
23609 /*#__PURE__*/
23610 function () {
23611 var _save = _asyncToGenerator(
23612 /*#__PURE__*/
23613 regenerator.mark(function _callee() {
23614 var attr, convMessage, resCommand;
23615 return regenerator.wrap(function _callee$(_context) {
23616 while (1) {
23617 switch (_context.prev = _context.next) {
23618 case 0:
23619 this._debug('save');
23620
23621 attr = internal(this).pendingAttributes;
23622
23623 if (!isEmpty_1(attr)) {
23624 _context.next = 5;
23625 break;
23626 }
23627
23628 this._debug('nothing touched, resolve with self');
23629
23630 return _context.abrupt("return", this);
23631
23632 case 5:
23633 this._debug('attr: %O', attr);
23634
23635 convMessage = new ConvCommand({
23636 attr: new JsonObjectMessage({
23637 data: JSON.stringify(encode(attr))
23638 })
23639 });
23640 _context.next = 9;
23641 return this._send(new GenericCommand({
23642 op: 'update',
23643 convMessage: convMessage
23644 }));
23645
23646 case 9:
23647 resCommand = _context.sent;
23648 this.updatedAt = resCommand.convMessage.udate;
23649 this._attributes = internal(this).currentAttributes;
23650 internal(this).pendingAttributes = {};
23651 return _context.abrupt("return", this);
23652
23653 case 14:
23654 case "end":
23655 return _context.stop();
23656 }
23657 }
23658 }, _callee, this);
23659 }));
23660
23661 function save() {
23662 return _save.apply(this, arguments);
23663 }
23664
23665 return save;
23666 }()
23667 /**
23668 * 从服务器更新对话的属性
23669 * @return {Promise.<this>} self
23670 */
23671 ;
23672
23673 _proto.fetch =
23674 /*#__PURE__*/
23675 function () {
23676 var _fetch = _asyncToGenerator(
23677 /*#__PURE__*/
23678 regenerator.mark(function _callee2() {
23679 var query;
23680 return regenerator.wrap(function _callee2$(_context2) {
23681 while (1) {
23682 switch (_context2.prev = _context2.next) {
23683 case 0:
23684 query = this._client.getQuery().equalTo('objectId', this.id);
23685 _context2.next = 3;
23686 return query.find();
23687
23688 case 3:
23689 return _context2.abrupt("return", this);
23690
23691 case 4:
23692 case "end":
23693 return _context2.stop();
23694 }
23695 }
23696 }, _callee2, this);
23697 }));
23698
23699 function fetch() {
23700 return _fetch.apply(this, arguments);
23701 }
23702
23703 return fetch;
23704 }()
23705 /**
23706 * 静音,客户端拒绝收到服务器端的离线推送通知
23707 * @return {Promise.<this>} self
23708 */
23709 ;
23710
23711 _proto.mute =
23712 /*#__PURE__*/
23713 function () {
23714 var _mute = _asyncToGenerator(
23715 /*#__PURE__*/
23716 regenerator.mark(function _callee3() {
23717 return regenerator.wrap(function _callee3$(_context3) {
23718 while (1) {
23719 switch (_context3.prev = _context3.next) {
23720 case 0:
23721 this._debug('mute');
23722
23723 _context3.next = 3;
23724 return this._send(new GenericCommand({
23725 op: 'mute'
23726 }));
23727
23728 case 3:
23729 if (!this.transient) {
23730 this.muted = true;
23731 this.mutedMembers = union(this.mutedMembers, [this._client.id]);
23732 }
23733
23734 return _context3.abrupt("return", this);
23735
23736 case 5:
23737 case "end":
23738 return _context3.stop();
23739 }
23740 }
23741 }, _callee3, this);
23742 }));
23743
23744 function mute() {
23745 return _mute.apply(this, arguments);
23746 }
23747
23748 return mute;
23749 }()
23750 /**
23751 * 取消静音
23752 * @return {Promise.<this>} self
23753 */
23754 ;
23755
23756 _proto.unmute =
23757 /*#__PURE__*/
23758 function () {
23759 var _unmute = _asyncToGenerator(
23760 /*#__PURE__*/
23761 regenerator.mark(function _callee4() {
23762 return regenerator.wrap(function _callee4$(_context4) {
23763 while (1) {
23764 switch (_context4.prev = _context4.next) {
23765 case 0:
23766 this._debug('unmute');
23767
23768 _context4.next = 3;
23769 return this._send(new GenericCommand({
23770 op: 'unmute'
23771 }));
23772
23773 case 3:
23774 if (!this.transient) {
23775 this.muted = false;
23776 this.mutedMembers = difference(this.mutedMembers, [this._client.id]);
23777 }
23778
23779 return _context4.abrupt("return", this);
23780
23781 case 5:
23782 case "end":
23783 return _context4.stop();
23784 }
23785 }
23786 }, _callee4, this);
23787 }));
23788
23789 function unmute() {
23790 return _unmute.apply(this, arguments);
23791 }
23792
23793 return unmute;
23794 }();
23795
23796 _proto._appendConversationSignature =
23797 /*#__PURE__*/
23798 function () {
23799 var _appendConversationSignature2 = _asyncToGenerator(
23800 /*#__PURE__*/
23801 regenerator.mark(function _callee5(command, action, clientIds) {
23802 var params, signatureResult;
23803 return regenerator.wrap(function _callee5$(_context5) {
23804 while (1) {
23805 switch (_context5.prev = _context5.next) {
23806 case 0:
23807 if (!this._client.options.conversationSignatureFactory) {
23808 _context5.next = 6;
23809 break;
23810 }
23811
23812 params = [this.id, this._client.id, clientIds.sort(), action];
23813 _context5.next = 4;
23814 return runSignatureFactory(this._client.options.conversationSignatureFactory, params);
23815
23816 case 4:
23817 signatureResult = _context5.sent;
23818 Object.assign(command.convMessage, keyRemap({
23819 signature: 's',
23820 timestamp: 't',
23821 nonce: 'n'
23822 }, signatureResult));
23823
23824 case 6:
23825 case "end":
23826 return _context5.stop();
23827 }
23828 }
23829 }, _callee5, this);
23830 }));
23831
23832 function _appendConversationSignature(_x, _x2, _x3) {
23833 return _appendConversationSignature2.apply(this, arguments);
23834 }
23835
23836 return _appendConversationSignature;
23837 }();
23838
23839 _proto._appendBlacklistSignature =
23840 /*#__PURE__*/
23841 function () {
23842 var _appendBlacklistSignature2 = _asyncToGenerator(
23843 /*#__PURE__*/
23844 regenerator.mark(function _callee6(command, action, clientIds) {
23845 var params, signatureResult;
23846 return regenerator.wrap(function _callee6$(_context6) {
23847 while (1) {
23848 switch (_context6.prev = _context6.next) {
23849 case 0:
23850 if (!this._client.options.blacklistSignatureFactory) {
23851 _context6.next = 6;
23852 break;
23853 }
23854
23855 params = [this._client.id, this.id, clientIds.sort(), action];
23856 _context6.next = 4;
23857 return runSignatureFactory(this._client.options.blacklistSignatureFactory, params);
23858
23859 case 4:
23860 signatureResult = _context6.sent;
23861 Object.assign(command.blacklistMessage, keyRemap({
23862 signature: 's',
23863 timestamp: 't',
23864 nonce: 'n'
23865 }, signatureResult));
23866
23867 case 6:
23868 case "end":
23869 return _context6.stop();
23870 }
23871 }
23872 }, _callee6, this);
23873 }));
23874
23875 function _appendBlacklistSignature(_x4, _x5, _x6) {
23876 return _appendBlacklistSignature2.apply(this, arguments);
23877 }
23878
23879 return _appendBlacklistSignature;
23880 }()
23881 /**
23882 * 增加成员
23883 * @param {String|String[]} clientIds 新增成员 client id
23884 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
23885 */
23886 ;
23887
23888 _proto.add =
23889 /*#__PURE__*/
23890 function () {
23891 var _add = _asyncToGenerator(
23892 /*#__PURE__*/
23893 regenerator.mark(function _callee7(clientIds) {
23894 var command, _ref4, convMessage, allowedPids;
23895
23896 return regenerator.wrap(function _callee7$(_context7) {
23897 while (1) {
23898 switch (_context7.prev = _context7.next) {
23899 case 0:
23900 this._debug('add', clientIds);
23901
23902 if (typeof clientIds === 'string') {
23903 clientIds = [clientIds]; // eslint-disable-line no-param-reassign
23904 }
23905
23906 command = new GenericCommand({
23907 op: 'add',
23908 convMessage: new ConvCommand({
23909 m: clientIds
23910 })
23911 });
23912 _context7.next = 5;
23913 return this._appendConversationSignature(command, 'add', clientIds);
23914
23915 case 5:
23916 _context7.next = 7;
23917 return this._send(command);
23918
23919 case 7:
23920 _ref4 = _context7.sent;
23921 convMessage = _ref4.convMessage;
23922 allowedPids = _ref4.convMessage.allowedPids;
23923
23924 this._addMembers(allowedPids);
23925
23926 return _context7.abrupt("return", createPartiallySuccess(convMessage));
23927
23928 case 12:
23929 case "end":
23930 return _context7.stop();
23931 }
23932 }
23933 }, _callee7, this);
23934 }));
23935
23936 function add(_x7) {
23937 return _add.apply(this, arguments);
23938 }
23939
23940 return add;
23941 }()
23942 /**
23943 * 剔除成员
23944 * @param {String|String[]} clientIds 成员 client id
23945 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
23946 */
23947 ;
23948
23949 _proto.remove =
23950 /*#__PURE__*/
23951 function () {
23952 var _remove = _asyncToGenerator(
23953 /*#__PURE__*/
23954 regenerator.mark(function _callee8(clientIds) {
23955 var command, _ref5, convMessage, allowedPids;
23956
23957 return regenerator.wrap(function _callee8$(_context8) {
23958 while (1) {
23959 switch (_context8.prev = _context8.next) {
23960 case 0:
23961 this._debug('remove', clientIds);
23962
23963 if (typeof clientIds === 'string') {
23964 clientIds = [clientIds]; // eslint-disable-line no-param-reassign
23965 }
23966
23967 command = new GenericCommand({
23968 op: 'remove',
23969 convMessage: new ConvCommand({
23970 m: clientIds
23971 })
23972 });
23973 _context8.next = 5;
23974 return this._appendConversationSignature(command, 'remove', clientIds);
23975
23976 case 5:
23977 _context8.next = 7;
23978 return this._send(command);
23979
23980 case 7:
23981 _ref5 = _context8.sent;
23982 convMessage = _ref5.convMessage;
23983 allowedPids = _ref5.convMessage.allowedPids;
23984
23985 this._removeMembers(allowedPids);
23986
23987 return _context8.abrupt("return", createPartiallySuccess(convMessage));
23988
23989 case 12:
23990 case "end":
23991 return _context8.stop();
23992 }
23993 }
23994 }, _callee8, this);
23995 }));
23996
23997 function remove(_x8) {
23998 return _remove.apply(this, arguments);
23999 }
24000
24001 return remove;
24002 }()
24003 /**
24004 * (当前用户)加入该对话
24005 * @return {Promise.<this>} self
24006 */
24007 ;
24008
24009 _proto.join =
24010 /*#__PURE__*/
24011 function () {
24012 var _join = _asyncToGenerator(
24013 /*#__PURE__*/
24014 regenerator.mark(function _callee9() {
24015 var _this3 = this;
24016
24017 return regenerator.wrap(function _callee9$(_context9) {
24018 while (1) {
24019 switch (_context9.prev = _context9.next) {
24020 case 0:
24021 this._debug('join');
24022
24023 return _context9.abrupt("return", this.add(this._client.id).then(function (_ref6) {
24024 var failures = _ref6.failures;
24025 if (failures[0]) throw failures[0];
24026 return _this3;
24027 }));
24028
24029 case 2:
24030 case "end":
24031 return _context9.stop();
24032 }
24033 }
24034 }, _callee9, this);
24035 }));
24036
24037 function join() {
24038 return _join.apply(this, arguments);
24039 }
24040
24041 return join;
24042 }()
24043 /**
24044 * (当前用户)退出该对话
24045 * @return {Promise.<this>} self
24046 */
24047 ;
24048
24049 _proto.quit =
24050 /*#__PURE__*/
24051 function () {
24052 var _quit = _asyncToGenerator(
24053 /*#__PURE__*/
24054 regenerator.mark(function _callee10() {
24055 var _this4 = this;
24056
24057 return regenerator.wrap(function _callee10$(_context10) {
24058 while (1) {
24059 switch (_context10.prev = _context10.next) {
24060 case 0:
24061 this._debug('quit');
24062
24063 return _context10.abrupt("return", this.remove(this._client.id).then(function (_ref7) {
24064 var failures = _ref7.failures;
24065 if (failures[0]) throw failures[0];
24066 return _this4;
24067 }));
24068
24069 case 2:
24070 case "end":
24071 return _context10.stop();
24072 }
24073 }
24074 }, _callee10, this);
24075 }));
24076
24077 function quit() {
24078 return _quit.apply(this, arguments);
24079 }
24080
24081 return quit;
24082 }()
24083 /**
24084 * 在该对话中禁言成员
24085 * @param {String|String[]} clientIds 成员 client id
24086 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
24087 */
24088 ;
24089
24090 _proto.muteMembers =
24091 /*#__PURE__*/
24092 function () {
24093 var _muteMembers = _asyncToGenerator(
24094 /*#__PURE__*/
24095 regenerator.mark(function _callee11(clientIds) {
24096 var command, _ref8, convMessage;
24097
24098 return regenerator.wrap(function _callee11$(_context11) {
24099 while (1) {
24100 switch (_context11.prev = _context11.next) {
24101 case 0:
24102 this._debug('mute', clientIds);
24103
24104 clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
24105
24106 command = new GenericCommand({
24107 op: OpType.add_shutup,
24108 convMessage: new ConvCommand({
24109 m: clientIds
24110 })
24111 });
24112 _context11.next = 5;
24113 return this._send(command);
24114
24115 case 5:
24116 _ref8 = _context11.sent;
24117 convMessage = _ref8.convMessage;
24118 return _context11.abrupt("return", createPartiallySuccess(convMessage));
24119
24120 case 8:
24121 case "end":
24122 return _context11.stop();
24123 }
24124 }
24125 }, _callee11, this);
24126 }));
24127
24128 function muteMembers(_x9) {
24129 return _muteMembers.apply(this, arguments);
24130 }
24131
24132 return muteMembers;
24133 }()
24134 /**
24135 * 在该对话中解除成员禁言
24136 * @param {String|String[]} clientIds 成员 client id
24137 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
24138 */
24139 ;
24140
24141 _proto.unmuteMembers =
24142 /*#__PURE__*/
24143 function () {
24144 var _unmuteMembers = _asyncToGenerator(
24145 /*#__PURE__*/
24146 regenerator.mark(function _callee12(clientIds) {
24147 var command, _ref9, convMessage;
24148
24149 return regenerator.wrap(function _callee12$(_context12) {
24150 while (1) {
24151 switch (_context12.prev = _context12.next) {
24152 case 0:
24153 this._debug('unmute', clientIds);
24154
24155 clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
24156
24157 command = new GenericCommand({
24158 op: OpType.remove_shutup,
24159 convMessage: new ConvCommand({
24160 m: clientIds
24161 })
24162 });
24163 _context12.next = 5;
24164 return this._send(command);
24165
24166 case 5:
24167 _ref9 = _context12.sent;
24168 convMessage = _ref9.convMessage;
24169 return _context12.abrupt("return", createPartiallySuccess(convMessage));
24170
24171 case 8:
24172 case "end":
24173 return _context12.stop();
24174 }
24175 }
24176 }, _callee12, this);
24177 }));
24178
24179 function unmuteMembers(_x10) {
24180 return _unmuteMembers.apply(this, arguments);
24181 }
24182
24183 return unmuteMembers;
24184 }()
24185 /**
24186 * 查询该对话禁言成员列表
24187 * @param {Object} [options]
24188 * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
24189 * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页。
24190 * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
24191 */
24192 ;
24193
24194 _proto.queryMutedMembers =
24195 /*#__PURE__*/
24196 function () {
24197 var _queryMutedMembers = _asyncToGenerator(
24198 /*#__PURE__*/
24199 regenerator.mark(function _callee13() {
24200 var _ref10,
24201 limit,
24202 next,
24203 command,
24204 _ref11,
24205 _ref11$convMessage,
24206 m,
24207 newNext,
24208 _args13 = arguments;
24209
24210 return regenerator.wrap(function _callee13$(_context13) {
24211 while (1) {
24212 switch (_context13.prev = _context13.next) {
24213 case 0:
24214 _ref10 = _args13.length > 0 && _args13[0] !== undefined ? _args13[0] : {}, limit = _ref10.limit, next = _ref10.next;
24215
24216 this._debug('query muted: limit %O, next: %O', limit, next);
24217
24218 command = new GenericCommand({
24219 op: OpType.query_shutup,
24220 convMessage: new ConvCommand({
24221 limit: limit,
24222 next: next
24223 })
24224 });
24225 _context13.next = 5;
24226 return this._send(command);
24227
24228 case 5:
24229 _ref11 = _context13.sent;
24230 _ref11$convMessage = _ref11.convMessage;
24231 m = _ref11$convMessage.m;
24232 newNext = _ref11$convMessage.next;
24233 return _context13.abrupt("return", {
24234 results: m,
24235 next: newNext
24236 });
24237
24238 case 10:
24239 case "end":
24240 return _context13.stop();
24241 }
24242 }
24243 }, _callee13, this);
24244 }));
24245
24246 function queryMutedMembers() {
24247 return _queryMutedMembers.apply(this, arguments);
24248 }
24249
24250 return queryMutedMembers;
24251 }()
24252 /**
24253 * 将用户加入该对话黑名单
24254 * @param {String|String[]} clientIds 成员 client id
24255 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
24256 */
24257 ;
24258
24259 _proto.blockMembers =
24260 /*#__PURE__*/
24261 function () {
24262 var _blockMembers = _asyncToGenerator(
24263 /*#__PURE__*/
24264 regenerator.mark(function _callee14(clientIds) {
24265 var command, _ref12, blacklistMessage;
24266
24267 return regenerator.wrap(function _callee14$(_context14) {
24268 while (1) {
24269 switch (_context14.prev = _context14.next) {
24270 case 0:
24271 this._debug('block', clientIds);
24272
24273 clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
24274
24275 command = new GenericCommand({
24276 cmd: 'blacklist',
24277 op: OpType.block,
24278 blacklistMessage: new BlacklistCommand({
24279 srcCid: this.id,
24280 toPids: clientIds
24281 })
24282 });
24283 _context14.next = 5;
24284 return this._appendBlacklistSignature(command, 'conversation-block-clients', clientIds);
24285
24286 case 5:
24287 _context14.next = 7;
24288 return this._send(command);
24289
24290 case 7:
24291 _ref12 = _context14.sent;
24292 blacklistMessage = _ref12.blacklistMessage;
24293 return _context14.abrupt("return", createPartiallySuccess(blacklistMessage));
24294
24295 case 10:
24296 case "end":
24297 return _context14.stop();
24298 }
24299 }
24300 }, _callee14, this);
24301 }));
24302
24303 function blockMembers(_x11) {
24304 return _blockMembers.apply(this, arguments);
24305 }
24306
24307 return blockMembers;
24308 }()
24309 /**
24310 * 将用户移出该对话黑名单
24311 * @param {String|String[]} clientIds 成员 client id
24312 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
24313 */
24314 ;
24315
24316 _proto.unblockMembers =
24317 /*#__PURE__*/
24318 function () {
24319 var _unblockMembers = _asyncToGenerator(
24320 /*#__PURE__*/
24321 regenerator.mark(function _callee15(clientIds) {
24322 var command, _ref13, blacklistMessage;
24323
24324 return regenerator.wrap(function _callee15$(_context15) {
24325 while (1) {
24326 switch (_context15.prev = _context15.next) {
24327 case 0:
24328 this._debug('unblock', clientIds);
24329
24330 clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
24331
24332 command = new GenericCommand({
24333 cmd: 'blacklist',
24334 op: OpType.unblock,
24335 blacklistMessage: new BlacklistCommand({
24336 srcCid: this.id,
24337 toPids: clientIds
24338 })
24339 });
24340 _context15.next = 5;
24341 return this._appendBlacklistSignature(command, 'conversation-unblock-clients', clientIds);
24342
24343 case 5:
24344 _context15.next = 7;
24345 return this._send(command);
24346
24347 case 7:
24348 _ref13 = _context15.sent;
24349 blacklistMessage = _ref13.blacklistMessage;
24350 return _context15.abrupt("return", createPartiallySuccess(blacklistMessage));
24351
24352 case 10:
24353 case "end":
24354 return _context15.stop();
24355 }
24356 }
24357 }, _callee15, this);
24358 }));
24359
24360 function unblockMembers(_x12) {
24361 return _unblockMembers.apply(this, arguments);
24362 }
24363
24364 return unblockMembers;
24365 }()
24366 /**
24367 * 查询该对话黑名单
24368 * @param {Object} [options]
24369 * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
24370 * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页
24371 * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
24372 */
24373 ;
24374
24375 _proto.queryBlockedMembers =
24376 /*#__PURE__*/
24377 function () {
24378 var _queryBlockedMembers = _asyncToGenerator(
24379 /*#__PURE__*/
24380 regenerator.mark(function _callee16() {
24381 var _ref14,
24382 limit,
24383 next,
24384 command,
24385 _ref15,
24386 _ref15$blacklistMessa,
24387 blockedPids,
24388 newNext,
24389 _args16 = arguments;
24390
24391 return regenerator.wrap(function _callee16$(_context16) {
24392 while (1) {
24393 switch (_context16.prev = _context16.next) {
24394 case 0:
24395 _ref14 = _args16.length > 0 && _args16[0] !== undefined ? _args16[0] : {}, limit = _ref14.limit, next = _ref14.next;
24396
24397 this._debug('query blocked: limit %O, next: %O', limit, next);
24398
24399 command = new GenericCommand({
24400 cmd: 'blacklist',
24401 op: OpType.query,
24402 blacklistMessage: new BlacklistCommand({
24403 srcCid: this.id,
24404 limit: limit,
24405 next: next
24406 })
24407 });
24408 _context16.next = 5;
24409 return this._send(command);
24410
24411 case 5:
24412 _ref15 = _context16.sent;
24413 _ref15$blacklistMessa = _ref15.blacklistMessage;
24414 blockedPids = _ref15$blacklistMessa.blockedPids;
24415 newNext = _ref15$blacklistMessa.next;
24416 return _context16.abrupt("return", {
24417 results: blockedPids,
24418 next: newNext
24419 });
24420
24421 case 10:
24422 case "end":
24423 return _context16.stop();
24424 }
24425 }
24426 }, _callee16, this);
24427 }));
24428
24429 function queryBlockedMembers() {
24430 return _queryBlockedMembers.apply(this, arguments);
24431 }
24432
24433 return queryBlockedMembers;
24434 }();
24435
24436 _proto.toFullJSON = function toFullJSON() {
24437 var creator = this.creator,
24438 system = this.system,
24439 transient = this.transient,
24440 createdAt = this.createdAt,
24441 updatedAt = this.updatedAt,
24442 _attributes = this._attributes;
24443 return _objectSpread({}, _ConversationBase.prototype.toFullJSON.call(this), {
24444 creator: creator,
24445 system: system,
24446 transient: transient,
24447 createdAt: getTime(createdAt),
24448 updatedAt: getTime(updatedAt)
24449 }, _attributes);
24450 };
24451
24452 _proto.toJSON = function toJSON() {
24453 var creator = this.creator,
24454 system = this.system,
24455 transient = this.transient,
24456 muted = this.muted,
24457 mutedMembers = this.mutedMembers,
24458 createdAt = this.createdAt,
24459 updatedAt = this.updatedAt,
24460 _attributes = this._attributes;
24461 return _objectSpread({}, _ConversationBase.prototype.toJSON.call(this), {
24462 creator: creator,
24463 system: system,
24464 transient: transient,
24465 muted: muted,
24466 mutedMembers: mutedMembers,
24467 createdAt: createdAt,
24468 updatedAt: updatedAt
24469 }, _attributes);
24470 };
24471
24472 _createClass(PersistentConversation, [{
24473 key: "createdAt",
24474 set: function set(value) {
24475 this._createdAt = decodeDate(value);
24476 },
24477 get: function get() {
24478 return this._createdAt;
24479 }
24480 }, {
24481 key: "updatedAt",
24482 set: function set(value) {
24483 this._updatedAt = decodeDate(value);
24484 },
24485 get: function get() {
24486 return this._updatedAt;
24487 }
24488 /**
24489 * 对话名字,对应 _Conversation 表中的 name
24490 * @type {String}
24491 */
24492
24493 }, {
24494 key: "name",
24495 get: function get() {
24496 return this.get('name');
24497 },
24498 set: function set(value) {
24499 this.set('name', value);
24500 }
24501 }]);
24502
24503 return PersistentConversation;
24504 }(ConversationBase);
24505
24506 /**
24507 * 对话成员角色枚举
24508 * @enum {String}
24509 * @since 4.0.0
24510 * @memberof module:leancloud-realtime
24511 */
24512
24513 var ConversationMemberRole = {
24514 /** 所有者 */
24515 OWNER: 'Owner',
24516
24517 /** 管理员 */
24518 MANAGER: 'Manager',
24519
24520 /** 成员 */
24521 MEMBER: 'Member'
24522 };
24523 Object.freeze(ConversationMemberRole);
24524
24525 var ConversationMemberInfo =
24526 /*#__PURE__*/
24527 function () {
24528 /**
24529 * 对话成员属性,保存了成员与某个对话相关的属性,对应 _ConversationMemberInfo 表
24530 * @since 4.0.0
24531 */
24532 function ConversationMemberInfo(_ref) {
24533 var conversation = _ref.conversation,
24534 memberId = _ref.memberId,
24535 role = _ref.role;
24536 if (!conversation) throw new Error('conversation requried');
24537 if (!memberId) throw new Error('memberId requried');
24538 Object.assign(internal(this), {
24539 conversation: conversation,
24540 memberId: memberId,
24541 role: role
24542 });
24543 }
24544 /**
24545 * 对话 Id
24546 * @type {String}
24547 * @readonly
24548 */
24549
24550
24551 var _proto = ConversationMemberInfo.prototype;
24552
24553 _proto.toJSON = function toJSON() {
24554 var conversationId = this.conversationId,
24555 memberId = this.memberId,
24556 role = this.role,
24557 isOwner = this.isOwner;
24558 return {
24559 conversationId: conversationId,
24560 memberId: memberId,
24561 role: role,
24562 isOwner: isOwner
24563 };
24564 };
24565
24566 _createClass(ConversationMemberInfo, [{
24567 key: "conversationId",
24568 get: function get() {
24569 return internal(this).conversation.id;
24570 }
24571 /**
24572 * 成员 Id
24573 * @type {String}
24574 * @readonly
24575 */
24576
24577 }, {
24578 key: "memberId",
24579 get: function get() {
24580 return internal(this).memberId;
24581 }
24582 /**
24583 * 角色
24584 * @type {module:leancloud-realtime.ConversationMemberRole | String}
24585 * @readonly
24586 */
24587
24588 }, {
24589 key: "role",
24590 get: function get() {
24591 if (this.isOwner) return ConversationMemberRole.OWNER;
24592 return internal(this).role;
24593 }
24594 /**
24595 * 是否是管理员
24596 * @type {Boolean}
24597 * @readonly
24598 */
24599
24600 }, {
24601 key: "isOwner",
24602 get: function get() {
24603 return this.memberId === internal(this).conversation.creator;
24604 }
24605 }]);
24606
24607 return ConversationMemberInfo;
24608 }();
24609
24610 /**
24611 * 普通对话
24612 *
24613 * 无法直接实例化,请使用 {@link IMClient#createConversation} 创建新的普通对话。
24614 * @extends PersistentConversation
24615 * @public
24616 */
24617
24618 var Conversation =
24619 /*#__PURE__*/
24620 function (_PersistentConversati) {
24621 _inheritsLoose(Conversation, _PersistentConversati);
24622
24623 function Conversation() {
24624 return _PersistentConversati.apply(this, arguments) || this;
24625 }
24626
24627 var _proto = Conversation.prototype;
24628
24629 _proto._addMembers = function _addMembers(members) {
24630 var _this = this;
24631
24632 _PersistentConversati.prototype._addMembers.call(this, members);
24633
24634 this.members = union(this.members, members);
24635
24636 var _internal = internal(this),
24637 memberInfoMap = _internal.memberInfoMap;
24638
24639 if (!memberInfoMap) return;
24640 members.forEach(function (memberId) {
24641 memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
24642 conversation: _this,
24643 memberId: memberId,
24644 role: ConversationMemberRole.MEMBER
24645 });
24646 });
24647 };
24648
24649 _proto._removeMembers = function _removeMembers(members) {
24650 _PersistentConversati.prototype._removeMembers.call(this, members);
24651
24652 this.members = difference(this.members, members);
24653
24654 var _internal2 = internal(this),
24655 memberInfoMap = _internal2.memberInfoMap;
24656
24657 if (!memberInfoMap) return;
24658 members.forEach(function (memberId) {
24659 delete memberInfoMap[memberId];
24660 });
24661 };
24662
24663 _proto._fetchAllMemberInfo =
24664 /*#__PURE__*/
24665 function () {
24666 var _fetchAllMemberInfo2 = _asyncToGenerator(
24667 /*#__PURE__*/
24668 regenerator.mark(function _callee() {
24669 var _this2 = this;
24670
24671 var response, memberInfos, memberInfoMap;
24672 return regenerator.wrap(function _callee$(_context) {
24673 while (1) {
24674 switch (_context.prev = _context.next) {
24675 case 0:
24676 _context.next = 2;
24677 return this._client._requestWithSessionToken({
24678 method: 'GET',
24679 path: '/classes/_ConversationMemberInfo',
24680 query: {
24681 where: {
24682 cid: this.id
24683 }
24684 }
24685 });
24686
24687 case 2:
24688 response = _context.sent;
24689 memberInfos = response.results.map(function (info) {
24690 return new ConversationMemberInfo({
24691 conversation: _this2,
24692 memberId: info.clientId,
24693 role: info.role
24694 });
24695 });
24696 memberInfoMap = {};
24697 memberInfos.forEach(function (memberInfo) {
24698 memberInfoMap[memberInfo.memberId] = memberInfo;
24699 });
24700 this.members.forEach(function (memberId) {
24701 memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
24702 conversation: _this2,
24703 memberId: memberId,
24704 role: ConversationMemberRole.MEMBER
24705 });
24706 });
24707 internal(this).memberInfoMap = memberInfoMap;
24708 return _context.abrupt("return", memberInfoMap);
24709
24710 case 9:
24711 case "end":
24712 return _context.stop();
24713 }
24714 }
24715 }, _callee, this);
24716 }));
24717
24718 function _fetchAllMemberInfo() {
24719 return _fetchAllMemberInfo2.apply(this, arguments);
24720 }
24721
24722 return _fetchAllMemberInfo;
24723 }()
24724 /**
24725 * 获取所有成员的对话属性
24726 * @since 4.0.0
24727 * @return {Promise.<ConversationMemberInfo[]>} 所有成员的对话属性列表
24728 */
24729 ;
24730
24731 _proto.getAllMemberInfo =
24732 /*#__PURE__*/
24733 function () {
24734 var _getAllMemberInfo = _asyncToGenerator(
24735 /*#__PURE__*/
24736 regenerator.mark(function _callee2() {
24737 var _ref,
24738 _ref$noCache,
24739 noCache,
24740 _internal3,
24741 memberInfoMap,
24742 _args2 = arguments;
24743
24744 return regenerator.wrap(function _callee2$(_context2) {
24745 while (1) {
24746 switch (_context2.prev = _context2.next) {
24747 case 0:
24748 _ref = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}, _ref$noCache = _ref.noCache, noCache = _ref$noCache === void 0 ? false : _ref$noCache;
24749 _internal3 = internal(this), memberInfoMap = _internal3.memberInfoMap;
24750
24751 if (!(!memberInfoMap || noCache)) {
24752 _context2.next = 6;
24753 break;
24754 }
24755
24756 _context2.next = 5;
24757 return this._fetchAllMemberInfo();
24758
24759 case 5:
24760 memberInfoMap = _context2.sent;
24761
24762 case 6:
24763 return _context2.abrupt("return", this.members.map(function (memberId) {
24764 return memberInfoMap[memberId];
24765 }));
24766
24767 case 7:
24768 case "end":
24769 return _context2.stop();
24770 }
24771 }
24772 }, _callee2, this);
24773 }));
24774
24775 function getAllMemberInfo() {
24776 return _getAllMemberInfo.apply(this, arguments);
24777 }
24778
24779 return getAllMemberInfo;
24780 }()
24781 /**
24782 * 获取指定成员的对话属性
24783 * @since 4.0.0
24784 * @param {String} memberId 成员 Id
24785 * @return {Promise.<ConversationMemberInfo>} 指定成员的对话属性
24786 */
24787 ;
24788
24789 _proto.getMemberInfo =
24790 /*#__PURE__*/
24791 function () {
24792 var _getMemberInfo = _asyncToGenerator(
24793 /*#__PURE__*/
24794 regenerator.mark(function _callee3(memberId) {
24795 var _internal4, memberInfoMap;
24796
24797 return regenerator.wrap(function _callee3$(_context3) {
24798 while (1) {
24799 switch (_context3.prev = _context3.next) {
24800 case 0:
24801 if (!(this.members.indexOf(memberId) === -1)) {
24802 _context3.next = 2;
24803 break;
24804 }
24805
24806 throw new Error("".concat(memberId, " is not the mumber of conversation[").concat(this.id, "]"));
24807
24808 case 2:
24809 _internal4 = internal(this), memberInfoMap = _internal4.memberInfoMap;
24810
24811 if (memberInfoMap && memberInfoMap[memberId]) {
24812 _context3.next = 6;
24813 break;
24814 }
24815
24816 _context3.next = 6;
24817 return this.getAllMemberInfo();
24818
24819 case 6:
24820 return _context3.abrupt("return", internal(this).memberInfoMap[memberId]);
24821
24822 case 7:
24823 case "end":
24824 return _context3.stop();
24825 }
24826 }
24827 }, _callee3, this);
24828 }));
24829
24830 function getMemberInfo(_x) {
24831 return _getMemberInfo.apply(this, arguments);
24832 }
24833
24834 return getMemberInfo;
24835 }()
24836 /**
24837 * 更新指定用户的角色
24838 * @since 4.0.0
24839 * @param {String} memberId 成员 Id
24840 * @param {module:leancloud-realtime.ConversationMemberRole | String} role 角色
24841 * @return {Promise.<this>} self
24842 */
24843 ;
24844
24845 _proto.updateMemberRole =
24846 /*#__PURE__*/
24847 function () {
24848 var _updateMemberRole = _asyncToGenerator(
24849 /*#__PURE__*/
24850 regenerator.mark(function _callee4(memberId, role) {
24851 var _internal5, memberInfos;
24852
24853 return regenerator.wrap(function _callee4$(_context4) {
24854 while (1) {
24855 switch (_context4.prev = _context4.next) {
24856 case 0:
24857 this._debug('update member role');
24858
24859 if (!(role === ConversationMemberRole.OWNER)) {
24860 _context4.next = 3;
24861 break;
24862 }
24863
24864 throw createError({
24865 code: ErrorCode.OWNER_PROMOTION_NOT_ALLOWED
24866 });
24867
24868 case 3:
24869 _context4.next = 5;
24870 return this._send(new GenericCommand({
24871 op: OpType.member_info_update,
24872 convMessage: new ConvCommand({
24873 targetClientId: memberId,
24874 info: new ConvMemberInfo({
24875 pid: memberId,
24876 role: role
24877 })
24878 })
24879 }));
24880
24881 case 5:
24882 _internal5 = internal(this), memberInfos = _internal5.memberInfos;
24883
24884 if (memberInfos && memberInfos[memberId]) {
24885 internal(memberInfos[memberId]).role = role;
24886 }
24887
24888 return _context4.abrupt("return", this);
24889
24890 case 8:
24891 case "end":
24892 return _context4.stop();
24893 }
24894 }
24895 }, _callee4, this);
24896 }));
24897
24898 function updateMemberRole(_x2, _x3) {
24899 return _updateMemberRole.apply(this, arguments);
24900 }
24901
24902 return updateMemberRole;
24903 }();
24904
24905 return Conversation;
24906 }(PersistentConversation);
24907
24908 /**
24909 * 聊天室。
24910 *
24911 * 无法直接实例化,请使用 {@link IMClient#createChatRoom} 创建新的聊天室。
24912 * @since 4.0.0
24913 * @extends PersistentConversation
24914 * @public
24915 */
24916
24917 var ChatRoom =
24918 /*#__PURE__*/
24919 function (_PersistentConversati) {
24920 _inheritsLoose(ChatRoom, _PersistentConversati);
24921
24922 function ChatRoom() {
24923 return _PersistentConversati.apply(this, arguments) || this;
24924 }
24925
24926 return ChatRoom;
24927 }(PersistentConversation);
24928
24929 /**
24930 * 服务号。
24931 *
24932 * 服务号不支持在客户端创建。
24933 * @since 4.0.0
24934 * @extends PersistentConversation
24935 * @public
24936 */
24937
24938 var ServiceConversation =
24939 /*#__PURE__*/
24940 function (_PersistentConversati) {
24941 _inheritsLoose(ServiceConversation, _PersistentConversati);
24942
24943 function ServiceConversation() {
24944 return _PersistentConversati.apply(this, arguments) || this;
24945 }
24946
24947 var _proto = ServiceConversation.prototype;
24948
24949 /**
24950 * 订阅该服务号
24951 * @return {Promise.<this>} self
24952 */
24953 _proto.subscribe =
24954 /*#__PURE__*/
24955 function () {
24956 var _subscribe = _asyncToGenerator(
24957 /*#__PURE__*/
24958 regenerator.mark(function _callee() {
24959 return regenerator.wrap(function _callee$(_context) {
24960 while (1) {
24961 switch (_context.prev = _context.next) {
24962 case 0:
24963 return _context.abrupt("return", this.join());
24964
24965 case 1:
24966 case "end":
24967 return _context.stop();
24968 }
24969 }
24970 }, _callee, this);
24971 }));
24972
24973 function subscribe() {
24974 return _subscribe.apply(this, arguments);
24975 }
24976
24977 return subscribe;
24978 }()
24979 /**
24980 * 退订该服务号
24981 * @return {Promise.<this>} self
24982 */
24983 ;
24984
24985 _proto.unsubscribe =
24986 /*#__PURE__*/
24987 function () {
24988 var _unsubscribe = _asyncToGenerator(
24989 /*#__PURE__*/
24990 regenerator.mark(function _callee2() {
24991 return regenerator.wrap(function _callee2$(_context2) {
24992 while (1) {
24993 switch (_context2.prev = _context2.next) {
24994 case 0:
24995 return _context2.abrupt("return", this.quit());
24996
24997 case 1:
24998 case "end":
24999 return _context2.stop();
25000 }
25001 }
25002 }, _callee2, this);
25003 }));
25004
25005 function unsubscribe() {
25006 return _unsubscribe.apply(this, arguments);
25007 }
25008
25009 return unsubscribe;
25010 }();
25011
25012 return ServiceConversation;
25013 }(PersistentConversation);
25014
25015 var transformNotFoundError = function transformNotFoundError(error) {
25016 return error.code === ErrorCode.CONVERSATION_NOT_FOUND ? createError({
25017 code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
25018 }) : error;
25019 };
25020 /**
25021 * 临时对话
25022 * @since 4.0.0
25023 * @extends ConversationBase
25024 * @public
25025 */
25026
25027
25028 var TemporaryConversation =
25029 /*#__PURE__*/
25030 function (_ConversationBase) {
25031 _inheritsLoose(TemporaryConversation, _ConversationBase);
25032
25033 /**
25034 * 无法直接实例化,请使用 {@link IMClient#createTemporaryConversation} 创建新的临时对话。
25035 */
25036 function TemporaryConversation(data, _ref, client) {
25037 var expiredAt = _ref.expiredAt;
25038 return _ConversationBase.call(this, _objectSpread({}, data, {
25039 expiredAt: expiredAt
25040 }), client) || this;
25041 }
25042 /**
25043 * 对话失效时间
25044 * @type {Date}
25045 */
25046
25047
25048 var _proto = TemporaryConversation.prototype;
25049
25050 _proto._send =
25051 /*#__PURE__*/
25052 function () {
25053 var _send2 = _asyncToGenerator(
25054 /*#__PURE__*/
25055 regenerator.mark(function _callee() {
25056 var _ConversationBase$pro,
25057 _len,
25058 args,
25059 _key,
25060 _args = arguments;
25061
25062 return regenerator.wrap(function _callee$(_context) {
25063 while (1) {
25064 switch (_context.prev = _context.next) {
25065 case 0:
25066 if (!this.expired) {
25067 _context.next = 2;
25068 break;
25069 }
25070
25071 throw createError({
25072 code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
25073 });
25074
25075 case 2:
25076 _context.prev = 2;
25077
25078 for (_len = _args.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
25079 args[_key] = _args[_key];
25080 }
25081
25082 _context.next = 6;
25083 return (_ConversationBase$pro = _ConversationBase.prototype._send).call.apply(_ConversationBase$pro, [this].concat(args));
25084
25085 case 6:
25086 return _context.abrupt("return", _context.sent);
25087
25088 case 9:
25089 _context.prev = 9;
25090 _context.t0 = _context["catch"](2);
25091 throw transformNotFoundError(_context.t0);
25092
25093 case 12:
25094 case "end":
25095 return _context.stop();
25096 }
25097 }
25098 }, _callee, this, [[2, 9]]);
25099 }));
25100
25101 function _send() {
25102 return _send2.apply(this, arguments);
25103 }
25104
25105 return _send;
25106 }();
25107
25108 _proto.send =
25109 /*#__PURE__*/
25110 function () {
25111 var _send3 = _asyncToGenerator(
25112 /*#__PURE__*/
25113 regenerator.mark(function _callee2() {
25114 var _ConversationBase$pro2,
25115 _len2,
25116 args,
25117 _key2,
25118 _args2 = arguments;
25119
25120 return regenerator.wrap(function _callee2$(_context2) {
25121 while (1) {
25122 switch (_context2.prev = _context2.next) {
25123 case 0:
25124 _context2.prev = 0;
25125
25126 for (_len2 = _args2.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
25127 args[_key2] = _args2[_key2];
25128 }
25129
25130 _context2.next = 4;
25131 return (_ConversationBase$pro2 = _ConversationBase.prototype.send).call.apply(_ConversationBase$pro2, [this].concat(args));
25132
25133 case 4:
25134 return _context2.abrupt("return", _context2.sent);
25135
25136 case 7:
25137 _context2.prev = 7;
25138 _context2.t0 = _context2["catch"](0);
25139 throw transformNotFoundError(_context2.t0);
25140
25141 case 10:
25142 case "end":
25143 return _context2.stop();
25144 }
25145 }
25146 }, _callee2, this, [[0, 7]]);
25147 }));
25148
25149 function send() {
25150 return _send3.apply(this, arguments);
25151 }
25152
25153 return send;
25154 }();
25155
25156 _proto.toFullJSON = function toFullJSON() {
25157 var expiredAt = this.expiredAt;
25158 return _objectSpread({}, _ConversationBase.prototype.toFullJSON.call(this), {
25159 expiredAt: getTime(expiredAt)
25160 });
25161 };
25162
25163 _proto.toJSON = function toJSON() {
25164 var expiredAt = this.expiredAt,
25165 expired = this.expired;
25166 return _objectSpread({}, _ConversationBase.prototype.toJSON.call(this), {
25167 expiredAt: expiredAt,
25168 expired: expired
25169 });
25170 };
25171
25172 _createClass(TemporaryConversation, [{
25173 key: "expiredAt",
25174 set: function set(value) {
25175 this._expiredAt = decodeDate(value);
25176 },
25177 get: function get() {
25178 return this._expiredAt;
25179 }
25180 /**
25181 * 对话是否已失效
25182 * @type {Boolean}
25183 */
25184
25185 }, {
25186 key: "expired",
25187 get: function get() {
25188 return this.expiredAt < new Date();
25189 }
25190 }]);
25191
25192 return TemporaryConversation;
25193 }(ConversationBase);
25194
25195 var debug$8 = browser('LC:ConversationQuery');
25196
25197 var ConversationQuery =
25198 /*#__PURE__*/
25199 function () {
25200 ConversationQuery._encode = function _encode(value) {
25201 if (value instanceof Date) {
25202 return {
25203 __type: 'Date',
25204 iso: value.toJSON()
25205 };
25206 }
25207
25208 if (value instanceof RegExp) {
25209 return value.source;
25210 }
25211
25212 return value;
25213 };
25214
25215 ConversationQuery._quote = function _quote(s) {
25216 return "\\Q".concat(s.replace('\\E', '\\E\\\\E\\Q'), "\\E");
25217 };
25218
25219 ConversationQuery._calculateFlag = function _calculateFlag(options) {
25220 return ['withLastMessagesRefreshed', 'compact'].reduce( // eslint-disable-next-line no-bitwise
25221 function (prev, key) {
25222 return (prev << 1) + Boolean(options[key]);
25223 }, 0);
25224 }
25225 /**
25226 * Create a ConversationQuery
25227 * @param {IMClient} client
25228 */
25229 ;
25230
25231 function ConversationQuery(client) {
25232 this._client = client;
25233 this._where = {};
25234 this._extraOptions = {};
25235 }
25236
25237 var _proto = ConversationQuery.prototype;
25238
25239 _proto._addCondition = function _addCondition(key, condition, value) {
25240 // Check if we already have a condition
25241 if (!this._where[key]) {
25242 this._where[key] = {};
25243 }
25244
25245 this._where[key][condition] = this.constructor._encode(value);
25246 return this;
25247 };
25248
25249 _proto.toJSON = function toJSON() {
25250 var json = {
25251 where: this._where,
25252 flag: this.constructor._calculateFlag(this._extraOptions)
25253 };
25254 if (typeof this._skip !== 'undefined') json.skip = this._skip;
25255 if (typeof this._limit !== 'undefined') json.limit = this._limit;
25256 if (typeof this._order !== 'undefined') json.sort = this._order;
25257 debug$8(json);
25258 return json;
25259 }
25260 /**
25261 * 增加查询条件,指定聊天室的组员包含某些成员即可返回
25262 * @param {string[]} peerIds - 成员 ID 列表
25263 * @return {ConversationQuery} self
25264 */
25265 ;
25266
25267 _proto.containsMembers = function containsMembers(peerIds) {
25268 return this.containsAll('m', peerIds);
25269 }
25270 /**
25271 * 增加查询条件,指定聊天室的组员条件满足条件的才返回
25272 *
25273 * @param {string[]} - 成员 ID 列表
25274 * @param {Boolean} includeSelf - 是否包含自己
25275 * @return {ConversationQuery} self
25276 */
25277 ;
25278
25279 _proto.withMembers = function withMembers(peerIds, includeSelf) {
25280 var peerIdsSet = new Set(peerIds);
25281
25282 if (includeSelf) {
25283 peerIdsSet.add(this._client.id);
25284 }
25285
25286 this.sizeEqualTo('m', peerIdsSet.size);
25287 return this.containsMembers(Array.from(peerIdsSet));
25288 }
25289 /**
25290 * 增加查询条件,当 conversation 的属性中对应的字段满足等于条件时即可返回
25291 *
25292 * @param {string} key
25293 * @param value
25294 * @return {ConversationQuery} self
25295 */
25296 ;
25297
25298 _proto.equalTo = function equalTo(key, value) {
25299 this._where[key] = this.constructor._encode(value);
25300 return this;
25301 }
25302 /**
25303 * 增加查询条件,当 conversation 的属性中对应的字段满足小于条件时即可返回
25304 * @param {string} key
25305 * @param value
25306 * @return {ConversationQuery} self
25307 */
25308 ;
25309
25310 _proto.lessThan = function lessThan(key, value) {
25311 return this._addCondition(key, '$lt', value);
25312 }
25313 /**
25314 * 增加查询条件,当 conversation 的属性中对应的字段满足小于等于条件时即可返回
25315 * @param {string} key
25316 * @param value
25317 * @return {ConversationQuery} self
25318 */
25319 ;
25320
25321 _proto.lessThanOrEqualTo = function lessThanOrEqualTo(key, value) {
25322 return this._addCondition(key, '$lte', value);
25323 }
25324 /**
25325 * 增加查询条件,当 conversation 的属性中对应的字段满足大于条件时即可返回
25326 *
25327 * @param {string} key
25328 * @param value
25329 * @return {ConversationQuery} self
25330 */
25331 ;
25332
25333 _proto.greaterThan = function greaterThan(key, value) {
25334 return this._addCondition(key, '$gt', value);
25335 }
25336 /**
25337 * 增加查询条件,当 conversation 的属性中对应的字段满足大于等于条件时即可返回
25338 *
25339 * @param {string} key
25340 * @param value
25341 * @return {ConversationQuery} self
25342 */
25343 ;
25344
25345 _proto.greaterThanOrEqualTo = function greaterThanOrEqualTo(key, value) {
25346 return this._addCondition(key, '$gte', value);
25347 }
25348 /**
25349 * 增加查询条件,当 conversation 的属性中对应的字段满足不等于条件时即可返回
25350 *
25351 * @param {string} key
25352 * @param value
25353 * @return {ConversationQuery} self
25354 */
25355 ;
25356
25357 _proto.notEqualTo = function notEqualTo(key, value) {
25358 return this._addCondition(key, '$ne', value);
25359 }
25360 /**
25361 * 增加查询条件,当 conversation 存在指定的字段时即可返回
25362 *
25363 * @since 3.5.0
25364 * @param {string} key
25365 * @return {ConversationQuery} self
25366 */
25367 ;
25368
25369 _proto.exists = function exists(key) {
25370 return this._addCondition(key, '$exists', true);
25371 }
25372 /**
25373 * 增加查询条件,当 conversation 不存在指定的字段时即可返回
25374 *
25375 * @since 3.5.0
25376 * @param {string} key
25377 * @return {ConversationQuery} self
25378 */
25379 ;
25380
25381 _proto.doesNotExist = function doesNotExist(key) {
25382 return this._addCondition(key, '$exists', false);
25383 }
25384 /**
25385 * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含在指定值中时即可返回
25386 *
25387 * @param {string} key
25388 * @param values
25389 * @return {ConversationQuery} self
25390 */
25391 ;
25392
25393 _proto.containedIn = function containedIn(key, values) {
25394 return this._addCondition(key, '$in', values);
25395 }
25396 /**
25397 * 增加查询条件,当 conversation 的属性中对应的字段对应的值不包含在指定值中时即可返回
25398 *
25399 * @param {string} key
25400 * @param values
25401 * @return {ConversationQuery} self
25402 */
25403 ;
25404
25405 _proto.notContainsIn = function notContainsIn(key, values) {
25406 return this._addCondition(key, '$nin', values);
25407 }
25408 /**
25409 * 增加查询条件,当conversation的属性中对应的字段中的元素包含所有的值才可返回
25410 *
25411 * @param {string} key
25412 * @param values
25413 * @return {ConversationQuery} self
25414 */
25415 ;
25416
25417 _proto.containsAll = function containsAll(key, values) {
25418 return this._addCondition(key, '$all', values);
25419 }
25420 /**
25421 * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含此字符串即可返回
25422 *
25423 * @param {string} key
25424 * @param {string} subString
25425 * @return {ConversationQuery} self
25426 */
25427 ;
25428
25429 _proto.contains = function contains(key, subString) {
25430 return this._addCondition(key, '$regex', ConversationQuery._quote(subString));
25431 }
25432 /**
25433 * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串起始即可返回
25434 *
25435 * @param {string} key
25436 * @param {string} prefix
25437 * @return {ConversationQuery} self
25438 */
25439 ;
25440
25441 _proto.startsWith = function startsWith(key, prefix) {
25442 return this._addCondition(key, '$regex', "^".concat(ConversationQuery._quote(prefix)));
25443 }
25444 /**
25445 * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串结束即可返回
25446 *
25447 * @param {string} key
25448 * @param {string} suffix
25449 * @return {ConversationQuery} self
25450 */
25451 ;
25452
25453 _proto.endsWith = function endsWith(key, suffix) {
25454 return this._addCondition(key, '$regex', "".concat(ConversationQuery._quote(suffix), "$"));
25455 }
25456 /**
25457 * 增加查询条件,当 conversation 的属性中对应的字段对应的值满足提供的正则表达式即可返回
25458 *
25459 * @param {string} key
25460 * @param {RegExp} regex
25461 * @return {ConversationQuery} self
25462 */
25463 ;
25464
25465 _proto.matches = function matches(key, regex) {
25466 this._addCondition(key, '$regex', regex); // Javascript regex options support mig as inline options but store them
25467 // as properties of the object. We support mi & should migrate them to
25468 // modifiers
25469
25470
25471 var _modifiers = '';
25472
25473 if (regex.ignoreCase) {
25474 _modifiers += 'i';
25475 }
25476
25477 if (regex.multiline) {
25478 _modifiers += 'm';
25479 }
25480
25481 if (_modifiers && _modifiers.length) {
25482 this._addCondition(key, '$options', _modifiers);
25483 }
25484
25485 return this;
25486 }
25487 /**
25488 * 添加查询约束条件,查找 key 类型是数组,该数组的长度匹配提供的数值
25489 *
25490 * @param {string} key
25491 * @param {Number} length
25492 * @return {ConversationQuery} self
25493 */
25494 ;
25495
25496 _proto.sizeEqualTo = function sizeEqualTo(key, length) {
25497 return this._addCondition(key, '$size', length);
25498 }
25499 /**
25500 * 设置返回集合的大小上限
25501 *
25502 * @param {Number} limit - 上限
25503 * @return {ConversationQuery} self
25504 */
25505 ;
25506
25507 _proto.limit = function limit(_limit) {
25508 this._limit = _limit;
25509 return this;
25510 }
25511 /**
25512 * 设置返回集合的起始位置,一般用于分页
25513 *
25514 * @param {Number} skip - 起始位置跳过几个对象
25515 * @return {ConversationQuery} self
25516 */
25517 ;
25518
25519 _proto.skip = function skip(_skip) {
25520 this._skip = _skip;
25521 return this;
25522 }
25523 /**
25524 * 设置返回集合按照指定key进行增序排列
25525 *
25526 * @param {string} key
25527 * @return {ConversationQuery} self
25528 */
25529 ;
25530
25531 _proto.ascending = function ascending(key) {
25532 this._order = key;
25533 return this;
25534 }
25535 /**
25536 * 设置返回集合按照指定key进行增序排列,如果已设置其他排序,原排序的优先级较高
25537 *
25538 * @param {string} key
25539 * @return {ConversationQuery} self
25540 */
25541 ;
25542
25543 _proto.addAscending = function addAscending(key) {
25544 if (this._order) {
25545 this._order += ",".concat(key);
25546 } else {
25547 this._order = key;
25548 }
25549
25550 return this;
25551 }
25552 /**
25553 * 设置返回集合按照指定 key 进行降序排列
25554 *
25555 * @param {string} key
25556 * @return {ConversationQuery} self
25557 */
25558 ;
25559
25560 _proto.descending = function descending(key) {
25561 this._order = "-".concat(key);
25562 return this;
25563 }
25564 /**
25565 * 设置返回集合按照指定 key 进行降序排列,如果已设置其他排序,原排序的优先级较高
25566 *
25567 * @param {string} key
25568 * @return {ConversationQuery} self
25569 */
25570 ;
25571
25572 _proto.addDescending = function addDescending(key) {
25573 if (this._order) {
25574 this._order += ",-".concat(key);
25575 } else {
25576 this._order = "-".concat(key);
25577 }
25578
25579 return this;
25580 }
25581 /**
25582 * 设置返回的 conversations 刷新最后一条消息
25583 * @param {Boolean} [enabled=true]
25584 * @return {ConversationQuery} self
25585 */
25586 ;
25587
25588 _proto.withLastMessagesRefreshed = function withLastMessagesRefreshed() {
25589 var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
25590 this._extraOptions.withLastMessagesRefreshed = enabled;
25591 return this;
25592 }
25593 /**
25594 * 设置返回的 conversations 为精简模式,即不含成员列表
25595 * @param {Boolean} [enabled=true]
25596 * @return {ConversationQuery} self
25597 */
25598 ;
25599
25600 _proto.compact = function compact() {
25601 var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
25602 this._extraOptions.compact = enabled;
25603 return this;
25604 }
25605 /**
25606 * 执行查询
25607 * @return {Promise.<ConversationBase[]>}
25608 */
25609 ;
25610
25611 _proto.find =
25612 /*#__PURE__*/
25613 function () {
25614 var _find = _asyncToGenerator(
25615 /*#__PURE__*/
25616 regenerator.mark(function _callee() {
25617 return regenerator.wrap(function _callee$(_context) {
25618 while (1) {
25619 switch (_context.prev = _context.next) {
25620 case 0:
25621 return _context.abrupt("return", this._client._executeQuery(this));
25622
25623 case 1:
25624 case "end":
25625 return _context.stop();
25626 }
25627 }
25628 }, _callee, this);
25629 }));
25630
25631 function find() {
25632 return _find.apply(this, arguments);
25633 }
25634
25635 return find;
25636 }();
25637
25638 return ConversationQuery;
25639 }();
25640
25641 var debug$9 = browser('LC:SessionManager');
25642
25643 var SessionManager =
25644 /*#__PURE__*/
25645 function () {
25646 function SessionManager() {
25647 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
25648 refresh = _ref.refresh,
25649 onBeforeGetSessionToken = _ref.onBeforeGetSessionToken;
25650
25651 this.refresh = refresh;
25652 this._onBeforeGetSessionToken = onBeforeGetSessionToken;
25653 this.setSessionToken(null, 0);
25654 }
25655
25656 var _proto = SessionManager.prototype;
25657
25658 _proto.setSessionToken = function setSessionToken(token, ttl) {
25659 debug$9('set session token', token, ttl);
25660 var sessionToken = new Expirable(token, ttl * 1000);
25661 this._sessionToken = sessionToken;
25662 delete this._pendingSessionTokenPromise;
25663 return sessionToken;
25664 };
25665
25666 _proto.setSessionTokenAsync =
25667 /*#__PURE__*/
25668 function () {
25669 var _setSessionTokenAsync = _asyncToGenerator(
25670 /*#__PURE__*/
25671 regenerator.mark(function _callee(promise) {
25672 var _this = this;
25673
25674 var currentSessionToken;
25675 return regenerator.wrap(function _callee$(_context) {
25676 while (1) {
25677 switch (_context.prev = _context.next) {
25678 case 0:
25679 currentSessionToken = this._sessionToken;
25680 this._pendingSessionTokenPromise = promise.catch(function (error) {
25681 // revert, otherwise the following getSessionToken calls
25682 // will all be rejected
25683 _this._sessionToken = currentSessionToken;
25684 throw error;
25685 });
25686 _context.t0 = this.setSessionToken;
25687 _context.t1 = this;
25688 _context.t2 = _toConsumableArray;
25689 _context.next = 7;
25690 return this._pendingSessionTokenPromise;
25691
25692 case 7:
25693 _context.t3 = _context.sent;
25694 _context.t4 = (0, _context.t2)(_context.t3);
25695 return _context.abrupt("return", _context.t0.apply.call(_context.t0, _context.t1, _context.t4));
25696
25697 case 10:
25698 case "end":
25699 return _context.stop();
25700 }
25701 }
25702 }, _callee, this);
25703 }));
25704
25705 function setSessionTokenAsync(_x) {
25706 return _setSessionTokenAsync.apply(this, arguments);
25707 }
25708
25709 return setSessionTokenAsync;
25710 }();
25711
25712 _proto.getSessionToken =
25713 /*#__PURE__*/
25714 function () {
25715 var _getSessionToken = _asyncToGenerator(
25716 /*#__PURE__*/
25717 regenerator.mark(function _callee2() {
25718 var _ref2,
25719 _ref2$autoRefresh,
25720 autoRefresh,
25721 _ref3,
25722 value,
25723 originalValue,
25724 _ref4,
25725 newValue,
25726 _args2 = arguments;
25727
25728 return regenerator.wrap(function _callee2$(_context2) {
25729 while (1) {
25730 switch (_context2.prev = _context2.next) {
25731 case 0:
25732 _ref2 = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}, _ref2$autoRefresh = _ref2.autoRefresh, autoRefresh = _ref2$autoRefresh === void 0 ? true : _ref2$autoRefresh;
25733 debug$9('get session token');
25734
25735 if (this._onBeforeGetSessionToken) {
25736 this._onBeforeGetSessionToken(this);
25737 }
25738
25739 _context2.t0 = this._sessionToken;
25740
25741 if (_context2.t0) {
25742 _context2.next = 8;
25743 break;
25744 }
25745
25746 _context2.next = 7;
25747 return this._pendingSessionTokenPromise;
25748
25749 case 7:
25750 _context2.t0 = _context2.sent;
25751
25752 case 8:
25753 _ref3 = _context2.t0;
25754 value = _ref3.value;
25755 originalValue = _ref3.originalValue;
25756
25757 if (!(value === Expirable.EXPIRED && autoRefresh && this.refresh)) {
25758 _context2.next = 19;
25759 break;
25760 }
25761
25762 debug$9('refresh expired session token');
25763 _context2.next = 15;
25764 return this.setSessionTokenAsync(this.refresh(this, originalValue));
25765
25766 case 15:
25767 _ref4 = _context2.sent;
25768 newValue = _ref4.value;
25769 debug$9('session token', newValue);
25770 return _context2.abrupt("return", newValue);
25771
25772 case 19:
25773 debug$9('session token', value);
25774 return _context2.abrupt("return", value);
25775
25776 case 21:
25777 case "end":
25778 return _context2.stop();
25779 }
25780 }
25781 }, _callee2, this);
25782 }));
25783
25784 function getSessionToken() {
25785 return _getSessionToken.apply(this, arguments);
25786 }
25787
25788 return getSessionToken;
25789 }();
25790
25791 _proto.revoke = function revoke() {
25792 if (this._sessionToken) this._sessionToken.expiredAt = -1;
25793 };
25794
25795 return SessionManager;
25796 }();
25797
25798 var _dec$2, _dec2, _class$3;
25799 var debug$a = browser('LC:IMClient');
25800 var INVITED$1 = INVITED,
25801 KICKED$1 = KICKED,
25802 MEMBERS_JOINED$1 = MEMBERS_JOINED,
25803 MEMBERS_LEFT$1 = MEMBERS_LEFT,
25804 MEMBER_INFO_UPDATED$1 = MEMBER_INFO_UPDATED,
25805 BLOCKED$1 = BLOCKED,
25806 UNBLOCKED$1 = UNBLOCKED,
25807 MEMBERS_BLOCKED$1 = MEMBERS_BLOCKED,
25808 MEMBERS_UNBLOCKED$1 = MEMBERS_UNBLOCKED,
25809 MUTED$1 = MUTED,
25810 UNMUTED$1 = UNMUTED,
25811 MEMBERS_MUTED$1 = MEMBERS_MUTED,
25812 MEMBERS_UNMUTED$1 = MEMBERS_UNMUTED,
25813 MESSAGE$2 = MESSAGE$1,
25814 UNREAD_MESSAGES_COUNT_UPDATE$1 = UNREAD_MESSAGES_COUNT_UPDATE,
25815 CLOSE$1 = CLOSE,
25816 CONFLICT$1 = CONFLICT,
25817 UNHANDLED_MESSAGE$1 = UNHANDLED_MESSAGE,
25818 CONVERSATION_INFO_UPDATED$1 = CONVERSATION_INFO_UPDATED,
25819 MESSAGE_RECALL$1 = MESSAGE_RECALL,
25820 MESSAGE_UPDATE$1 = MESSAGE_UPDATE,
25821 INFO_UPDATED$1 = INFO_UPDATED;
25822
25823 var isTemporaryConversatrionId = function isTemporaryConversatrionId(id) {
25824 return /^_tmp:/.test(id);
25825 };
25826 /**
25827 * 1 patch-msg
25828 * 1 temp-conv-msg
25829 * 0 auto-bind-deviceid-and-installation
25830 * 1 transient-msg-ack
25831 * 1 keep-notification
25832 * 1 partial-failed-msg
25833 * @ignore
25834 */
25835
25836
25837 var configBitmap = 59;
25838 var IMClient = (_dec$2 = throttle(1000), _dec2 = throttle(1000), (_class$3 =
25839 /*#__PURE__*/
25840 function (_EventEmitter) {
25841 _inheritsLoose(IMClient, _EventEmitter);
25842
25843 /**
25844 * 无法直接实例化,请使用 {@link Realtime#createIMClient} 创建新的 IMClient。
25845 *
25846 * @extends EventEmitter
25847 */
25848 function IMClient(id) {
25849 var _this;
25850
25851 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25852 var props = arguments.length > 2 ? arguments[2] : undefined;
25853
25854 if (!(id === undefined || typeof id === 'string')) {
25855 throw new TypeError("Client id [".concat(id, "] is not a String"));
25856 }
25857
25858 _this = _EventEmitter.call(this) || this;
25859 Object.assign(_assertThisInitialized(_this), {
25860 /**
25861 * @var id {String} 客户端 id
25862 * @memberof IMClient#
25863 */
25864 id: id,
25865 options: options
25866 }, props);
25867
25868 if (!_this._messageParser) {
25869 throw new Error('IMClient must be initialized with a MessageParser');
25870 }
25871
25872 _this._conversationCache = new Cache("client:".concat(_this.id));
25873 _this._ackMessageBuffer = {};
25874 internal(_assertThisInitialized(_this)).lastPatchTime = Date.now();
25875 internal(_assertThisInitialized(_this)).lastNotificationTime = undefined;
25876 internal(_assertThisInitialized(_this))._eventemitter = new eventemitter3();
25877
25878 if (debug$a.enabled) {
25879 values_1(Event).forEach(function (event) {
25880 return _this.on(event, function () {
25881 for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) {
25882 payload[_key] = arguments[_key];
25883 }
25884
25885 return _this._debug("".concat(event, " event emitted. %o"), payload);
25886 });
25887 });
25888 } // onIMClientCreate hook
25889
25890
25891 applyDecorators(_this._plugins.onIMClientCreate, _assertThisInitialized(_this));
25892 return _this;
25893 }
25894
25895 var _proto = IMClient.prototype;
25896
25897 _proto._debug = function _debug() {
25898 for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
25899 params[_key2] = arguments[_key2];
25900 }
25901
25902 debug$a.apply(void 0, params.concat(["[".concat(this.id, "]")]));
25903 }
25904 /**
25905 * @override
25906 * @private
25907 */
25908 ;
25909
25910 _proto._dispatchCommand =
25911 /*#__PURE__*/
25912 function () {
25913 var _dispatchCommand2 = _asyncToGenerator(
25914 /*#__PURE__*/
25915 regenerator.mark(function _callee(command) {
25916 return regenerator.wrap(function _callee$(_context) {
25917 while (1) {
25918 switch (_context.prev = _context.next) {
25919 case 0:
25920 this._debug(trim(command), 'received');
25921
25922 if (command.serverTs && command.notificationType === 1) {
25923 internal(this).lastNotificationTime = getTime(decodeDate(command.serverTs));
25924 }
25925
25926 _context.t0 = command.cmd;
25927 _context.next = _context.t0 === CommandType.conv ? 5 : _context.t0 === CommandType.direct ? 6 : _context.t0 === CommandType.session ? 7 : _context.t0 === CommandType.unread ? 8 : _context.t0 === CommandType.rcp ? 9 : _context.t0 === CommandType.patch ? 10 : 11;
25928 break;
25929
25930 case 5:
25931 return _context.abrupt("return", this._dispatchConvMessage(command));
25932
25933 case 6:
25934 return _context.abrupt("return", this._dispatchDirectMessage(command));
25935
25936 case 7:
25937 return _context.abrupt("return", this._dispatchSessionMessage(command));
25938
25939 case 8:
25940 return _context.abrupt("return", this._dispatchUnreadMessage(command));
25941
25942 case 9:
25943 return _context.abrupt("return", this._dispatchRcpMessage(command));
25944
25945 case 10:
25946 return _context.abrupt("return", this._dispatchPatchMessage(command));
25947
25948 case 11:
25949 return _context.abrupt("return", this.emit(UNHANDLED_MESSAGE$1, command));
25950
25951 case 12:
25952 case "end":
25953 return _context.stop();
25954 }
25955 }
25956 }, _callee, this);
25957 }));
25958
25959 function _dispatchCommand(_x) {
25960 return _dispatchCommand2.apply(this, arguments);
25961 }
25962
25963 return _dispatchCommand;
25964 }();
25965
25966 _proto._dispatchSessionMessage =
25967 /*#__PURE__*/
25968 function () {
25969 var _dispatchSessionMessage2 = _asyncToGenerator(
25970 /*#__PURE__*/
25971 regenerator.mark(function _callee2(message) {
25972 var _message$sessionMessa, code, reason;
25973
25974 return regenerator.wrap(function _callee2$(_context2) {
25975 while (1) {
25976 switch (_context2.prev = _context2.next) {
25977 case 0:
25978 _message$sessionMessa = message.sessionMessage, code = _message$sessionMessa.code, reason = _message$sessionMessa.reason;
25979 _context2.t0 = message.op;
25980 _context2.next = _context2.t0 === OpType.closed ? 4 : 8;
25981 break;
25982
25983 case 4:
25984 internal(this)._eventemitter.emit('close');
25985
25986 if (!(code === ErrorCode.SESSION_CONFLICT)) {
25987 _context2.next = 7;
25988 break;
25989 }
25990
25991 return _context2.abrupt("return", this.emit(CONFLICT$1, {
25992 reason: reason
25993 }));
25994
25995 case 7:
25996 return _context2.abrupt("return", this.emit(CLOSE$1, {
25997 code: code,
25998 reason: reason
25999 }));
26000
26001 case 8:
26002 this.emit(UNHANDLED_MESSAGE$1, message);
26003 throw new Error('Unrecognized session command');
26004
26005 case 10:
26006 case "end":
26007 return _context2.stop();
26008 }
26009 }
26010 }, _callee2, this);
26011 }));
26012
26013 function _dispatchSessionMessage(_x2) {
26014 return _dispatchSessionMessage2.apply(this, arguments);
26015 }
26016
26017 return _dispatchSessionMessage;
26018 }();
26019
26020 _proto._dispatchUnreadMessage = function _dispatchUnreadMessage(_ref) {
26021 var _this2 = this;
26022
26023 var _ref$unreadMessage = _ref.unreadMessage,
26024 convs = _ref$unreadMessage.convs,
26025 notifTime = _ref$unreadMessage.notifTime;
26026 internal(this).lastUnreadNotifTime = notifTime; // ensure all converstions are cached
26027
26028 return this.getConversations(convs.map(function (conv) {
26029 return conv.cid;
26030 })).then(function () {
26031 return (// update conversations data
26032 Promise.all(convs.map(function (_ref2) {
26033 var cid = _ref2.cid,
26034 unread = _ref2.unread,
26035 mid = _ref2.mid,
26036 ts = _ref2.timestamp,
26037 from = _ref2.from,
26038 data = _ref2.data,
26039 binaryMsg = _ref2.binaryMsg,
26040 patchTimestamp = _ref2.patchTimestamp,
26041 mentioned = _ref2.mentioned;
26042
26043 var conversation = _this2._conversationCache.get(cid); // deleted conversation
26044
26045
26046 if (!conversation) return null;
26047 var timestamp;
26048
26049 if (ts) {
26050 timestamp = decodeDate(ts);
26051 conversation.lastMessageAt = timestamp; // eslint-disable-line no-param-reassign
26052 }
26053
26054 return (mid ? _this2._messageParser.parse(binaryMsg || data).then(function (message) {
26055 var messageProps = {
26056 id: mid,
26057 cid: cid,
26058 timestamp: timestamp,
26059 updatedAt: patchTimestamp,
26060 from: from
26061 };
26062 Object.assign(message, messageProps);
26063 conversation.lastMessage = message; // eslint-disable-line no-param-reassign
26064 }) : Promise.resolve()).then(function () {
26065 conversation._setUnreadMessagesMentioned(mentioned);
26066
26067 var countNotUpdated = unread === internal(conversation).unreadMessagesCount;
26068 if (countNotUpdated) return null; // to be filtered
26069 // manipulate internal property directly to skip unreadmessagescountupdate event
26070
26071 internal(conversation).unreadMessagesCount = unread;
26072 return conversation;
26073 }); // filter conversations without unread count update
26074 })).then(function (conversations) {
26075 return conversations.filter(function (conversation) {
26076 return conversation;
26077 });
26078 })
26079 );
26080 }).then(function (conversations) {
26081 if (conversations.length) {
26082 /**
26083 * 未读消息数目更新
26084 * @event IMClient#UNREAD_MESSAGES_COUNT_UPDATE
26085 * @since 3.4.0
26086 * @param {Conversation[]} conversations 未读消息数目有更新的对话列表
26087 */
26088 _this2.emit(UNREAD_MESSAGES_COUNT_UPDATE$1, conversations);
26089 }
26090 });
26091 };
26092
26093 _proto._dispatchRcpMessage =
26094 /*#__PURE__*/
26095 function () {
26096 var _dispatchRcpMessage2 = _asyncToGenerator(
26097 /*#__PURE__*/
26098 regenerator.mark(function _callee3(message) {
26099 var rcpMessage, read, conversationId, messageId, timestamp, conversation;
26100 return regenerator.wrap(function _callee3$(_context3) {
26101 while (1) {
26102 switch (_context3.prev = _context3.next) {
26103 case 0:
26104 rcpMessage = message.rcpMessage, read = message.rcpMessage.read;
26105 conversationId = rcpMessage.cid;
26106 messageId = rcpMessage.id;
26107 timestamp = decodeDate(rcpMessage.t);
26108 conversation = this._conversationCache.get(conversationId); // conversation not cached means the client does not send the message
26109 // during this session
26110
26111 if (conversation) {
26112 _context3.next = 7;
26113 break;
26114 }
26115
26116 return _context3.abrupt("return");
26117
26118 case 7:
26119 conversation._handleReceipt({
26120 messageId: messageId,
26121 timestamp: timestamp,
26122 read: read
26123 });
26124
26125 case 8:
26126 case "end":
26127 return _context3.stop();
26128 }
26129 }
26130 }, _callee3, this);
26131 }));
26132
26133 function _dispatchRcpMessage(_x3) {
26134 return _dispatchRcpMessage2.apply(this, arguments);
26135 }
26136
26137 return _dispatchRcpMessage;
26138 }();
26139
26140 _proto._dispatchPatchMessage = function _dispatchPatchMessage(_ref3) {
26141 var _this3 = this;
26142
26143 var patches = _ref3.patchMessage.patches;
26144 // ensure all converstions are cached
26145 return this.getConversations(patches.map(function (patch) {
26146 return patch.cid;
26147 })).then(function () {
26148 return Promise.all(patches.map(function (_ref4) {
26149 var cid = _ref4.cid,
26150 mid = _ref4.mid,
26151 timestamp = _ref4.timestamp,
26152 recall = _ref4.recall,
26153 data = _ref4.data,
26154 patchTimestamp = _ref4.patchTimestamp,
26155 from = _ref4.from,
26156 binaryMsg = _ref4.binaryMsg,
26157 mentionAll = _ref4.mentionAll,
26158 mentionPids = _ref4.mentionPids,
26159 patchCode = _ref4.patchCode,
26160 patchReason = _ref4.patchReason;
26161
26162 var conversation = _this3._conversationCache.get(cid); // deleted conversation
26163
26164
26165 if (!conversation) return null;
26166 return _this3._messageParser.parse(binaryMsg || data).then(function (message) {
26167 var patchTime = getTime(decodeDate(patchTimestamp));
26168 var messageProps = {
26169 id: mid,
26170 cid: cid,
26171 timestamp: timestamp,
26172 updatedAt: patchTime,
26173 from: from,
26174 mentionList: mentionPids,
26175 mentionedAll: mentionAll
26176 };
26177 Object.assign(message, messageProps);
26178
26179 message._setStatus(MessageStatus.SENT);
26180
26181 message._updateMentioned(_this3.id);
26182
26183 if (internal(_this3).lastPatchTime < patchTime) {
26184 internal(_this3).lastPatchTime = patchTime;
26185 } // update conversation lastMessage
26186
26187
26188 if (conversation.lastMessage && conversation.lastMessage.id === mid) {
26189 conversation.lastMessage = message; // eslint-disable-line no-param-reassign
26190 }
26191
26192 var reason;
26193
26194 if (patchCode) {
26195 reason = {
26196 code: patchCode.toNumber(),
26197 detail: patchReason
26198 };
26199 }
26200
26201 if (recall) {
26202 /**
26203 * 消息被撤回
26204 * @event IMClient#MESSAGE_RECALL
26205 * @param {AVMessage} message 被撤回的消息
26206 * @param {ConversationBase} conversation 消息所在的会话
26207 * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
26208 */
26209 _this3.emit(MESSAGE_RECALL$1, message, conversation, reason);
26210 /**
26211 * 消息被撤回
26212 * @event ConversationBase#MESSAGE_RECALL
26213 * @param {AVMessage} message 被撤回的消息
26214 * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
26215 */
26216
26217
26218 conversation.emit(MESSAGE_RECALL$1, message, reason);
26219 } else {
26220 /**
26221 * 消息被修改
26222 * @event IMClient#MESSAGE_UPDATE
26223 * @param {AVMessage} message 被修改的消息
26224 * @param {ConversationBase} conversation 消息所在的会话
26225 * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
26226 */
26227 _this3.emit(MESSAGE_UPDATE$1, message, conversation, reason);
26228 /**
26229 * 消息被修改
26230 * @event ConversationBase#MESSAGE_UPDATE
26231 * @param {AVMessage} message 被修改的消息
26232 * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
26233 */
26234
26235
26236 conversation.emit(MESSAGE_UPDATE$1, message, reason);
26237 }
26238 });
26239 }));
26240 });
26241 };
26242
26243 _proto._dispatchConvMessage =
26244 /*#__PURE__*/
26245 function () {
26246 var _dispatchConvMessage2 = _asyncToGenerator(
26247 /*#__PURE__*/
26248 regenerator.mark(function _callee4(message) {
26249 var convMessage, _message$convMessage, initBy, m, info, attr, conversation, payload, _payload, _payload2, _payload3, _payload4, _payload5, _payload6, _payload7, _payload8, _payload9, _payload10, _payload11, pid, role, _internal, memberInfoMap, memberInfo, _payload12, attributes, _payload13;
26250
26251 return regenerator.wrap(function _callee4$(_context4) {
26252 while (1) {
26253 switch (_context4.prev = _context4.next) {
26254 case 0:
26255 convMessage = message.convMessage, _message$convMessage = message.convMessage, initBy = _message$convMessage.initBy, m = _message$convMessage.m, info = _message$convMessage.info, attr = _message$convMessage.attr;
26256 _context4.next = 3;
26257 return this.getConversation(convMessage.cid);
26258
26259 case 3:
26260 conversation = _context4.sent;
26261 _context4.t0 = message.op;
26262 _context4.next = _context4.t0 === OpType.joined ? 7 : _context4.t0 === OpType.left ? 12 : _context4.t0 === OpType.members_joined ? 17 : _context4.t0 === OpType.members_left ? 22 : _context4.t0 === OpType.members_blocked ? 27 : _context4.t0 === OpType.members_unblocked ? 31 : _context4.t0 === OpType.blocked ? 35 : _context4.t0 === OpType.unblocked ? 39 : _context4.t0 === OpType.members_shutuped ? 43 : _context4.t0 === OpType.members_unshutuped ? 47 : _context4.t0 === OpType.shutuped ? 51 : _context4.t0 === OpType.unshutuped ? 55 : _context4.t0 === OpType.member_info_changed ? 59 : _context4.t0 === OpType.updated ? 71 : 77;
26263 break;
26264
26265 case 7:
26266 conversation._addMembers([this.id]);
26267
26268 payload = {
26269 invitedBy: initBy
26270 };
26271 /**
26272 * 当前用户被添加至某个对话
26273 * @event IMClient#INVITED
26274 * @param {Object} payload
26275 * @param {String} payload.invitedBy 邀请者 id
26276 * @param {ConversationBase} conversation
26277 */
26278
26279 this.emit(INVITED$1, payload, conversation);
26280 /**
26281 * 当前用户被添加至当前对话
26282 * @event ConversationBase#INVITED
26283 * @param {Object} payload
26284 * @param {String} payload.invitedBy 该移除操作的发起者 id
26285 */
26286
26287 conversation.emit(INVITED$1, payload);
26288 return _context4.abrupt("return");
26289
26290 case 12:
26291 conversation._removeMembers([this.id]);
26292
26293 _payload = {
26294 kickedBy: initBy
26295 };
26296 /**
26297 * 当前用户被从某个对话中移除
26298 * @event IMClient#KICKED
26299 * @param {Object} payload
26300 * @param {String} payload.kickedBy 该移除操作的发起者 id
26301 * @param {ConversationBase} conversation
26302 */
26303
26304 this.emit(KICKED$1, _payload, conversation);
26305 /**
26306 * 当前用户被从当前对话中移除
26307 * @event ConversationBase#KICKED
26308 * @param {Object} payload
26309 * @param {String} payload.kickedBy 该移除操作的发起者 id
26310 */
26311
26312 conversation.emit(KICKED$1, _payload);
26313 return _context4.abrupt("return");
26314
26315 case 17:
26316 conversation._addMembers(m);
26317
26318 _payload2 = {
26319 invitedBy: initBy,
26320 members: m
26321 };
26322 /**
26323 * 有用户被添加至某个对话
26324 * @event IMClient#MEMBERS_JOINED
26325 * @param {Object} payload
26326 * @param {String[]} payload.members 被添加的用户 id 列表
26327 * @param {String} payload.invitedBy 邀请者 id
26328 * @param {ConversationBase} conversation
26329 */
26330
26331 this.emit(MEMBERS_JOINED$1, _payload2, conversation);
26332 /**
26333 * 有成员被添加至当前对话
26334 * @event ConversationBase#MEMBERS_JOINED
26335 * @param {Object} payload
26336 * @param {String[]} payload.members 被添加的成员 id 列表
26337 * @param {String} payload.invitedBy 邀请者 id
26338 */
26339
26340 conversation.emit(MEMBERS_JOINED$1, _payload2);
26341 return _context4.abrupt("return");
26342
26343 case 22:
26344 conversation._removeMembers(m);
26345
26346 _payload3 = {
26347 kickedBy: initBy,
26348 members: m
26349 };
26350 /**
26351 * 有成员被从某个对话中移除
26352 * @event IMClient#MEMBERS_LEFT
26353 * @param {Object} payload
26354 * @param {String[]} payload.members 被移除的成员 id 列表
26355 * @param {String} payload.kickedBy 该移除操作的发起者 id
26356 * @param {ConversationBase} conversation
26357 */
26358
26359 this.emit(MEMBERS_LEFT$1, _payload3, conversation);
26360 /**
26361 * 有成员被从当前对话中移除
26362 * @event ConversationBase#MEMBERS_LEFT
26363 * @param {Object} payload
26364 * @param {String[]} payload.members 被移除的成员 id 列表
26365 * @param {String} payload.kickedBy 该移除操作的发起者 id
26366 */
26367
26368 conversation.emit(MEMBERS_LEFT$1, _payload3);
26369 return _context4.abrupt("return");
26370
26371 case 27:
26372 _payload4 = {
26373 blockedBy: initBy,
26374 members: m
26375 };
26376 /**
26377 * 有成员被加入某个对话的黑名单
26378 * @event IMClient#MEMBERS_BLOCKED
26379 * @param {Object} payload
26380 * @param {String[]} payload.members 成员 id 列表
26381 * @param {String} payload.blockedBy 该操作的发起者 id
26382 * @param {ConversationBase} conversation
26383 */
26384
26385 this.emit(MEMBERS_BLOCKED$1, _payload4, conversation);
26386 /**
26387 * 有成员被加入当前对话的黑名单
26388 * @event ConversationBase#MEMBERS_BLOCKED
26389 * @param {Object} payload
26390 * @param {String[]} payload.members 成员 id 列表
26391 * @param {String} payload.blockedBy 该操作的发起者 id
26392 */
26393
26394 conversation.emit(MEMBERS_BLOCKED$1, _payload4);
26395 return _context4.abrupt("return");
26396
26397 case 31:
26398 _payload5 = {
26399 unblockedBy: initBy,
26400 members: m
26401 };
26402 /**
26403 * 有成员被移出某个对话的黑名单
26404 * @event IMClient#MEMBERS_UNBLOCKED
26405 * @param {Object} payload
26406 * @param {String[]} payload.members 成员 id 列表
26407 * @param {String} payload.unblockedBy 该操作的发起者 id
26408 * @param {ConversationBase} conversation
26409 */
26410
26411 this.emit(MEMBERS_UNBLOCKED$1, _payload5, conversation);
26412 /**
26413 * 有成员被移出当前对话的黑名单
26414 * @event ConversationBase#MEMBERS_UNBLOCKED
26415 * @param {Object} payload
26416 * @param {String[]} payload.members 成员 id 列表
26417 * @param {String} payload.unblockedBy 该操作的发起者 id
26418 */
26419
26420 conversation.emit(MEMBERS_UNBLOCKED$1, _payload5);
26421 return _context4.abrupt("return");
26422
26423 case 35:
26424 _payload6 = {
26425 blockedBy: initBy
26426 };
26427 /**
26428 * 当前用户被加入某个对话的黑名单
26429 * @event IMClient#BLOCKED
26430 * @param {Object} payload
26431 * @param {String} payload.blockedBy 该操作的发起者 id
26432 * @param {ConversationBase} conversation
26433 */
26434
26435 this.emit(BLOCKED$1, _payload6, conversation);
26436 /**
26437 * 当前用户被加入当前对话的黑名单
26438 * @event ConversationBase#BLOCKED
26439 * @param {Object} payload
26440 * @param {String} payload.blockedBy 该操作的发起者 id
26441 */
26442
26443 conversation.emit(BLOCKED$1, _payload6);
26444 return _context4.abrupt("return");
26445
26446 case 39:
26447 _payload7 = {
26448 unblockedBy: initBy
26449 };
26450 /**
26451 * 当前用户被移出某个对话的黑名单
26452 * @event IMClient#UNBLOCKED
26453 * @param {Object} payload
26454 * @param {String} payload.unblockedBy 该操作的发起者 id
26455 * @param {ConversationBase} conversation
26456 */
26457
26458 this.emit(UNBLOCKED$1, _payload7, conversation);
26459 /**
26460 * 当前用户被移出当前对话的黑名单
26461 * @event ConversationBase#UNBLOCKED
26462 * @param {Object} payload
26463 * @param {String} payload.unblockedBy 该操作的发起者 id
26464 */
26465
26466 conversation.emit(UNBLOCKED$1, _payload7);
26467 return _context4.abrupt("return");
26468
26469 case 43:
26470 _payload8 = {
26471 mutedBy: initBy,
26472 members: m
26473 };
26474 /**
26475 * 有成员在某个对话中被禁言
26476 * @event IMClient#MEMBERS_MUTED
26477 * @param {Object} payload
26478 * @param {String[]} payload.members 成员 id 列表
26479 * @param {String} payload.mutedBy 该操作的发起者 id
26480 * @param {ConversationBase} conversation
26481 */
26482
26483 this.emit(MEMBERS_MUTED$1, _payload8, conversation);
26484 /**
26485 * 有成员在当前对话中被禁言
26486 * @event ConversationBase#MEMBERS_MUTED
26487 * @param {Object} payload
26488 * @param {String[]} payload.members 成员 id 列表
26489 * @param {String} payload.mutedBy 该操作的发起者 id
26490 */
26491
26492 conversation.emit(MEMBERS_MUTED$1, _payload8);
26493 return _context4.abrupt("return");
26494
26495 case 47:
26496 _payload9 = {
26497 unmutedBy: initBy,
26498 members: m
26499 };
26500 /**
26501 * 有成员在某个对话中被解除禁言
26502 * @event IMClient#MEMBERS_UNMUTED
26503 * @param {Object} payload
26504 * @param {String[]} payload.members 成员 id 列表
26505 * @param {String} payload.unmutedBy 该操作的发起者 id
26506 * @param {ConversationBase} conversation
26507 */
26508
26509 this.emit(MEMBERS_UNMUTED$1, _payload9, conversation);
26510 /**
26511 * 有成员在当前对话中被解除禁言
26512 * @event ConversationBase#MEMBERS_UNMUTED
26513 * @param {Object} payload
26514 * @param {String[]} payload.members 成员 id 列表
26515 * @param {String} payload.unmutedBy 该操作的发起者 id
26516 */
26517
26518 conversation.emit(MEMBERS_UNMUTED$1, _payload9);
26519 return _context4.abrupt("return");
26520
26521 case 51:
26522 _payload10 = {
26523 mutedBy: initBy
26524 };
26525 /**
26526 * 有成员在某个对话中被禁言
26527 * @event IMClient#MUTED
26528 * @param {Object} payload
26529 * @param {String} payload.mutedBy 该操作的发起者 id
26530 * @param {ConversationBase} conversation
26531 */
26532
26533 this.emit(MUTED$1, _payload10, conversation);
26534 /**
26535 * 有成员在当前对话中被禁言
26536 * @event ConversationBase#MUTED
26537 * @param {Object} payload
26538 * @param {String} payload.mutedBy 该操作的发起者 id
26539 */
26540
26541 conversation.emit(MUTED$1, _payload10);
26542 return _context4.abrupt("return");
26543
26544 case 55:
26545 _payload11 = {
26546 unmutedBy: initBy
26547 };
26548 /**
26549 * 有成员在某个对话中被解除禁言
26550 * @event IMClient#UNMUTED
26551 * @param {Object} payload
26552 * @param {String} payload.unmutedBy 该操作的发起者 id
26553 * @param {ConversationBase} conversation
26554 */
26555
26556 this.emit(UNMUTED$1, _payload11, conversation);
26557 /**
26558 * 有成员在当前对话中被解除禁言
26559 * @event ConversationBase#UNMUTED
26560 * @param {Object} payload
26561 * @param {String} payload.unmutedBy 该操作的发起者 id
26562 */
26563
26564 conversation.emit(UNMUTED$1, _payload11);
26565 return _context4.abrupt("return");
26566
26567 case 59:
26568 pid = info.pid, role = info.role;
26569 _internal = internal(conversation), memberInfoMap = _internal.memberInfoMap; // 如果不存在缓存,且不是 role 的更新,则不通知
26570
26571 if (!(!memberInfoMap && !role)) {
26572 _context4.next = 63;
26573 break;
26574 }
26575
26576 return _context4.abrupt("return");
26577
26578 case 63:
26579 _context4.next = 65;
26580 return conversation.getMemberInfo(pid);
26581
26582 case 65:
26583 memberInfo = _context4.sent;
26584 internal(memberInfo).role = role;
26585 _payload12 = {
26586 member: pid,
26587 memberInfo: memberInfo,
26588 updatedBy: initBy
26589 };
26590 /**
26591 * 有成员的对话信息被更新
26592 * @event IMClient#MEMBER_INFO_UPDATED
26593 * @param {Object} payload
26594 * @param {String} payload.member 被更新对话信息的成员 id
26595 * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
26596 * @param {String} payload.updatedBy 该操作的发起者 id
26597 * @param {ConversationBase} conversation
26598 */
26599
26600 this.emit(MEMBER_INFO_UPDATED$1, _payload12, conversation);
26601 /**
26602 * 有成员的对话信息被更新
26603 * @event ConversationBase#MEMBER_INFO_UPDATED
26604 * @param {Object} payload
26605 * @param {String} payload.member 被更新对话信息的成员 id
26606 * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
26607 * @param {String} payload.updatedBy 该操作的发起者 id
26608 */
26609
26610 conversation.emit(MEMBER_INFO_UPDATED$1, _payload12);
26611 return _context4.abrupt("return");
26612
26613 case 71:
26614 attributes = decode(JSON.parse(attr.data));
26615
26616 conversation._updateServerAttributes(attributes);
26617
26618 _payload13 = {
26619 attributes: attributes,
26620 updatedBy: initBy
26621 };
26622 /**
26623 * 该对话信息被更新
26624 * @event IMClient#CONVERSATION_INFO_UPDATED
26625 * @param {Object} payload
26626 * @param {Object} payload.attributes 被更新的属性
26627 * @param {String} payload.updatedBy 该操作的发起者 id
26628 * @param {ConversationBase} conversation
26629 */
26630
26631 this.emit(CONVERSATION_INFO_UPDATED$1, _payload13, conversation);
26632 /**
26633 * 有对话信息被更新
26634 * @event ConversationBase#INFO_UPDATED
26635 * @param {Object} payload
26636 * @param {Object} payload.attributes 被更新的属性
26637 * @param {String} payload.updatedBy 该操作的发起者 id
26638 */
26639
26640 conversation.emit(INFO_UPDATED$1, _payload13);
26641 return _context4.abrupt("return");
26642
26643 case 77:
26644 this.emit(UNHANDLED_MESSAGE$1, message);
26645 throw new Error('Unrecognized conversation command');
26646
26647 case 79:
26648 case "end":
26649 return _context4.stop();
26650 }
26651 }
26652 }, _callee4, this);
26653 }));
26654
26655 function _dispatchConvMessage(_x4) {
26656 return _dispatchConvMessage2.apply(this, arguments);
26657 }
26658
26659 return _dispatchConvMessage;
26660 }();
26661
26662 _proto._dispatchDirectMessage = function _dispatchDirectMessage(originalMessage) {
26663 var _this4 = this;
26664
26665 var directMessage = originalMessage.directMessage,
26666 _originalMessage$dire = originalMessage.directMessage,
26667 id = _originalMessage$dire.id,
26668 cid = _originalMessage$dire.cid,
26669 fromPeerId = _originalMessage$dire.fromPeerId,
26670 timestamp = _originalMessage$dire.timestamp,
26671 transient = _originalMessage$dire.transient,
26672 patchTimestamp = _originalMessage$dire.patchTimestamp,
26673 mentionPids = _originalMessage$dire.mentionPids,
26674 mentionAll = _originalMessage$dire.mentionAll,
26675 binaryMsg = _originalMessage$dire.binaryMsg,
26676 msg = _originalMessage$dire.msg;
26677 var content = binaryMsg ? binaryMsg.toArrayBuffer() : msg;
26678 return Promise.all([this.getConversation(directMessage.cid), this._messageParser.parse(content)]).then(function (_ref5) {
26679 var _ref6 = _slicedToArray(_ref5, 2),
26680 conversation = _ref6[0],
26681 message = _ref6[1];
26682
26683 // deleted conversation
26684 if (!conversation) return undefined;
26685 var messageProps = {
26686 id: id,
26687 cid: cid,
26688 timestamp: timestamp,
26689 updatedAt: patchTimestamp,
26690 from: fromPeerId,
26691 mentionList: mentionPids,
26692 mentionedAll: mentionAll
26693 };
26694 Object.assign(message, messageProps);
26695
26696 message._updateMentioned(_this4.id);
26697
26698 message._setStatus(MessageStatus.SENT); // filter outgoing message sent from another device
26699
26700
26701 if (message.from !== _this4.id) {
26702 if (!(transient || conversation.transient)) {
26703 _this4._sendAck(message);
26704 }
26705 }
26706
26707 return _this4._dispatchParsedMessage(message, conversation);
26708 });
26709 };
26710
26711 _proto._dispatchParsedMessage = function _dispatchParsedMessage(message, conversation) {
26712 var _this5 = this;
26713
26714 // beforeMessageDispatch hook
26715 return applyDispatcher(this._plugins.beforeMessageDispatch, [message, conversation]).then(function (shouldDispatch) {
26716 if (shouldDispatch === false) return;
26717 conversation.lastMessage = message; // eslint-disable-line no-param-reassign
26718
26719 conversation.lastMessageAt = message.timestamp; // eslint-disable-line no-param-reassign
26720 // filter outgoing message sent from another device
26721
26722 if (message.from !== _this5.id) {
26723 conversation.unreadMessagesCount += 1; // eslint-disable-line no-param-reassign
26724
26725 if (message.mentioned) conversation._setUnreadMessagesMentioned(true);
26726 }
26727 /**
26728 * 当前用户收到消息
26729 * @event IMClient#MESSAGE
26730 * @param {Message} message
26731 * @param {ConversationBase} conversation 收到消息的对话
26732 */
26733
26734
26735 _this5.emit(MESSAGE$2, message, conversation);
26736 /**
26737 * 当前对话收到消息
26738 * @event ConversationBase#MESSAGE
26739 * @param {Message} message
26740 */
26741
26742
26743 conversation.emit(MESSAGE$2, message);
26744 });
26745 };
26746
26747 _proto._sendAck = function _sendAck(message) {
26748 this._debug('send ack for %O', message);
26749
26750 var cid = message.cid;
26751
26752 if (!cid) {
26753 throw new Error('missing cid');
26754 }
26755
26756 if (!this._ackMessageBuffer[cid]) {
26757 this._ackMessageBuffer[cid] = [];
26758 }
26759
26760 this._ackMessageBuffer[cid].push(message);
26761
26762 return this._doSendAck();
26763 } // jsdoc-ignore-start
26764 ;
26765
26766 _proto. // jsdoc-ignore-end
26767 _doSendAck = function _doSendAck() {
26768 var _this6 = this;
26769
26770 // if not connected, just skip everything
26771 if (!this._connection.is('connected')) return;
26772
26773 this._debug('do send ack %O', this._ackMessageBuffer);
26774
26775 Promise.all(Object.keys(this._ackMessageBuffer).map(function (cid) {
26776 var convAckMessages = _this6._ackMessageBuffer[cid];
26777 var timestamps = convAckMessages.map(function (message) {
26778 return message.timestamp;
26779 });
26780 var command = new GenericCommand({
26781 cmd: 'ack',
26782 peerId: _this6.id,
26783 ackMessage: new AckCommand({
26784 cid: cid,
26785 fromts: Math.min.apply(null, timestamps),
26786 tots: Math.max.apply(null, timestamps)
26787 })
26788 });
26789 delete _this6._ackMessageBuffer[cid];
26790 return _this6._send(command, false).catch(function (error) {
26791 _this6._debug('send ack failed: %O', error);
26792
26793 _this6._ackMessageBuffer[cid] = convAckMessages;
26794 });
26795 }));
26796 };
26797
26798 _proto._omitPeerId = function _omitPeerId(value) {
26799 internal(this).peerIdOmittable = value;
26800 };
26801
26802 _proto._send = function _send(cmd) {
26803 var _this$_connection;
26804
26805 var command = cmd;
26806
26807 if (!internal(this).peerIdOmittable && this.id) {
26808 command.peerId = this.id;
26809 }
26810
26811 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
26812 args[_key3 - 1] = arguments[_key3];
26813 }
26814
26815 return (_this$_connection = this._connection).send.apply(_this$_connection, [command].concat(args));
26816 };
26817
26818 _proto._open =
26819 /*#__PURE__*/
26820 function () {
26821 var _open2 = _asyncToGenerator(
26822 /*#__PURE__*/
26823 regenerator.mark(function _callee5(appId, tag, deviceId) {
26824 var isReconnect,
26825 _internal2,
26826 lastUnreadNotifTime,
26827 lastPatchTime,
26828 lastNotificationTime,
26829 command,
26830 signatureResult,
26831 sessionToken,
26832 resCommand,
26833 _resCommand,
26834 peerId,
26835 sessionMessage,
26836 _resCommand$sessionMe,
26837 token,
26838 tokenTTL,
26839 code,
26840 serverTs,
26841 serverTime,
26842 _args5 = arguments;
26843
26844 return regenerator.wrap(function _callee5$(_context5) {
26845 while (1) {
26846 switch (_context5.prev = _context5.next) {
26847 case 0:
26848 isReconnect = _args5.length > 3 && _args5[3] !== undefined ? _args5[3] : false;
26849
26850 this._debug('open session');
26851
26852 _internal2 = internal(this), lastUnreadNotifTime = _internal2.lastUnreadNotifTime, lastPatchTime = _internal2.lastPatchTime, lastNotificationTime = _internal2.lastNotificationTime;
26853 command = new GenericCommand({
26854 cmd: 'session',
26855 op: 'open',
26856 appId: appId,
26857 peerId: this.id,
26858 sessionMessage: new SessionCommand({
26859 ua: "js/".concat(version),
26860 r: isReconnect,
26861 lastUnreadNotifTime: lastUnreadNotifTime,
26862 lastPatchTime: lastPatchTime,
26863 configBitmap: configBitmap
26864 })
26865 });
26866
26867 if (isReconnect) {
26868 _context5.next = 13;
26869 break;
26870 }
26871
26872 Object.assign(command.sessionMessage, trim({
26873 tag: tag,
26874 deviceId: deviceId
26875 }));
26876
26877 if (!this.options.signatureFactory) {
26878 _context5.next = 11;
26879 break;
26880 }
26881
26882 _context5.next = 9;
26883 return runSignatureFactory(this.options.signatureFactory, [this._identity]);
26884
26885 case 9:
26886 signatureResult = _context5.sent;
26887 Object.assign(command.sessionMessage, keyRemap({
26888 signature: 's',
26889 timestamp: 't',
26890 nonce: 'n'
26891 }, signatureResult));
26892
26893 case 11:
26894 _context5.next = 17;
26895 break;
26896
26897 case 13:
26898 _context5.next = 15;
26899 return this._sessionManager.getSessionToken({
26900 autoRefresh: false
26901 });
26902
26903 case 15:
26904 sessionToken = _context5.sent;
26905
26906 if (sessionToken && sessionToken !== Expirable.EXPIRED) {
26907 Object.assign(command.sessionMessage, {
26908 st: sessionToken
26909 });
26910 }
26911
26912 case 17:
26913 _context5.prev = 17;
26914 _context5.next = 20;
26915 return this._send(command);
26916
26917 case 20:
26918 resCommand = _context5.sent;
26919 _context5.next = 32;
26920 break;
26921
26922 case 23:
26923 _context5.prev = 23;
26924 _context5.t0 = _context5["catch"](17);
26925
26926 if (!(_context5.t0.code === ErrorCode.SESSION_TOKEN_EXPIRED)) {
26927 _context5.next = 31;
26928 break;
26929 }
26930
26931 if (this._sessionManager) {
26932 _context5.next = 28;
26933 break;
26934 }
26935
26936 throw new Error('Unexpected session expiration');
26937
26938 case 28:
26939 debug$a('Session token expired, reopening');
26940
26941 this._sessionManager.revoke();
26942
26943 return _context5.abrupt("return", this._open(appId, tag, deviceId, isReconnect));
26944
26945 case 31:
26946 throw _context5.t0;
26947
26948 case 32:
26949 _resCommand = resCommand, peerId = _resCommand.peerId, sessionMessage = _resCommand.sessionMessage, _resCommand$sessionMe = _resCommand.sessionMessage, token = _resCommand$sessionMe.st, tokenTTL = _resCommand$sessionMe.stTtl, code = _resCommand$sessionMe.code, serverTs = _resCommand.serverTs;
26950
26951 if (!code) {
26952 _context5.next = 35;
26953 break;
26954 }
26955
26956 throw createError(sessionMessage);
26957
26958 case 35:
26959 if (peerId) {
26960 this.id = peerId;
26961 if (!this._identity) this._identity = peerId;
26962
26963 if (token) {
26964 this._sessionManager = this._sessionManager || this._createSessionManager();
26965
26966 this._sessionManager.setSessionToken(token, tokenTTL);
26967 }
26968
26969 serverTime = getTime(decodeDate(serverTs));
26970
26971 if (serverTs) {
26972 internal(this).lastPatchTime = serverTime;
26973 }
26974
26975 if (lastNotificationTime) {
26976 // Do not await for it as this is failable
26977 this._syncNotifications(lastNotificationTime).catch(function (error) {
26978 return console.warn('Syncing notifications failed:', error);
26979 });
26980 } else {
26981 // Set timestamp to now for next reconnection
26982 internal(this).lastNotificationTime = serverTime;
26983 }
26984 } else {
26985 console.warn('Unexpected session opened without peerId.');
26986 }
26987
26988 return _context5.abrupt("return", undefined);
26989
26990 case 37:
26991 case "end":
26992 return _context5.stop();
26993 }
26994 }
26995 }, _callee5, this, [[17, 23]]);
26996 }));
26997
26998 function _open(_x5, _x6, _x7) {
26999 return _open2.apply(this, arguments);
27000 }
27001
27002 return _open;
27003 }();
27004
27005 _proto._syncNotifications =
27006 /*#__PURE__*/
27007 function () {
27008 var _syncNotifications2 = _asyncToGenerator(
27009 /*#__PURE__*/
27010 regenerator.mark(function _callee6(timestamp) {
27011 var _this7 = this;
27012
27013 var _ref7, hasMore, notifications;
27014
27015 return regenerator.wrap(function _callee6$(_context6) {
27016 while (1) {
27017 switch (_context6.prev = _context6.next) {
27018 case 0:
27019 _context6.next = 2;
27020 return this._fetchNotifications(timestamp);
27021
27022 case 2:
27023 _ref7 = _context6.sent;
27024 hasMore = _ref7.hasMore;
27025 notifications = _ref7.notifications;
27026 notifications.forEach(function (notification) {
27027 var cmd = notification.cmd,
27028 op = notification.op,
27029 serverTs = notification.serverTs,
27030 notificationType = notification.notificationType,
27031 payload = _objectWithoutProperties(notification, ["cmd", "op", "serverTs", "notificationType"]);
27032
27033 _this7._dispatchCommand(_defineProperty({
27034 cmd: CommandType[cmd],
27035 op: OpType[op],
27036 serverTs: serverTs,
27037 notificationType: notificationType
27038 }, "".concat(cmd, "Message"), payload));
27039 });
27040
27041 if (!hasMore) {
27042 _context6.next = 8;
27043 break;
27044 }
27045
27046 return _context6.abrupt("return", this._syncNotifications(internal(this).lastNotificationTime));
27047
27048 case 8:
27049 return _context6.abrupt("return", undefined);
27050
27051 case 9:
27052 case "end":
27053 return _context6.stop();
27054 }
27055 }
27056 }, _callee6, this);
27057 }));
27058
27059 function _syncNotifications(_x8) {
27060 return _syncNotifications2.apply(this, arguments);
27061 }
27062
27063 return _syncNotifications;
27064 }();
27065
27066 _proto._fetchNotifications =
27067 /*#__PURE__*/
27068 function () {
27069 var _fetchNotifications2 = _asyncToGenerator(
27070 /*#__PURE__*/
27071 regenerator.mark(function _callee7(timestamp) {
27072 return regenerator.wrap(function _callee7$(_context7) {
27073 while (1) {
27074 switch (_context7.prev = _context7.next) {
27075 case 0:
27076 return _context7.abrupt("return", this._requestWithSessionToken({
27077 method: 'GET',
27078 path: '/rtm/notifications',
27079 query: {
27080 start_ts: timestamp,
27081 notification_type: 'permanent'
27082 }
27083 }));
27084
27085 case 1:
27086 case "end":
27087 return _context7.stop();
27088 }
27089 }
27090 }, _callee7, this);
27091 }));
27092
27093 function _fetchNotifications(_x9) {
27094 return _fetchNotifications2.apply(this, arguments);
27095 }
27096
27097 return _fetchNotifications;
27098 }();
27099
27100 _proto._createSessionManager = function _createSessionManager() {
27101 var _this8 = this;
27102
27103 debug$a('create SessionManager');
27104 return new SessionManager({
27105 onBeforeGetSessionToken: this._connection.checkConnectionAvailability.bind(this._connection),
27106 refresh: function refresh(manager, expiredSessionToken) {
27107 return manager.setSessionTokenAsync(Promise.resolve(new GenericCommand({
27108 cmd: 'session',
27109 op: 'refresh',
27110 sessionMessage: new SessionCommand({
27111 ua: "js/".concat(version),
27112 st: expiredSessionToken
27113 })
27114 })).then(
27115 /*#__PURE__*/
27116 function () {
27117 var _ref8 = _asyncToGenerator(
27118 /*#__PURE__*/
27119 regenerator.mark(function _callee8(command) {
27120 var signatureResult;
27121 return regenerator.wrap(function _callee8$(_context8) {
27122 while (1) {
27123 switch (_context8.prev = _context8.next) {
27124 case 0:
27125 if (!_this8.options.signatureFactory) {
27126 _context8.next = 5;
27127 break;
27128 }
27129
27130 _context8.next = 3;
27131 return runSignatureFactory(_this8.options.signatureFactory, [_this8._identity]);
27132
27133 case 3:
27134 signatureResult = _context8.sent;
27135 Object.assign(command.sessionMessage, keyRemap({
27136 signature: 's',
27137 timestamp: 't',
27138 nonce: 'n'
27139 }, signatureResult));
27140
27141 case 5:
27142 return _context8.abrupt("return", command);
27143
27144 case 6:
27145 case "end":
27146 return _context8.stop();
27147 }
27148 }
27149 }, _callee8, this);
27150 }));
27151
27152 return function (_x10) {
27153 return _ref8.apply(this, arguments);
27154 };
27155 }()).then(_this8._send.bind(_this8)).then(function (_ref9) {
27156 var _ref9$sessionMessage = _ref9.sessionMessage,
27157 token = _ref9$sessionMessage.st,
27158 ttl = _ref9$sessionMessage.stTtl;
27159 return [token, ttl];
27160 }));
27161 }
27162 });
27163 };
27164
27165 _proto._requestWithSessionToken =
27166 /*#__PURE__*/
27167 function () {
27168 var _requestWithSessionToken2 = _asyncToGenerator(
27169 /*#__PURE__*/
27170 regenerator.mark(function _callee9(_ref10) {
27171 var headers, query, params, sessionToken;
27172 return regenerator.wrap(function _callee9$(_context9) {
27173 while (1) {
27174 switch (_context9.prev = _context9.next) {
27175 case 0:
27176 headers = _ref10.headers, query = _ref10.query, params = _objectWithoutProperties(_ref10, ["headers", "query"]);
27177 _context9.next = 3;
27178 return this._sessionManager.getSessionToken();
27179
27180 case 3:
27181 sessionToken = _context9.sent;
27182 return _context9.abrupt("return", this._request(_objectSpread({
27183 headers: _objectSpread({
27184 'X-LC-IM-Session-Token': sessionToken
27185 }, headers),
27186 query: _objectSpread({
27187 client_id: this.id
27188 }, query)
27189 }, params)));
27190
27191 case 5:
27192 case "end":
27193 return _context9.stop();
27194 }
27195 }
27196 }, _callee9, this);
27197 }));
27198
27199 function _requestWithSessionToken(_x11) {
27200 return _requestWithSessionToken2.apply(this, arguments);
27201 }
27202
27203 return _requestWithSessionToken;
27204 }()
27205 /**
27206 * 关闭客户端
27207 * @return {Promise}
27208 */
27209 ;
27210
27211 _proto.close =
27212 /*#__PURE__*/
27213 function () {
27214 var _close = _asyncToGenerator(
27215 /*#__PURE__*/
27216 regenerator.mark(function _callee10() {
27217 var _ee, command;
27218
27219 return regenerator.wrap(function _callee10$(_context10) {
27220 while (1) {
27221 switch (_context10.prev = _context10.next) {
27222 case 0:
27223 this._debug('close session');
27224
27225 _ee = internal(this)._eventemitter;
27226
27227 _ee.emit('beforeclose');
27228
27229 if (!this._connection.is('connected')) {
27230 _context10.next = 7;
27231 break;
27232 }
27233
27234 command = new GenericCommand({
27235 cmd: 'session',
27236 op: 'close'
27237 });
27238 _context10.next = 7;
27239 return this._send(command);
27240
27241 case 7:
27242 _ee.emit('close');
27243
27244 this.emit(CLOSE$1, {
27245 code: 0
27246 });
27247
27248 case 9:
27249 case "end":
27250 return _context10.stop();
27251 }
27252 }
27253 }, _callee10, this);
27254 }));
27255
27256 function close() {
27257 return _close.apply(this, arguments);
27258 }
27259
27260 return close;
27261 }()
27262 /**
27263 * 获取 client 列表中在线的 client,每次查询最多 20 个 clientId,超出部分会被忽略
27264 * @param {String[]} clientIds 要查询的 client ids
27265 * @return {Primse.<String[]>} 在线的 client ids
27266 */
27267 ;
27268
27269 _proto.ping =
27270 /*#__PURE__*/
27271 function () {
27272 var _ping = _asyncToGenerator(
27273 /*#__PURE__*/
27274 regenerator.mark(function _callee11(clientIds) {
27275 var command, resCommand;
27276 return regenerator.wrap(function _callee11$(_context11) {
27277 while (1) {
27278 switch (_context11.prev = _context11.next) {
27279 case 0:
27280 this._debug('ping');
27281
27282 if (clientIds instanceof Array) {
27283 _context11.next = 3;
27284 break;
27285 }
27286
27287 throw new TypeError("clientIds ".concat(clientIds, " is not an Array"));
27288
27289 case 3:
27290 if (clientIds.length) {
27291 _context11.next = 5;
27292 break;
27293 }
27294
27295 return _context11.abrupt("return", Promise.resolve([]));
27296
27297 case 5:
27298 command = new GenericCommand({
27299 cmd: 'session',
27300 op: 'query',
27301 sessionMessage: new SessionCommand({
27302 sessionPeerIds: clientIds
27303 })
27304 });
27305 _context11.next = 8;
27306 return this._send(command);
27307
27308 case 8:
27309 resCommand = _context11.sent;
27310 return _context11.abrupt("return", resCommand.sessionMessage.onlineSessionPeerIds);
27311
27312 case 10:
27313 case "end":
27314 return _context11.stop();
27315 }
27316 }
27317 }, _callee11, this);
27318 }));
27319
27320 function ping(_x12) {
27321 return _ping.apply(this, arguments);
27322 }
27323
27324 return ping;
27325 }()
27326 /**
27327 * 获取某个特定的对话
27328 * @param {String} id 对话 id,对应 _Conversation 表中的 objectId
27329 * @param {Boolean} [noCache=false] 强制不从缓存中获取
27330 * @return {Promise.<ConversationBase>} 如果 id 对应的对话不存在则返回 null
27331 */
27332 ;
27333
27334 _proto.getConversation =
27335 /*#__PURE__*/
27336 function () {
27337 var _getConversation = _asyncToGenerator(
27338 /*#__PURE__*/
27339 regenerator.mark(function _callee12(id) {
27340 var noCache,
27341 cachedConversation,
27342 _args12 = arguments;
27343 return regenerator.wrap(function _callee12$(_context12) {
27344 while (1) {
27345 switch (_context12.prev = _context12.next) {
27346 case 0:
27347 noCache = _args12.length > 1 && _args12[1] !== undefined ? _args12[1] : false;
27348
27349 if (!(typeof id !== 'string')) {
27350 _context12.next = 3;
27351 break;
27352 }
27353
27354 throw new TypeError("".concat(id, " is not a String"));
27355
27356 case 3:
27357 if (noCache) {
27358 _context12.next = 7;
27359 break;
27360 }
27361
27362 cachedConversation = this._conversationCache.get(id);
27363
27364 if (!cachedConversation) {
27365 _context12.next = 7;
27366 break;
27367 }
27368
27369 return _context12.abrupt("return", cachedConversation);
27370
27371 case 7:
27372 if (!isTemporaryConversatrionId(id)) {
27373 _context12.next = 14;
27374 break;
27375 }
27376
27377 _context12.next = 10;
27378 return this._getTemporaryConversations([id]);
27379
27380 case 10:
27381 _context12.t0 = _context12.sent[0];
27382
27383 if (_context12.t0) {
27384 _context12.next = 13;
27385 break;
27386 }
27387
27388 _context12.t0 = null;
27389
27390 case 13:
27391 return _context12.abrupt("return", _context12.t0);
27392
27393 case 14:
27394 return _context12.abrupt("return", this.getQuery().equalTo('objectId', id).find().then(function (conversations) {
27395 return conversations[0] || null;
27396 }));
27397
27398 case 15:
27399 case "end":
27400 return _context12.stop();
27401 }
27402 }
27403 }, _callee12, this);
27404 }));
27405
27406 function getConversation(_x13) {
27407 return _getConversation.apply(this, arguments);
27408 }
27409
27410 return getConversation;
27411 }()
27412 /**
27413 * 通过 id 批量获取某个特定的对话
27414 * @since 3.4.0
27415 * @param {String[]} ids 对话 id 列表,对应 _Conversation 表中的 objectId
27416 * @param {Boolean} [noCache=false] 强制不从缓存中获取
27417 * @return {Promise.<ConversationBase[]>} 如果 id 对应的对话不存在则返回 null
27418 */
27419 ;
27420
27421 _proto.getConversations =
27422 /*#__PURE__*/
27423 function () {
27424 var _getConversations = _asyncToGenerator(
27425 /*#__PURE__*/
27426 regenerator.mark(function _callee13(ids) {
27427 var _this9 = this;
27428
27429 var noCache,
27430 remoteConversationIds,
27431 remoteTemporaryConversationIds,
27432 query,
27433 remoteTemporaryConversationsPromise,
27434 _args13 = arguments;
27435 return regenerator.wrap(function _callee13$(_context13) {
27436 while (1) {
27437 switch (_context13.prev = _context13.next) {
27438 case 0:
27439 noCache = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : false;
27440 remoteConversationIds = noCache ? ids : ids.filter(function (id) {
27441 return _this9._conversationCache.get(id) === null;
27442 });
27443
27444 if (!remoteConversationIds.length) {
27445 _context13.next = 9;
27446 break;
27447 }
27448
27449 remoteTemporaryConversationIds = remove_1(remoteConversationIds, isTemporaryConversatrionId);
27450 query = [];
27451
27452 if (remoteConversationIds.length) {
27453 query.push(this.getQuery().containedIn('objectId', remoteConversationIds).limit(999).find());
27454 }
27455
27456 if (remoteTemporaryConversationIds.length) {
27457 remoteTemporaryConversationsPromise = remoteTemporaryConversationIds.map(this._getTemporaryConversations.bind(this));
27458 query.push.apply(query, _toConsumableArray(remoteTemporaryConversationsPromise));
27459 }
27460
27461 _context13.next = 9;
27462 return Promise.all(query);
27463
27464 case 9:
27465 return _context13.abrupt("return", ids.map(function (id) {
27466 return _this9._conversationCache.get(id);
27467 }));
27468
27469 case 10:
27470 case "end":
27471 return _context13.stop();
27472 }
27473 }
27474 }, _callee13, this);
27475 }));
27476
27477 function getConversations(_x14) {
27478 return _getConversations.apply(this, arguments);
27479 }
27480
27481 return getConversations;
27482 }();
27483
27484 _proto._getTemporaryConversations =
27485 /*#__PURE__*/
27486 function () {
27487 var _getTemporaryConversations2 = _asyncToGenerator(
27488 /*#__PURE__*/
27489 regenerator.mark(function _callee14(ids) {
27490 var command, resCommand;
27491 return regenerator.wrap(function _callee14$(_context14) {
27492 while (1) {
27493 switch (_context14.prev = _context14.next) {
27494 case 0:
27495 command = new GenericCommand({
27496 cmd: 'conv',
27497 op: 'query',
27498 convMessage: new ConvCommand({
27499 tempConvIds: ids
27500 })
27501 });
27502 _context14.next = 3;
27503 return this._send(command);
27504
27505 case 3:
27506 resCommand = _context14.sent;
27507 return _context14.abrupt("return", this._handleQueryResults(resCommand));
27508
27509 case 5:
27510 case "end":
27511 return _context14.stop();
27512 }
27513 }
27514 }, _callee14, this);
27515 }));
27516
27517 function _getTemporaryConversations(_x15) {
27518 return _getTemporaryConversations2.apply(this, arguments);
27519 }
27520
27521 return _getTemporaryConversations;
27522 }()
27523 /**
27524 * 构造一个 ConversationQuery 来查询对话
27525 * @return {ConversationQuery.<PersistentConversation>}
27526 */
27527 ;
27528
27529 _proto.getQuery = function getQuery() {
27530 return new ConversationQuery(this);
27531 }
27532 /**
27533 * 构造一个 ConversationQuery 来查询聊天室
27534 * @return {ConversationQuery.<ChatRoom>}
27535 */
27536 ;
27537
27538 _proto.getChatRoomQuery = function getChatRoomQuery() {
27539 return this.getQuery().equalTo('tr', true);
27540 }
27541 /**
27542 * 构造一个 ConversationQuery 来查询服务号
27543 * @return {ConversationQuery.<ServiceConversation>}
27544 */
27545 ;
27546
27547 _proto.getServiceConversationQuery = function getServiceConversationQuery() {
27548 return this.getQuery().equalTo('sys', true);
27549 };
27550
27551 _proto._executeQuery =
27552 /*#__PURE__*/
27553 function () {
27554 var _executeQuery2 = _asyncToGenerator(
27555 /*#__PURE__*/
27556 regenerator.mark(function _callee15(query) {
27557 var queryJSON, command, resCommand;
27558 return regenerator.wrap(function _callee15$(_context15) {
27559 while (1) {
27560 switch (_context15.prev = _context15.next) {
27561 case 0:
27562 queryJSON = query.toJSON();
27563 queryJSON.where = new JsonObjectMessage({
27564 data: JSON.stringify(encode(queryJSON.where))
27565 });
27566 command = new GenericCommand({
27567 cmd: 'conv',
27568 op: 'query',
27569 convMessage: new ConvCommand(queryJSON)
27570 });
27571 _context15.next = 5;
27572 return this._send(command);
27573
27574 case 5:
27575 resCommand = _context15.sent;
27576 return _context15.abrupt("return", this._handleQueryResults(resCommand));
27577
27578 case 7:
27579 case "end":
27580 return _context15.stop();
27581 }
27582 }
27583 }, _callee15, this);
27584 }));
27585
27586 function _executeQuery(_x16) {
27587 return _executeQuery2.apply(this, arguments);
27588 }
27589
27590 return _executeQuery;
27591 }();
27592
27593 _proto._handleQueryResults =
27594 /*#__PURE__*/
27595 function () {
27596 var _handleQueryResults2 = _asyncToGenerator(
27597 /*#__PURE__*/
27598 regenerator.mark(function _callee16(resCommand) {
27599 var conversations, commandString;
27600 return regenerator.wrap(function _callee16$(_context16) {
27601 while (1) {
27602 switch (_context16.prev = _context16.next) {
27603 case 0:
27604 _context16.prev = 0;
27605 conversations = decode(JSON.parse(resCommand.convMessage.results.data));
27606 _context16.next = 8;
27607 break;
27608
27609 case 4:
27610 _context16.prev = 4;
27611 _context16.t0 = _context16["catch"](0);
27612 commandString = JSON.stringify(trim(resCommand));
27613 throw new Error("Parse query result failed: ".concat(_context16.t0.message, ". Command: ").concat(commandString));
27614
27615 case 8:
27616 _context16.next = 10;
27617 return Promise.all(conversations.map(this._parseConversationFromRawData.bind(this)));
27618
27619 case 10:
27620 conversations = _context16.sent;
27621 return _context16.abrupt("return", conversations.map(this._upsertConversationToCache.bind(this)));
27622
27623 case 12:
27624 case "end":
27625 return _context16.stop();
27626 }
27627 }
27628 }, _callee16, this, [[0, 4]]);
27629 }));
27630
27631 function _handleQueryResults(_x17) {
27632 return _handleQueryResults2.apply(this, arguments);
27633 }
27634
27635 return _handleQueryResults;
27636 }();
27637
27638 _proto._upsertConversationToCache = function _upsertConversationToCache(fetchedConversation) {
27639 var conversation = this._conversationCache.get(fetchedConversation.id);
27640
27641 if (!conversation) {
27642 conversation = fetchedConversation;
27643
27644 this._debug('no match, set cache');
27645
27646 this._conversationCache.set(fetchedConversation.id, fetchedConversation);
27647 } else {
27648 this._debug('update cached conversation');
27649
27650 ['creator', 'createdAt', 'updatedAt', 'lastMessageAt', 'lastMessage', 'mutedMembers', 'members', '_attributes', 'transient', 'muted'].forEach(function (key) {
27651 var value = fetchedConversation[key];
27652 if (value !== undefined) conversation[key] = value;
27653 });
27654 if (conversation._reset) conversation._reset();
27655 }
27656
27657 return conversation;
27658 }
27659 /**
27660 * 反序列化消息,与 {@link Message#toFullJSON} 相对。
27661 * @param {Object}
27662 * @return {AVMessage} 解析后的消息
27663 * @since 4.0.0
27664 */
27665 ;
27666
27667 _proto.parseMessage =
27668 /*#__PURE__*/
27669 function () {
27670 var _parseMessage = _asyncToGenerator(
27671 /*#__PURE__*/
27672 regenerator.mark(function _callee17(_ref11) {
27673 var data, _ref11$bin, bin, properties, content, message;
27674
27675 return regenerator.wrap(function _callee17$(_context17) {
27676 while (1) {
27677 switch (_context17.prev = _context17.next) {
27678 case 0:
27679 data = _ref11.data, _ref11$bin = _ref11.bin, bin = _ref11$bin === void 0 ? false : _ref11$bin, properties = _objectWithoutProperties(_ref11, ["data", "bin"]);
27680 content = bin ? base64Arraybuffer_2(data) : data;
27681 _context17.next = 4;
27682 return this._messageParser.parse(content);
27683
27684 case 4:
27685 message = _context17.sent;
27686 Object.assign(message, properties);
27687
27688 message._updateMentioned(this.id);
27689
27690 return _context17.abrupt("return", message);
27691
27692 case 8:
27693 case "end":
27694 return _context17.stop();
27695 }
27696 }
27697 }, _callee17, this);
27698 }));
27699
27700 function parseMessage(_x18) {
27701 return _parseMessage.apply(this, arguments);
27702 }
27703
27704 return parseMessage;
27705 }()
27706 /**
27707 * 反序列化对话,与 {@link Conversation#toFullJSON} 相对。
27708 * @param {Object}
27709 * @return {ConversationBase} 解析后的对话
27710 * @since 4.0.0
27711 */
27712 ;
27713
27714 _proto.parseConversation =
27715 /*#__PURE__*/
27716 function () {
27717 var _parseConversation = _asyncToGenerator(
27718 /*#__PURE__*/
27719 regenerator.mark(function _callee18(_ref12) {
27720 var id, lastMessageAt, lastMessage, lastDeliveredAt, lastReadAt, unreadMessagesCount, members, mentioned, properties, conversationData, transient, system, expiredAt;
27721 return regenerator.wrap(function _callee18$(_context18) {
27722 while (1) {
27723 switch (_context18.prev = _context18.next) {
27724 case 0:
27725 id = _ref12.id, lastMessageAt = _ref12.lastMessageAt, lastMessage = _ref12.lastMessage, lastDeliveredAt = _ref12.lastDeliveredAt, lastReadAt = _ref12.lastReadAt, unreadMessagesCount = _ref12.unreadMessagesCount, members = _ref12.members, mentioned = _ref12.mentioned, properties = _objectWithoutProperties(_ref12, ["id", "lastMessageAt", "lastMessage", "lastDeliveredAt", "lastReadAt", "unreadMessagesCount", "members", "mentioned"]);
27726 conversationData = {
27727 id: id,
27728 lastMessageAt: lastMessageAt,
27729 lastMessage: lastMessage,
27730 lastDeliveredAt: lastDeliveredAt,
27731 lastReadAt: lastReadAt,
27732 unreadMessagesCount: unreadMessagesCount,
27733 members: members,
27734 mentioned: mentioned
27735 };
27736
27737 if (!lastMessage) {
27738 _context18.next = 7;
27739 break;
27740 }
27741
27742 _context18.next = 5;
27743 return this.parseMessage(lastMessage);
27744
27745 case 5:
27746 conversationData.lastMessage = _context18.sent;
27747
27748 conversationData.lastMessage._setStatus(MessageStatus.SENT);
27749
27750 case 7:
27751 transient = properties.transient, system = properties.system, expiredAt = properties.expiredAt;
27752
27753 if (!transient) {
27754 _context18.next = 10;
27755 break;
27756 }
27757
27758 return _context18.abrupt("return", new ChatRoom(conversationData, properties, this));
27759
27760 case 10:
27761 if (!system) {
27762 _context18.next = 12;
27763 break;
27764 }
27765
27766 return _context18.abrupt("return", new ServiceConversation(conversationData, properties, this));
27767
27768 case 12:
27769 if (!(expiredAt || isTemporaryConversatrionId(id))) {
27770 _context18.next = 14;
27771 break;
27772 }
27773
27774 return _context18.abrupt("return", new TemporaryConversation(conversationData, {
27775 expiredAt: expiredAt
27776 }, this));
27777
27778 case 14:
27779 return _context18.abrupt("return", new Conversation(conversationData, properties, this));
27780
27781 case 15:
27782 case "end":
27783 return _context18.stop();
27784 }
27785 }
27786 }, _callee18, this);
27787 }));
27788
27789 function parseConversation(_x19) {
27790 return _parseConversation.apply(this, arguments);
27791 }
27792
27793 return parseConversation;
27794 }();
27795
27796 _proto._parseConversationFromRawData =
27797 /*#__PURE__*/
27798 function () {
27799 var _parseConversationFromRawData2 = _asyncToGenerator(
27800 /*#__PURE__*/
27801 regenerator.mark(function _callee19(rawData) {
27802 var data, ttl;
27803 return regenerator.wrap(function _callee19$(_context19) {
27804 while (1) {
27805 switch (_context19.prev = _context19.next) {
27806 case 0:
27807 data = keyRemap({
27808 objectId: 'id',
27809 lm: 'lastMessageAt',
27810 m: 'members',
27811 tr: 'transient',
27812 sys: 'system',
27813 c: 'creator',
27814 mu: 'mutedMembers'
27815 }, rawData);
27816
27817 if (data.msg) {
27818 data.lastMessage = {
27819 data: data.msg,
27820 bin: data.bin,
27821 from: data.msg_from,
27822 id: data.msg_mid,
27823 timestamp: data.msg_timestamp,
27824 updatedAt: data.patch_timestamp
27825 };
27826 delete data.lastMessageFrom;
27827 delete data.lastMessageId;
27828 delete data.lastMessageTimestamp;
27829 delete data.lastMessagePatchTimestamp;
27830 }
27831
27832 ttl = data.ttl;
27833 if (ttl) data.expiredAt = Date.now() + ttl * 1000;
27834 return _context19.abrupt("return", this.parseConversation(data));
27835
27836 case 5:
27837 case "end":
27838 return _context19.stop();
27839 }
27840 }
27841 }, _callee19, this);
27842 }));
27843
27844 function _parseConversationFromRawData(_x20) {
27845 return _parseConversationFromRawData2.apply(this, arguments);
27846 }
27847
27848 return _parseConversationFromRawData;
27849 }()
27850 /**
27851 * 创建一个对话
27852 * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
27853 * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
27854 * @param {String} [options.name] 对话的名字
27855 * @param {Boolean} [options.unique=true] 唯一对话,当其为 true 时,如果当前已经有相同成员的对话存在则返回该对话,否则会创建新的对话
27856 * @return {Promise.<Conversation>}
27857 */
27858 ;
27859
27860 _proto.createConversation =
27861 /*#__PURE__*/
27862 function () {
27863 var _createConversation = _asyncToGenerator(
27864 /*#__PURE__*/
27865 regenerator.mark(function _callee20() {
27866 var _ref13,
27867 m,
27868 name,
27869 transient,
27870 _ref13$unique,
27871 unique,
27872 tempConv,
27873 tempConvTTL,
27874 properties,
27875 members,
27876 attr,
27877 startCommandJson,
27878 command,
27879 params,
27880 signatureResult,
27881 _ref14,
27882 _ref14$convMessage,
27883 cid,
27884 cdate,
27885 ttl,
27886 data,
27887 conversation,
27888 _args20 = arguments;
27889
27890 return regenerator.wrap(function _callee20$(_context20) {
27891 while (1) {
27892 switch (_context20.prev = _context20.next) {
27893 case 0:
27894 _ref13 = _args20.length > 0 && _args20[0] !== undefined ? _args20[0] : {}, m = _ref13.members, name = _ref13.name, transient = _ref13.transient, _ref13$unique = _ref13.unique, unique = _ref13$unique === void 0 ? true : _ref13$unique, tempConv = _ref13._tempConv, tempConvTTL = _ref13._tempConvTTL, properties = _objectWithoutProperties(_ref13, ["members", "name", "transient", "unique", "_tempConv", "_tempConvTTL"]);
27895
27896 if (transient || Array.isArray(m)) {
27897 _context20.next = 3;
27898 break;
27899 }
27900
27901 throw new TypeError("conversation members ".concat(m, " is not an array"));
27902
27903 case 3:
27904 members = new Set(m);
27905 members.add(this.id);
27906 members = Array.from(members).sort();
27907 attr = properties || {};
27908
27909 if (!name) {
27910 _context20.next = 11;
27911 break;
27912 }
27913
27914 if (!(typeof name !== 'string')) {
27915 _context20.next = 10;
27916 break;
27917 }
27918
27919 throw new TypeError("conversation name ".concat(name, " is not a string"));
27920
27921 case 10:
27922 attr.name = name;
27923
27924 case 11:
27925 attr = new JsonObjectMessage({
27926 data: JSON.stringify(encode(attr))
27927 });
27928 startCommandJson = {
27929 m: members,
27930 attr: attr,
27931 transient: transient,
27932 unique: unique,
27933 tempConv: tempConv,
27934 tempConvTTL: tempConvTTL
27935 };
27936 command = new GenericCommand({
27937 cmd: 'conv',
27938 op: 'start',
27939 convMessage: new ConvCommand(startCommandJson)
27940 });
27941
27942 if (!this.options.conversationSignatureFactory) {
27943 _context20.next = 20;
27944 break;
27945 }
27946
27947 params = [null, this._identity, members, 'create'];
27948 _context20.next = 18;
27949 return runSignatureFactory(this.options.conversationSignatureFactory, params);
27950
27951 case 18:
27952 signatureResult = _context20.sent;
27953 Object.assign(command.convMessage, keyRemap({
27954 signature: 's',
27955 timestamp: 't',
27956 nonce: 'n'
27957 }, signatureResult));
27958
27959 case 20:
27960 _context20.next = 22;
27961 return this._send(command);
27962
27963 case 22:
27964 _ref14 = _context20.sent;
27965 _ref14$convMessage = _ref14.convMessage;
27966 cid = _ref14$convMessage.cid;
27967 cdate = _ref14$convMessage.cdate;
27968 ttl = _ref14$convMessage.tempConvTTL;
27969 data = _objectSpread({
27970 name: name,
27971 transient: transient,
27972 unique: unique,
27973 id: cid,
27974 createdAt: cdate,
27975 updatedAt: cdate,
27976 lastMessageAt: null,
27977 creator: this.id,
27978 members: transient ? [] : members
27979 }, properties);
27980 if (ttl) data.expiredAt = Date.now() + ttl * 1000;
27981 _context20.next = 31;
27982 return this.parseConversation(data);
27983
27984 case 31:
27985 conversation = _context20.sent;
27986 return _context20.abrupt("return", this._upsertConversationToCache(conversation));
27987
27988 case 33:
27989 case "end":
27990 return _context20.stop();
27991 }
27992 }
27993 }, _callee20, this);
27994 }));
27995
27996 function createConversation() {
27997 return _createConversation.apply(this, arguments);
27998 }
27999
28000 return createConversation;
28001 }()
28002 /**
28003 * 创建一个聊天室
28004 * @since 4.0.0
28005 * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
28006 * @param {String} [options.name] 对话的名字
28007 * @return {Promise.<ChatRoom>}
28008 */
28009 ;
28010
28011 _proto.createChatRoom =
28012 /*#__PURE__*/
28013 function () {
28014 var _createChatRoom = _asyncToGenerator(
28015 /*#__PURE__*/
28016 regenerator.mark(function _callee21(param) {
28017 return regenerator.wrap(function _callee21$(_context21) {
28018 while (1) {
28019 switch (_context21.prev = _context21.next) {
28020 case 0:
28021 return _context21.abrupt("return", this.createConversation(_objectSpread({}, param, {
28022 transient: true,
28023 members: null,
28024 unique: false,
28025 _tempConv: false
28026 })));
28027
28028 case 1:
28029 case "end":
28030 return _context21.stop();
28031 }
28032 }
28033 }, _callee21, this);
28034 }));
28035
28036 function createChatRoom(_x21) {
28037 return _createChatRoom.apply(this, arguments);
28038 }
28039
28040 return createChatRoom;
28041 }()
28042 /**
28043 * 创建一个临时对话
28044 * @since 4.0.0
28045 * @param {Object} options
28046 * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
28047 * @param {String} [options.ttl] 对话存在时间,单位为秒,最大值与默认值均为 86400(一天),过期后该对话不再可用。
28048 * @return {Promise.<TemporaryConversation>}
28049 */
28050 ;
28051
28052 _proto.createTemporaryConversation =
28053 /*#__PURE__*/
28054 function () {
28055 var _createTemporaryConversation = _asyncToGenerator(
28056 /*#__PURE__*/
28057 regenerator.mark(function _callee22(_ref15) {
28058 var _tempConvTTL, param;
28059
28060 return regenerator.wrap(function _callee22$(_context22) {
28061 while (1) {
28062 switch (_context22.prev = _context22.next) {
28063 case 0:
28064 _tempConvTTL = _ref15.ttl, param = _objectWithoutProperties(_ref15, ["ttl"]);
28065 return _context22.abrupt("return", this.createConversation(_objectSpread({}, param, {
28066 transient: false,
28067 unique: false,
28068 _tempConv: true,
28069 _tempConvTTL: _tempConvTTL
28070 })));
28071
28072 case 2:
28073 case "end":
28074 return _context22.stop();
28075 }
28076 }
28077 }, _callee22, this);
28078 }));
28079
28080 function createTemporaryConversation(_x22) {
28081 return _createTemporaryConversation.apply(this, arguments);
28082 }
28083
28084 return createTemporaryConversation;
28085 }() // jsdoc-ignore-start
28086 ;
28087
28088 _proto. // jsdoc-ignore-end
28089 _doSendRead = function _doSendRead() {
28090 var _this10 = this;
28091
28092 // if not connected, just skip everything
28093 if (!this._connection.is('connected')) return;
28094 var buffer = internal(this).readConversationsBuffer;
28095 var conversations = Array.from(buffer);
28096 if (!conversations.length) return;
28097 var ids = conversations.map(function (conversation) {
28098 if (!(conversation instanceof ConversationBase)) {
28099 throw new TypeError("".concat(conversation, " is not a Conversation"));
28100 }
28101
28102 return conversation.id;
28103 });
28104
28105 this._debug("mark [".concat(ids, "] as read"));
28106
28107 buffer.clear();
28108
28109 this._sendReadCommand(conversations).catch(function (error) {
28110 _this10._debug('send read failed: %O', error);
28111
28112 conversations.forEach(buffer.add.bind(buffer));
28113 });
28114 };
28115
28116 _proto._sendReadCommand = function _sendReadCommand(conversations) {
28117 var _this11 = this;
28118
28119 return this._send(new GenericCommand({
28120 cmd: 'read',
28121 readMessage: new ReadCommand({
28122 convs: conversations.map(function (conversation) {
28123 return new ReadTuple({
28124 cid: conversation.id,
28125 mid: conversation.lastMessage && conversation.lastMessage.from !== _this11.id ? conversation.lastMessage.id : undefined,
28126 timestamp: (conversation.lastMessageAt || new Date()).getTime()
28127 });
28128 })
28129 })
28130 }), false);
28131 };
28132
28133 return IMClient;
28134 }(eventemitter3), (_applyDecoratedDescriptor(_class$3.prototype, "_doSendAck", [_dec$2], Object.getOwnPropertyDescriptor(_class$3.prototype, "_doSendAck"), _class$3.prototype), _applyDecoratedDescriptor(_class$3.prototype, "_doSendRead", [_dec2], Object.getOwnPropertyDescriptor(_class$3.prototype, "_doSendRead"), _class$3.prototype)), _class$3));
28135 /**
28136 * 修改、撤回消息的原因
28137 * @typedef PatchReason
28138 * @type {Object}
28139 * @property {number} code 负数为内置 code,正数为开发者在 hook 中自定义的 code。比如因为敏感词过滤被修改的 code 为 -4408。
28140 * @property {string} [detail] 具体的原因说明。
28141 */
28142
28143 var RECONNECT_ERROR = 'reconnecterror';
28144
28145 var CoreEvent = /*#__PURE__*/Object.freeze({
28146 RECONNECT_ERROR: RECONNECT_ERROR,
28147 DISCONNECT: DISCONNECT,
28148 RECONNECT: RECONNECT,
28149 RETRY: RETRY,
28150 SCHEDULE: SCHEDULE,
28151 OFFLINE: OFFLINE,
28152 ONLINE: ONLINE
28153 });
28154
28155 var _class$4;
28156
28157 var // jsdoc-ignore-end
28158 BinaryMessage = IE10Compatible(_class$4 =
28159 /*#__PURE__*/
28160 function (_Message) {
28161 _inheritsLoose(BinaryMessage, _Message);
28162
28163 /**
28164 * 二进制消息
28165 * @extends Message
28166 * @param {ArrayBuffer} buffer
28167 * @since 4.0.0
28168 */
28169 function BinaryMessage(buffer) {
28170 if (!(buffer instanceof ArrayBuffer)) {
28171 throw new TypeError("".concat(buffer, " is not an ArrayBuffer"));
28172 }
28173
28174 return _Message.call(this, buffer) || this;
28175 }
28176 /**
28177 * @type ArrayBuffer
28178 */
28179
28180
28181 BinaryMessage.validate = function validate(target) {
28182 return target instanceof ArrayBuffer;
28183 };
28184
28185 var _proto = BinaryMessage.prototype;
28186
28187 _proto.toJSON = function toJSON() {
28188 return _objectSpread({}, _Message.prototype._toJSON.call(this), {
28189 data: base64Arraybuffer_1(this.content)
28190 });
28191 };
28192
28193 _proto.toFullJSON = function toFullJSON() {
28194 return _objectSpread({}, _Message.prototype.toFullJSON.call(this), {
28195 bin: true,
28196 data: base64Arraybuffer_1(this.content)
28197 });
28198 };
28199
28200 _createClass(BinaryMessage, [{
28201 key: "buffer",
28202 get: function get() {
28203 return this.content;
28204 },
28205 set: function set(buffer) {
28206 this.content = buffer;
28207 }
28208 }]);
28209
28210 return BinaryMessage;
28211 }(Message)) || _class$4;
28212
28213 var _dec$3, _class$5;
28214
28215 var // jsdoc-ignore-end
28216 TextMessage = (_dec$3 = messageType(-1), _dec$3(_class$5 = IE10Compatible(_class$5 =
28217 /*#__PURE__*/
28218 function (_TypedMessage) {
28219 _inheritsLoose(TextMessage, _TypedMessage);
28220
28221 /**
28222 * 文类类型消息
28223 * @extends TypedMessage
28224 * @param {String} [text='']
28225 * @throws {TypeError} text 不是 String 类型
28226 */
28227 function TextMessage() {
28228 var _this;
28229
28230 var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
28231
28232 if (typeof text !== 'string') {
28233 throw new TypeError("".concat(text, " is not a string"));
28234 }
28235
28236 _this = _TypedMessage.call(this) || this;
28237
28238 _this.setText(text);
28239
28240 return _this;
28241 }
28242
28243 return TextMessage;
28244 }(TypedMessage)) || _class$5) || _class$5);
28245 /**
28246 * @name TYPE
28247 * @memberof TextMessage
28248 * @type Number
28249 * @static
28250 * @const
28251 */
28252
28253 var _class$6;
28254 var debug$b = browser('LC:MessageParser');
28255
28256 var tryParseJson = function tryParseJson(target, key, descriptor) {
28257 var fn = descriptor.value; // eslint-disable-next-line no-param-reassign
28258
28259 descriptor.value = function wrapper(param) {
28260 var content;
28261
28262 if (typeof param !== 'string') {
28263 content = param;
28264 } else {
28265 try {
28266 content = JSON.parse(param);
28267 } catch (error) {
28268 content = param;
28269 }
28270 }
28271
28272 return fn.call(this, content);
28273 };
28274 };
28275
28276 var applyPlugins = function applyPlugins(target, key, descriptor) {
28277 var fn = descriptor.value; // eslint-disable-next-line no-param-reassign
28278
28279 descriptor.value = function wrapper(json) {
28280 var _this = this;
28281
28282 return Promise.resolve(json).then(applyMiddlewares(this._plugins.beforeMessageParse)).then(function (decoratedJson) {
28283 return fn.call(_this, decoratedJson);
28284 }).then(applyMiddlewares(this._plugins.afterMessageParse));
28285 };
28286 };
28287
28288 var MessageParser = (_class$6 =
28289 /*#__PURE__*/
28290 function () {
28291 function MessageParser() {
28292 var plugins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
28293 this._plugins = plugins;
28294 this._messageClasses = [];
28295 }
28296
28297 var _proto = MessageParser.prototype;
28298
28299 _proto.register = function register(messageClass) {
28300 if (messageClass && messageClass.parse && messageClass.prototype && messageClass.prototype.getPayload) {
28301 this._messageClasses.unshift(messageClass);
28302 } else {
28303 throw new TypeError('Invalid messageClass');
28304 }
28305 } // jsdoc-ignore-start
28306 ;
28307
28308 _proto. // jsdoc-ignore-end
28309 parse = function parse(content) {
28310 debug$b('parsing message: %O', content); // eslint-disable-next-line no-restricted-syntax
28311
28312 var _iteratorNormalCompletion = true;
28313 var _didIteratorError = false;
28314 var _iteratorError = undefined;
28315
28316 try {
28317 for (var _iterator = this._messageClasses[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
28318 var Klass = _step.value;
28319 var contentCopy = isPlainObject_1(content) ? Object.assign({}, content) : content;
28320 var valid = void 0;
28321 var result = void 0;
28322
28323 try {
28324 valid = Klass.validate(contentCopy);
28325 } catch (error) {// eslint-disable-line no-empty
28326 }
28327
28328 if (valid) {
28329 try {
28330 result = Klass.parse(contentCopy);
28331 } catch (error) {
28332 console.warn('parsing a valid message content error', {
28333 error: error,
28334 Klass: Klass,
28335 content: contentCopy
28336 });
28337 }
28338
28339 if (result !== undefined) {
28340 debug$b('parse result: %O', result);
28341 return result;
28342 }
28343 }
28344 }
28345 } catch (err) {
28346 _didIteratorError = true;
28347 _iteratorError = err;
28348 } finally {
28349 try {
28350 if (!_iteratorNormalCompletion && _iterator.return != null) {
28351 _iterator.return();
28352 }
28353 } finally {
28354 if (_didIteratorError) {
28355 throw _iteratorError;
28356 }
28357 }
28358 }
28359
28360 throw new Error('No Message Class matched');
28361 };
28362
28363 return MessageParser;
28364 }(), (_applyDecoratedDescriptor(_class$6.prototype, "parse", [tryParseJson, applyPlugins], Object.getOwnPropertyDescriptor(_class$6.prototype, "parse"), _class$6.prototype)), _class$6);
28365
28366 var debug$c = browser('LC:IMPlugin');
28367 /**
28368 * 消息优先级枚举
28369 * @enum {Number}
28370 * @since 3.3.0
28371 */
28372
28373 var MessagePriority = {
28374 /** 高 */
28375 HIGH: 1,
28376
28377 /** 普通 */
28378 NORMAL: 2,
28379
28380 /** 低 */
28381 LOW: 3
28382 };
28383 Object.freeze(MessagePriority);
28384 /**
28385 * 为 Conversation 定义一个新属性
28386 * @param {String} prop 属性名
28387 * @param {Object} [descriptor] 属性的描述符,参见 {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor#Description getOwnPropertyDescriptor#Description - MDN},默认为该属性名对应的 Conversation 自定义属性的 getter/setter
28388 * @returns void
28389 * @example
28390 *
28391 * conversation.get('type');
28392 * conversation.set('type', 1);
28393 *
28394 * // equals to
28395 * defineConversationProperty('type');
28396 * conversation.type;
28397 * conversation.type = 1;
28398 */
28399
28400 var defineConversationProperty = function defineConversationProperty(prop) {
28401 var descriptor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
28402 get: function get() {
28403 return this.get(prop);
28404 },
28405 set: function set(value) {
28406 this.set(prop, value);
28407 }
28408 };
28409 Object.defineProperty(Conversation.prototype, prop, descriptor);
28410 };
28411
28412 var onRealtimeCreate = function onRealtimeCreate(realtime) {
28413 /* eslint-disable no-param-reassign */
28414 var deviceId = v4_1();
28415 realtime._IMClients = {};
28416 realtime._IMClientsCreationCount = 0;
28417 var messageParser = new MessageParser(realtime._plugins);
28418 realtime._messageParser = messageParser;
28419
28420 var signAVUser =
28421 /*#__PURE__*/
28422 function () {
28423 var _ref = _asyncToGenerator(
28424 /*#__PURE__*/
28425 regenerator.mark(function _callee(user) {
28426 return regenerator.wrap(function _callee$(_context) {
28427 while (1) {
28428 switch (_context.prev = _context.next) {
28429 case 0:
28430 return _context.abrupt("return", realtime._request({
28431 method: 'POST',
28432 path: '/rtm/sign',
28433 data: {
28434 session_token: user.getSessionToken()
28435 }
28436 }));
28437
28438 case 1:
28439 case "end":
28440 return _context.stop();
28441 }
28442 }
28443 }, _callee, this);
28444 }));
28445
28446 return function signAVUser(_x) {
28447 return _ref.apply(this, arguments);
28448 };
28449 }();
28450 /**
28451 * 注册消息类
28452 *
28453 * 在接收消息、查询消息时,会按照消息类注册顺序的逆序依次尝试解析消息内容
28454 *
28455 * @memberof Realtime
28456 * @instance
28457 * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
28458 * 建议继承自 {@link TypedMessage}
28459 * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
28460 */
28461
28462
28463 var register = function register(messageClass) {
28464 return ensureArray(messageClass).map(messageParser.register.bind(messageParser));
28465 };
28466
28467 register(ensureArray(realtime._plugins.messageClasses));
28468 /**
28469 * 创建一个即时通讯客户端,多次创建相同 id 的客户端会返回同一个实例
28470 * @memberof Realtime
28471 * @instance
28472 * @param {String|AV.User} [identity] 客户端 identity,如果不指定该参数,服务端会随机生成一个字符串作为 identity,
28473 * 如果传入一个已登录的 AV.User,则会使用该用户的 id 作为客户端 identity 登录。
28474 * @param {Object} [options]
28475 * @param {Function} [options.signatureFactory] open session 时的签名方法 // TODO need details
28476 * @param {Function} [options.conversationSignatureFactory] 对话创建、增减成员操作时的签名方法
28477 * @param {Function} [options.blacklistSignatureFactory] 黑名单操作时的签名方法
28478 * @param {String} [options.tag] 客户端类型标记,以支持单点登录功能
28479 * @param {String} [options.isReconnect=false] 单点登录时标记该次登录是不是应用启动时自动重新登录
28480 * @return {Promise.<IMClient>}
28481 */
28482
28483 var createIMClient =
28484 /*#__PURE__*/
28485 function () {
28486 var _ref2 = _asyncToGenerator(
28487 /*#__PURE__*/
28488 regenerator.mark(function _callee2(identity) {
28489 var _realtime$_open$then;
28490
28491 var _ref3,
28492 tag,
28493 isReconnect,
28494 clientOptions,
28495 lagecyTag,
28496 id,
28497 buildinOptions,
28498 sessionToken,
28499 _tag,
28500 promise,
28501 _args2 = arguments;
28502
28503 return regenerator.wrap(function _callee2$(_context2) {
28504 while (1) {
28505 switch (_context2.prev = _context2.next) {
28506 case 0:
28507 _ref3 = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {}, tag = _ref3.tag, isReconnect = _ref3.isReconnect, clientOptions = _objectWithoutProperties(_ref3, ["tag", "isReconnect"]);
28508 lagecyTag = _args2.length > 2 ? _args2[2] : undefined;
28509 buildinOptions = {};
28510
28511 if (!identity) {
28512 _context2.next = 19;
28513 break;
28514 }
28515
28516 if (!(typeof identity === 'string')) {
28517 _context2.next = 8;
28518 break;
28519 }
28520
28521 id = identity;
28522 _context2.next = 17;
28523 break;
28524
28525 case 8:
28526 if (!(identity.id && identity.getSessionToken)) {
28527 _context2.next = 16;
28528 break;
28529 }
28530
28531 id = identity.id;
28532 sessionToken = identity.getSessionToken();
28533
28534 if (sessionToken) {
28535 _context2.next = 13;
28536 break;
28537 }
28538
28539 throw new Error('User must be authenticated');
28540
28541 case 13:
28542 buildinOptions.signatureFactory = signAVUser;
28543 _context2.next = 17;
28544 break;
28545
28546 case 16:
28547 throw new TypeError('Identity must be a String or an AV.User');
28548
28549 case 17:
28550 if (!(realtime._IMClients[id] !== undefined)) {
28551 _context2.next = 19;
28552 break;
28553 }
28554
28555 return _context2.abrupt("return", realtime._IMClients[id]);
28556
28557 case 19:
28558 if (lagecyTag) {
28559 console.warn('DEPRECATION createIMClient tag param: Use options.tag instead.');
28560 }
28561
28562 _tag = tag || lagecyTag;
28563 promise = (_realtime$_open$then = realtime._open().then(function (connection) {
28564 var client = new IMClient(id, _objectSpread({}, buildinOptions, clientOptions), {
28565 _connection: connection,
28566 _request: realtime._request.bind(realtime),
28567 _messageParser: messageParser,
28568 _plugins: realtime._plugins,
28569 _identity: identity
28570 });
28571 connection.on(RECONNECT, function () {
28572 return client._open(realtime._options.appId, _tag, deviceId, true)
28573 /**
28574 * 客户端连接恢复正常,该事件通常在 {@link Realtime#event:RECONNECT} 之后发生
28575 * @event IMClient#RECONNECT
28576 * @see Realtime#event:RECONNECT
28577 * @since 3.2.0
28578 */
28579
28580 /**
28581 * 客户端重新登录发生错误(网络连接已恢复,但重新登录错误)
28582 * @event IMClient#RECONNECT_ERROR
28583 * @since 3.2.0
28584 */
28585 .then(function () {
28586 return client.emit(RECONNECT);
28587 }, function (error) {
28588 return client.emit(RECONNECT_ERROR, error);
28589 });
28590 });
28591
28592 internal(client)._eventemitter.on('beforeclose', function () {
28593 delete realtime._IMClients[client.id];
28594
28595 if (realtime._firstIMClient === client) {
28596 delete realtime._firstIMClient;
28597 }
28598 }, realtime);
28599
28600 internal(client)._eventemitter.on('close', function () {
28601 realtime._deregister(client);
28602 }, realtime);
28603
28604 return client._open(realtime._options.appId, _tag, deviceId, isReconnect).then(function () {
28605 realtime._IMClients[client.id] = client;
28606 realtime._IMClientsCreationCount += 1;
28607
28608 if (realtime._IMClientsCreationCount === 1) {
28609 client._omitPeerId(true);
28610
28611 realtime._firstIMClient = client;
28612 } else if (realtime._IMClientsCreationCount > 1 && realtime._firstIMClient) {
28613 realtime._firstIMClient._omitPeerId(false);
28614 }
28615
28616 realtime._register(client);
28617
28618 return client;
28619 }).catch(function (error) {
28620 delete realtime._IMClients[client.id];
28621 throw error;
28622 });
28623 })).then.apply(_realtime$_open$then, _toConsumableArray(finalize(function () {
28624 realtime._deregisterPending(promise);
28625 })));
28626
28627 if (identity) {
28628 realtime._IMClients[id] = promise;
28629 }
28630
28631 realtime._registerPending(promise);
28632
28633 return _context2.abrupt("return", promise);
28634
28635 case 25:
28636 case "end":
28637 return _context2.stop();
28638 }
28639 }
28640 }, _callee2, this);
28641 }));
28642
28643 return function createIMClient(_x2) {
28644 return _ref2.apply(this, arguments);
28645 };
28646 }();
28647
28648 Object.assign(realtime, {
28649 register: register,
28650 createIMClient: createIMClient
28651 });
28652 /* eslint-enable no-param-reassign */
28653 };
28654
28655 var beforeCommandDispatch = function beforeCommandDispatch(command, realtime) {
28656 var isIMCommand = command.service === null || command.service === 2;
28657 if (!isIMCommand) return true;
28658 var targetClient = command.peerId ? realtime._IMClients[command.peerId] : realtime._firstIMClient;
28659
28660 if (targetClient) {
28661 Promise.resolve(targetClient).then(function (client) {
28662 return client._dispatchCommand(command);
28663 }).catch(debug$c);
28664 } else {
28665 debug$c('[WARN] Unexpected message received without any live client match: %O', trim(command));
28666 }
28667
28668 return false;
28669 };
28670
28671 var IMPlugin = {
28672 name: 'leancloud-realtime-plugin-im',
28673 onRealtimeCreate: onRealtimeCreate,
28674 beforeCommandDispatch: beforeCommandDispatch,
28675 messageClasses: [Message, BinaryMessage, RecalledMessage, TextMessage]
28676 };
28677
28678 Realtime.defineConversationProperty = defineConversationProperty;
28679 Realtime.__preRegisteredPlugins = [IMPlugin];
28680
28681 var Event$1 = _objectSpread({}, CoreEvent, Event);
28682
28683 exports.Event = Event$1;
28684 exports.ErrorCode = ErrorCode;
28685 exports.Protocals = message;
28686 exports.Promise = polyfilledPromise;
28687 exports.EventEmitter = eventemitter3;
28688 exports.Realtime = Realtime;
28689 exports.debug = debug$2;
28690 exports.Message = Message;
28691 exports.BinaryMessage = BinaryMessage;
28692 exports.TypedMessage = TypedMessage;
28693 exports.TextMessage = TextMessage;
28694 exports.RecalledMessage = RecalledMessage;
28695 exports.MessagePriority = MessagePriority;
28696 exports.MessageStatus = MessageStatus;
28697 exports.MessageQueryDirection = MessageQueryDirection;
28698 exports.defineConversationProperty = defineConversationProperty;
28699 exports.IMPlugin = IMPlugin;
28700 exports.messageType = messageType;
28701 exports.messageField = messageField;
28702 exports.IE10Compatible = IE10Compatible;
28703 exports.ConversationMemberRole = ConversationMemberRole;
28704 exports.Conversation = Conversation;
28705 exports.ChatRoom = ChatRoom;
28706 exports.ServiceConversation = ServiceConversation;
28707 exports.TemporaryConversation = TemporaryConversation;
28708
28709 Object.defineProperty(exports, '__esModule', { value: true });
28710
28711}));
28712//# sourceMappingURL=realtime-browser.js.map