· 8 years ago · Feb 08, 2017, 10:10 AM
1(function webpackUniversalModuleDefinition(root, factory) {
2 if(typeof exports === 'object' && typeof module === 'object')
3 module.exports = factory();
4 else if(typeof define === 'function' && define.amd)
5 define([], factory);
6 else if(typeof exports === 'object')
7 exports["AV"] = factory();
8 else
9 root["AV"] = factory();
10})(this, function() {
11return /******/ (function(modules) { // webpackBootstrap
12/******/ // The module cache
13/******/ var installedModules = {};
14/******/
15/******/ // The require function
16/******/ function __webpack_require__(moduleId) {
17/******/
18/******/ // Check if module is in cache
19/******/ if(installedModules[moduleId])
20/******/ return installedModules[moduleId].exports;
21/******/
22/******/ // Create a new module (and put it into the cache)
23/******/ var module = installedModules[moduleId] = {
24/******/ i: moduleId,
25/******/ l: false,
26/******/ exports: {}
27/******/ };
28/******/
29/******/ // Execute the module function
30/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
31/******/
32/******/ // Flag the module as loaded
33/******/ module.l = true;
34/******/
35/******/ // Return the exports of the module
36/******/ return module.exports;
37/******/ }
38/******/
39/******/
40/******/ // expose the modules object (__webpack_modules__)
41/******/ __webpack_require__.m = modules;
42/******/
43/******/ // expose the module cache
44/******/ __webpack_require__.c = installedModules;
45/******/
46/******/ // identity function for calling harmony imports with the correct context
47/******/ __webpack_require__.i = function(value) { return value; };
48/******/
49/******/ // define getter function for harmony exports
50/******/ __webpack_require__.d = function(exports, name, getter) {
51/******/ if(!__webpack_require__.o(exports, name)) {
52/******/ Object.defineProperty(exports, name, {
53/******/ configurable: false,
54/******/ enumerable: true,
55/******/ get: getter
56/******/ });
57/******/ }
58/******/ };
59/******/
60/******/ // getDefaultExport function for compatibility with non-harmony modules
61/******/ __webpack_require__.n = function(module) {
62/******/ var getter = module && module.__esModule ?
63/******/ function getDefault() { return module['default']; } :
64/******/ function getModuleExports() { return module; };
65/******/ __webpack_require__.d(getter, 'a', getter);
66/******/ return getter;
67/******/ };
68/******/
69/******/ // Object.prototype.hasOwnProperty.call
70/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
71/******/
72/******/ // __webpack_public_path__
73/******/ __webpack_require__.p = "";
74/******/
75/******/ // Load entry module and return exports
76/******/ return __webpack_require__(__webpack_require__.s = 64);
77/******/ })
78/************************************************************************/
79/******/ ([
80/* 0 */
81/***/ (function(module, exports, __webpack_require__) {
82
83var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Underscore.js 1.8.3
84// http://underscorejs.org
85// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
86// Underscore may be freely distributed under the MIT license.
87
88(function() {
89
90 // Baseline setup
91 // --------------
92
93 // Establish the root object, `window` in the browser, or `exports` on the server.
94 var root = this;
95
96 // Save the previous value of the `_` variable.
97 var previousUnderscore = root._;
98
99 // Save bytes in the minified (but not gzipped) version:
100 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
101
102 // Create quick reference variables for speed access to core prototypes.
103 var
104 push = ArrayProto.push,
105 slice = ArrayProto.slice,
106 toString = ObjProto.toString,
107 hasOwnProperty = ObjProto.hasOwnProperty;
108
109 // All **ECMAScript 5** native function implementations that we hope to use
110 // are declared here.
111 var
112 nativeIsArray = Array.isArray,
113 nativeKeys = Object.keys,
114 nativeBind = FuncProto.bind,
115 nativeCreate = Object.create;
116
117 // Naked function reference for surrogate-prototype-swapping.
118 var Ctor = function(){};
119
120 // Create a safe reference to the Underscore object for use below.
121 var _ = function(obj) {
122 if (obj instanceof _) return obj;
123 if (!(this instanceof _)) return new _(obj);
124 this._wrapped = obj;
125 };
126
127 // Export the Underscore object for **Node.js**, with
128 // backwards-compatibility for the old `require()` API. If we're in
129 // the browser, add `_` as a global object.
130 if (true) {
131 if (typeof module !== 'undefined' && module.exports) {
132 exports = module.exports = _;
133 }
134 exports._ = _;
135 } else {
136 root._ = _;
137 }
138
139 // Current version.
140 _.VERSION = '1.8.3';
141
142 // Internal function that returns an efficient (for current engines) version
143 // of the passed-in callback, to be repeatedly applied in other Underscore
144 // functions.
145 var optimizeCb = function(func, context, argCount) {
146 if (context === void 0) return func;
147 switch (argCount == null ? 3 : argCount) {
148 case 1: return function(value) {
149 return func.call(context, value);
150 };
151 case 2: return function(value, other) {
152 return func.call(context, value, other);
153 };
154 case 3: return function(value, index, collection) {
155 return func.call(context, value, index, collection);
156 };
157 case 4: return function(accumulator, value, index, collection) {
158 return func.call(context, accumulator, value, index, collection);
159 };
160 }
161 return function() {
162 return func.apply(context, arguments);
163 };
164 };
165
166 // A mostly-internal function to generate callbacks that can be applied
167 // to each element in a collection, returning the desired result — either
168 // identity, an arbitrary callback, a property matcher, or a property accessor.
169 var cb = function(value, context, argCount) {
170 if (value == null) return _.identity;
171 if (_.isFunction(value)) return optimizeCb(value, context, argCount);
172 if (_.isObject(value)) return _.matcher(value);
173 return _.property(value);
174 };
175 _.iteratee = function(value, context) {
176 return cb(value, context, Infinity);
177 };
178
179 // An internal function for creating assigner functions.
180 var createAssigner = function(keysFunc, undefinedOnly) {
181 return function(obj) {
182 var length = arguments.length;
183 if (length < 2 || obj == null) return obj;
184 for (var index = 1; index < length; index++) {
185 var source = arguments[index],
186 keys = keysFunc(source),
187 l = keys.length;
188 for (var i = 0; i < l; i++) {
189 var key = keys[i];
190 if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
191 }
192 }
193 return obj;
194 };
195 };
196
197 // An internal function for creating a new object that inherits from another.
198 var baseCreate = function(prototype) {
199 if (!_.isObject(prototype)) return {};
200 if (nativeCreate) return nativeCreate(prototype);
201 Ctor.prototype = prototype;
202 var result = new Ctor;
203 Ctor.prototype = null;
204 return result;
205 };
206
207 var property = function(key) {
208 return function(obj) {
209 return obj == null ? void 0 : obj[key];
210 };
211 };
212
213 // Helper for collection methods to determine whether a collection
214 // should be iterated as an array or as an object
215 // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
216 // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
217 var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
218 var getLength = property('length');
219 var isArrayLike = function(collection) {
220 var length = getLength(collection);
221 return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
222 };
223
224 // Collection Functions
225 // --------------------
226
227 // The cornerstone, an `each` implementation, aka `forEach`.
228 // Handles raw objects in addition to array-likes. Treats all
229 // sparse array-likes as if they were dense.
230 _.each = _.forEach = function(obj, iteratee, context) {
231 iteratee = optimizeCb(iteratee, context);
232 var i, length;
233 if (isArrayLike(obj)) {
234 for (i = 0, length = obj.length; i < length; i++) {
235 iteratee(obj[i], i, obj);
236 }
237 } else {
238 var keys = _.keys(obj);
239 for (i = 0, length = keys.length; i < length; i++) {
240 iteratee(obj[keys[i]], keys[i], obj);
241 }
242 }
243 return obj;
244 };
245
246 // Return the results of applying the iteratee to each element.
247 _.map = _.collect = function(obj, iteratee, context) {
248 iteratee = cb(iteratee, context);
249 var keys = !isArrayLike(obj) && _.keys(obj),
250 length = (keys || obj).length,
251 results = Array(length);
252 for (var index = 0; index < length; index++) {
253 var currentKey = keys ? keys[index] : index;
254 results[index] = iteratee(obj[currentKey], currentKey, obj);
255 }
256 return results;
257 };
258
259 // Create a reducing function iterating left or right.
260 function createReduce(dir) {
261 // Optimized iterator function as using arguments.length
262 // in the main function will deoptimize the, see #1991.
263 function iterator(obj, iteratee, memo, keys, index, length) {
264 for (; index >= 0 && index < length; index += dir) {
265 var currentKey = keys ? keys[index] : index;
266 memo = iteratee(memo, obj[currentKey], currentKey, obj);
267 }
268 return memo;
269 }
270
271 return function(obj, iteratee, memo, context) {
272 iteratee = optimizeCb(iteratee, context, 4);
273 var keys = !isArrayLike(obj) && _.keys(obj),
274 length = (keys || obj).length,
275 index = dir > 0 ? 0 : length - 1;
276 // Determine the initial value if none is provided.
277 if (arguments.length < 3) {
278 memo = obj[keys ? keys[index] : index];
279 index += dir;
280 }
281 return iterator(obj, iteratee, memo, keys, index, length);
282 };
283 }
284
285 // **Reduce** builds up a single result from a list of values, aka `inject`,
286 // or `foldl`.
287 _.reduce = _.foldl = _.inject = createReduce(1);
288
289 // The right-associative version of reduce, also known as `foldr`.
290 _.reduceRight = _.foldr = createReduce(-1);
291
292 // Return the first value which passes a truth test. Aliased as `detect`.
293 _.find = _.detect = function(obj, predicate, context) {
294 var key;
295 if (isArrayLike(obj)) {
296 key = _.findIndex(obj, predicate, context);
297 } else {
298 key = _.findKey(obj, predicate, context);
299 }
300 if (key !== void 0 && key !== -1) return obj[key];
301 };
302
303 // Return all the elements that pass a truth test.
304 // Aliased as `select`.
305 _.filter = _.select = function(obj, predicate, context) {
306 var results = [];
307 predicate = cb(predicate, context);
308 _.each(obj, function(value, index, list) {
309 if (predicate(value, index, list)) results.push(value);
310 });
311 return results;
312 };
313
314 // Return all the elements for which a truth test fails.
315 _.reject = function(obj, predicate, context) {
316 return _.filter(obj, _.negate(cb(predicate)), context);
317 };
318
319 // Determine whether all of the elements match a truth test.
320 // Aliased as `all`.
321 _.every = _.all = function(obj, predicate, context) {
322 predicate = cb(predicate, context);
323 var keys = !isArrayLike(obj) && _.keys(obj),
324 length = (keys || obj).length;
325 for (var index = 0; index < length; index++) {
326 var currentKey = keys ? keys[index] : index;
327 if (!predicate(obj[currentKey], currentKey, obj)) return false;
328 }
329 return true;
330 };
331
332 // Determine if at least one element in the object matches a truth test.
333 // Aliased as `any`.
334 _.some = _.any = function(obj, predicate, context) {
335 predicate = cb(predicate, context);
336 var keys = !isArrayLike(obj) && _.keys(obj),
337 length = (keys || obj).length;
338 for (var index = 0; index < length; index++) {
339 var currentKey = keys ? keys[index] : index;
340 if (predicate(obj[currentKey], currentKey, obj)) return true;
341 }
342 return false;
343 };
344
345 // Determine if the array or object contains a given item (using `===`).
346 // Aliased as `includes` and `include`.
347 _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
348 if (!isArrayLike(obj)) obj = _.values(obj);
349 if (typeof fromIndex != 'number' || guard) fromIndex = 0;
350 return _.indexOf(obj, item, fromIndex) >= 0;
351 };
352
353 // Invoke a method (with arguments) on every item in a collection.
354 _.invoke = function(obj, method) {
355 var args = slice.call(arguments, 2);
356 var isFunc = _.isFunction(method);
357 return _.map(obj, function(value) {
358 var func = isFunc ? method : value[method];
359 return func == null ? func : func.apply(value, args);
360 });
361 };
362
363 // Convenience version of a common use case of `map`: fetching a property.
364 _.pluck = function(obj, key) {
365 return _.map(obj, _.property(key));
366 };
367
368 // Convenience version of a common use case of `filter`: selecting only objects
369 // containing specific `key:value` pairs.
370 _.where = function(obj, attrs) {
371 return _.filter(obj, _.matcher(attrs));
372 };
373
374 // Convenience version of a common use case of `find`: getting the first object
375 // containing specific `key:value` pairs.
376 _.findWhere = function(obj, attrs) {
377 return _.find(obj, _.matcher(attrs));
378 };
379
380 // Return the maximum element (or element-based computation).
381 _.max = function(obj, iteratee, context) {
382 var result = -Infinity, lastComputed = -Infinity,
383 value, computed;
384 if (iteratee == null && obj != null) {
385 obj = isArrayLike(obj) ? obj : _.values(obj);
386 for (var i = 0, length = obj.length; i < length; i++) {
387 value = obj[i];
388 if (value > result) {
389 result = value;
390 }
391 }
392 } else {
393 iteratee = cb(iteratee, context);
394 _.each(obj, function(value, index, list) {
395 computed = iteratee(value, index, list);
396 if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
397 result = value;
398 lastComputed = computed;
399 }
400 });
401 }
402 return result;
403 };
404
405 // Return the minimum element (or element-based computation).
406 _.min = function(obj, iteratee, context) {
407 var result = Infinity, lastComputed = Infinity,
408 value, computed;
409 if (iteratee == null && obj != null) {
410 obj = isArrayLike(obj) ? obj : _.values(obj);
411 for (var i = 0, length = obj.length; i < length; i++) {
412 value = obj[i];
413 if (value < result) {
414 result = value;
415 }
416 }
417 } else {
418 iteratee = cb(iteratee, context);
419 _.each(obj, function(value, index, list) {
420 computed = iteratee(value, index, list);
421 if (computed < lastComputed || computed === Infinity && result === Infinity) {
422 result = value;
423 lastComputed = computed;
424 }
425 });
426 }
427 return result;
428 };
429
430 // Shuffle a collection, using the modern version of the
431 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
432 _.shuffle = function(obj) {
433 var set = isArrayLike(obj) ? obj : _.values(obj);
434 var length = set.length;
435 var shuffled = Array(length);
436 for (var index = 0, rand; index < length; index++) {
437 rand = _.random(0, index);
438 if (rand !== index) shuffled[index] = shuffled[rand];
439 shuffled[rand] = set[index];
440 }
441 return shuffled;
442 };
443
444 // Sample **n** random values from a collection.
445 // If **n** is not specified, returns a single random element.
446 // The internal `guard` argument allows it to work with `map`.
447 _.sample = function(obj, n, guard) {
448 if (n == null || guard) {
449 if (!isArrayLike(obj)) obj = _.values(obj);
450 return obj[_.random(obj.length - 1)];
451 }
452 return _.shuffle(obj).slice(0, Math.max(0, n));
453 };
454
455 // Sort the object's values by a criterion produced by an iteratee.
456 _.sortBy = function(obj, iteratee, context) {
457 iteratee = cb(iteratee, context);
458 return _.pluck(_.map(obj, function(value, index, list) {
459 return {
460 value: value,
461 index: index,
462 criteria: iteratee(value, index, list)
463 };
464 }).sort(function(left, right) {
465 var a = left.criteria;
466 var b = right.criteria;
467 if (a !== b) {
468 if (a > b || a === void 0) return 1;
469 if (a < b || b === void 0) return -1;
470 }
471 return left.index - right.index;
472 }), 'value');
473 };
474
475 // An internal function used for aggregate "group by" operations.
476 var group = function(behavior) {
477 return function(obj, iteratee, context) {
478 var result = {};
479 iteratee = cb(iteratee, context);
480 _.each(obj, function(value, index) {
481 var key = iteratee(value, index, obj);
482 behavior(result, value, key);
483 });
484 return result;
485 };
486 };
487
488 // Groups the object's values by a criterion. Pass either a string attribute
489 // to group by, or a function that returns the criterion.
490 _.groupBy = group(function(result, value, key) {
491 if (_.has(result, key)) result[key].push(value); else result[key] = [value];
492 });
493
494 // Indexes the object's values by a criterion, similar to `groupBy`, but for
495 // when you know that your index values will be unique.
496 _.indexBy = group(function(result, value, key) {
497 result[key] = value;
498 });
499
500 // Counts instances of an object that group by a certain criterion. Pass
501 // either a string attribute to count by, or a function that returns the
502 // criterion.
503 _.countBy = group(function(result, value, key) {
504 if (_.has(result, key)) result[key]++; else result[key] = 1;
505 });
506
507 // Safely create a real, live array from anything iterable.
508 _.toArray = function(obj) {
509 if (!obj) return [];
510 if (_.isArray(obj)) return slice.call(obj);
511 if (isArrayLike(obj)) return _.map(obj, _.identity);
512 return _.values(obj);
513 };
514
515 // Return the number of elements in an object.
516 _.size = function(obj) {
517 if (obj == null) return 0;
518 return isArrayLike(obj) ? obj.length : _.keys(obj).length;
519 };
520
521 // Split a collection into two arrays: one whose elements all satisfy the given
522 // predicate, and one whose elements all do not satisfy the predicate.
523 _.partition = function(obj, predicate, context) {
524 predicate = cb(predicate, context);
525 var pass = [], fail = [];
526 _.each(obj, function(value, key, obj) {
527 (predicate(value, key, obj) ? pass : fail).push(value);
528 });
529 return [pass, fail];
530 };
531
532 // Array Functions
533 // ---------------
534
535 // Get the first element of an array. Passing **n** will return the first N
536 // values in the array. Aliased as `head` and `take`. The **guard** check
537 // allows it to work with `_.map`.
538 _.first = _.head = _.take = function(array, n, guard) {
539 if (array == null) return void 0;
540 if (n == null || guard) return array[0];
541 return _.initial(array, array.length - n);
542 };
543
544 // Returns everything but the last entry of the array. Especially useful on
545 // the arguments object. Passing **n** will return all the values in
546 // the array, excluding the last N.
547 _.initial = function(array, n, guard) {
548 return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
549 };
550
551 // Get the last element of an array. Passing **n** will return the last N
552 // values in the array.
553 _.last = function(array, n, guard) {
554 if (array == null) return void 0;
555 if (n == null || guard) return array[array.length - 1];
556 return _.rest(array, Math.max(0, array.length - n));
557 };
558
559 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
560 // Especially useful on the arguments object. Passing an **n** will return
561 // the rest N values in the array.
562 _.rest = _.tail = _.drop = function(array, n, guard) {
563 return slice.call(array, n == null || guard ? 1 : n);
564 };
565
566 // Trim out all falsy values from an array.
567 _.compact = function(array) {
568 return _.filter(array, _.identity);
569 };
570
571 // Internal implementation of a recursive `flatten` function.
572 var flatten = function(input, shallow, strict, startIndex) {
573 var output = [], idx = 0;
574 for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
575 var value = input[i];
576 if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
577 //flatten current level of array or arguments object
578 if (!shallow) value = flatten(value, shallow, strict);
579 var j = 0, len = value.length;
580 output.length += len;
581 while (j < len) {
582 output[idx++] = value[j++];
583 }
584 } else if (!strict) {
585 output[idx++] = value;
586 }
587 }
588 return output;
589 };
590
591 // Flatten out an array, either recursively (by default), or just one level.
592 _.flatten = function(array, shallow) {
593 return flatten(array, shallow, false);
594 };
595
596 // Return a version of the array that does not contain the specified value(s).
597 _.without = function(array) {
598 return _.difference(array, slice.call(arguments, 1));
599 };
600
601 // Produce a duplicate-free version of the array. If the array has already
602 // been sorted, you have the option of using a faster algorithm.
603 // Aliased as `unique`.
604 _.uniq = _.unique = function(array, isSorted, iteratee, context) {
605 if (!_.isBoolean(isSorted)) {
606 context = iteratee;
607 iteratee = isSorted;
608 isSorted = false;
609 }
610 if (iteratee != null) iteratee = cb(iteratee, context);
611 var result = [];
612 var seen = [];
613 for (var i = 0, length = getLength(array); i < length; i++) {
614 var value = array[i],
615 computed = iteratee ? iteratee(value, i, array) : value;
616 if (isSorted) {
617 if (!i || seen !== computed) result.push(value);
618 seen = computed;
619 } else if (iteratee) {
620 if (!_.contains(seen, computed)) {
621 seen.push(computed);
622 result.push(value);
623 }
624 } else if (!_.contains(result, value)) {
625 result.push(value);
626 }
627 }
628 return result;
629 };
630
631 // Produce an array that contains the union: each distinct element from all of
632 // the passed-in arrays.
633 _.union = function() {
634 return _.uniq(flatten(arguments, true, true));
635 };
636
637 // Produce an array that contains every item shared between all the
638 // passed-in arrays.
639 _.intersection = function(array) {
640 var result = [];
641 var argsLength = arguments.length;
642 for (var i = 0, length = getLength(array); i < length; i++) {
643 var item = array[i];
644 if (_.contains(result, item)) continue;
645 for (var j = 1; j < argsLength; j++) {
646 if (!_.contains(arguments[j], item)) break;
647 }
648 if (j === argsLength) result.push(item);
649 }
650 return result;
651 };
652
653 // Take the difference between one array and a number of other arrays.
654 // Only the elements present in just the first array will remain.
655 _.difference = function(array) {
656 var rest = flatten(arguments, true, true, 1);
657 return _.filter(array, function(value){
658 return !_.contains(rest, value);
659 });
660 };
661
662 // Zip together multiple lists into a single array -- elements that share
663 // an index go together.
664 _.zip = function() {
665 return _.unzip(arguments);
666 };
667
668 // Complement of _.zip. Unzip accepts an array of arrays and groups
669 // each array's elements on shared indices
670 _.unzip = function(array) {
671 var length = array && _.max(array, getLength).length || 0;
672 var result = Array(length);
673
674 for (var index = 0; index < length; index++) {
675 result[index] = _.pluck(array, index);
676 }
677 return result;
678 };
679
680 // Converts lists into objects. Pass either a single array of `[key, value]`
681 // pairs, or two parallel arrays of the same length -- one of keys, and one of
682 // the corresponding values.
683 _.object = function(list, values) {
684 var result = {};
685 for (var i = 0, length = getLength(list); i < length; i++) {
686 if (values) {
687 result[list[i]] = values[i];
688 } else {
689 result[list[i][0]] = list[i][1];
690 }
691 }
692 return result;
693 };
694
695 // Generator function to create the findIndex and findLastIndex functions
696 function createPredicateIndexFinder(dir) {
697 return function(array, predicate, context) {
698 predicate = cb(predicate, context);
699 var length = getLength(array);
700 var index = dir > 0 ? 0 : length - 1;
701 for (; index >= 0 && index < length; index += dir) {
702 if (predicate(array[index], index, array)) return index;
703 }
704 return -1;
705 };
706 }
707
708 // Returns the first index on an array-like that passes a predicate test
709 _.findIndex = createPredicateIndexFinder(1);
710 _.findLastIndex = createPredicateIndexFinder(-1);
711
712 // Use a comparator function to figure out the smallest index at which
713 // an object should be inserted so as to maintain order. Uses binary search.
714 _.sortedIndex = function(array, obj, iteratee, context) {
715 iteratee = cb(iteratee, context, 1);
716 var value = iteratee(obj);
717 var low = 0, high = getLength(array);
718 while (low < high) {
719 var mid = Math.floor((low + high) / 2);
720 if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
721 }
722 return low;
723 };
724
725 // Generator function to create the indexOf and lastIndexOf functions
726 function createIndexFinder(dir, predicateFind, sortedIndex) {
727 return function(array, item, idx) {
728 var i = 0, length = getLength(array);
729 if (typeof idx == 'number') {
730 if (dir > 0) {
731 i = idx >= 0 ? idx : Math.max(idx + length, i);
732 } else {
733 length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
734 }
735 } else if (sortedIndex && idx && length) {
736 idx = sortedIndex(array, item);
737 return array[idx] === item ? idx : -1;
738 }
739 if (item !== item) {
740 idx = predicateFind(slice.call(array, i, length), _.isNaN);
741 return idx >= 0 ? idx + i : -1;
742 }
743 for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
744 if (array[idx] === item) return idx;
745 }
746 return -1;
747 };
748 }
749
750 // Return the position of the first occurrence of an item in an array,
751 // or -1 if the item is not included in the array.
752 // If the array is large and already in sort order, pass `true`
753 // for **isSorted** to use binary search.
754 _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
755 _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
756
757 // Generate an integer Array containing an arithmetic progression. A port of
758 // the native Python `range()` function. See
759 // [the Python documentation](http://docs.python.org/library/functions.html#range).
760 _.range = function(start, stop, step) {
761 if (stop == null) {
762 stop = start || 0;
763 start = 0;
764 }
765 step = step || 1;
766
767 var length = Math.max(Math.ceil((stop - start) / step), 0);
768 var range = Array(length);
769
770 for (var idx = 0; idx < length; idx++, start += step) {
771 range[idx] = start;
772 }
773
774 return range;
775 };
776
777 // Function (ahem) Functions
778 // ------------------
779
780 // Determines whether to execute a function as a constructor
781 // or a normal function with the provided arguments
782 var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
783 if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
784 var self = baseCreate(sourceFunc.prototype);
785 var result = sourceFunc.apply(self, args);
786 if (_.isObject(result)) return result;
787 return self;
788 };
789
790 // Create a function bound to a given object (assigning `this`, and arguments,
791 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
792 // available.
793 _.bind = function(func, context) {
794 if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
795 if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
796 var args = slice.call(arguments, 2);
797 var bound = function() {
798 return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
799 };
800 return bound;
801 };
802
803 // Partially apply a function by creating a version that has had some of its
804 // arguments pre-filled, without changing its dynamic `this` context. _ acts
805 // as a placeholder, allowing any combination of arguments to be pre-filled.
806 _.partial = function(func) {
807 var boundArgs = slice.call(arguments, 1);
808 var bound = function() {
809 var position = 0, length = boundArgs.length;
810 var args = Array(length);
811 for (var i = 0; i < length; i++) {
812 args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
813 }
814 while (position < arguments.length) args.push(arguments[position++]);
815 return executeBound(func, bound, this, this, args);
816 };
817 return bound;
818 };
819
820 // Bind a number of an object's methods to that object. Remaining arguments
821 // are the method names to be bound. Useful for ensuring that all callbacks
822 // defined on an object belong to it.
823 _.bindAll = function(obj) {
824 var i, length = arguments.length, key;
825 if (length <= 1) throw new Error('bindAll must be passed function names');
826 for (i = 1; i < length; i++) {
827 key = arguments[i];
828 obj[key] = _.bind(obj[key], obj);
829 }
830 return obj;
831 };
832
833 // Memoize an expensive function by storing its results.
834 _.memoize = function(func, hasher) {
835 var memoize = function(key) {
836 var cache = memoize.cache;
837 var address = '' + (hasher ? hasher.apply(this, arguments) : key);
838 if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
839 return cache[address];
840 };
841 memoize.cache = {};
842 return memoize;
843 };
844
845 // Delays a function for the given number of milliseconds, and then calls
846 // it with the arguments supplied.
847 _.delay = function(func, wait) {
848 var args = slice.call(arguments, 2);
849 return setTimeout(function(){
850 return func.apply(null, args);
851 }, wait);
852 };
853
854 // Defers a function, scheduling it to run after the current call stack has
855 // cleared.
856 _.defer = _.partial(_.delay, _, 1);
857
858 // Returns a function, that, when invoked, will only be triggered at most once
859 // during a given window of time. Normally, the throttled function will run
860 // as much as it can, without ever going more than once per `wait` duration;
861 // but if you'd like to disable the execution on the leading edge, pass
862 // `{leading: false}`. To disable execution on the trailing edge, ditto.
863 _.throttle = function(func, wait, options) {
864 var context, args, result;
865 var timeout = null;
866 var previous = 0;
867 if (!options) options = {};
868 var later = function() {
869 previous = options.leading === false ? 0 : _.now();
870 timeout = null;
871 result = func.apply(context, args);
872 if (!timeout) context = args = null;
873 };
874 return function() {
875 var now = _.now();
876 if (!previous && options.leading === false) previous = now;
877 var remaining = wait - (now - previous);
878 context = this;
879 args = arguments;
880 if (remaining <= 0 || remaining > wait) {
881 if (timeout) {
882 clearTimeout(timeout);
883 timeout = null;
884 }
885 previous = now;
886 result = func.apply(context, args);
887 if (!timeout) context = args = null;
888 } else if (!timeout && options.trailing !== false) {
889 timeout = setTimeout(later, remaining);
890 }
891 return result;
892 };
893 };
894
895 // Returns a function, that, as long as it continues to be invoked, will not
896 // be triggered. The function will be called after it stops being called for
897 // N milliseconds. If `immediate` is passed, trigger the function on the
898 // leading edge, instead of the trailing.
899 _.debounce = function(func, wait, immediate) {
900 var timeout, args, context, timestamp, result;
901
902 var later = function() {
903 var last = _.now() - timestamp;
904
905 if (last < wait && last >= 0) {
906 timeout = setTimeout(later, wait - last);
907 } else {
908 timeout = null;
909 if (!immediate) {
910 result = func.apply(context, args);
911 if (!timeout) context = args = null;
912 }
913 }
914 };
915
916 return function() {
917 context = this;
918 args = arguments;
919 timestamp = _.now();
920 var callNow = immediate && !timeout;
921 if (!timeout) timeout = setTimeout(later, wait);
922 if (callNow) {
923 result = func.apply(context, args);
924 context = args = null;
925 }
926
927 return result;
928 };
929 };
930
931 // Returns the first function passed as an argument to the second,
932 // allowing you to adjust arguments, run code before and after, and
933 // conditionally execute the original function.
934 _.wrap = function(func, wrapper) {
935 return _.partial(wrapper, func);
936 };
937
938 // Returns a negated version of the passed-in predicate.
939 _.negate = function(predicate) {
940 return function() {
941 return !predicate.apply(this, arguments);
942 };
943 };
944
945 // Returns a function that is the composition of a list of functions, each
946 // consuming the return value of the function that follows.
947 _.compose = function() {
948 var args = arguments;
949 var start = args.length - 1;
950 return function() {
951 var i = start;
952 var result = args[start].apply(this, arguments);
953 while (i--) result = args[i].call(this, result);
954 return result;
955 };
956 };
957
958 // Returns a function that will only be executed on and after the Nth call.
959 _.after = function(times, func) {
960 return function() {
961 if (--times < 1) {
962 return func.apply(this, arguments);
963 }
964 };
965 };
966
967 // Returns a function that will only be executed up to (but not including) the Nth call.
968 _.before = function(times, func) {
969 var memo;
970 return function() {
971 if (--times > 0) {
972 memo = func.apply(this, arguments);
973 }
974 if (times <= 1) func = null;
975 return memo;
976 };
977 };
978
979 // Returns a function that will be executed at most one time, no matter how
980 // often you call it. Useful for lazy initialization.
981 _.once = _.partial(_.before, 2);
982
983 // Object Functions
984 // ----------------
985
986 // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
987 var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
988 var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
989 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
990
991 function collectNonEnumProps(obj, keys) {
992 var nonEnumIdx = nonEnumerableProps.length;
993 var constructor = obj.constructor;
994 var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
995
996 // Constructor is a special case.
997 var prop = 'constructor';
998 if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
999
1000 while (nonEnumIdx--) {
1001 prop = nonEnumerableProps[nonEnumIdx];
1002 if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
1003 keys.push(prop);
1004 }
1005 }
1006 }
1007
1008 // Retrieve the names of an object's own properties.
1009 // Delegates to **ECMAScript 5**'s native `Object.keys`
1010 _.keys = function(obj) {
1011 if (!_.isObject(obj)) return [];
1012 if (nativeKeys) return nativeKeys(obj);
1013 var keys = [];
1014 for (var key in obj) if (_.has(obj, key)) keys.push(key);
1015 // Ahem, IE < 9.
1016 if (hasEnumBug) collectNonEnumProps(obj, keys);
1017 return keys;
1018 };
1019
1020 // Retrieve all the property names of an object.
1021 _.allKeys = function(obj) {
1022 if (!_.isObject(obj)) return [];
1023 var keys = [];
1024 for (var key in obj) keys.push(key);
1025 // Ahem, IE < 9.
1026 if (hasEnumBug) collectNonEnumProps(obj, keys);
1027 return keys;
1028 };
1029
1030 // Retrieve the values of an object's properties.
1031 _.values = function(obj) {
1032 var keys = _.keys(obj);
1033 var length = keys.length;
1034 var values = Array(length);
1035 for (var i = 0; i < length; i++) {
1036 values[i] = obj[keys[i]];
1037 }
1038 return values;
1039 };
1040
1041 // Returns the results of applying the iteratee to each element of the object
1042 // In contrast to _.map it returns an object
1043 _.mapObject = function(obj, iteratee, context) {
1044 iteratee = cb(iteratee, context);
1045 var keys = _.keys(obj),
1046 length = keys.length,
1047 results = {},
1048 currentKey;
1049 for (var index = 0; index < length; index++) {
1050 currentKey = keys[index];
1051 results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
1052 }
1053 return results;
1054 };
1055
1056 // Convert an object into a list of `[key, value]` pairs.
1057 _.pairs = function(obj) {
1058 var keys = _.keys(obj);
1059 var length = keys.length;
1060 var pairs = Array(length);
1061 for (var i = 0; i < length; i++) {
1062 pairs[i] = [keys[i], obj[keys[i]]];
1063 }
1064 return pairs;
1065 };
1066
1067 // Invert the keys and values of an object. The values must be serializable.
1068 _.invert = function(obj) {
1069 var result = {};
1070 var keys = _.keys(obj);
1071 for (var i = 0, length = keys.length; i < length; i++) {
1072 result[obj[keys[i]]] = keys[i];
1073 }
1074 return result;
1075 };
1076
1077 // Return a sorted list of the function names available on the object.
1078 // Aliased as `methods`
1079 _.functions = _.methods = function(obj) {
1080 var names = [];
1081 for (var key in obj) {
1082 if (_.isFunction(obj[key])) names.push(key);
1083 }
1084 return names.sort();
1085 };
1086
1087 // Extend a given object with all the properties in passed-in object(s).
1088 _.extend = createAssigner(_.allKeys);
1089
1090 // Assigns a given object with all the own properties in the passed-in object(s)
1091 // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
1092 _.extendOwn = _.assign = createAssigner(_.keys);
1093
1094 // Returns the first key on an object that passes a predicate test
1095 _.findKey = function(obj, predicate, context) {
1096 predicate = cb(predicate, context);
1097 var keys = _.keys(obj), key;
1098 for (var i = 0, length = keys.length; i < length; i++) {
1099 key = keys[i];
1100 if (predicate(obj[key], key, obj)) return key;
1101 }
1102 };
1103
1104 // Return a copy of the object only containing the whitelisted properties.
1105 _.pick = function(object, oiteratee, context) {
1106 var result = {}, obj = object, iteratee, keys;
1107 if (obj == null) return result;
1108 if (_.isFunction(oiteratee)) {
1109 keys = _.allKeys(obj);
1110 iteratee = optimizeCb(oiteratee, context);
1111 } else {
1112 keys = flatten(arguments, false, false, 1);
1113 iteratee = function(value, key, obj) { return key in obj; };
1114 obj = Object(obj);
1115 }
1116 for (var i = 0, length = keys.length; i < length; i++) {
1117 var key = keys[i];
1118 var value = obj[key];
1119 if (iteratee(value, key, obj)) result[key] = value;
1120 }
1121 return result;
1122 };
1123
1124 // Return a copy of the object without the blacklisted properties.
1125 _.omit = function(obj, iteratee, context) {
1126 if (_.isFunction(iteratee)) {
1127 iteratee = _.negate(iteratee);
1128 } else {
1129 var keys = _.map(flatten(arguments, false, false, 1), String);
1130 iteratee = function(value, key) {
1131 return !_.contains(keys, key);
1132 };
1133 }
1134 return _.pick(obj, iteratee, context);
1135 };
1136
1137 // Fill in a given object with default properties.
1138 _.defaults = createAssigner(_.allKeys, true);
1139
1140 // Creates an object that inherits from the given prototype object.
1141 // If additional properties are provided then they will be added to the
1142 // created object.
1143 _.create = function(prototype, props) {
1144 var result = baseCreate(prototype);
1145 if (props) _.extendOwn(result, props);
1146 return result;
1147 };
1148
1149 // Create a (shallow-cloned) duplicate of an object.
1150 _.clone = function(obj) {
1151 if (!_.isObject(obj)) return obj;
1152 return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
1153 };
1154
1155 // Invokes interceptor with the obj, and then returns obj.
1156 // The primary purpose of this method is to "tap into" a method chain, in
1157 // order to perform operations on intermediate results within the chain.
1158 _.tap = function(obj, interceptor) {
1159 interceptor(obj);
1160 return obj;
1161 };
1162
1163 // Returns whether an object has a given set of `key:value` pairs.
1164 _.isMatch = function(object, attrs) {
1165 var keys = _.keys(attrs), length = keys.length;
1166 if (object == null) return !length;
1167 var obj = Object(object);
1168 for (var i = 0; i < length; i++) {
1169 var key = keys[i];
1170 if (attrs[key] !== obj[key] || !(key in obj)) return false;
1171 }
1172 return true;
1173 };
1174
1175
1176 // Internal recursive comparison function for `isEqual`.
1177 var eq = function(a, b, aStack, bStack) {
1178 // Identical objects are equal. `0 === -0`, but they aren't identical.
1179 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
1180 if (a === b) return a !== 0 || 1 / a === 1 / b;
1181 // A strict comparison is necessary because `null == undefined`.
1182 if (a == null || b == null) return a === b;
1183 // Unwrap any wrapped objects.
1184 if (a instanceof _) a = a._wrapped;
1185 if (b instanceof _) b = b._wrapped;
1186 // Compare `[[Class]]` names.
1187 var className = toString.call(a);
1188 if (className !== toString.call(b)) return false;
1189 switch (className) {
1190 // Strings, numbers, regular expressions, dates, and booleans are compared by value.
1191 case '[object RegExp]':
1192 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
1193 case '[object String]':
1194 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
1195 // equivalent to `new String("5")`.
1196 return '' + a === '' + b;
1197 case '[object Number]':
1198 // `NaN`s are equivalent, but non-reflexive.
1199 // Object(NaN) is equivalent to NaN
1200 if (+a !== +a) return +b !== +b;
1201 // An `egal` comparison is performed for other numeric values.
1202 return +a === 0 ? 1 / +a === 1 / b : +a === +b;
1203 case '[object Date]':
1204 case '[object Boolean]':
1205 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1206 // millisecond representations. Note that invalid dates with millisecond representations
1207 // of `NaN` are not equivalent.
1208 return +a === +b;
1209 }
1210
1211 var areArrays = className === '[object Array]';
1212 if (!areArrays) {
1213 if (typeof a != 'object' || typeof b != 'object') return false;
1214
1215 // Objects with different constructors are not equivalent, but `Object`s or `Array`s
1216 // from different frames are.
1217 var aCtor = a.constructor, bCtor = b.constructor;
1218 if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
1219 _.isFunction(bCtor) && bCtor instanceof bCtor)
1220 && ('constructor' in a && 'constructor' in b)) {
1221 return false;
1222 }
1223 }
1224 // Assume equality for cyclic structures. The algorithm for detecting cyclic
1225 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1226
1227 // Initializing stack of traversed objects.
1228 // It's done here since we only need them for objects and arrays comparison.
1229 aStack = aStack || [];
1230 bStack = bStack || [];
1231 var length = aStack.length;
1232 while (length--) {
1233 // Linear search. Performance is inversely proportional to the number of
1234 // unique nested structures.
1235 if (aStack[length] === a) return bStack[length] === b;
1236 }
1237
1238 // Add the first object to the stack of traversed objects.
1239 aStack.push(a);
1240 bStack.push(b);
1241
1242 // Recursively compare objects and arrays.
1243 if (areArrays) {
1244 // Compare array lengths to determine if a deep comparison is necessary.
1245 length = a.length;
1246 if (length !== b.length) return false;
1247 // Deep compare the contents, ignoring non-numeric properties.
1248 while (length--) {
1249 if (!eq(a[length], b[length], aStack, bStack)) return false;
1250 }
1251 } else {
1252 // Deep compare objects.
1253 var keys = _.keys(a), key;
1254 length = keys.length;
1255 // Ensure that both objects contain the same number of properties before comparing deep equality.
1256 if (_.keys(b).length !== length) return false;
1257 while (length--) {
1258 // Deep compare each member
1259 key = keys[length];
1260 if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
1261 }
1262 }
1263 // Remove the first object from the stack of traversed objects.
1264 aStack.pop();
1265 bStack.pop();
1266 return true;
1267 };
1268
1269 // Perform a deep comparison to check if two objects are equal.
1270 _.isEqual = function(a, b) {
1271 return eq(a, b);
1272 };
1273
1274 // Is a given array, string, or object empty?
1275 // An "empty" object has no enumerable own-properties.
1276 _.isEmpty = function(obj) {
1277 if (obj == null) return true;
1278 if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
1279 return _.keys(obj).length === 0;
1280 };
1281
1282 // Is a given value a DOM element?
1283 _.isElement = function(obj) {
1284 return !!(obj && obj.nodeType === 1);
1285 };
1286
1287 // Is a given value an array?
1288 // Delegates to ECMA5's native Array.isArray
1289 _.isArray = nativeIsArray || function(obj) {
1290 return toString.call(obj) === '[object Array]';
1291 };
1292
1293 // Is a given variable an object?
1294 _.isObject = function(obj) {
1295 var type = typeof obj;
1296 return type === 'function' || type === 'object' && !!obj;
1297 };
1298
1299 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
1300 _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
1301 _['is' + name] = function(obj) {
1302 return toString.call(obj) === '[object ' + name + ']';
1303 };
1304 });
1305
1306 // Define a fallback version of the method in browsers (ahem, IE < 9), where
1307 // there isn't any inspectable "Arguments" type.
1308 if (!_.isArguments(arguments)) {
1309 _.isArguments = function(obj) {
1310 return _.has(obj, 'callee');
1311 };
1312 }
1313
1314 // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
1315 // IE 11 (#1621), and in Safari 8 (#1929).
1316 if (typeof /./ != 'function' && typeof Int8Array != 'object') {
1317 _.isFunction = function(obj) {
1318 return typeof obj == 'function' || false;
1319 };
1320 }
1321
1322 // Is a given object a finite number?
1323 _.isFinite = function(obj) {
1324 return isFinite(obj) && !isNaN(parseFloat(obj));
1325 };
1326
1327 // Is the given value `NaN`? (NaN is the only number which does not equal itself).
1328 _.isNaN = function(obj) {
1329 return _.isNumber(obj) && obj !== +obj;
1330 };
1331
1332 // Is a given value a boolean?
1333 _.isBoolean = function(obj) {
1334 return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
1335 };
1336
1337 // Is a given value equal to null?
1338 _.isNull = function(obj) {
1339 return obj === null;
1340 };
1341
1342 // Is a given variable undefined?
1343 _.isUndefined = function(obj) {
1344 return obj === void 0;
1345 };
1346
1347 // Shortcut function for checking if an object has a given property directly
1348 // on itself (in other words, not on a prototype).
1349 _.has = function(obj, key) {
1350 return obj != null && hasOwnProperty.call(obj, key);
1351 };
1352
1353 // Utility Functions
1354 // -----------------
1355
1356 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1357 // previous owner. Returns a reference to the Underscore object.
1358 _.noConflict = function() {
1359 root._ = previousUnderscore;
1360 return this;
1361 };
1362
1363 // Keep the identity function around for default iteratees.
1364 _.identity = function(value) {
1365 return value;
1366 };
1367
1368 // Predicate-generating functions. Often useful outside of Underscore.
1369 _.constant = function(value) {
1370 return function() {
1371 return value;
1372 };
1373 };
1374
1375 _.noop = function(){};
1376
1377 _.property = property;
1378
1379 // Generates a function for a given object that returns a given property.
1380 _.propertyOf = function(obj) {
1381 return obj == null ? function(){} : function(key) {
1382 return obj[key];
1383 };
1384 };
1385
1386 // Returns a predicate for checking whether an object has a given set of
1387 // `key:value` pairs.
1388 _.matcher = _.matches = function(attrs) {
1389 attrs = _.extendOwn({}, attrs);
1390 return function(obj) {
1391 return _.isMatch(obj, attrs);
1392 };
1393 };
1394
1395 // Run a function **n** times.
1396 _.times = function(n, iteratee, context) {
1397 var accum = Array(Math.max(0, n));
1398 iteratee = optimizeCb(iteratee, context, 1);
1399 for (var i = 0; i < n; i++) accum[i] = iteratee(i);
1400 return accum;
1401 };
1402
1403 // Return a random integer between min and max (inclusive).
1404 _.random = function(min, max) {
1405 if (max == null) {
1406 max = min;
1407 min = 0;
1408 }
1409 return min + Math.floor(Math.random() * (max - min + 1));
1410 };
1411
1412 // A (possibly faster) way to get the current timestamp as an integer.
1413 _.now = Date.now || function() {
1414 return new Date().getTime();
1415 };
1416
1417 // List of HTML entities for escaping.
1418 var escapeMap = {
1419 '&': '&',
1420 '<': '<',
1421 '>': '>',
1422 '"': '"',
1423 "'": ''',
1424 '`': '`'
1425 };
1426 var unescapeMap = _.invert(escapeMap);
1427
1428 // Functions for escaping and unescaping strings to/from HTML interpolation.
1429 var createEscaper = function(map) {
1430 var escaper = function(match) {
1431 return map[match];
1432 };
1433 // Regexes for identifying a key that needs to be escaped
1434 var source = '(?:' + _.keys(map).join('|') + ')';
1435 var testRegexp = RegExp(source);
1436 var replaceRegexp = RegExp(source, 'g');
1437 return function(string) {
1438 string = string == null ? '' : '' + string;
1439 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
1440 };
1441 };
1442 _.escape = createEscaper(escapeMap);
1443 _.unescape = createEscaper(unescapeMap);
1444
1445 // If the value of the named `property` is a function then invoke it with the
1446 // `object` as context; otherwise, return it.
1447 _.result = function(object, property, fallback) {
1448 var value = object == null ? void 0 : object[property];
1449 if (value === void 0) {
1450 value = fallback;
1451 }
1452 return _.isFunction(value) ? value.call(object) : value;
1453 };
1454
1455 // Generate a unique integer id (unique within the entire client session).
1456 // Useful for temporary DOM ids.
1457 var idCounter = 0;
1458 _.uniqueId = function(prefix) {
1459 var id = ++idCounter + '';
1460 return prefix ? prefix + id : id;
1461 };
1462
1463 // By default, Underscore uses ERB-style template delimiters, change the
1464 // following template settings to use alternative delimiters.
1465 _.templateSettings = {
1466 evaluate : /<%([\s\S]+?)%>/g,
1467 interpolate : /<%=([\s\S]+?)%>/g,
1468 escape : /<%-([\s\S]+?)%>/g
1469 };
1470
1471 // When customizing `templateSettings`, if you don't want to define an
1472 // interpolation, evaluation or escaping regex, we need one that is
1473 // guaranteed not to match.
1474 var noMatch = /(.)^/;
1475
1476 // Certain characters need to be escaped so that they can be put into a
1477 // string literal.
1478 var escapes = {
1479 "'": "'",
1480 '\\': '\\',
1481 '\r': 'r',
1482 '\n': 'n',
1483 '\u2028': 'u2028',
1484 '\u2029': 'u2029'
1485 };
1486
1487 var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
1488
1489 var escapeChar = function(match) {
1490 return '\\' + escapes[match];
1491 };
1492
1493 // JavaScript micro-templating, similar to John Resig's implementation.
1494 // Underscore templating handles arbitrary delimiters, preserves whitespace,
1495 // and correctly escapes quotes within interpolated code.
1496 // NB: `oldSettings` only exists for backwards compatibility.
1497 _.template = function(text, settings, oldSettings) {
1498 if (!settings && oldSettings) settings = oldSettings;
1499 settings = _.defaults({}, settings, _.templateSettings);
1500
1501 // Combine delimiters into one regular expression via alternation.
1502 var matcher = RegExp([
1503 (settings.escape || noMatch).source,
1504 (settings.interpolate || noMatch).source,
1505 (settings.evaluate || noMatch).source
1506 ].join('|') + '|$', 'g');
1507
1508 // Compile the template source, escaping string literals appropriately.
1509 var index = 0;
1510 var source = "__p+='";
1511 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1512 source += text.slice(index, offset).replace(escaper, escapeChar);
1513 index = offset + match.length;
1514
1515 if (escape) {
1516 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1517 } else if (interpolate) {
1518 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1519 } else if (evaluate) {
1520 source += "';\n" + evaluate + "\n__p+='";
1521 }
1522
1523 // Adobe VMs need the match returned to produce the correct offest.
1524 return match;
1525 });
1526 source += "';\n";
1527
1528 // If a variable is not specified, place data values in local scope.
1529 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1530
1531 source = "var __t,__p='',__j=Array.prototype.join," +
1532 "print=function(){__p+=__j.call(arguments,'');};\n" +
1533 source + 'return __p;\n';
1534
1535 try {
1536 var render = new Function(settings.variable || 'obj', '_', source);
1537 } catch (e) {
1538 e.source = source;
1539 throw e;
1540 }
1541
1542 var template = function(data) {
1543 return render.call(this, data, _);
1544 };
1545
1546 // Provide the compiled source as a convenience for precompilation.
1547 var argument = settings.variable || 'obj';
1548 template.source = 'function(' + argument + '){\n' + source + '}';
1549
1550 return template;
1551 };
1552
1553 // Add a "chain" function. Start chaining a wrapped Underscore object.
1554 _.chain = function(obj) {
1555 var instance = _(obj);
1556 instance._chain = true;
1557 return instance;
1558 };
1559
1560 // OOP
1561 // ---------------
1562 // If Underscore is called as a function, it returns a wrapped object that
1563 // can be used OO-style. This wrapper holds altered versions of all the
1564 // underscore functions. Wrapped objects may be chained.
1565
1566 // Helper function to continue chaining intermediate results.
1567 var result = function(instance, obj) {
1568 return instance._chain ? _(obj).chain() : obj;
1569 };
1570
1571 // Add your own custom functions to the Underscore object.
1572 _.mixin = function(obj) {
1573 _.each(_.functions(obj), function(name) {
1574 var func = _[name] = obj[name];
1575 _.prototype[name] = function() {
1576 var args = [this._wrapped];
1577 push.apply(args, arguments);
1578 return result(this, func.apply(_, args));
1579 };
1580 });
1581 };
1582
1583 // Add all of the Underscore functions to the wrapper object.
1584 _.mixin(_);
1585
1586 // Add all mutator Array functions to the wrapper.
1587 _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1588 var method = ArrayProto[name];
1589 _.prototype[name] = function() {
1590 var obj = this._wrapped;
1591 method.apply(obj, arguments);
1592 if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
1593 return result(this, obj);
1594 };
1595 });
1596
1597 // Add all accessor Array functions to the wrapper.
1598 _.each(['concat', 'join', 'slice'], function(name) {
1599 var method = ArrayProto[name];
1600 _.prototype[name] = function() {
1601 return result(this, method.apply(this._wrapped, arguments));
1602 };
1603 });
1604
1605 // Extracts the result from a wrapped and chained object.
1606 _.prototype.value = function() {
1607 return this._wrapped;
1608 };
1609
1610 // Provide unwrapping proxy for some methods used in engine operations
1611 // such as arithmetic and JSON stringification.
1612 _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
1613
1614 _.prototype.toString = function() {
1615 return '' + this._wrapped;
1616 };
1617
1618 // AMD registration happens at the end for compatibility with AMD loaders
1619 // that may not enforce next-turn semantics on modules. Even though general
1620 // practice for AMD registration is to be anonymous, underscore registers
1621 // as a named module because, like jQuery, it is a base library that is
1622 // popular enough to be bundled in a third party lib, but not be part of
1623 // an AMD load request. Those cases could generate an error when an
1624 // anonymous define() is called outside of a loader request.
1625 if (true) {
1626 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
1627 return _;
1628 }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1629 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1630 }
1631}.call(this));
1632
1633
1634/***/ }),
1635/* 1 */
1636/***/ (function(module, exports, __webpack_require__) {
1637
1638"use strict";
1639
1640
1641var _ = __webpack_require__(0);
1642var Promise = __webpack_require__(51).Promise;
1643
1644Promise._continueWhile = function (predicate, asyncFunction) {
1645 if (predicate()) {
1646 return asyncFunction().then(function () {
1647 return Promise._continueWhile(predicate, asyncFunction);
1648 });
1649 }
1650 return Promise.resolve();
1651};
1652
1653module.exports = Promise;
1654
1655/***/ }),
1656/* 2 */
1657/***/ (function(module, exports, __webpack_require__) {
1658
1659"use strict";
1660
1661
1662var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
1663
1664var request = __webpack_require__(7);
1665var debug = __webpack_require__(5)('leancloud:request');
1666var md5 = __webpack_require__(56);
1667var Promise = __webpack_require__(1);
1668var Cache = __webpack_require__(16);
1669var AVError = __webpack_require__(3);
1670var AV = __webpack_require__(6);
1671var _ = __webpack_require__(0);
1672
1673var _require = __webpack_require__(4),
1674 getSessionToken = _require.getSessionToken;
1675
1676var getServerURLPromise = void 0;
1677
1678// æœåŠ¡å™¨è¯·æ±‚çš„èŠ‚ç‚¹ host
1679var API_HOST = {
1680 cn: 'https://api.leancloud.cn',
1681 us: 'https://us-api.leancloud.cn'
1682};
1683
1684// 计算 X-LC-Sign çš„ç¾å方法
1685var sign = function sign(key, isMasterKey) {
1686 var now = new Date().getTime();
1687 var signature = md5(now + key);
1688 if (isMasterKey) {
1689 return signature + ',' + now + ',master';
1690 }
1691 return signature + ',' + now;
1692};
1693
1694var requestsCount = 0;
1695
1696var ajax = function ajax(method, resourceUrl, data) {
1697 var headers = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1698 var onprogress = arguments[4];
1699
1700 var count = requestsCount++;
1701
1702 debug('request(' + count + ')', method, resourceUrl, data, headers);
1703
1704 return new Promise(function (resolve, reject) {
1705 var req = request(method, resourceUrl).set(headers).send(data);
1706 if (onprogress) {
1707 req.on('progress', onprogress);
1708 }
1709 req.end(function (err, res) {
1710 if (res) {
1711 debug('response(' + count + ')', res.status, res.body || res.text, res.header);
1712 }
1713 if (err) {
1714 if (res) {
1715 err.statusCode = res.status;
1716 err.responseText = res.text;
1717 err.response = res.body;
1718 }
1719 return reject(err);
1720 }
1721 return resolve(res.body);
1722 });
1723 });
1724};
1725
1726var setAppId = function setAppId(headers, signKey) {
1727 if (signKey) {
1728 headers['X-LC-Sign'] = sign(AV.applicationKey);
1729 } else {
1730 headers['X-LC-Key'] = AV.applicationKey;
1731 }
1732};
1733
1734var setHeaders = function setHeaders() {
1735 var authOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1736 var signKey = arguments[1];
1737
1738 var headers = {
1739 'X-LC-Id': AV.applicationId,
1740 'Content-Type': 'application/json;charset=UTF-8'
1741 };
1742 var useMasterKey = false;
1743 if (typeof authOptions.useMasterKey === 'boolean') {
1744 useMasterKey = authOptions.useMasterKey;
1745 } else if (typeof AV._useMasterKey === 'boolean') {
1746 useMasterKey = AV._useMasterKey;
1747 }
1748 if (useMasterKey) {
1749 if (AV.masterKey) {
1750 if (signKey) {
1751 headers['X-LC-Sign'] = sign(AV.masterKey, true);
1752 } else {
1753 headers['X-LC-Key'] = AV.masterKey + ',master';
1754 }
1755 } else {
1756 console.warn('masterKey is not set, fall back to use appKey');
1757 setAppId(headers, signKey);
1758 }
1759 } else {
1760 setAppId(headers, signKey);
1761 }
1762 if (AV.hookKey) {
1763 headers['X-LC-Hook-Key'] = AV.hookKey;
1764 }
1765 if (AV._config.applicationProduction !== null) {
1766 headers['X-LC-Prod'] = String(AV._config.applicationProduction);
1767 }
1768 headers[ false ? 'User-Agent' : 'X-LC-UA'] = AV._config.userAgent;
1769
1770 return Promise.resolve().then(function () {
1771 // Pass the session token
1772 var sessionToken = getSessionToken(authOptions);
1773 if (sessionToken) {
1774 headers['X-LC-Session'] = sessionToken;
1775 } else if (!AV._config.disableCurrentUser) {
1776 return AV.User.currentAsync().then(function (currentUser) {
1777 if (currentUser && currentUser._sessionToken) {
1778 headers['X-LC-Session'] = currentUser._sessionToken;
1779 }
1780 return headers;
1781 });
1782 }
1783 return headers;
1784 });
1785};
1786
1787var createApiUrl = function createApiUrl(route, className, objectId, method, dataObject) {
1788 // TODO: 兼容 AV.serverURL æ—§æ–¹å¼è®¾ç½® API Host,åŽç»åŽ»æŽ‰
1789 if (AV.serverURL) {
1790 AV._config.APIServerURL = AV.serverURL;
1791 console.warn('Please use AV._config.APIServerURL to replace AV.serverURL, and it is an internal interface.');
1792 }
1793
1794 var apiURL = AV._config.APIServerURL || API_HOST.cn;
1795
1796 if (apiURL.charAt(apiURL.length - 1) !== '/') {
1797 apiURL += '/';
1798 }
1799 apiURL += '1.1/' + route;
1800 if (className) {
1801 apiURL += '/' + className;
1802 }
1803 if (objectId) {
1804 apiURL += '/' + objectId;
1805 }
1806 if ((route === 'users' || route === 'classes') && dataObject) {
1807 apiURL += '?';
1808 if (dataObject._fetchWhenSave) {
1809 delete dataObject._fetchWhenSave;
1810 apiURL += '&new=true';
1811 }
1812 if (dataObject._where) {
1813 apiURL += '&where=' + encodeURIComponent(JSON.stringify(dataObject._where));
1814 delete dataObject._where;
1815 }
1816 }
1817
1818 if (method.toLowerCase() === 'get') {
1819 if (apiURL.indexOf('?') === -1) {
1820 apiURL += '?';
1821 }
1822 for (var k in dataObject) {
1823 if (_typeof(dataObject[k]) === 'object') {
1824 dataObject[k] = JSON.stringify(dataObject[k]);
1825 }
1826 apiURL += '&' + k + '=' + encodeURIComponent(dataObject[k]);
1827 }
1828 }
1829
1830 return apiURL;
1831};
1832
1833var cacheServerURL = function cacheServerURL(serverURL, ttl) {
1834 if (typeof ttl !== 'number') {
1835 ttl = 3600;
1836 }
1837 return Cache.setAsync('APIServerURL', serverURL, ttl * 1000);
1838};
1839
1840// handle AV._request Error
1841var handleError = function handleError(error) {
1842 return new Promise(function (resolve, reject) {
1843 /**
1844 When API request need to redirect to the right location,
1845 can't use browser redirect by http status 307, as the reason of CORS,
1846 so API server response http status 410 and the param "location" for this case.
1847 */
1848 if (error.statusCode === 410) {
1849 cacheServerURL(error.response.api_server, error.response.ttl).then(function () {
1850 resolve(error.response.location);
1851 }).catch(reject);
1852 } else {
1853 var errorJSON = {
1854 code: error.code || -1,
1855 error: error.message || error.responseText
1856 };
1857 if (error.response && error.response.code) {
1858 errorJSON = error.response;
1859 } else if (error.responseText) {
1860 try {
1861 errorJSON = JSON.parse(error.responseText);
1862 } catch (e) {
1863 // If we fail to parse the error text, that's okay.
1864 }
1865 }
1866
1867 // Transform the error into an instance of AVError by trying to parse
1868 // the error string as JSON.
1869 reject(new AVError(errorJSON.code, errorJSON.error));
1870 }
1871 });
1872};
1873
1874var setServerUrl = function setServerUrl(serverURL) {
1875 AV._config.APIServerURL = 'https://' + serverURL;
1876
1877 // æ ¹æ®æ–° URL 釿–°è®¾ç½®åŒºåŸŸ
1878 var newRegion = _.findKey(API_HOST, function (item) {
1879 return item === AV._config.APIServerURL;
1880 });
1881 if (newRegion) {
1882 AV._config.region = newRegion;
1883 }
1884};
1885
1886var refreshServerUrlByRouter = function refreshServerUrlByRouter() {
1887 var url = 'https://app-router.leancloud.cn/1/route?appId=' + AV.applicationId;
1888 return ajax('get', url).then(function (servers) {
1889 if (servers.api_server) {
1890 setServerUrl(servers.api_server);
1891 return cacheServerURL(servers.api_server, servers.ttl);
1892 }
1893 }, function (error) {
1894 // bypass all non-4XX errors
1895 if (error.statusCode >= 400 && error.statusCode < 500) {
1896 throw error;
1897 }
1898 });
1899};
1900
1901var setServerUrlByRegion = function setServerUrlByRegion() {
1902 var region = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'cn';
1903
1904 getServerURLPromise = new Promise(function (resolve, reject) {
1905 // 如果用户在 init 之å‰è®¾ç½®äº† APIServerURL,则跳过请求 router
1906 if (AV._config.APIServerURL) {
1907 resolve();
1908 return;
1909 }
1910 // if not china server region, do not use router
1911 if (region === 'cn') {
1912 return Cache.getAsync('APIServerURL').then(function (serverURL) {
1913 if (serverURL) {
1914 setServerUrl(serverURL);
1915 } else {
1916 return refreshServerUrlByRouter();
1917 }
1918 }).then(function () {
1919 resolve();
1920 }).catch(function (error) {
1921 reject(error);
1922 });
1923 } else {
1924 AV._config.region = region;
1925 AV._config.APIServerURL = API_HOST[region];
1926 resolve();
1927 }
1928 });
1929};
1930
1931/**
1932 * route is classes, users, login, etc.
1933 * objectId is null if there is no associated objectId.
1934 * method is the http method for the REST API.
1935 * dataObject is the payload as an object, or null if there is none.
1936 * @ignore
1937 */
1938var AVRequest = function AVRequest(route, className, objectId, method) {
1939 var dataObject = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
1940 var authOptions = arguments[5];
1941
1942 if (!AV.applicationId) {
1943 throw new Error('You must specify your applicationId using AV.init()');
1944 }
1945
1946 if (!AV.applicationKey && !AV.masterKey) {
1947 throw new Error('You must specify a AppKey using AV.init()');
1948 }
1949
1950 if (!getServerURLPromise) {
1951 return Promise.reject(new Error('Not initialized'));
1952 }
1953 return getServerURLPromise.then(function () {
1954 var apiURL = createApiUrl(route, className, objectId, method, dataObject);
1955 return setHeaders(authOptions).then(function (headers) {
1956 return ajax(method, apiURL, dataObject, headers).then(null, function (res) {
1957 return handleError(res).then(function (location) {
1958 return ajax(method, location, dataObject, headers);
1959 });
1960 });
1961 });
1962 });
1963};
1964
1965module.exports = {
1966 ajax: ajax,
1967 request: AVRequest,
1968 setServerUrlByRegion: setServerUrlByRegion
1969};
1970
1971/***/ }),
1972/* 3 */
1973/***/ (function(module, exports, __webpack_require__) {
1974
1975"use strict";
1976
1977
1978var _ = __webpack_require__(0);
1979
1980/**
1981 * @class AV.Error
1982 */
1983
1984function AVError(code, message) {
1985 var error = new Error(message);
1986 error.code = code;
1987 return error;
1988}
1989
1990_.extend(AVError, /** @lends AV.Error */{
1991 /**
1992 * Error code indicating some error other than those enumerated here.
1993 * @constant
1994 */
1995 OTHER_CAUSE: -1,
1996
1997 /**
1998 * Error code indicating that something has gone wrong with the server.
1999 * If you get this error code, it is AV's fault. Contact us at
2000 * https://avoscloud.com/help
2001 * @constant
2002 */
2003 INTERNAL_SERVER_ERROR: 1,
2004
2005 /**
2006 * Error code indicating the connection to the AV servers failed.
2007 * @constant
2008 */
2009 CONNECTION_FAILED: 100,
2010
2011 /**
2012 * Error code indicating the specified object doesn't exist.
2013 * @constant
2014 */
2015 OBJECT_NOT_FOUND: 101,
2016
2017 /**
2018 * Error code indicating you tried to query with a datatype that doesn't
2019 * support it, like exact matching an array or object.
2020 * @constant
2021 */
2022 INVALID_QUERY: 102,
2023
2024 /**
2025 * Error code indicating a missing or invalid classname. Classnames are
2026 * case-sensitive. They must start with a letter, and a-zA-Z0-9_ are the
2027 * only valid characters.
2028 * @constant
2029 */
2030 INVALID_CLASS_NAME: 103,
2031
2032 /**
2033 * Error code indicating an unspecified object id.
2034 * @constant
2035 */
2036 MISSING_OBJECT_ID: 104,
2037
2038 /**
2039 * Error code indicating an invalid key name. Keys are case-sensitive. They
2040 * must start with a letter, and a-zA-Z0-9_ are the only valid characters.
2041 * @constant
2042 */
2043 INVALID_KEY_NAME: 105,
2044
2045 /**
2046 * Error code indicating a malformed pointer. You should not see this unless
2047 * you have been mucking about changing internal AV code.
2048 * @constant
2049 */
2050 INVALID_POINTER: 106,
2051
2052 /**
2053 * Error code indicating that badly formed JSON was received upstream. This
2054 * either indicates you have done something unusual with modifying how
2055 * things encode to JSON, or the network is failing badly.
2056 * @constant
2057 */
2058 INVALID_JSON: 107,
2059
2060 /**
2061 * Error code indicating that the feature you tried to access is only
2062 * available internally for testing purposes.
2063 * @constant
2064 */
2065 COMMAND_UNAVAILABLE: 108,
2066
2067 /**
2068 * You must call AV.initialize before using the AV library.
2069 * @constant
2070 */
2071 NOT_INITIALIZED: 109,
2072
2073 /**
2074 * Error code indicating that a field was set to an inconsistent type.
2075 * @constant
2076 */
2077 INCORRECT_TYPE: 111,
2078
2079 /**
2080 * Error code indicating an invalid channel name. A channel name is either
2081 * an empty string (the broadcast channel) or contains only a-zA-Z0-9_
2082 * characters.
2083 * @constant
2084 */
2085 INVALID_CHANNEL_NAME: 112,
2086
2087 /**
2088 * Error code indicating that push is misconfigured.
2089 * @constant
2090 */
2091 PUSH_MISCONFIGURED: 115,
2092
2093 /**
2094 * Error code indicating that the object is too large.
2095 * @constant
2096 */
2097 OBJECT_TOO_LARGE: 116,
2098
2099 /**
2100 * Error code indicating that the operation isn't allowed for clients.
2101 * @constant
2102 */
2103 OPERATION_FORBIDDEN: 119,
2104
2105 /**
2106 * Error code indicating the result was not found in the cache.
2107 * @constant
2108 */
2109 CACHE_MISS: 120,
2110
2111 /**
2112 * Error code indicating that an invalid key was used in a nested
2113 * JSONObject.
2114 * @constant
2115 */
2116 INVALID_NESTED_KEY: 121,
2117
2118 /**
2119 * Error code indicating that an invalid filename was used for AVFile.
2120 * A valid file name contains only a-zA-Z0-9_. characters and is between 1
2121 * and 128 characters.
2122 * @constant
2123 */
2124 INVALID_FILE_NAME: 122,
2125
2126 /**
2127 * Error code indicating an invalid ACL was provided.
2128 * @constant
2129 */
2130 INVALID_ACL: 123,
2131
2132 /**
2133 * Error code indicating that the request timed out on the server. Typically
2134 * this indicates that the request is too expensive to run.
2135 * @constant
2136 */
2137 TIMEOUT: 124,
2138
2139 /**
2140 * Error code indicating that the email address was invalid.
2141 * @constant
2142 */
2143 INVALID_EMAIL_ADDRESS: 125,
2144
2145 /**
2146 * Error code indicating a missing content type.
2147 * @constant
2148 */
2149 MISSING_CONTENT_TYPE: 126,
2150
2151 /**
2152 * Error code indicating a missing content length.
2153 * @constant
2154 */
2155 MISSING_CONTENT_LENGTH: 127,
2156
2157 /**
2158 * Error code indicating an invalid content length.
2159 * @constant
2160 */
2161 INVALID_CONTENT_LENGTH: 128,
2162
2163 /**
2164 * Error code indicating a file that was too large.
2165 * @constant
2166 */
2167 FILE_TOO_LARGE: 129,
2168
2169 /**
2170 * Error code indicating an error saving a file.
2171 * @constant
2172 */
2173 FILE_SAVE_ERROR: 130,
2174
2175 /**
2176 * Error code indicating an error deleting a file.
2177 * @constant
2178 */
2179 FILE_DELETE_ERROR: 153,
2180
2181 /**
2182 * Error code indicating that a unique field was given a value that is
2183 * already taken.
2184 * @constant
2185 */
2186 DUPLICATE_VALUE: 137,
2187
2188 /**
2189 * Error code indicating that a role's name is invalid.
2190 * @constant
2191 */
2192 INVALID_ROLE_NAME: 139,
2193
2194 /**
2195 * Error code indicating that an application quota was exceeded. Upgrade to
2196 * resolve.
2197 * @constant
2198 */
2199 EXCEEDED_QUOTA: 140,
2200
2201 /**
2202 * Error code indicating that a Cloud Code script failed.
2203 * @constant
2204 */
2205 SCRIPT_FAILED: 141,
2206
2207 /**
2208 * Error code indicating that a Cloud Code validation failed.
2209 * @constant
2210 */
2211 VALIDATION_ERROR: 142,
2212
2213 /**
2214 * Error code indicating that invalid image data was provided.
2215 * @constant
2216 */
2217 INVALID_IMAGE_DATA: 150,
2218
2219 /**
2220 * Error code indicating an unsaved file.
2221 * @constant
2222 */
2223 UNSAVED_FILE_ERROR: 151,
2224
2225 /**
2226 * Error code indicating an invalid push time.
2227 */
2228 INVALID_PUSH_TIME_ERROR: 152,
2229
2230 /**
2231 * Error code indicating that the username is missing or empty.
2232 * @constant
2233 */
2234 USERNAME_MISSING: 200,
2235
2236 /**
2237 * Error code indicating that the password is missing or empty.
2238 * @constant
2239 */
2240 PASSWORD_MISSING: 201,
2241
2242 /**
2243 * Error code indicating that the username has already been taken.
2244 * @constant
2245 */
2246 USERNAME_TAKEN: 202,
2247
2248 /**
2249 * Error code indicating that the email has already been taken.
2250 * @constant
2251 */
2252 EMAIL_TAKEN: 203,
2253
2254 /**
2255 * Error code indicating that the email is missing, but must be specified.
2256 * @constant
2257 */
2258 EMAIL_MISSING: 204,
2259
2260 /**
2261 * Error code indicating that a user with the specified email was not found.
2262 * @constant
2263 */
2264 EMAIL_NOT_FOUND: 205,
2265
2266 /**
2267 * Error code indicating that a user object without a valid session could
2268 * not be altered.
2269 * @constant
2270 */
2271 SESSION_MISSING: 206,
2272
2273 /**
2274 * Error code indicating that a user can only be created through signup.
2275 * @constant
2276 */
2277 MUST_CREATE_USER_THROUGH_SIGNUP: 207,
2278
2279 /**
2280 * Error code indicating that an an account being linked is already linked
2281 * to another user.
2282 * @constant
2283 */
2284 ACCOUNT_ALREADY_LINKED: 208,
2285
2286 /**
2287 * Error code indicating that a user cannot be linked to an account because
2288 * that account's id could not be found.
2289 * @constant
2290 */
2291 LINKED_ID_MISSING: 250,
2292
2293 /**
2294 * Error code indicating that a user with a linked (e.g. Facebook) account
2295 * has an invalid session.
2296 * @constant
2297 */
2298 INVALID_LINKED_SESSION: 251,
2299
2300 /**
2301 * Error code indicating that a service being linked (e.g. Facebook or
2302 * Twitter) is unsupported.
2303 * @constant
2304 */
2305 UNSUPPORTED_SERVICE: 252,
2306 /**
2307 * Error code indicating a real error code is unavailable because
2308 * we had to use an XDomainRequest object to allow CORS requests in
2309 * Internet Explorer, which strips the body from HTTP responses that have
2310 * a non-2XX status code.
2311 * @constant
2312 */
2313 X_DOMAIN_REQUEST: 602
2314});
2315
2316module.exports = AVError;
2317
2318/***/ }),
2319/* 4 */
2320/***/ (function(module, exports, __webpack_require__) {
2321
2322"use strict";
2323
2324
2325var _ = __webpack_require__(0);
2326
2327// Helper function to check null or undefined.
2328var isNullOrUndefined = function isNullOrUndefined(x) {
2329 return _.isNull(x) || _.isUndefined(x);
2330};
2331
2332var ensureArray = function ensureArray(target) {
2333 if (_.isArray(target)) {
2334 return target;
2335 }
2336 if (target === undefined || target === null) {
2337 return [];
2338 }
2339 return [target];
2340};
2341
2342var getSessionToken = function getSessionToken(authOptions) {
2343 if (authOptions.sessionToken) {
2344 return authOptions.sessionToken;
2345 }
2346 if (authOptions.user && typeof authOptions.user.getSessionToken === 'function') {
2347 return authOptions.user.getSessionToken();
2348 }
2349};
2350
2351var tap = function tap(interceptor) {
2352 return function (value) {
2353 return interceptor(value), value;
2354 };
2355};
2356
2357module.exports = {
2358 isNullOrUndefined: isNullOrUndefined,
2359 ensureArray: ensureArray,
2360 getSessionToken: getSessionToken,
2361 tap: tap
2362};
2363
2364/***/ }),
2365/* 5 */
2366/***/ (function(module, exports, __webpack_require__) {
2367
2368/**
2369 * This is the web browser implementation of `debug()`.
2370 *
2371 * Expose `debug()` as the module.
2372 */
2373
2374exports = module.exports = __webpack_require__(50);
2375exports.log = log;
2376exports.formatArgs = formatArgs;
2377exports.save = save;
2378exports.load = load;
2379exports.useColors = useColors;
2380exports.storage = 'undefined' != typeof chrome
2381 && 'undefined' != typeof chrome.storage
2382 ? chrome.storage.local
2383 : localstorage();
2384
2385/**
2386 * Colors.
2387 */
2388
2389exports.colors = [
2390 'lightseagreen',
2391 'forestgreen',
2392 'goldenrod',
2393 'dodgerblue',
2394 'darkorchid',
2395 'crimson'
2396];
2397
2398/**
2399 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
2400 * and the Firebug extension (any Firefox version) are known
2401 * to support "%c" CSS customizations.
2402 *
2403 * TODO: add a `localStorage` variable to explicitly enable/disable colors
2404 */
2405
2406function useColors() {
2407 // NB: In an Electron preload script, document will be defined but not fully
2408 // initialized. Since we know we're in Chrome, we'll just detect this case
2409 // explicitly
2410 if (typeof window !== 'undefined' && window && typeof window.process !== 'undefined' && window.process.type === 'renderer') {
2411 return true;
2412 }
2413
2414 // is webkit? http://stackoverflow.com/a/16459606/376773
2415 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
2416 return (typeof document !== 'undefined' && document && 'WebkitAppearance' in document.documentElement.style) ||
2417 // is firebug? http://stackoverflow.com/a/398120/376773
2418 (typeof window !== 'undefined' && window && window.console && (console.firebug || (console.exception && console.table))) ||
2419 // is firefox >= v31?
2420 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
2421 (typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
2422 // double check webkit in userAgent just in case we are in a worker
2423 (typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
2424}
2425
2426/**
2427 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
2428 */
2429
2430exports.formatters.j = function(v) {
2431 try {
2432 return JSON.stringify(v);
2433 } catch (err) {
2434 return '[UnexpectedJSONParseError]: ' + err.message;
2435 }
2436};
2437
2438
2439/**
2440 * Colorize log arguments if enabled.
2441 *
2442 * @api public
2443 */
2444
2445function formatArgs(args) {
2446 var useColors = this.useColors;
2447
2448 args[0] = (useColors ? '%c' : '')
2449 + this.namespace
2450 + (useColors ? ' %c' : ' ')
2451 + args[0]
2452 + (useColors ? '%c ' : ' ')
2453 + '+' + exports.humanize(this.diff);
2454
2455 if (!useColors) return;
2456
2457 var c = 'color: ' + this.color;
2458 args.splice(1, 0, c, 'color: inherit')
2459
2460 // the final "%c" is somewhat tricky, because there could be other
2461 // arguments passed either before or after the %c, so we need to
2462 // figure out the correct index to insert the CSS into
2463 var index = 0;
2464 var lastC = 0;
2465 args[0].replace(/%[a-zA-Z%]/g, function(match) {
2466 if ('%%' === match) return;
2467 index++;
2468 if ('%c' === match) {
2469 // we only are interested in the *last* %c
2470 // (the user may have provided their own)
2471 lastC = index;
2472 }
2473 });
2474
2475 args.splice(lastC, 0, c);
2476}
2477
2478/**
2479 * Invokes `console.log()` when available.
2480 * No-op when `console.log` is not a "function".
2481 *
2482 * @api public
2483 */
2484
2485function log() {
2486 // this hackery is required for IE8/9, where
2487 // the `console.log` function doesn't have 'apply'
2488 return 'object' === typeof console
2489 && console.log
2490 && Function.prototype.apply.call(console.log, console, arguments);
2491}
2492
2493/**
2494 * Save `namespaces`.
2495 *
2496 * @param {String} namespaces
2497 * @api private
2498 */
2499
2500function save(namespaces) {
2501 try {
2502 if (null == namespaces) {
2503 exports.storage.removeItem('debug');
2504 } else {
2505 exports.storage.debug = namespaces;
2506 }
2507 } catch(e) {}
2508}
2509
2510/**
2511 * Load `namespaces`.
2512 *
2513 * @return {String} returns the previously persisted debug modes
2514 * @api private
2515 */
2516
2517function load() {
2518 try {
2519 return exports.storage.debug;
2520 } catch(e) {}
2521
2522 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
2523 if (typeof process !== 'undefined' && 'env' in process) {
2524 return process.env.DEBUG;
2525 }
2526}
2527
2528/**
2529 * Enable namespaces listed in `localStorage.debug` initially.
2530 */
2531
2532exports.enable(load());
2533
2534/**
2535 * Localstorage attempts to return the localstorage.
2536 *
2537 * This is necessary because safari throws
2538 * when a user disables cookies/localstorage
2539 * and you attempt to access it.
2540 *
2541 * @return {LocalStorage}
2542 * @api private
2543 */
2544
2545function localstorage() {
2546 try {
2547 return window.localStorage;
2548 } catch (e) {}
2549}
2550
2551
2552/***/ }),
2553/* 6 */
2554/***/ (function(module, exports, __webpack_require__) {
2555
2556"use strict";
2557/* WEBPACK VAR INJECTION */(function(global) {
2558
2559var _ = __webpack_require__(0);
2560var userAgent = __webpack_require__(41);
2561
2562var _require = __webpack_require__(4),
2563 isNullOrUndefined = _require.isNullOrUndefined;
2564
2565var AV = global.AV || {};
2566
2567// All internal configuration items
2568AV._config = AV._config || {};
2569var AVConfig = AV._config;
2570
2571_.extend(AVConfig, {
2572
2573 // æœåŠ¡å™¨èŠ‚ç‚¹åœ°åŒºï¼Œé»˜è®¤ä¸å›½å¤§é™†
2574 region: 'cn',
2575
2576 // æœåŠ¡å™¨çš„ URL,默认åˆå§‹åŒ–时被设置为大陆节点地å€
2577 APIServerURL: AVConfig.APIServerURL || '',
2578
2579 // ç¦ç”¨ currentUser,通常用于多用户环境
2580 disableCurrentUser: false,
2581
2582 // Internal config can modifie the UserAgent
2583 userAgent: userAgent,
2584
2585 // set production environment or test environment
2586 // 1: production environment, 0: test environment, null: default environment
2587 applicationProduction: null
2588});
2589
2590/**
2591 * Contains all AV API classes and functions.
2592 * @namespace AV
2593 */
2594
2595// Helpers
2596// -------
2597
2598// Shared empty constructor function to aid in prototype-chain creation.
2599var EmptyConstructor = function EmptyConstructor() {};
2600
2601// Helper function to correctly set up the prototype chain, for subclasses.
2602// Similar to `goog.inherits`, but uses a hash of prototype properties and
2603// class properties to be extended.
2604var inherits = function inherits(parent, protoProps, staticProps) {
2605 var child;
2606
2607 // The constructor function for the new subclass is either defined by you
2608 // (the "constructor" property in your `extend` definition), or defaulted
2609 // by us to simply call the parent's constructor.
2610 if (protoProps && protoProps.hasOwnProperty('constructor')) {
2611 child = protoProps.constructor;
2612 } else {
2613 /** @ignore */
2614 child = function child() {
2615 parent.apply(this, arguments);
2616 };
2617 }
2618
2619 // Inherit class (static) properties from parent.
2620 _.extend(child, parent);
2621
2622 // Set the prototype chain to inherit from `parent`, without calling
2623 // `parent`'s constructor function.
2624 EmptyConstructor.prototype = parent.prototype;
2625 child.prototype = new EmptyConstructor();
2626
2627 // Add prototype properties (instance properties) to the subclass,
2628 // if supplied.
2629 if (protoProps) {
2630 _.extend(child.prototype, protoProps);
2631 }
2632
2633 // Add static properties to the constructor function, if supplied.
2634 if (staticProps) {
2635 _.extend(child, staticProps);
2636 }
2637
2638 // Correctly set child's `prototype.constructor`.
2639 child.prototype.constructor = child;
2640
2641 // Set a convenience property in case the parent's prototype is
2642 // needed later.
2643 child.__super__ = parent.prototype;
2644
2645 return child;
2646};
2647
2648/**
2649 * Call this method to set production environment variable.
2650 * @function AV.setProduction
2651 * @param {Boolean} production True is production environment,and
2652 * it's true by default.
2653 */
2654AV.setProduction = function (production) {
2655 if (!isNullOrUndefined(production)) {
2656 AVConfig.applicationProduction = production ? 1 : 0;
2657 } else {
2658 // change to default value
2659 AVConfig.applicationProduction = null;
2660 }
2661};
2662
2663/**
2664 * Returns prefix for localStorage keys used by this instance of AV.
2665 * @param {String} path The relative suffix to append to it.
2666 * null or undefined is treated as the empty string.
2667 * @return {String} The full key name.
2668 * @private
2669 */
2670AV._getAVPath = function (path) {
2671 if (!AV.applicationId) {
2672 throw new Error("You need to call AV.initialize before using AV.");
2673 }
2674 if (!path) {
2675 path = "";
2676 }
2677 if (!_.isString(path)) {
2678 throw new Error("Tried to get a localStorage path that wasn't a String.");
2679 }
2680 if (path[0] === "/") {
2681 path = path.substring(1);
2682 }
2683 return "AV/" + AV.applicationId + "/" + path;
2684};
2685
2686/**
2687 * Returns the unique string for this app on this machine.
2688 * Gets reset when localStorage is cleared.
2689 * @private
2690 */
2691AV._installationId = null;
2692AV._getInstallationId = function () {
2693 // See if it's cached in RAM.
2694 if (AV._installationId) {
2695 return AV.Promise.resolve(AV._installationId);
2696 }
2697
2698 // Try to get it from localStorage.
2699 var path = AV._getAVPath("installationId");
2700 return AV.localStorage.getItemAsync(path).then(function (_installationId) {
2701 AV._installationId = _installationId;
2702 if (!AV._installationId) {
2703 // It wasn't in localStorage, so create a new one.
2704 var hexOctet = function hexOctet() {
2705 return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
2706 };
2707 AV._installationId = hexOctet() + hexOctet() + "-" + hexOctet() + "-" + hexOctet() + "-" + hexOctet() + "-" + hexOctet() + hexOctet() + hexOctet();
2708 return AV.localStorage.setItemAsync(path, AV._installationId);
2709 } else {
2710 return _installationId;
2711 }
2712 });
2713};
2714
2715AV._parseDate = function (iso8601) {
2716 var regexp = new RegExp("^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2})" + "T" + "([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})" + "(.([0-9]+))?" + "Z$");
2717 var match = regexp.exec(iso8601);
2718 if (!match) {
2719 return null;
2720 }
2721
2722 var year = match[1] || 0;
2723 var month = (match[2] || 1) - 1;
2724 var day = match[3] || 0;
2725 var hour = match[4] || 0;
2726 var minute = match[5] || 0;
2727 var second = match[6] || 0;
2728 var milli = match[8] || 0;
2729
2730 return new Date(Date.UTC(year, month, day, hour, minute, second, milli));
2731};
2732
2733// A self-propagating extend function.
2734AV._extend = function (protoProps, classProps) {
2735 var child = inherits(this, protoProps, classProps);
2736 child.extend = this.extend;
2737 return child;
2738};
2739
2740// Helper function to get a value from a Backbone object as a property
2741// or as a function.
2742AV._getValue = function (object, prop) {
2743 if (!(object && object[prop])) {
2744 return null;
2745 }
2746 return _.isFunction(object[prop]) ? object[prop]() : object[prop];
2747};
2748
2749/**
2750 * Converts a value in a AV Object into the appropriate representation.
2751 * This is the JS equivalent of Java's AV.maybeReferenceAndEncode(Object)
2752 * if seenObjects is falsey. Otherwise any AV.Objects not in
2753 * seenObjects will be fully embedded rather than encoded
2754 * as a pointer. This array will be used to prevent going into an infinite
2755 * loop because we have circular references. If <seenObjects>
2756 * is set, then none of the AV Objects that are serialized can be dirty.
2757 * @private
2758 */
2759AV._encode = function (value, seenObjects, disallowObjects) {
2760 if (value instanceof AV.Object) {
2761 if (disallowObjects) {
2762 throw new Error("AV.Objects not allowed here");
2763 }
2764 if (!seenObjects || _.include(seenObjects, value) || !value._hasData) {
2765 return value._toPointer();
2766 }
2767 if (!value.dirty()) {
2768 seenObjects = seenObjects.concat(value);
2769 return AV._encode(value._toFullJSON(seenObjects), seenObjects, disallowObjects);
2770 }
2771 throw new Error("Tried to save an object with a pointer to a new, unsaved object.");
2772 }
2773 if (value instanceof AV.ACL) {
2774 return value.toJSON();
2775 }
2776 if (_.isDate(value)) {
2777 return { "__type": "Date", "iso": value.toJSON() };
2778 }
2779 if (value instanceof AV.GeoPoint) {
2780 return value.toJSON();
2781 }
2782 if (_.isArray(value)) {
2783 return _.map(value, function (x) {
2784 return AV._encode(x, seenObjects, disallowObjects);
2785 });
2786 }
2787 if (_.isRegExp(value)) {
2788 return value.source;
2789 }
2790 if (value instanceof AV.Relation) {
2791 return value.toJSON();
2792 }
2793 if (value instanceof AV.Op) {
2794 return value.toJSON();
2795 }
2796 if (value instanceof AV.File) {
2797 if (!value.url() && !value.id) {
2798 throw new Error("Tried to save an object containing an unsaved file.");
2799 }
2800 return value._toFullJSON();
2801 }
2802 if (_.isObject(value)) {
2803 return _.mapObject(value, function (v, k) {
2804 return AV._encode(v, seenObjects, disallowObjects);
2805 });
2806 }
2807 return value;
2808};
2809
2810/**
2811 * The inverse function of AV._encode.
2812 * @private
2813 */
2814AV._decode = function (value, key) {
2815 if (!_.isObject(value) || _.isDate(value)) {
2816 return value;
2817 }
2818 if (_.isArray(value)) {
2819 return _.map(value, function (v) {
2820 return AV._decode(v);
2821 });
2822 }
2823 if (value instanceof AV.Object) {
2824 return value;
2825 }
2826 if (value instanceof AV.File) {
2827 return value;
2828 }
2829 if (value instanceof AV.Op) {
2830 return value;
2831 }
2832 if (value instanceof AV.GeoPoint) {
2833 return value;
2834 }
2835 if (value instanceof AV.ACL) {
2836 return value;
2837 }
2838 if (key === 'ACL') {
2839 return new AV.ACL(value);
2840 }
2841 if (value.__op) {
2842 return AV.Op._decode(value);
2843 }
2844 var className;
2845 if (value.__type === "Pointer") {
2846 className = value.className;
2847 var pointer = AV.Object._create(className);
2848 if (Object.keys(value).length > 3) {
2849 var v = _.clone(value);
2850 delete v.__type;
2851 delete v.className;
2852 pointer._finishFetch(v, true);
2853 } else {
2854 pointer._finishFetch({ objectId: value.objectId }, false);
2855 }
2856 return pointer;
2857 }
2858 if (value.__type === "Object") {
2859 // It's an Object included in a query result.
2860 className = value.className;
2861 var _v = _.clone(value);
2862 delete _v.__type;
2863 delete _v.className;
2864 var object = AV.Object._create(className);
2865 object._finishFetch(_v, true);
2866 return object;
2867 }
2868 if (value.__type === "Date") {
2869 return AV._parseDate(value.iso);
2870 }
2871 if (value.__type === "GeoPoint") {
2872 return new AV.GeoPoint({
2873 latitude: value.latitude,
2874 longitude: value.longitude
2875 });
2876 }
2877 if (value.__type === "Relation") {
2878 if (!key) throw new Error('key missing decoding a Relation');
2879 var relation = new AV.Relation(null, key);
2880 relation.targetClassName = value.className;
2881 return relation;
2882 }
2883 if (value.__type === 'File') {
2884 var file = new AV.File(value.name);
2885 var _v2 = _.clone(value);
2886 delete _v2.__type;
2887 file._finishFetch(_v2);
2888 return file;
2889 }
2890 return _.mapObject(value, AV._decode);
2891};
2892
2893AV._encodeObjectOrArray = function (value) {
2894 var encodeAVObject = function encodeAVObject(object) {
2895 if (object && object._toFullJSON) {
2896 object = object._toFullJSON([]);
2897 }
2898
2899 return _.mapObject(object, function (value) {
2900 return AV._encode(value, []);
2901 });
2902 };
2903
2904 if (_.isArray(value)) {
2905 return value.map(function (object) {
2906 return encodeAVObject(object);
2907 });
2908 } else {
2909 return encodeAVObject(value);
2910 }
2911};
2912
2913AV._arrayEach = _.each;
2914
2915/**
2916 * Does a deep traversal of every item in object, calling func on every one.
2917 * @param {Object} object The object or array to traverse deeply.
2918 * @param {Function} func The function to call for every item. It will
2919 * be passed the item as an argument. If it returns a truthy value, that
2920 * value will replace the item in its parent container.
2921 * @returns {} the result of calling func on the top-level object itself.
2922 * @private
2923 */
2924AV._traverse = function (object, func, seen) {
2925 if (object instanceof AV.Object) {
2926 seen = seen || [];
2927 if (_.indexOf(seen, object) >= 0) {
2928 // We've already visited this object in this call.
2929 return;
2930 }
2931 seen.push(object);
2932 AV._traverse(object.attributes, func, seen);
2933 return func(object);
2934 }
2935 if (object instanceof AV.Relation || object instanceof AV.File) {
2936 // Nothing needs to be done, but we don't want to recurse into the
2937 // object's parent infinitely, so we catch this case.
2938 return func(object);
2939 }
2940 if (_.isArray(object)) {
2941 _.each(object, function (child, index) {
2942 var newChild = AV._traverse(child, func, seen);
2943 if (newChild) {
2944 object[index] = newChild;
2945 }
2946 });
2947 return func(object);
2948 }
2949 if (_.isObject(object)) {
2950 AV._each(object, function (child, key) {
2951 var newChild = AV._traverse(child, func, seen);
2952 if (newChild) {
2953 object[key] = newChild;
2954 }
2955 });
2956 return func(object);
2957 }
2958 return func(object);
2959};
2960
2961/**
2962 * This is like _.each, except:
2963 * * it doesn't work for so-called array-like objects,
2964 * * it does work for dictionaries with a "length" attribute.
2965 * @private
2966 */
2967AV._objectEach = AV._each = function (obj, callback) {
2968 if (_.isObject(obj)) {
2969 _.each(_.keys(obj), function (key) {
2970 callback(obj[key], key);
2971 });
2972 } else {
2973 _.each(obj, callback);
2974 }
2975};
2976
2977module.exports = AV;
2978/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8)))
2979
2980/***/ }),
2981/* 7 */
2982/***/ (function(module, exports, __webpack_require__) {
2983
2984/**
2985 * Root reference for iframes.
2986 */
2987
2988var root;
2989if (typeof window !== 'undefined') { // Browser window
2990 root = window;
2991} else if (typeof self !== 'undefined') { // Web Worker
2992 root = self;
2993} else { // Other environments
2994 console.warn("Using browser-only version of superagent in non-browser environment");
2995 root = this;
2996}
2997
2998var Emitter = __webpack_require__(48);
2999var RequestBase = __webpack_require__(59);
3000var isObject = __webpack_require__(11);
3001var isFunction = __webpack_require__(58);
3002var ResponseBase = __webpack_require__(60);
3003var shouldRetry = __webpack_require__(61);
3004
3005/**
3006 * Noop.
3007 */
3008
3009function noop(){};
3010
3011/**
3012 * Expose `request`.
3013 */
3014
3015var request = exports = module.exports = function(method, url) {
3016 // callback
3017 if ('function' == typeof url) {
3018 return new exports.Request('GET', method).end(url);
3019 }
3020
3021 // url first
3022 if (1 == arguments.length) {
3023 return new exports.Request('GET', method);
3024 }
3025
3026 return new exports.Request(method, url);
3027}
3028
3029exports.Request = Request;
3030
3031/**
3032 * Determine XHR.
3033 */
3034
3035request.getXHR = function () {
3036 if (root.XMLHttpRequest
3037 && (!root.location || 'file:' != root.location.protocol
3038 || !root.ActiveXObject)) {
3039 return new XMLHttpRequest;
3040 } else {
3041 try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
3042 try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
3043 try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
3044 try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
3045 }
3046 throw Error("Browser-only verison of superagent could not find XHR");
3047};
3048
3049/**
3050 * Removes leading and trailing whitespace, added to support IE.
3051 *
3052 * @param {String} s
3053 * @return {String}
3054 * @api private
3055 */
3056
3057var trim = ''.trim
3058 ? function(s) { return s.trim(); }
3059 : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
3060
3061/**
3062 * Serialize the given `obj`.
3063 *
3064 * @param {Object} obj
3065 * @return {String}
3066 * @api private
3067 */
3068
3069function serialize(obj) {
3070 if (!isObject(obj)) return obj;
3071 var pairs = [];
3072 for (var key in obj) {
3073 pushEncodedKeyValuePair(pairs, key, obj[key]);
3074 }
3075 return pairs.join('&');
3076}
3077
3078/**
3079 * Helps 'serialize' with serializing arrays.
3080 * Mutates the pairs array.
3081 *
3082 * @param {Array} pairs
3083 * @param {String} key
3084 * @param {Mixed} val
3085 */
3086
3087function pushEncodedKeyValuePair(pairs, key, val) {
3088 if (val != null) {
3089 if (Array.isArray(val)) {
3090 val.forEach(function(v) {
3091 pushEncodedKeyValuePair(pairs, key, v);
3092 });
3093 } else if (isObject(val)) {
3094 for(var subkey in val) {
3095 pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]);
3096 }
3097 } else {
3098 pairs.push(encodeURIComponent(key)
3099 + '=' + encodeURIComponent(val));
3100 }
3101 } else if (val === null) {
3102 pairs.push(encodeURIComponent(key));
3103 }
3104}
3105
3106/**
3107 * Expose serialization method.
3108 */
3109
3110 request.serializeObject = serialize;
3111
3112 /**
3113 * Parse the given x-www-form-urlencoded `str`.
3114 *
3115 * @param {String} str
3116 * @return {Object}
3117 * @api private
3118 */
3119
3120function parseString(str) {
3121 var obj = {};
3122 var pairs = str.split('&');
3123 var pair;
3124 var pos;
3125
3126 for (var i = 0, len = pairs.length; i < len; ++i) {
3127 pair = pairs[i];
3128 pos = pair.indexOf('=');
3129 if (pos == -1) {
3130 obj[decodeURIComponent(pair)] = '';
3131 } else {
3132 obj[decodeURIComponent(pair.slice(0, pos))] =
3133 decodeURIComponent(pair.slice(pos + 1));
3134 }
3135 }
3136
3137 return obj;
3138}
3139
3140/**
3141 * Expose parser.
3142 */
3143
3144request.parseString = parseString;
3145
3146/**
3147 * Default MIME type map.
3148 *
3149 * superagent.types.xml = 'application/xml';
3150 *
3151 */
3152
3153request.types = {
3154 html: 'text/html',
3155 json: 'application/json',
3156 xml: 'application/xml',
3157 urlencoded: 'application/x-www-form-urlencoded',
3158 'form': 'application/x-www-form-urlencoded',
3159 'form-data': 'application/x-www-form-urlencoded'
3160};
3161
3162/**
3163 * Default serialization map.
3164 *
3165 * superagent.serialize['application/xml'] = function(obj){
3166 * return 'generated xml here';
3167 * };
3168 *
3169 */
3170
3171 request.serialize = {
3172 'application/x-www-form-urlencoded': serialize,
3173 'application/json': JSON.stringify
3174 };
3175
3176 /**
3177 * Default parsers.
3178 *
3179 * superagent.parse['application/xml'] = function(str){
3180 * return { object parsed from str };
3181 * };
3182 *
3183 */
3184
3185request.parse = {
3186 'application/x-www-form-urlencoded': parseString,
3187 'application/json': JSON.parse
3188};
3189
3190/**
3191 * Parse the given header `str` into
3192 * an object containing the mapped fields.
3193 *
3194 * @param {String} str
3195 * @return {Object}
3196 * @api private
3197 */
3198
3199function parseHeader(str) {
3200 var lines = str.split(/\r?\n/);
3201 var fields = {};
3202 var index;
3203 var line;
3204 var field;
3205 var val;
3206
3207 lines.pop(); // trailing CRLF
3208
3209 for (var i = 0, len = lines.length; i < len; ++i) {
3210 line = lines[i];
3211 index = line.indexOf(':');
3212 field = line.slice(0, index).toLowerCase();
3213 val = trim(line.slice(index + 1));
3214 fields[field] = val;
3215 }
3216
3217 return fields;
3218}
3219
3220/**
3221 * Check if `mime` is json or has +json structured syntax suffix.
3222 *
3223 * @param {String} mime
3224 * @return {Boolean}
3225 * @api private
3226 */
3227
3228function isJSON(mime) {
3229 return /[\/+]json\b/.test(mime);
3230}
3231
3232/**
3233 * Initialize a new `Response` with the given `xhr`.
3234 *
3235 * - set flags (.ok, .error, etc)
3236 * - parse header
3237 *
3238 * Examples:
3239 *
3240 * Aliasing `superagent` as `request` is nice:
3241 *
3242 * request = superagent;
3243 *
3244 * We can use the promise-like API, or pass callbacks:
3245 *
3246 * request.get('/').end(function(res){});
3247 * request.get('/', function(res){});
3248 *
3249 * Sending data can be chained:
3250 *
3251 * request
3252 * .post('/user')
3253 * .send({ name: 'tj' })
3254 * .end(function(res){});
3255 *
3256 * Or passed to `.send()`:
3257 *
3258 * request
3259 * .post('/user')
3260 * .send({ name: 'tj' }, function(res){});
3261 *
3262 * Or passed to `.post()`:
3263 *
3264 * request
3265 * .post('/user', { name: 'tj' })
3266 * .end(function(res){});
3267 *
3268 * Or further reduced to a single call for simple cases:
3269 *
3270 * request
3271 * .post('/user', { name: 'tj' }, function(res){});
3272 *
3273 * @param {XMLHTTPRequest} xhr
3274 * @param {Object} options
3275 * @api private
3276 */
3277
3278function Response(req) {
3279 this.req = req;
3280 this.xhr = this.req.xhr;
3281 // responseText is accessible only if responseType is '' or 'text' and on older browsers
3282 this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
3283 ? this.xhr.responseText
3284 : null;
3285 this.statusText = this.req.xhr.statusText;
3286 var status = this.xhr.status;
3287 // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
3288 if (status === 1223) {
3289 status = 204;
3290 }
3291 this._setStatusProperties(status);
3292 this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
3293 // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
3294 // getResponseHeader still works. so we get content-type even if getting
3295 // other headers fails.
3296 this.header['content-type'] = this.xhr.getResponseHeader('content-type');
3297 this._setHeaderProperties(this.header);
3298
3299 if (null === this.text && req._responseType) {
3300 this.body = this.xhr.response;
3301 } else {
3302 this.body = this.req.method != 'HEAD'
3303 ? this._parseBody(this.text ? this.text : this.xhr.response)
3304 : null;
3305 }
3306}
3307
3308ResponseBase(Response.prototype);
3309
3310/**
3311 * Parse the given body `str`.
3312 *
3313 * Used for auto-parsing of bodies. Parsers
3314 * are defined on the `superagent.parse` object.
3315 *
3316 * @param {String} str
3317 * @return {Mixed}
3318 * @api private
3319 */
3320
3321Response.prototype._parseBody = function(str){
3322 var parse = request.parse[this.type];
3323 if(this.req._parser) {
3324 return this.req._parser(this, str);
3325 }
3326 if (!parse && isJSON(this.type)) {
3327 parse = request.parse['application/json'];
3328 }
3329 return parse && str && (str.length || str instanceof Object)
3330 ? parse(str)
3331 : null;
3332};
3333
3334/**
3335 * Return an `Error` representative of this response.
3336 *
3337 * @return {Error}
3338 * @api public
3339 */
3340
3341Response.prototype.toError = function(){
3342 var req = this.req;
3343 var method = req.method;
3344 var url = req.url;
3345
3346 var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
3347 var err = new Error(msg);
3348 err.status = this.status;
3349 err.method = method;
3350 err.url = url;
3351
3352 return err;
3353};
3354
3355/**
3356 * Expose `Response`.
3357 */
3358
3359request.Response = Response;
3360
3361/**
3362 * Initialize a new `Request` with the given `method` and `url`.
3363 *
3364 * @param {String} method
3365 * @param {String} url
3366 * @api public
3367 */
3368
3369function Request(method, url) {
3370 var self = this;
3371 this._query = this._query || [];
3372 this.method = method;
3373 this.url = url;
3374 this.header = {}; // preserves header name case
3375 this._header = {}; // coerces header names to lowercase
3376 this.on('end', function(){
3377 var err = null;
3378 var res = null;
3379
3380 try {
3381 res = new Response(self);
3382 } catch(e) {
3383 err = new Error('Parser is unable to parse the response');
3384 err.parse = true;
3385 err.original = e;
3386 // issue #675: return the raw response if the response parsing fails
3387 if (self.xhr) {
3388 // ie9 doesn't have 'response' property
3389 err.rawResponse = typeof self.xhr.responseType == 'undefined' ? self.xhr.responseText : self.xhr.response;
3390 // issue #876: return the http status code if the response parsing fails
3391 err.status = self.xhr.status ? self.xhr.status : null;
3392 err.statusCode = err.status; // backwards-compat only
3393 } else {
3394 err.rawResponse = null;
3395 err.status = null;
3396 }
3397
3398 return self.callback(err);
3399 }
3400
3401 self.emit('response', res);
3402
3403 var new_err;
3404 try {
3405 if (!self._isResponseOK(res)) {
3406 new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
3407 new_err.original = err;
3408 new_err.response = res;
3409 new_err.status = res.status;
3410 }
3411 } catch(e) {
3412 new_err = e; // #985 touching res may cause INVALID_STATE_ERR on old Android
3413 }
3414
3415 // #1000 don't catch errors from the callback to avoid double calling it
3416 if (new_err) {
3417 self.callback(new_err, res);
3418 } else {
3419 self.callback(null, res);
3420 }
3421 });
3422}
3423
3424/**
3425 * Mixin `Emitter` and `RequestBase`.
3426 */
3427
3428Emitter(Request.prototype);
3429RequestBase(Request.prototype);
3430
3431/**
3432 * Set Content-Type to `type`, mapping values from `request.types`.
3433 *
3434 * Examples:
3435 *
3436 * superagent.types.xml = 'application/xml';
3437 *
3438 * request.post('/')
3439 * .type('xml')
3440 * .send(xmlstring)
3441 * .end(callback);
3442 *
3443 * request.post('/')
3444 * .type('application/xml')
3445 * .send(xmlstring)
3446 * .end(callback);
3447 *
3448 * @param {String} type
3449 * @return {Request} for chaining
3450 * @api public
3451 */
3452
3453Request.prototype.type = function(type){
3454 this.set('Content-Type', request.types[type] || type);
3455 return this;
3456};
3457
3458/**
3459 * Set Accept to `type`, mapping values from `request.types`.
3460 *
3461 * Examples:
3462 *
3463 * superagent.types.json = 'application/json';
3464 *
3465 * request.get('/agent')
3466 * .accept('json')
3467 * .end(callback);
3468 *
3469 * request.get('/agent')
3470 * .accept('application/json')
3471 * .end(callback);
3472 *
3473 * @param {String} accept
3474 * @return {Request} for chaining
3475 * @api public
3476 */
3477
3478Request.prototype.accept = function(type){
3479 this.set('Accept', request.types[type] || type);
3480 return this;
3481};
3482
3483/**
3484 * Set Authorization field value with `user` and `pass`.
3485 *
3486 * @param {String} user
3487 * @param {String} pass
3488 * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic')
3489 * @return {Request} for chaining
3490 * @api public
3491 */
3492
3493Request.prototype.auth = function(user, pass, options){
3494 if (!options) {
3495 options = {
3496 type: 'function' === typeof btoa ? 'basic' : 'auto',
3497 }
3498 }
3499
3500 switch (options.type) {
3501 case 'basic':
3502 this.set('Authorization', 'Basic ' + btoa(user + ':' + pass));
3503 break;
3504
3505 case 'auto':
3506 this.username = user;
3507 this.password = pass;
3508 break;
3509 }
3510 return this;
3511};
3512
3513/**
3514 * Add query-string `val`.
3515 *
3516 * Examples:
3517 *
3518 * request.get('/shoes')
3519 * .query('size=10')
3520 * .query({ color: 'blue' })
3521 *
3522 * @param {Object|String} val
3523 * @return {Request} for chaining
3524 * @api public
3525 */
3526
3527Request.prototype.query = function(val){
3528 if ('string' != typeof val) val = serialize(val);
3529 if (val) this._query.push(val);
3530 return this;
3531};
3532
3533/**
3534 * Queue the given `file` as an attachment to the specified `field`,
3535 * with optional `options` (or filename).
3536 *
3537 * ``` js
3538 * request.post('/upload')
3539 * .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
3540 * .end(callback);
3541 * ```
3542 *
3543 * @param {String} field
3544 * @param {Blob|File} file
3545 * @param {String|Object} options
3546 * @return {Request} for chaining
3547 * @api public
3548 */
3549
3550Request.prototype.attach = function(field, file, options){
3551 if (this._data) {
3552 throw Error("superagent can't mix .send() and .attach()");
3553 }
3554
3555 this._getFormData().append(field, file, options || file.name);
3556 return this;
3557};
3558
3559Request.prototype._getFormData = function(){
3560 if (!this._formData) {
3561 this._formData = new root.FormData();
3562 }
3563 return this._formData;
3564};
3565
3566/**
3567 * Invoke the callback with `err` and `res`
3568 * and handle arity check.
3569 *
3570 * @param {Error} err
3571 * @param {Response} res
3572 * @api private
3573 */
3574
3575Request.prototype.callback = function(err, res){
3576 // console.log(this._retries, this._maxRetries)
3577 if (this._maxRetries && this._retries++ < this._maxRetries && shouldRetry(err, res)) {
3578 return this._retry();
3579 }
3580
3581 var fn = this._callback;
3582 this.clearTimeout();
3583
3584 if (err) {
3585 if (this._maxRetries) err.retries = this._retries - 1;
3586 this.emit('error', err);
3587 }
3588
3589 fn(err, res);
3590};
3591
3592/**
3593 * Invoke callback with x-domain error.
3594 *
3595 * @api private
3596 */
3597
3598Request.prototype.crossDomainError = function(){
3599 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.');
3600 err.crossDomain = true;
3601
3602 err.status = this.status;
3603 err.method = this.method;
3604 err.url = this.url;
3605
3606 this.callback(err);
3607};
3608
3609// This only warns, because the request is still likely to work
3610Request.prototype.buffer = Request.prototype.ca = Request.prototype.agent = function(){
3611 console.warn("This is not supported in browser version of superagent");
3612 return this;
3613};
3614
3615// This throws, because it can't send/receive data as expected
3616Request.prototype.pipe = Request.prototype.write = function(){
3617 throw Error("Streaming is not supported in browser version of superagent");
3618};
3619
3620/**
3621 * Compose querystring to append to req.url
3622 *
3623 * @api private
3624 */
3625
3626Request.prototype._appendQueryString = function(){
3627 var query = this._query.join('&');
3628 if (query) {
3629 this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query;
3630 }
3631
3632 if (this._sort) {
3633 var index = this.url.indexOf('?');
3634 if (index >= 0) {
3635 var queryArr = this.url.substring(index + 1).split('&');
3636 if (isFunction(this._sort)) {
3637 queryArr.sort(this._sort);
3638 } else {
3639 queryArr.sort();
3640 }
3641 this.url = this.url.substring(0, index) + '?' + queryArr.join('&');
3642 }
3643 }
3644};
3645
3646/**
3647 * Check if `obj` is a host object,
3648 * we don't want to serialize these :)
3649 *
3650 * @param {Object} obj
3651 * @return {Boolean}
3652 * @api private
3653 */
3654Request.prototype._isHost = function _isHost(obj) {
3655 // Native objects stringify to [object File], [object Blob], [object FormData], etc.
3656 return obj && 'object' === typeof obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]';
3657}
3658
3659/**
3660 * Initiate request, invoking callback `fn(res)`
3661 * with an instanceof `Response`.
3662 *
3663 * @param {Function} fn
3664 * @return {Request} for chaining
3665 * @api public
3666 */
3667
3668Request.prototype.end = function(fn){
3669 if (this._endCalled) {
3670 console.warn("Warning: .end() was called twice. This is not supported in superagent");
3671 }
3672 this._endCalled = true;
3673
3674 // store callback
3675 this._callback = fn || noop;
3676
3677 // querystring
3678 this._appendQueryString();
3679
3680 return this._end();
3681};
3682
3683Request.prototype._end = function() {
3684 var self = this;
3685 var xhr = this.xhr = request.getXHR();
3686 var data = this._formData || this._data;
3687
3688 this._setTimeouts();
3689
3690 // state change
3691 xhr.onreadystatechange = function(){
3692 var readyState = xhr.readyState;
3693 if (readyState >= 2 && self._responseTimeoutTimer) {
3694 clearTimeout(self._responseTimeoutTimer);
3695 }
3696 if (4 != readyState) {
3697 return;
3698 }
3699
3700 // In IE9, reads to any property (e.g. status) off of an aborted XHR will
3701 // result in the error "Could not complete the operation due to error c00c023f"
3702 var status;
3703 try { status = xhr.status } catch(e) { status = 0; }
3704
3705 if (!status) {
3706 if (self.timedout || self._aborted) return;
3707 return self.crossDomainError();
3708 }
3709 self.emit('end');
3710 };
3711
3712 // progress
3713 var handleProgress = function(direction, e) {
3714 if (e.total > 0) {
3715 e.percent = e.loaded / e.total * 100;
3716 }
3717 e.direction = direction;
3718 self.emit('progress', e);
3719 }
3720 if (this.hasListeners('progress')) {
3721 try {
3722 xhr.onprogress = handleProgress.bind(null, 'download');
3723 if (xhr.upload) {
3724 xhr.upload.onprogress = handleProgress.bind(null, 'upload');
3725 }
3726 } catch(e) {
3727 // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
3728 // Reported here:
3729 // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
3730 }
3731 }
3732
3733 // initiate request
3734 try {
3735 if (this.username && this.password) {
3736 xhr.open(this.method, this.url, true, this.username, this.password);
3737 } else {
3738 xhr.open(this.method, this.url, true);
3739 }
3740 } catch (err) {
3741 // see #1149
3742 return this.callback(err);
3743 }
3744
3745 // CORS
3746 if (this._withCredentials) xhr.withCredentials = true;
3747
3748 // body
3749 if (!this._formData && 'GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) {
3750 // serialize stuff
3751 var contentType = this._header['content-type'];
3752 var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
3753 if (!serialize && isJSON(contentType)) {
3754 serialize = request.serialize['application/json'];
3755 }
3756 if (serialize) data = serialize(data);
3757 }
3758
3759 // set header fields
3760 for (var field in this.header) {
3761 if (null == this.header[field]) continue;
3762 xhr.setRequestHeader(field, this.header[field]);
3763 }
3764
3765 if (this._responseType) {
3766 xhr.responseType = this._responseType;
3767 }
3768
3769 // send stuff
3770 this.emit('request', this);
3771
3772 // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
3773 // We need null here if data is undefined
3774 xhr.send(typeof data !== 'undefined' ? data : null);
3775 return this;
3776};
3777
3778/**
3779 * GET `url` with optional callback `fn(res)`.
3780 *
3781 * @param {String} url
3782 * @param {Mixed|Function} [data] or fn
3783 * @param {Function} [fn]
3784 * @return {Request}
3785 * @api public
3786 */
3787
3788request.get = function(url, data, fn){
3789 var req = request('GET', url);
3790 if ('function' == typeof data) fn = data, data = null;
3791 if (data) req.query(data);
3792 if (fn) req.end(fn);
3793 return req;
3794};
3795
3796/**
3797 * HEAD `url` with optional callback `fn(res)`.
3798 *
3799 * @param {String} url
3800 * @param {Mixed|Function} [data] or fn
3801 * @param {Function} [fn]
3802 * @return {Request}
3803 * @api public
3804 */
3805
3806request.head = function(url, data, fn){
3807 var req = request('HEAD', url);
3808 if ('function' == typeof data) fn = data, data = null;
3809 if (data) req.send(data);
3810 if (fn) req.end(fn);
3811 return req;
3812};
3813
3814/**
3815 * OPTIONS query to `url` with optional callback `fn(res)`.
3816 *
3817 * @param {String} url
3818 * @param {Mixed|Function} [data] or fn
3819 * @param {Function} [fn]
3820 * @return {Request}
3821 * @api public
3822 */
3823
3824request.options = function(url, data, fn){
3825 var req = request('OPTIONS', url);
3826 if ('function' == typeof data) fn = data, data = null;
3827 if (data) req.send(data);
3828 if (fn) req.end(fn);
3829 return req;
3830};
3831
3832/**
3833 * DELETE `url` with optional `data` and callback `fn(res)`.
3834 *
3835 * @param {String} url
3836 * @param {Mixed} [data]
3837 * @param {Function} [fn]
3838 * @return {Request}
3839 * @api public
3840 */
3841
3842function del(url, data, fn){
3843 var req = request('DELETE', url);
3844 if ('function' == typeof data) fn = data, data = null;
3845 if (data) req.send(data);
3846 if (fn) req.end(fn);
3847 return req;
3848};
3849
3850request['del'] = del;
3851request['delete'] = del;
3852
3853/**
3854 * PATCH `url` with optional `data` and callback `fn(res)`.
3855 *
3856 * @param {String} url
3857 * @param {Mixed} [data]
3858 * @param {Function} [fn]
3859 * @return {Request}
3860 * @api public
3861 */
3862
3863request.patch = function(url, data, fn){
3864 var req = request('PATCH', url);
3865 if ('function' == typeof data) fn = data, data = null;
3866 if (data) req.send(data);
3867 if (fn) req.end(fn);
3868 return req;
3869};
3870
3871/**
3872 * POST `url` with optional `data` and callback `fn(res)`.
3873 *
3874 * @param {String} url
3875 * @param {Mixed} [data]
3876 * @param {Function} [fn]
3877 * @return {Request}
3878 * @api public
3879 */
3880
3881request.post = function(url, data, fn){
3882 var req = request('POST', url);
3883 if ('function' == typeof data) fn = data, data = null;
3884 if (data) req.send(data);
3885 if (fn) req.end(fn);
3886 return req;
3887};
3888
3889/**
3890 * PUT `url` with optional `data` and callback `fn(res)`.
3891 *
3892 * @param {String} url
3893 * @param {Mixed|Function} [data] or fn
3894 * @param {Function} [fn]
3895 * @return {Request}
3896 * @api public
3897 */
3898
3899request.put = function(url, data, fn){
3900 var req = request('PUT', url);
3901 if ('function' == typeof data) fn = data, data = null;
3902 if (data) req.send(data);
3903 if (fn) req.end(fn);
3904 return req;
3905};
3906
3907
3908/***/ }),
3909/* 8 */
3910/***/ (function(module, exports) {
3911
3912var g;
3913
3914// This works in non-strict mode
3915g = (function() {
3916 return this;
3917})();
3918
3919try {
3920 // This works if eval is allowed (see CSP)
3921 g = g || Function("return this")() || (1,eval)("this");
3922} catch(e) {
3923 // This works if the window reference is available
3924 if(typeof window === "object")
3925 g = window;
3926}
3927
3928// g can still be undefined, but nothing to do about it...
3929// We return undefined, instead of nothing here, so it's
3930// easier to handle this case. if(!global) { ...}
3931
3932module.exports = g;
3933
3934
3935/***/ }),
3936/* 9 */
3937/***/ (function(module, exports, __webpack_require__) {
3938
3939"use strict";
3940
3941
3942var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
3943
3944var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
3945
3946function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3947
3948var FormData = function () {
3949 function FormData() {
3950 _classCallCheck(this, FormData);
3951
3952 this._entries = [];
3953 }
3954
3955 _createClass(FormData, [{
3956 key: 'append',
3957 value: function append(name, value) {
3958 if (typeof name !== 'string') {
3959 throw new TypeError('FormData name must be a string');
3960 }
3961 if (typeof value !== 'string') {
3962 if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) !== 'object' || typeof value.uri !== 'string') {
3963 throw new TypeError('FormData value must be a string or { uri: tempFilePath }');
3964 }
3965 }
3966 this._entries.push([name, value]);
3967 }
3968 }, {
3969 key: 'set',
3970 value: function set(name, value) {
3971 var entry = this.get(name);
3972 if (entry) {
3973 entry[1] = value;
3974 } else {
3975 this.append(name, value);
3976 }
3977 }
3978 }, {
3979 key: 'delete',
3980 value: function _delete(name) {
3981 this._entries = this._entries.filter(function (entry) {
3982 return entry[0] !== name;
3983 });
3984 }
3985 }, {
3986 key: 'entries',
3987 value: function entries() {
3988 return this._entries;
3989 }
3990 }, {
3991 key: 'get',
3992 value: function get(name) {
3993 return this._entries.find(function (entry) {
3994 return entry[0] === name;
3995 });
3996 }
3997 }, {
3998 key: 'getAll',
3999 value: function getAll(name) {
4000 return this._entries.filter(function (entry) {
4001 return entry[0] === name;
4002 });
4003 }
4004 }, {
4005 key: 'has',
4006 value: function has(name) {
4007 return this._entries.some(function (entry) {
4008 return entry[0] === name;
4009 });
4010 }
4011 }, {
4012 key: 'keys',
4013 value: function keys() {
4014 return this._entries.map(function (entry) {
4015 return entry[0];
4016 });
4017 }
4018 }, {
4019 key: 'values',
4020 value: function values() {
4021 return this._entries.map(function (entry) {
4022 return entry[1];
4023 });
4024 }
4025 }]);
4026
4027 return FormData;
4028}();
4029
4030module.exports = FormData;
4031
4032/***/ }),
4033/* 10 */
4034/***/ (function(module, exports, __webpack_require__) {
4035
4036"use strict";
4037/**
4038 * @author Toru Nagashima
4039 * @copyright 2015 Toru Nagashima. All rights reserved.
4040 * See LICENSE file in root directory for full license.
4041 */
4042
4043
4044
4045/**
4046 * Creates a unique key.
4047 *
4048 * @param {string} name - A name to create.
4049 * @returns {symbol|string}
4050 * @private
4051 */
4052var createUniqueKey = exports.createUniqueKey = (typeof Symbol !== "undefined" ?
4053 Symbol :
4054 function createUniqueKey(name) {
4055 return "[[" + name + "_" + Math.random().toFixed(8).slice(2) + "]]";
4056 });
4057
4058/**
4059 * The key of listeners.
4060 *
4061 * @type {symbol|string}
4062 * @private
4063 */
4064exports.LISTENERS = createUniqueKey("listeners");
4065
4066/**
4067 * A value of kind for listeners which are registered in the capturing phase.
4068 *
4069 * @type {number}
4070 * @private
4071 */
4072exports.CAPTURE = 1;
4073
4074/**
4075 * A value of kind for listeners which are registered in the bubbling phase.
4076 *
4077 * @type {number}
4078 * @private
4079 */
4080exports.BUBBLE = 2;
4081
4082/**
4083 * A value of kind for listeners which are registered as an attribute.
4084 *
4085 * @type {number}
4086 * @private
4087 */
4088exports.ATTRIBUTE = 3;
4089
4090/**
4091 * @typedef object ListenerNode
4092 * @property {function} listener - A listener function.
4093 * @property {number} kind - The kind of the listener.
4094 * @property {ListenerNode|null} next - The next node.
4095 * If this node is the last, this is `null`.
4096 */
4097
4098/**
4099 * Creates a node of singly linked list for a list of listeners.
4100 *
4101 * @param {function} listener - A listener function.
4102 * @param {number} kind - The kind of the listener.
4103 * @returns {ListenerNode} The created listener node.
4104 */
4105exports.newNode = function newNode(listener, kind) {
4106 return {listener: listener, kind: kind, next: null};
4107};
4108
4109
4110/***/ }),
4111/* 11 */
4112/***/ (function(module, exports) {
4113
4114/**
4115 * Check if `obj` is an object.
4116 *
4117 * @param {Object} obj
4118 * @return {Boolean}
4119 * @api private
4120 */
4121
4122function isObject(obj) {
4123 return null !== obj && 'object' === typeof obj;
4124}
4125
4126module.exports = isObject;
4127
4128
4129/***/ }),
4130/* 12 */
4131/***/ (function(module, exports, __webpack_require__) {
4132
4133"use strict";
4134
4135
4136var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4137
4138function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4139
4140var Storage = function () {
4141 function Storage() {
4142 _classCallCheck(this, Storage);
4143 }
4144
4145 _createClass(Storage, [{
4146 key: 'getItem',
4147 value: function getItem(key) {
4148 return wx.getStorageSync(key);
4149 }
4150 }, {
4151 key: 'setItem',
4152 value: function setItem(key, value) {
4153 return wx.setStorageSync(key, value);
4154 }
4155 }, {
4156 key: 'removeItem',
4157 value: function removeItem(key) {
4158 return this.setItem(key, '');
4159 }
4160 }, {
4161 key: 'clear',
4162 value: function clear() {
4163 return wx.clearStorageSync();
4164 }
4165 }]);
4166
4167 return Storage;
4168}();
4169
4170module.exports = new Storage();
4171
4172/***/ }),
4173/* 13 */
4174/***/ (function(module, exports, __webpack_require__) {
4175
4176"use strict";
4177
4178
4179module.exports = {};
4180
4181/***/ }),
4182/* 14 */
4183/***/ (function(module, exports, __webpack_require__) {
4184
4185"use strict";
4186
4187
4188var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4189
4190function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4191
4192function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4193
4194function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
4195
4196var assign = __webpack_require__(21);
4197var EventTarget = __webpack_require__(20);
4198
4199var CONNECTING = 0;
4200var OPEN = 1;
4201var CLOSING = 2;
4202var CLOSED = 3;
4203
4204var EVENTS = ['open', 'error', 'message', 'close'];
4205
4206var instance = void 0;
4207
4208function errorHandler(event) {
4209 // 安å“å°ç¨‹åºä¼šè¯¡å¼‚åœ°è§¦å‘ onSocketError 回调
4210 // 通过比较 message 过滤掉
4211 if (event.message === "") return;
4212 if (instance) {
4213 instance._readyState = CLOSED;
4214 instance.dispatchEvent({
4215 type: 'error',
4216 message: event.errMsg
4217 });
4218 }
4219}
4220
4221var WebSocket = function (_EventTarget) {
4222 _inherits(WebSocket, _EventTarget);
4223
4224 function WebSocket(url, protocal) {
4225 _classCallCheck(this, WebSocket);
4226
4227 if (!url) {
4228 throw new TypeError('Failed to construct \'WebSocket\': url required');
4229 }
4230 if (protocal) {
4231 throw new Error('subprotocal not supported in weapp');
4232 }
4233
4234 var _this = _possibleConstructorReturn(this, (WebSocket.__proto__ || Object.getPrototypeOf(WebSocket)).call(this));
4235
4236 _this._url = url;
4237 _this._protocal = ''; // default value according to specs
4238 _this._readyState = CONNECTING;
4239 if (instance) {
4240 instance.dispatchEvent({
4241 type: 'close'
4242 });
4243 }
4244 instance = _this;
4245
4246 wx.onSocketOpen(function (event) {
4247 if (instance) {
4248 instance._readyState = OPEN;
4249 instance.dispatchEvent({
4250 type: 'open'
4251 });
4252 }
4253 });
4254 wx.onSocketError(errorHandler);
4255 wx.onSocketMessage(function (event) {
4256 if (instance) {
4257 var data = event.data,
4258 origin = event.origin,
4259 ports = event.ports,
4260 source = event.source;
4261
4262 instance.dispatchEvent({
4263 data: data,
4264 origin: origin,
4265 ports: ports,
4266 source: source,
4267 type: 'message'
4268 });
4269 }
4270 });
4271 wx.onSocketClose(function (event) {
4272 if (instance) {
4273 instance._readyState = CLOSED;
4274 var code = event.code,
4275 reason = event.reason,
4276 wasClean = event.wasClean;
4277
4278 instance.dispatchEvent({
4279 code: code,
4280 reason: reason,
4281 wasClean: wasClean,
4282 type: 'close'
4283 });
4284 instance = null;
4285 }
4286 });
4287
4288 wx.connectSocket({
4289 url: url,
4290 fail: function fail(error) {
4291 return setTimeout(function () {
4292 return errorHandler(error);
4293 }, 0);
4294 }
4295 });
4296 return _this;
4297 }
4298
4299 _createClass(WebSocket, [{
4300 key: 'close',
4301 value: function close() {
4302 if (this.readyState === CONNECTING) {
4303 console.warn('close WebSocket which is connecting might not work');
4304 }
4305 wx.closeSocket();
4306 }
4307 }, {
4308 key: 'send',
4309 value: function send(data) {
4310 if (this.readyState !== OPEN) {
4311 throw new Error('INVALID_STATE_ERR');
4312 }
4313
4314 if (typeof data !== 'string') {
4315 throw new TypeError('only string typed data are supported');
4316 }
4317
4318 wx.sendSocketMessage({
4319 data: data
4320 });
4321 }
4322 }, {
4323 key: 'url',
4324 get: function get() {
4325 return this._url;
4326 }
4327 }, {
4328 key: 'protocal',
4329 get: function get() {
4330 return this._protocal;
4331 }
4332 }, {
4333 key: 'readyState',
4334 get: function get() {
4335 return this._readyState;
4336 }
4337 }]);
4338
4339 return WebSocket;
4340}(EventTarget(EVENTS));
4341
4342assign(WebSocket, {
4343 CONNECTING: CONNECTING,
4344 OPEN: OPEN,
4345 CLOSING: CLOSING,
4346 CLOSED: CLOSED
4347});
4348
4349module.exports = WebSocket;
4350
4351/***/ }),
4352/* 15 */
4353/***/ (function(module, exports, __webpack_require__) {
4354
4355"use strict";
4356
4357
4358var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4359
4360function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4361
4362function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4363
4364function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4365
4366function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
4367
4368var assign = __webpack_require__(21);
4369var EventTarget = __webpack_require__(20);
4370var FormData = __webpack_require__(9);
4371
4372var UNSENT = 0;
4373var OPENED = 1;
4374var HEADERS_RECEIVED = 2;
4375var LOADING = 3;
4376var DONE = 4;
4377
4378var REQUEST_EVENTS = ['abort', 'error', 'load', 'loadstart', 'progress', 'timeout', 'loadend', 'readystatechange'];
4379
4380function successCallback(response) {
4381 this.status = response.statusCode;
4382 this.statusText = response.statusCode;
4383 var text = response.data;
4384 if (typeof text !== 'string') {
4385 text = JSON.stringify(text);
4386 }
4387 this.responseText = this.response = text;
4388 this.readyState = DONE;
4389 this.dispatchEvent({ type: 'readystatechange' });
4390}
4391
4392var XMLHttpRequest = function (_EventTarget) {
4393 _inherits(XMLHttpRequest, _EventTarget);
4394
4395 function XMLHttpRequest() {
4396 _classCallCheck(this, XMLHttpRequest);
4397
4398 var _this = _possibleConstructorReturn(this, (XMLHttpRequest.__proto__ || Object.getPrototypeOf(XMLHttpRequest)).call(this));
4399
4400 _this.readyState = UNSENT;
4401 _this._headers = {};
4402 return _this;
4403 }
4404
4405 _createClass(XMLHttpRequest, [{
4406 key: 'abort',
4407 value: function abort() {
4408 throw new Error('not supported in weapp');
4409 }
4410 }, {
4411 key: 'getAllResponseHeaders',
4412 value: function getAllResponseHeaders() {
4413 console.warn('getAllResponseHeaders always returns \'\'');
4414 return '';
4415 }
4416 }, {
4417 key: 'getResponseHeader',
4418 value: function getResponseHeader(key) {
4419 if (key === 'content-type') {
4420 console.warn('get content-type always returns \'application/json\'');
4421 return 'application/json';
4422 }
4423 console.warn('getResponseHeader always returns \'\'');
4424 return '';
4425 }
4426 }, {
4427 key: 'overrideMimeType',
4428 value: function overrideMimeType() {
4429 throw new Error('not supported in weapp');
4430 }
4431 }, {
4432 key: 'open',
4433 value: function open(method, url) {
4434 var async = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
4435
4436 if (this.readyState !== UNSENT) {
4437 throw new Error('request is already opened');
4438 }
4439 if (!async) {
4440 throw new Error('sync request is not supported');
4441 }
4442 this._method = method;
4443 this._url = url;
4444 this.readyState = OPENED;
4445 this.dispatchEvent({ type: 'readystatechange' });
4446 }
4447 }, {
4448 key: 'setRequestHeader',
4449 value: function setRequestHeader(header, value) {
4450 if (this.readyState !== OPENED) {
4451 throw new Error('request is not opened');
4452 }
4453 this._headers[header.toLowerCase()] = value;
4454 }
4455 }, {
4456 key: 'send',
4457 value: function send(data) {
4458 var _this2 = this;
4459
4460 if (this.readyState !== OPENED) {
4461 throw new Error('request is not opened');
4462 }
4463 if (data instanceof FormData) {
4464 var entries = data.entries();
4465 var blobs = entries.filter(function (entry) {
4466 return typeof entry[1] !== 'string';
4467 });
4468 if (blobs.length === 0) {
4469 throw new Error('Must specify a Blob field in FormData');
4470 }
4471 if (blobs.length > 1) {
4472 console.warn('Only the first Blob will be send in Weapp');
4473 }
4474 var restData = entries.filter(function (entry) {
4475 return typeof entry[1] === 'string';
4476 }).reduce(function (result, entry) {
4477 return assign(result, _defineProperty({}, entry[0], entry[1]));
4478 }, {});
4479 wx.uploadFile({
4480 url: this._url,
4481 name: blobs[0][0],
4482 filePath: blobs[0][1].uri,
4483 formData: restData,
4484 header: this._headers,
4485 success: successCallback.bind(this),
4486 fail: function fail(error) {
4487 console.error('wx.uploadFile failed:');
4488 console.error(error);
4489 _this2.status = 0;
4490 _this2.readyState = DONE;
4491 _this2.dispatchEvent({ type: 'readystatechange' });
4492 _this2.dispatchEvent({ type: 'error' });
4493 }
4494 });
4495 } else {
4496 wx.request({
4497 url: this._url,
4498 data: data || '',
4499 // method 的 value 居然必须为大写
4500 method: this._method.toUpperCase(),
4501 header: this._headers,
4502 success: successCallback.bind(this),
4503 fail: function fail(error) {
4504 _this2.status = 0;
4505 _this2.readyState = DONE;
4506 _this2.dispatchEvent({ type: 'readystatechange' });
4507 _this2.dispatchEvent({ type: 'error' });
4508 }
4509 });
4510 }
4511 }
4512 }]);
4513
4514 return XMLHttpRequest;
4515}(EventTarget(REQUEST_EVENTS));
4516
4517assign(XMLHttpRequest, {
4518 UNSENT: UNSENT,
4519 OPENED: OPENED,
4520 HEADERS_RECEIVED: HEADERS_RECEIVED,
4521 LOADING: LOADING,
4522 DONE: DONE
4523});
4524
4525module.exports = XMLHttpRequest;
4526
4527/***/ }),
4528/* 16 */
4529/***/ (function(module, exports, __webpack_require__) {
4530
4531"use strict";
4532
4533
4534var storage = __webpack_require__(17);
4535var AV = __webpack_require__(6);
4536
4537var removeAsync = exports.removeAsync = storage.removeItemAsync.bind(storage);
4538
4539var getCacheData = function getCacheData(cacheData, key) {
4540 try {
4541 cacheData = JSON.parse(cacheData);
4542 } catch (e) {
4543 return null;
4544 }
4545 if (cacheData) {
4546 var expired = cacheData.expiredAt && cacheData.expiredAt < Date.now();
4547 if (!expired) {
4548 return cacheData.value;
4549 }
4550 return removeAsync(key).then(function () {
4551 return null;
4552 });
4553 }
4554 return null;
4555};
4556
4557exports.getAsync = function (key) {
4558 key = AV.applicationId + '/' + key;
4559 return storage.getItemAsync(key).then(function (cache) {
4560 return getCacheData(cache, key);
4561 });
4562};
4563
4564exports.setAsync = function (key, value, ttl) {
4565 var cache = { value: value };
4566 if (typeof ttl === 'number') {
4567 cache.expiredAt = Date.now() + ttl;
4568 }
4569 return storage.setItemAsync(AV.applicationId + '/' + key, JSON.stringify(cache));
4570};
4571
4572/***/ }),
4573/* 17 */
4574/***/ (function(module, exports, __webpack_require__) {
4575
4576"use strict";
4577
4578
4579var _ = __webpack_require__(0);
4580var Promise = __webpack_require__(1);
4581var localStorage = __webpack_require__(46);
4582
4583var syncApiNames = ['getItem', 'setItem', 'removeItem', 'clear'];
4584
4585if (!localStorage.async) {
4586 // wrap sync apis with async ones.
4587 _(syncApiNames).each(function (apiName) {
4588 if (typeof localStorage[apiName] === 'function') {
4589 localStorage[apiName + 'Async'] = function () {
4590 return Promise.resolve(localStorage[apiName].apply(localStorage, arguments));
4591 };
4592 }
4593 });
4594} else {
4595 _(syncApiNames).each(function (apiName) {
4596 if (typeof localStorage[apiName] !== 'function') {
4597 localStorage[apiName] = function () {
4598 var error = new Error('Synchronous API [' + apiName + '] is not available in this runtime.');
4599 error.code = 'SYNC_API_NOT_AVAILABLE';
4600 throw error;
4601 };
4602 }
4603 });
4604}
4605
4606module.exports = localStorage;
4607
4608/***/ }),
4609/* 18 */
4610/***/ (function(module, exports, __webpack_require__) {
4611
4612"use strict";
4613
4614
4615module.exports = '2.1.1';
4616
4617/***/ }),
4618/* 19 */
4619/***/ (function(module, exports) {
4620
4621var charenc = {
4622 // UTF-8 encoding
4623 utf8: {
4624 // Convert a string to a byte array
4625 stringToBytes: function(str) {
4626 return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));
4627 },
4628
4629 // Convert a byte array to a string
4630 bytesToString: function(bytes) {
4631 return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));
4632 }
4633 },
4634
4635 // Binary encoding
4636 bin: {
4637 // Convert a string to a byte array
4638 stringToBytes: function(str) {
4639 for (var bytes = [], i = 0; i < str.length; i++)
4640 bytes.push(str.charCodeAt(i) & 0xFF);
4641 return bytes;
4642 },
4643
4644 // Convert a byte array to a string
4645 bytesToString: function(bytes) {
4646 for (var str = [], i = 0; i < bytes.length; i++)
4647 str.push(String.fromCharCode(bytes[i]));
4648 return str.join('');
4649 }
4650 }
4651};
4652
4653module.exports = charenc;
4654
4655
4656/***/ }),
4657/* 20 */
4658/***/ (function(module, exports, __webpack_require__) {
4659
4660"use strict";
4661/**
4662 * @author Toru Nagashima
4663 * @copyright 2015 Toru Nagashima. All rights reserved.
4664 * See LICENSE file in root directory for full license.
4665 */
4666
4667
4668
4669//-----------------------------------------------------------------------------
4670// Requirements
4671//-----------------------------------------------------------------------------
4672
4673var Commons = __webpack_require__(10);
4674var CustomEventTarget = __webpack_require__(52);
4675var EventWrapper = __webpack_require__(53);
4676var LISTENERS = Commons.LISTENERS;
4677var CAPTURE = Commons.CAPTURE;
4678var BUBBLE = Commons.BUBBLE;
4679var ATTRIBUTE = Commons.ATTRIBUTE;
4680var newNode = Commons.newNode;
4681var defineCustomEventTarget = CustomEventTarget.defineCustomEventTarget;
4682var createEventWrapper = EventWrapper.createEventWrapper;
4683var STOP_IMMEDIATE_PROPAGATION_FLAG =
4684 EventWrapper.STOP_IMMEDIATE_PROPAGATION_FLAG;
4685
4686//-----------------------------------------------------------------------------
4687// Constants
4688//-----------------------------------------------------------------------------
4689
4690/**
4691 * A flag which shows there is the native `EventTarget` interface object.
4692 *
4693 * @type {boolean}
4694 * @private
4695 */
4696var HAS_EVENTTARGET_INTERFACE = (
4697 typeof window !== "undefined" &&
4698 typeof window.EventTarget !== "undefined"
4699);
4700
4701//-----------------------------------------------------------------------------
4702// Public Interface
4703//-----------------------------------------------------------------------------
4704
4705/**
4706 * An implementation for `EventTarget` interface.
4707 *
4708 * @constructor
4709 * @public
4710 */
4711var EventTarget = module.exports = function EventTarget() {
4712 if (this instanceof EventTarget) {
4713 // this[LISTENERS] is a Map.
4714 // Its key is event type.
4715 // Its value is ListenerNode object or null.
4716 //
4717 // interface ListenerNode {
4718 // var listener: Function
4719 // var kind: CAPTURE|BUBBLE|ATTRIBUTE
4720 // var next: ListenerNode|null
4721 // }
4722 Object.defineProperty(this, LISTENERS, {value: Object.create(null)});
4723 }
4724 else if (arguments.length === 1 && Array.isArray(arguments[0])) {
4725 return defineCustomEventTarget(EventTarget, arguments[0]);
4726 }
4727 else if (arguments.length > 0) {
4728 var types = Array(arguments.length);
4729 for (var i = 0; i < arguments.length; ++i) {
4730 types[i] = arguments[i];
4731 }
4732
4733 // To use to extend with attribute listener properties.
4734 // e.g.
4735 // class MyCustomObject extends EventTarget("message", "error") {
4736 // //...
4737 // }
4738 return defineCustomEventTarget(EventTarget, types);
4739 }
4740 else {
4741 throw new TypeError("Cannot call a class as a function");
4742 }
4743};
4744
4745EventTarget.prototype = Object.create(
4746 (HAS_EVENTTARGET_INTERFACE ? window.EventTarget : Object).prototype,
4747 {
4748 constructor: {
4749 value: EventTarget,
4750 writable: true,
4751 configurable: true
4752 },
4753
4754 addEventListener: {
4755 value: function addEventListener(type, listener, capture) {
4756 if (listener == null) {
4757 return false;
4758 }
4759 if (typeof listener !== "function" && typeof listener !== "object") {
4760 throw new TypeError("\"listener\" is not an object.");
4761 }
4762
4763 var kind = (capture ? CAPTURE : BUBBLE);
4764 var node = this[LISTENERS][type];
4765 if (node == null) {
4766 this[LISTENERS][type] = newNode(listener, kind);
4767 return true;
4768 }
4769
4770 var prev = null;
4771 while (node != null) {
4772 if (node.listener === listener && node.kind === kind) {
4773 // Should ignore a duplicated listener.
4774 return false;
4775 }
4776 prev = node;
4777 node = node.next;
4778 }
4779
4780 prev.next = newNode(listener, kind);
4781 return true;
4782 },
4783 configurable: true,
4784 writable: true
4785 },
4786
4787 removeEventListener: {
4788 value: function removeEventListener(type, listener, capture) {
4789 if (listener == null) {
4790 return false;
4791 }
4792
4793 var kind = (capture ? CAPTURE : BUBBLE);
4794 var prev = null;
4795 var node = this[LISTENERS][type];
4796 while (node != null) {
4797 if (node.listener === listener && node.kind === kind) {
4798 if (prev == null) {
4799 this[LISTENERS][type] = node.next;
4800 }
4801 else {
4802 prev.next = node.next;
4803 }
4804 return true;
4805 }
4806
4807 prev = node;
4808 node = node.next;
4809 }
4810
4811 return false;
4812 },
4813 configurable: true,
4814 writable: true
4815 },
4816
4817 dispatchEvent: {
4818 value: function dispatchEvent(event) {
4819 // If listeners aren't registered, terminate.
4820 var node = this[LISTENERS][event.type];
4821 if (node == null) {
4822 return true;
4823 }
4824
4825 // Since we cannot rewrite several properties, so wrap object.
4826 var wrapped = createEventWrapper(event, this);
4827
4828 // This doesn't process capturing phase and bubbling phase.
4829 // This isn't participating in a tree.
4830 while (node != null) {
4831 if (typeof node.listener === "function") {
4832 node.listener.call(this, wrapped);
4833 }
4834 else if (node.kind !== ATTRIBUTE && typeof node.listener.handleEvent === "function") {
4835 node.listener.handleEvent(wrapped);
4836 }
4837
4838 if (wrapped[STOP_IMMEDIATE_PROPAGATION_FLAG]) {
4839 break;
4840 }
4841 node = node.next;
4842 }
4843
4844 return !wrapped.defaultPrevented;
4845 },
4846 configurable: true,
4847 writable: true
4848 }
4849 }
4850);
4851
4852
4853/***/ }),
4854/* 21 */
4855/***/ (function(module, exports, __webpack_require__) {
4856
4857"use strict";
4858/*
4859object-assign
4860(c) Sindre Sorhus
4861@license MIT
4862*/
4863
4864
4865/* eslint-disable no-unused-vars */
4866var getOwnPropertySymbols = Object.getOwnPropertySymbols;
4867var hasOwnProperty = Object.prototype.hasOwnProperty;
4868var propIsEnumerable = Object.prototype.propertyIsEnumerable;
4869
4870function toObject(val) {
4871 if (val === null || val === undefined) {
4872 throw new TypeError('Object.assign cannot be called with null or undefined');
4873 }
4874
4875 return Object(val);
4876}
4877
4878function shouldUseNative() {
4879 try {
4880 if (!Object.assign) {
4881 return false;
4882 }
4883
4884 // Detect buggy property enumeration order in older V8 versions.
4885
4886 // https://bugs.chromium.org/p/v8/issues/detail?id=4118
4887 var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
4888 test1[5] = 'de';
4889 if (Object.getOwnPropertyNames(test1)[0] === '5') {
4890 return false;
4891 }
4892
4893 // https://bugs.chromium.org/p/v8/issues/detail?id=3056
4894 var test2 = {};
4895 for (var i = 0; i < 10; i++) {
4896 test2['_' + String.fromCharCode(i)] = i;
4897 }
4898 var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
4899 return test2[n];
4900 });
4901 if (order2.join('') !== '0123456789') {
4902 return false;
4903 }
4904
4905 // https://bugs.chromium.org/p/v8/issues/detail?id=3056
4906 var test3 = {};
4907 'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
4908 test3[letter] = letter;
4909 });
4910 if (Object.keys(Object.assign({}, test3)).join('') !==
4911 'abcdefghijklmnopqrst') {
4912 return false;
4913 }
4914
4915 return true;
4916 } catch (err) {
4917 // We don't expect any of the above to throw, but better to be safe.
4918 return false;
4919 }
4920}
4921
4922module.exports = shouldUseNative() ? Object.assign : function (target, source) {
4923 var from;
4924 var to = toObject(target);
4925 var symbols;
4926
4927 for (var s = 1; s < arguments.length; s++) {
4928 from = Object(arguments[s]);
4929
4930 for (var key in from) {
4931 if (hasOwnProperty.call(from, key)) {
4932 to[key] = from[key];
4933 }
4934 }
4935
4936 if (getOwnPropertySymbols) {
4937 symbols = getOwnPropertySymbols(from);
4938 for (var i = 0; i < symbols.length; i++) {
4939 if (propIsEnumerable.call(from, symbols[i])) {
4940 to[symbols[i]] = from[symbols[i]];
4941 }
4942 }
4943 }
4944 }
4945
4946 return to;
4947};
4948
4949
4950/***/ }),
4951/* 22 */
4952/***/ (function(module, exports, __webpack_require__) {
4953
4954"use strict";
4955
4956
4957var polyfill = __webpack_require__(24).polyfill;
4958window = window || {};
4959polyfill();
4960polyfill(window);
4961try {
4962 localStorage = localStorage || __webpack_require__(12);
4963} catch (e) {}
4964try {
4965 XMLHttpRequest = XMLHttpRequest || __webpack_require__(15);
4966} catch (e) {}
4967try {
4968 FormData = FormData || __webpack_require__(9);
4969} catch (e) {}
4970try {
4971 WebSocket = WebSocket || __webpack_require__(14);
4972} catch (e) {}
4973try {
4974 navigator = navigator || __webpack_require__(13);
4975} catch (e) {}
4976
4977/***/ }),
4978/* 23 */
4979/***/ (function(module, exports, __webpack_require__) {
4980
4981"use strict";
4982
4983
4984/*!
4985 * LeanCloud JavaScript SDK
4986 * https://leancloud.cn
4987 *
4988 * Copyright 2016 LeanCloud.cn, Inc.
4989 * The LeanCloud JavaScript SDK is freely distributable under the MIT license.
4990 */
4991
4992var AV = __webpack_require__(6);
4993
4994AV._ = __webpack_require__(0);
4995AV.version = __webpack_require__(18);
4996AV.Promise = __webpack_require__(1);
4997AV.localStorage = __webpack_require__(17);
4998AV.Cache = __webpack_require__(16);
4999AV.Error = __webpack_require__(3);
5000
5001__webpack_require__(30);
5002__webpack_require__(27)(AV);
5003__webpack_require__(29)(AV);
5004__webpack_require__(25)(AV);
5005__webpack_require__(33)(AV);
5006__webpack_require__(36)(AV);
5007__webpack_require__(28)(AV);
5008__webpack_require__(32)(AV);
5009__webpack_require__(37)(AV);
5010__webpack_require__(45)(AV);
5011__webpack_require__(35)(AV);
5012__webpack_require__(26)(AV);
5013__webpack_require__(34)(AV);
5014__webpack_require__(39)(AV);
5015__webpack_require__(38)(AV);
5016__webpack_require__(31)(AV);
5017
5018module.exports = AV;
5019
5020/**
5021 * Options to controll the authentication for an operation
5022 * @typedef {Object} AuthOptions
5023 * @property {String} [sessionToken] Specify a user to excute the operation as.
5024 * @property {AV.User} [user] Specify a user to excute the operation as. The user must have _sessionToken. This option will be ignored if sessionToken option provided.
5025 * @property {Boolean} [useMasterKey] Indicates whether masterKey is used for this operation. Only valid when masterKey is set.
5026 */
5027
5028/***/ }),
5029/* 24 */
5030/***/ (function(module, exports, __webpack_require__) {
5031
5032"use strict";
5033/* WEBPACK VAR INJECTION */(function(global) {
5034
5035var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
5036
5037var localStorage = __webpack_require__(12);
5038var XMLHttpRequest = __webpack_require__(15);
5039var FormData = __webpack_require__(9);
5040var WebSocket = __webpack_require__(14);
5041var navigator = __webpack_require__(13);
5042
5043module.exports = {
5044 polyfill: function polyfill() {
5045 var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : global || window;
5046
5047 if ((typeof target === 'undefined' ? 'undefined' : _typeof(target)) !== 'object') {
5048 throw new Error('polyfill target is not an Object');
5049 }
5050 var polyfills = {
5051 localStorage: localStorage,
5052 XMLHttpRequest: XMLHttpRequest,
5053 FormData: FormData,
5054 WebSocket: WebSocket,
5055 Object: Object,
5056 navigator: navigator
5057 };
5058 for (var k in polyfills) {
5059 if (!target[k]) target[k] = polyfills[k];
5060 }
5061 },
5062
5063 localStorage: localStorage,
5064 XMLHttpRequest: XMLHttpRequest,
5065 FormData: FormData,
5066 WebSocket: WebSocket
5067};
5068/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8)))
5069
5070/***/ }),
5071/* 25 */
5072/***/ (function(module, exports, __webpack_require__) {
5073
5074"use strict";
5075
5076
5077var _ = __webpack_require__(0);
5078
5079module.exports = function (AV) {
5080 var PUBLIC_KEY = "*";
5081
5082 /**
5083 * Creates a new ACL.
5084 * If no argument is given, the ACL has no permissions for anyone.
5085 * If the argument is a AV.User, the ACL will have read and write
5086 * permission for only that user.
5087 * If the argument is any other JSON object, that object will be interpretted
5088 * as a serialized ACL created with toJSON().
5089 * @see AV.Object#setACL
5090 * @class
5091 *
5092 * <p>An ACL, or Access Control List can be added to any
5093 * <code>AV.Object</code> to restrict access to only a subset of users
5094 * of your application.</p>
5095 */
5096 AV.ACL = function (arg1) {
5097 var self = this;
5098 self.permissionsById = {};
5099 if (_.isObject(arg1)) {
5100 if (arg1 instanceof AV.User) {
5101 self.setReadAccess(arg1, true);
5102 self.setWriteAccess(arg1, true);
5103 } else {
5104 if (_.isFunction(arg1)) {
5105 throw new Error('AV.ACL() called with a function. Did you forget ()?');
5106 }
5107 AV._objectEach(arg1, function (accessList, userId) {
5108 if (!_.isString(userId)) {
5109 throw new Error('Tried to create an ACL with an invalid userId.');
5110 }
5111 self.permissionsById[userId] = {};
5112 AV._objectEach(accessList, function (allowed, permission) {
5113 if (permission !== "read" && permission !== "write") {
5114 throw new Error('Tried to create an ACL with an invalid permission type.');
5115 }
5116 if (!_.isBoolean(allowed)) {
5117 throw new Error('Tried to create an ACL with an invalid permission value.');
5118 }
5119 self.permissionsById[userId][permission] = allowed;
5120 });
5121 });
5122 }
5123 }
5124 };
5125
5126 /**
5127 * Returns a JSON-encoded version of the ACL.
5128 * @return {Object}
5129 */
5130 AV.ACL.prototype.toJSON = function () {
5131 return _.clone(this.permissionsById);
5132 };
5133
5134 AV.ACL.prototype._setAccess = function (accessType, userId, allowed) {
5135 if (userId instanceof AV.User) {
5136 userId = userId.id;
5137 } else if (userId instanceof AV.Role) {
5138 userId = "role:" + userId.getName();
5139 }
5140 if (!_.isString(userId)) {
5141 throw new Error('userId must be a string.');
5142 }
5143 if (!_.isBoolean(allowed)) {
5144 throw new Error('allowed must be either true or false.');
5145 }
5146 var permissions = this.permissionsById[userId];
5147 if (!permissions) {
5148 if (!allowed) {
5149 // The user already doesn't have this permission, so no action needed.
5150 return;
5151 } else {
5152 permissions = {};
5153 this.permissionsById[userId] = permissions;
5154 }
5155 }
5156
5157 if (allowed) {
5158 this.permissionsById[userId][accessType] = true;
5159 } else {
5160 delete permissions[accessType];
5161 if (_.isEmpty(permissions)) {
5162 delete permissions[userId];
5163 }
5164 }
5165 };
5166
5167 AV.ACL.prototype._getAccess = function (accessType, userId) {
5168 if (userId instanceof AV.User) {
5169 userId = userId.id;
5170 } else if (userId instanceof AV.Role) {
5171 userId = "role:" + userId.getName();
5172 }
5173 var permissions = this.permissionsById[userId];
5174 if (!permissions) {
5175 return false;
5176 }
5177 return permissions[accessType] ? true : false;
5178 };
5179
5180 /**
5181 * Set whether the given user is allowed to read this object.
5182 * @param userId An instance of AV.User or its objectId.
5183 * @param {Boolean} allowed Whether that user should have read access.
5184 */
5185 AV.ACL.prototype.setReadAccess = function (userId, allowed) {
5186 this._setAccess("read", userId, allowed);
5187 };
5188
5189 /**
5190 * Get whether the given user id is *explicitly* allowed to read this object.
5191 * Even if this returns false, the user may still be able to access it if
5192 * getPublicReadAccess returns true or a role that the user belongs to has
5193 * write access.
5194 * @param userId An instance of AV.User or its objectId, or a AV.Role.
5195 * @return {Boolean}
5196 */
5197 AV.ACL.prototype.getReadAccess = function (userId) {
5198 return this._getAccess("read", userId);
5199 };
5200
5201 /**
5202 * Set whether the given user id is allowed to write this object.
5203 * @param userId An instance of AV.User or its objectId, or a AV.Role..
5204 * @param {Boolean} allowed Whether that user should have write access.
5205 */
5206 AV.ACL.prototype.setWriteAccess = function (userId, allowed) {
5207 this._setAccess("write", userId, allowed);
5208 };
5209
5210 /**
5211 * Get whether the given user id is *explicitly* allowed to write this object.
5212 * Even if this returns false, the user may still be able to write it if
5213 * getPublicWriteAccess returns true or a role that the user belongs to has
5214 * write access.
5215 * @param userId An instance of AV.User or its objectId, or a AV.Role.
5216 * @return {Boolean}
5217 */
5218 AV.ACL.prototype.getWriteAccess = function (userId) {
5219 return this._getAccess("write", userId);
5220 };
5221
5222 /**
5223 * Set whether the public is allowed to read this object.
5224 * @param {Boolean} allowed
5225 */
5226 AV.ACL.prototype.setPublicReadAccess = function (allowed) {
5227 this.setReadAccess(PUBLIC_KEY, allowed);
5228 };
5229
5230 /**
5231 * Get whether the public is allowed to read this object.
5232 * @return {Boolean}
5233 */
5234 AV.ACL.prototype.getPublicReadAccess = function () {
5235 return this.getReadAccess(PUBLIC_KEY);
5236 };
5237
5238 /**
5239 * Set whether the public is allowed to write this object.
5240 * @param {Boolean} allowed
5241 */
5242 AV.ACL.prototype.setPublicWriteAccess = function (allowed) {
5243 this.setWriteAccess(PUBLIC_KEY, allowed);
5244 };
5245
5246 /**
5247 * Get whether the public is allowed to write this object.
5248 * @return {Boolean}
5249 */
5250 AV.ACL.prototype.getPublicWriteAccess = function () {
5251 return this.getWriteAccess(PUBLIC_KEY);
5252 };
5253
5254 /**
5255 * Get whether users belonging to the given role are allowed
5256 * to read this object. Even if this returns false, the role may
5257 * still be able to write it if a parent role has read access.
5258 *
5259 * @param role The name of the role, or a AV.Role object.
5260 * @return {Boolean} true if the role has read access. false otherwise.
5261 * @throws {String} If role is neither a AV.Role nor a String.
5262 */
5263 AV.ACL.prototype.getRoleReadAccess = function (role) {
5264 if (role instanceof AV.Role) {
5265 // Normalize to the String name
5266 role = role.getName();
5267 }
5268 if (_.isString(role)) {
5269 return this.getReadAccess("role:" + role);
5270 }
5271 throw new Error('role must be a AV.Role or a String');
5272 };
5273
5274 /**
5275 * Get whether users belonging to the given role are allowed
5276 * to write this object. Even if this returns false, the role may
5277 * still be able to write it if a parent role has write access.
5278 *
5279 * @param role The name of the role, or a AV.Role object.
5280 * @return {Boolean} true if the role has write access. false otherwise.
5281 * @throws {String} If role is neither a AV.Role nor a String.
5282 */
5283 AV.ACL.prototype.getRoleWriteAccess = function (role) {
5284 if (role instanceof AV.Role) {
5285 // Normalize to the String name
5286 role = role.getName();
5287 }
5288 if (_.isString(role)) {
5289 return this.getWriteAccess("role:" + role);
5290 }
5291 throw new Error('role must be a AV.Role or a String');
5292 };
5293
5294 /**
5295 * Set whether users belonging to the given role are allowed
5296 * to read this object.
5297 *
5298 * @param role The name of the role, or a AV.Role object.
5299 * @param {Boolean} allowed Whether the given role can read this object.
5300 * @throws {String} If role is neither a AV.Role nor a String.
5301 */
5302 AV.ACL.prototype.setRoleReadAccess = function (role, allowed) {
5303 if (role instanceof AV.Role) {
5304 // Normalize to the String name
5305 role = role.getName();
5306 }
5307 if (_.isString(role)) {
5308 this.setReadAccess("role:" + role, allowed);
5309 return;
5310 }
5311 throw new Error('role must be a AV.Role or a String');
5312 };
5313
5314 /**
5315 * Set whether users belonging to the given role are allowed
5316 * to write this object.
5317 *
5318 * @param role The name of the role, or a AV.Role object.
5319 * @param {Boolean} allowed Whether the given role can write this object.
5320 * @throws {String} If role is neither a AV.Role nor a String.
5321 */
5322 AV.ACL.prototype.setRoleWriteAccess = function (role, allowed) {
5323 if (role instanceof AV.Role) {
5324 // Normalize to the String name
5325 role = role.getName();
5326 }
5327 if (_.isString(role)) {
5328 this.setWriteAccess("role:" + role, allowed);
5329 return;
5330 }
5331 throw new Error('role must be a AV.Role or a String');
5332 };
5333};
5334
5335/***/ }),
5336/* 26 */
5337/***/ (function(module, exports, __webpack_require__) {
5338
5339"use strict";
5340
5341
5342var _ = __webpack_require__(0);
5343var AVRequest = __webpack_require__(2).request;
5344
5345module.exports = function (AV) {
5346 /**
5347 * Contains functions for calling and declaring
5348 * <p><strong><em>
5349 * Some functions are only available from Cloud Code.
5350 * </em></strong></p>
5351 *
5352 * @namespace
5353 */
5354 AV.Cloud = AV.Cloud || {};
5355
5356 _.extend(AV.Cloud, /** @lends AV.Cloud */{
5357 /**
5358 * Makes a call to a cloud function.
5359 * @param {String} name The function name.
5360 * @param {Object} data The parameters to send to the cloud function.
5361 * @param {AuthOptions} options
5362 * @return {Promise} A promise that will be resolved with the result
5363 * of the function.
5364 */
5365 run: function run(name, data, options) {
5366 var request = AVRequest('functions', name, null, 'POST', AV._encode(data, null, true), options);
5367
5368 return request.then(function (resp) {
5369 return AV._decode(resp).result;
5370 });
5371 },
5372
5373 /**
5374 * Makes a call to a cloud function, you can send {AV.Object} as param or a field of param; the response
5375 * from server will also be parsed as an {AV.Object}, array of {AV.Object}, or object includes {AV.Object}
5376 * @param {String} name The function name.
5377 * @param {Object} data The parameters to send to the cloud function.
5378 * @param {AuthOptions} options
5379 * @return {Promise} A promise that will be resolved with the result of the function.
5380 */
5381 rpc: function rpc(name, data, options) {
5382 if (_.isArray(data)) {
5383 return Promise.reject(new Error('Can\'t pass Array as the param of rpc function in JavaScript SDK.'));
5384 }
5385
5386 return AVRequest('call', name, null, 'POST', AV._encodeObjectOrArray(data), options).then(function (resp) {
5387 return AV._decode(resp).result;
5388 });
5389 },
5390
5391 /**
5392 * Make a call to request server date time.
5393 * @return {Promise.<Date>} A promise that will be resolved with the result
5394 * of the function.
5395 * @since 0.5.9
5396 */
5397 getServerDate: function getServerDate() {
5398 var request = AVRequest("date", null, null, 'GET');
5399
5400 return request.then(function (resp) {
5401 return AV._decode(resp);
5402 });
5403 },
5404
5405 /**
5406 * Makes a call to request a sms code for operation verification.
5407 * @param {Object} data The mobile phone number string or a JSON
5408 * object that contains mobilePhoneNumber,template,op,ttl,name etc.
5409 * @return {Promise} A promise that will be resolved with the result
5410 * of the function.
5411 */
5412 requestSmsCode: function requestSmsCode(data) {
5413 if (_.isString(data)) {
5414 data = { mobilePhoneNumber: data };
5415 }
5416 if (!data.mobilePhoneNumber) {
5417 throw new Error('Missing mobilePhoneNumber.');
5418 }
5419 var request = AVRequest("requestSmsCode", null, null, 'POST', data);
5420 return request;
5421 },
5422
5423 /**
5424 * Makes a call to verify sms code that sent by AV.Cloud.requestSmsCode
5425 * @param {String} code The sms code sent by AV.Cloud.requestSmsCode
5426 * @param {phone} phone The mobile phoner number(optional).
5427 * @return {Promise} A promise that will be resolved with the result
5428 * of the function.
5429 */
5430 verifySmsCode: function verifySmsCode(code, phone) {
5431 if (!code) throw new Error('Missing sms code.');
5432 var params = {};
5433 if (_.isString(phone)) {
5434 params['mobilePhoneNumber'] = phone;
5435 }
5436
5437 var request = AVRequest("verifySmsCode", code, null, 'POST', params);
5438 return request;
5439 }
5440 });
5441};
5442
5443/***/ }),
5444/* 27 */
5445/***/ (function(module, exports, __webpack_require__) {
5446
5447"use strict";
5448
5449
5450var _ = __webpack_require__(0);
5451
5452module.exports = function (AV) {
5453 var eventSplitter = /\s+/;
5454 var slice = Array.prototype.slice;
5455
5456 /**
5457 * @class
5458 *
5459 * <p>AV.Events is a fork of Backbone's Events module, provided for your
5460 * convenience.</p>
5461 *
5462 * <p>A module that can be mixed in to any object in order to provide
5463 * it with custom events. You may bind callback functions to an event
5464 * with `on`, or remove these functions with `off`.
5465 * Triggering an event fires all callbacks in the order that `on` was
5466 * called.
5467 *
5468 * @private
5469 * @example
5470 * var object = {};
5471 * _.extend(object, AV.Events);
5472 * object.on('expand', function(){ alert('expanded'); });
5473 * object.trigger('expand');</pre></p>
5474 *
5475 */
5476 AV.Events = {
5477 /**
5478 * Bind one or more space separated events, `events`, to a `callback`
5479 * function. Passing `"all"` will bind the callback to all events fired.
5480 */
5481 on: function on(events, callback, context) {
5482
5483 var calls, event, node, tail, list;
5484 if (!callback) {
5485 return this;
5486 }
5487 events = events.split(eventSplitter);
5488 calls = this._callbacks || (this._callbacks = {});
5489
5490 // Create an immutable callback list, allowing traversal during
5491 // modification. The tail is an empty object that will always be used
5492 // as the next node.
5493 event = events.shift();
5494 while (event) {
5495 list = calls[event];
5496 node = list ? list.tail : {};
5497 node.next = tail = {};
5498 node.context = context;
5499 node.callback = callback;
5500 calls[event] = { tail: tail, next: list ? list.next : node };
5501 event = events.shift();
5502 }
5503
5504 return this;
5505 },
5506
5507 /**
5508 * Remove one or many callbacks. If `context` is null, removes all callbacks
5509 * with that function. If `callback` is null, removes all callbacks for the
5510 * event. If `events` is null, removes all bound callbacks for all events.
5511 */
5512 off: function off(events, callback, context) {
5513 var event, calls, node, tail, cb, ctx;
5514
5515 // No events, or removing *all* events.
5516 if (!(calls = this._callbacks)) {
5517 return;
5518 }
5519 if (!(events || callback || context)) {
5520 delete this._callbacks;
5521 return this;
5522 }
5523
5524 // Loop through the listed events and contexts, splicing them out of the
5525 // linked list of callbacks if appropriate.
5526 events = events ? events.split(eventSplitter) : _.keys(calls);
5527 event = events.shift();
5528 while (event) {
5529 node = calls[event];
5530 delete calls[event];
5531 if (!node || !(callback || context)) {
5532 continue;
5533 }
5534 // Create a new list, omitting the indicated callbacks.
5535 tail = node.tail;
5536 node = node.next;
5537 while (node !== tail) {
5538 cb = node.callback;
5539 ctx = node.context;
5540 if (callback && cb !== callback || context && ctx !== context) {
5541 this.on(event, cb, ctx);
5542 }
5543 node = node.next;
5544 }
5545 event = events.shift();
5546 }
5547
5548 return this;
5549 },
5550
5551 /**
5552 * Trigger one or many events, firing all bound callbacks. Callbacks are
5553 * passed the same arguments as `trigger` is, apart from the event name
5554 * (unless you're listening on `"all"`, which will cause your callback to
5555 * receive the true name of the event as the first argument).
5556 */
5557 trigger: function trigger(events) {
5558 var event, node, calls, tail, args, all, rest;
5559 if (!(calls = this._callbacks)) {
5560 return this;
5561 }
5562 all = calls.all;
5563 events = events.split(eventSplitter);
5564 rest = slice.call(arguments, 1);
5565
5566 // For each event, walk through the linked list of callbacks twice,
5567 // first to trigger the event, then to trigger any `"all"` callbacks.
5568 event = events.shift();
5569 while (event) {
5570 node = calls[event];
5571 if (node) {
5572 tail = node.tail;
5573 while ((node = node.next) !== tail) {
5574 node.callback.apply(node.context || this, rest);
5575 }
5576 }
5577 node = all;
5578 if (node) {
5579 tail = node.tail;
5580 args = [event].concat(rest);
5581 while ((node = node.next) !== tail) {
5582 node.callback.apply(node.context || this, args);
5583 }
5584 }
5585 event = events.shift();
5586 }
5587
5588 return this;
5589 }
5590 };
5591
5592 /**
5593 * @function
5594 */
5595 AV.Events.bind = AV.Events.on;
5596
5597 /**
5598 * @function
5599 */
5600 AV.Events.unbind = AV.Events.off;
5601};
5602
5603/***/ }),
5604/* 28 */
5605/***/ (function(module, exports, __webpack_require__) {
5606
5607"use strict";
5608
5609
5610var _ = __webpack_require__(0);
5611var cos = __webpack_require__(42);
5612var qiniu = __webpack_require__(43);
5613var s3 = __webpack_require__(44);
5614var AVError = __webpack_require__(3);
5615var AVRequest = __webpack_require__(2).request;
5616var Promise = __webpack_require__(1);
5617
5618var _require = __webpack_require__(4),
5619 tap = _require.tap;
5620
5621var debug = __webpack_require__(5)('leancloud:file');
5622
5623module.exports = function (AV) {
5624
5625 // 挂载一些é…ç½®
5626 var avConfig = AV._config;
5627
5628 var hexOctet = function hexOctet() {
5629 return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
5630 };
5631
5632 // port from browserify path module
5633 // since react-native packager won't shim node modules.
5634 var extname = function extname(path) {
5635 return path.match(/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/)[4];
5636 };
5637
5638 var b64Digit = function b64Digit(number) {
5639 if (number < 26) {
5640 return String.fromCharCode(65 + number);
5641 }
5642 if (number < 52) {
5643 return String.fromCharCode(97 + (number - 26));
5644 }
5645 if (number < 62) {
5646 return String.fromCharCode(48 + (number - 52));
5647 }
5648 if (number === 62) {
5649 return '+';
5650 }
5651 if (number === 63) {
5652 return '/';
5653 }
5654 throw new Error('Tried to encode large digit ' + number + ' in base64.');
5655 };
5656
5657 var encodeBase64 = function encodeBase64(array) {
5658 var chunks = [];
5659 chunks.length = Math.ceil(array.length / 3);
5660 _.times(chunks.length, function (i) {
5661 var b1 = array[i * 3];
5662 var b2 = array[i * 3 + 1] || 0;
5663 var b3 = array[i * 3 + 2] || 0;
5664
5665 var has2 = i * 3 + 1 < array.length;
5666 var has3 = i * 3 + 2 < array.length;
5667
5668 chunks[i] = [b64Digit(b1 >> 2 & 0x3F), b64Digit(b1 << 4 & 0x30 | b2 >> 4 & 0x0F), has2 ? b64Digit(b2 << 2 & 0x3C | b3 >> 6 & 0x03) : "=", has3 ? b64Digit(b3 & 0x3F) : "="].join("");
5669 });
5670 return chunks.join("");
5671 };
5672
5673 /**
5674 * An AV.File is a local representation of a file that is saved to the AV
5675 * cloud.
5676 * @param name {String} The file's name. This will change to a unique value
5677 * once the file has finished saving.
5678 * @param data {Array} The data for the file, as either:
5679 * 1. an Array of byte value Numbers, or
5680 * 2. an Object like { base64: "..." } with a base64-encoded String.
5681 * 3. a File object selected with a file upload control. (3) only works
5682 * in Firefox 3.6+, Safari 6.0.2+, Chrome 7+, and IE 10+.
5683 * 4.a Buffer object in Node.js runtime.
5684 *
5685 * For example:<pre>
5686 * var fileUploadControl = $("#profilePhotoFileUpload")[0];
5687 * if (fileUploadControl.files.length > 0) {
5688 * var file = fileUploadControl.files[0];
5689 * var name = "photo.jpg";
5690 * var file = new AV.File(name, file);
5691 * file.save().then(function() {
5692 * // The file has been saved to AV.
5693 * }, function(error) {
5694 * // The file either could not be read, or could not be saved to AV.
5695 * });
5696 * }</pre>
5697 *
5698 * @class
5699 * @param [mimeType] {String} Content-Type header to use for the file. If
5700 * this is omitted, the content type will be inferred from the name's
5701 * extension.
5702 */
5703 AV.File = function (name, data, mimeType) {
5704
5705 this.attributes = {
5706 name: name,
5707 url: '',
5708 metaData: {},
5709 // 用æ¥å˜å‚¨è½¬æ¢åŽè¦ä¸Šä¼ çš„ base64 String
5710 base64: ''
5711 };
5712
5713 this._extName = '';
5714
5715 var owner = void 0;
5716 if (data && data.owner) {
5717 owner = data.owner;
5718 } else if (!AV._config.disableCurrentUser) {
5719 try {
5720 owner = AV.User.current();
5721 } catch (error) {
5722 if ('SYNC_API_NOT_AVAILABLE' === error.code) {
5723 console.warn('Get current user failed. It seems this runtime use an async storage system, please create AV.File in the callback of AV.User.currentAsync().');
5724 } else {
5725 throw error;
5726 }
5727 }
5728 }
5729
5730 this.attributes.metaData = {
5731 owner: owner ? owner.id : 'unknown'
5732 };
5733
5734 this.set('mime_type', mimeType);
5735
5736 if (_.isArray(data)) {
5737 this.attributes.metaData.size = data.length;
5738 data = { base64: encodeBase64(data) };
5739 }
5740 if (data && data.base64) {
5741 var parseBase64 = __webpack_require__(47);
5742 var dataBase64 = parseBase64(data.base64, mimeType);
5743 this._source = Promise.resolve({ data: dataBase64, type: mimeType });
5744 } else if (data && data.blob) {
5745 if (!data.blob.type && mimeType) {
5746 data.blob.type = mimeType;
5747 }
5748 if (!data.blob.name) {
5749 data.blob.name = name;
5750 }
5751 if (true) {
5752 this._extName = extname(data.blob.uri);
5753 }
5754 this._source = Promise.resolve({ data: data.blob, type: mimeType });
5755 } else if (typeof File !== "undefined" && data instanceof File) {
5756 if (data.size) {
5757 this.attributes.metaData.size = data.size;
5758 }
5759 if (data.name) {
5760 this._extName = extname(data.name);
5761 }
5762 this._source = Promise.resolve({ data: data, type: mimeType });
5763 } else if (typeof Buffer !== "undefined" && Buffer.isBuffer(data)) {
5764 this.attributes.metaData.size = data.length;
5765 this._source = Promise.resolve({ data: data, type: mimeType });
5766 } else if (_.isString(data)) {
5767 throw new Error("Creating a AV.File from a String is not yet supported.");
5768 }
5769 };
5770
5771 /**
5772 * Creates a fresh AV.File object with exists url for saving to AVOS Cloud.
5773 * @param {String} name the file name
5774 * @param {String} url the file url.
5775 * @param {Object} [metaData] the file metadata object.
5776 * @param {String} [type] Content-Type header to use for the file. If
5777 * this is omitted, the content type will be inferred from the name's
5778 * extension.
5779 * @return {AV.File} the file object
5780 */
5781 AV.File.withURL = function (name, url, metaData, type) {
5782 if (!name || !url) {
5783 throw new Error("Please provide file name and url");
5784 }
5785 var file = new AV.File(name, null, type);
5786 //copy metaData properties to file.
5787 if (metaData) {
5788 for (var prop in metaData) {
5789 if (!file.attributes.metaData[prop]) file.attributes.metaData[prop] = metaData[prop];
5790 }
5791 }
5792 file.attributes.url = url;
5793 //Mark the file is from external source.
5794 file.attributes.metaData.__source = 'external';
5795 return file;
5796 };
5797
5798 /**
5799 * Creates a file object with exists objectId.
5800 * @param {String} objectId The objectId string
5801 * @return {AV.File} the file object
5802 */
5803 AV.File.createWithoutData = function (objectId) {
5804 var file = new AV.File();
5805 file.id = objectId;
5806 return file;
5807 };
5808
5809 AV.File.prototype = {
5810 className: '_File',
5811
5812 _toFullJSON: function _toFullJSON(seenObjects) {
5813 var _this = this;
5814
5815 var json = _.clone(this.attributes);
5816 AV._objectEach(json, function (val, key) {
5817 json[key] = AV._encode(val, seenObjects);
5818 });
5819 AV._objectEach(this._operations, function (val, key) {
5820 json[key] = val;
5821 });
5822
5823 if (_.has(this, "id")) {
5824 json.objectId = this.id;
5825 }
5826 _(['createdAt', 'updatedAt']).each(function (key) {
5827 if (_.has(_this, key)) {
5828 var val = _this[key];
5829 json[key] = _.isDate(val) ? val.toJSON() : val;
5830 }
5831 });
5832 json.__type = "File";
5833 return json;
5834 },
5835 toJSON: function toJSON() {
5836 var json = this._toFullJSON();
5837 // add id and keep __type for backward compatible
5838 if (_.has(this, 'id')) {
5839 json.id = this.id;
5840 }
5841 return json;
5842 },
5843
5844
5845 /**
5846 * Returns the ACL for this file.
5847 * @returns {AV.ACL} An instance of AV.ACL.
5848 */
5849 getACL: function getACL() {
5850 return this._acl;
5851 },
5852
5853 /**
5854 * Sets the ACL to be used for this file.
5855 * @param {AV.ACL} acl An instance of AV.ACL.
5856 */
5857 setACL: function setACL(acl) {
5858 if (!(acl instanceof AV.ACL)) {
5859 return new AVError(AVError.OTHER_CAUSE, 'ACL must be a AV.ACL.');
5860 }
5861 this._acl = acl;
5862 },
5863
5864 /**
5865 * Gets the name of the file. Before save is called, this is the filename
5866 * given by the user. After save is called, that name gets prefixed with a
5867 * unique identifier.
5868 */
5869 name: function name() {
5870 return this.get('name');
5871 },
5872
5873 /**
5874 * Gets the url of the file. It is only available after you save the file or
5875 * after you get the file from a AV.Object.
5876 * @return {String}
5877 */
5878 url: function url() {
5879 return this.get('url');
5880 },
5881
5882 /**
5883 * Gets the attributs of the file object.
5884 * @param {String} The attribute name which want to get.
5885 * @returns {Any}
5886 */
5887 get: function get(attrName) {
5888 switch (attrName) {
5889 case 'objectId':
5890 return this.id;
5891 case 'url':
5892 case 'name':
5893 case 'mime_type':
5894 case 'metaData':
5895 case 'createdAt':
5896 case 'updatedAt':
5897 return this.attributes[attrName];
5898 default:
5899 return this.attributes.metaData[attrName];
5900 }
5901 },
5902
5903 /**
5904 * Set the metaData of the file object.
5905 * @param {Object} Object is an key value Object for setting metaData.
5906 * @param {String} attr is an optional metadata key.
5907 * @param {Object} value is an optional metadata value.
5908 * @returns {String|Number|Array|Object}
5909 */
5910 set: function set() {
5911 var _this2 = this;
5912
5913 var set = function set(attrName, value) {
5914 switch (attrName) {
5915 case 'name':
5916 case 'url':
5917 case 'mime_type':
5918 case 'base64':
5919 case 'metaData':
5920 _this2.attributes[attrName] = value;
5921 break;
5922 default:
5923 // File å¹¶éžä¸€ä¸ª AVObject,ä¸èƒ½å®Œå…¨è‡ªå®šä¹‰å…¶ä»–属性,所以åªèƒ½éƒ½æ”¾åœ¨ metaData 上é¢
5924 _this2.attributes.metaData[attrName] = value;
5925 break;
5926 }
5927 };
5928
5929 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
5930 args[_key] = arguments[_key];
5931 }
5932
5933 switch (args.length) {
5934 case 1:
5935 // ä¼ å…¥ä¸€ä¸ª Object
5936 for (var k in args[0]) {
5937 set(k, args[0][k]);
5938 }
5939 break;
5940 case 2:
5941 set(args[0], args[1]);
5942 break;
5943 }
5944 },
5945
5946 /**
5947 * <p>Returns the file's metadata JSON object if no arguments is given.Returns the
5948 * metadata value if a key is given.Set metadata value if key and value are both given.</p>
5949 * <p><pre>
5950 * var metadata = file.metaData(); //Get metadata JSON object.
5951 * var size = file.metaData('size'); // Get the size metadata value.
5952 * file.metaData('format', 'jpeg'); //set metadata attribute and value.
5953 *</pre></p>
5954 * @return {Object} The file's metadata JSON object.
5955 * @param {String} attr an optional metadata key.
5956 * @param {Object} value an optional metadata value.
5957 **/
5958 metaData: function metaData(attr, value) {
5959 if (attr && value) {
5960 this.attributes.metaData[attr] = value;
5961 return this;
5962 } else if (attr && !value) {
5963 return this.attributes.metaData[attr];
5964 } else {
5965 return this.attributes.metaData;
5966 }
5967 },
5968
5969 /**
5970 * 如果文件是图片,获å–图片的缩略图URL。å¯ä»¥ä¼ 入宽度ã€é«˜åº¦ã€è´¨é‡ã€æ ¼å¼ç‰å‚数。
5971 * @return {String} 缩略图URL
5972 * @param {Number} width 宽度,å•ä½ï¼šåƒç´
5973 * @param {Number} heigth 高度,å•ä½ï¼šåƒç´
5974 * @param {Number} quality è´¨é‡ï¼Œ1-100的数å—,默认100
5975 * @param {Number} scaleToFit 是å¦å°†å›¾ç‰‡è‡ªé€‚应大å°ã€‚默认为true。
5976 * @param {String} fmt æ ¼å¼ï¼Œé»˜è®¤ä¸ºpng,也å¯ä»¥ä¸ºjpeg,gifç‰æ ¼å¼ã€‚
5977 */
5978
5979 thumbnailURL: function thumbnailURL(width, height, quality, scaleToFit, fmt) {
5980 var url = this.attributes.url;
5981 if (!url) {
5982 throw new Error('Invalid url.');
5983 }
5984 if (!width || !height || width <= 0 || height <= 0) {
5985 throw new Error('Invalid width or height value.');
5986 }
5987 quality = quality || 100;
5988 scaleToFit = !scaleToFit ? true : scaleToFit;
5989 if (quality <= 0 || quality > 100) {
5990 throw new Error('Invalid quality value.');
5991 }
5992 fmt = fmt || 'png';
5993 var mode = scaleToFit ? 2 : 1;
5994 return url + '?imageView/' + mode + '/w/' + width + '/h/' + height + '/q/' + quality + '/format/' + fmt;
5995 },
5996
5997 /**
5998 * Returns the file's size.
5999 * @return {Number} The file's size in bytes.
6000 **/
6001 size: function size() {
6002 return this.metaData().size;
6003 },
6004
6005 /**
6006 * Returns the file's owner.
6007 * @return {String} The file's owner id.
6008 */
6009 ownerId: function ownerId() {
6010 return this.metaData().owner;
6011 },
6012
6013 /**
6014 * Destroy the file.
6015 * @param {AuthOptions} options
6016 * @return {Promise} A promise that is fulfilled when the destroy
6017 * completes.
6018 */
6019 destroy: function destroy(options) {
6020 if (!this.id) {
6021 return Promise.reject(new Error('The file id is not eixsts.'));
6022 }
6023 var request = AVRequest("files", null, this.id, 'DELETE', null, options);
6024 return request;
6025 },
6026
6027 /**
6028 * Request Qiniu upload token
6029 * @param {string} type
6030 * @return {Promise} Resolved with the response
6031 * @private
6032 */
6033 _fileToken: function _fileToken(type) {
6034 var route = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'fileTokens';
6035
6036 var name = this.attributes.name;
6037
6038 // Create 16-bits uuid as qiniu key.
6039 var extName = extname(name) || this._extName;
6040 var key = hexOctet() + hexOctet() + hexOctet() + hexOctet() + hexOctet() + extName;
6041 var data = {
6042 key: key,
6043 name: name,
6044 ACL: this._acl,
6045 mime_type: type,
6046 metaData: this.attributes.metaData
6047 };
6048 this._qiniu_key = key;
6049 return AVRequest(route, null, null, 'POST', data);
6050 },
6051
6052
6053 /**
6054 * @callback UploadProgressCallback
6055 * @param {XMLHttpRequestProgressEvent} event - The progress event with 'loaded' and 'total' attributes
6056 */
6057 /**
6058 * Saves the file to the AV cloud.
6059 * @param {Object} [options]
6060 * @param {UploadProgressCallback} [options.onprogress] æ–‡ä»¶ä¸Šä¼ è¿›åº¦ï¼Œåœ¨ Node.js 与å°ç¨‹åºä¸æ— æ•ˆï¼Œå›žè°ƒå‚æ•°è¯´æ˜Žè¯¦è§ {@link UploadProgressCallback}。
6061 * @return {Promise} Promise that is resolved when the save finishes.
6062 */
6063 save: function save(options) {
6064 var _this3 = this;
6065
6066 if (this.id) {
6067 throw new Error('File already saved. If you want to manipulate a file, use AV.Query to get it.');
6068 }
6069 if (!this._previousSave) {
6070 if (this._source) {
6071 this._previousSave = this._source.then(function (_ref) {
6072 var data = _ref.data,
6073 type = _ref.type;
6074 return _this3._fileToken(type).then(function (uploadInfo) {
6075 if (uploadInfo.mime_type) {
6076 _this3.set('mime_type', uploadInfo.mime_type);
6077 }
6078 _this3._token = uploadInfo.token;
6079
6080 var uploadPromise = void 0;
6081 switch (uploadInfo.provider) {
6082 case 's3':
6083 uploadPromise = s3(uploadInfo, data, _this3, options);
6084 break;
6085 case 'qcloud':
6086 uploadPromise = cos(uploadInfo, data, _this3, options);
6087 break;
6088 case 'qiniu':
6089 default:
6090 uploadPromise = qiniu(uploadInfo, data, _this3, options);
6091 break;
6092 }
6093 return uploadPromise.then(tap(function () {
6094 return _this3._callback(true);
6095 }), function (error) {
6096 _this3._callback(false);
6097 throw error;
6098 });
6099 });
6100 });
6101 } else if (this.attributes.url && this.attributes.metaData.__source === 'external') {
6102 // external link file.
6103 var data = {
6104 name: this.attributes.name,
6105 ACL: this._acl,
6106 metaData: this.attributes.metaData,
6107 mime_type: this.mimeType,
6108 url: this.attributes.url
6109 };
6110 this._previousSave = AVRequest('files', this.attributes.name, null, 'post', data).then(function (response) {
6111 _this3.attributes.name = response.name;
6112 _this3.attributes.url = response.url;
6113 _this3.id = response.objectId;
6114 if (response.size) {
6115 _this3.attributes.metaData.size = response.size;
6116 }
6117 return _this3;
6118 });
6119 }
6120 }
6121 return this._previousSave;
6122 },
6123 _callback: function _callback(success) {
6124 AVRequest('fileCallback', null, null, 'post', {
6125 token: this._token,
6126 result: success
6127 }).catch(debug);
6128 delete this._token;
6129 },
6130
6131
6132 /**
6133 * fetch the file from server. If the server's representation of the
6134 * model differs from its current attributes, they will be overriden,
6135 * @param {AuthOptions} options AuthOptions plus 'keys' and 'include' option.
6136 * @return {Promise} A promise that is fulfilled when the fetch
6137 * completes.
6138 */
6139 fetch: function fetch(options) {
6140 var options = null;
6141
6142 var request = AVRequest('files', null, this.id, 'GET', options);
6143 return request.then(this._finishFetch.bind(this));
6144 },
6145 _finishFetch: function _finishFetch(response) {
6146 var value = AV.Object.prototype.parse(response);
6147 value.attributes = {
6148 name: value.name,
6149 url: value.url,
6150 mime_type: value.mime_type,
6151 bucket: value.bucket
6152 };
6153 value.attributes.metaData = value.metaData || {};
6154 value.id = value.objectId;
6155 // clean
6156 delete value.objectId;
6157 delete value.metaData;
6158 delete value.url;
6159 delete value.name;
6160 delete value.mime_type;
6161 delete value.bucket;
6162 _.extend(this, value);
6163 return this;
6164 }
6165 };
6166};
6167
6168/***/ }),
6169/* 29 */
6170/***/ (function(module, exports, __webpack_require__) {
6171
6172"use strict";
6173
6174
6175var _ = __webpack_require__(0);
6176
6177/*global navigator: false */
6178module.exports = function (AV) {
6179 /**
6180 * Creates a new GeoPoint with any of the following forms:<br>
6181 * @example
6182 * new GeoPoint(otherGeoPoint)
6183 * new GeoPoint(30, 30)
6184 * new GeoPoint([30, 30])
6185 * new GeoPoint({latitude: 30, longitude: 30})
6186 * new GeoPoint() // defaults to (0, 0)
6187 * @class
6188 *
6189 * <p>Represents a latitude / longitude point that may be associated
6190 * with a key in a AVObject or used as a reference point for geo queries.
6191 * This allows proximity-based queries on the key.</p>
6192 *
6193 * <p>Only one key in a class may contain a GeoPoint.</p>
6194 *
6195 * <p>Example:<pre>
6196 * var point = new AV.GeoPoint(30.0, -20.0);
6197 * var object = new AV.Object("PlaceObject");
6198 * object.set("location", point);
6199 * object.save();</pre></p>
6200 */
6201 AV.GeoPoint = function (arg1, arg2) {
6202 if (_.isArray(arg1)) {
6203 AV.GeoPoint._validate(arg1[0], arg1[1]);
6204 this.latitude = arg1[0];
6205 this.longitude = arg1[1];
6206 } else if (_.isObject(arg1)) {
6207 AV.GeoPoint._validate(arg1.latitude, arg1.longitude);
6208 this.latitude = arg1.latitude;
6209 this.longitude = arg1.longitude;
6210 } else if (_.isNumber(arg1) && _.isNumber(arg2)) {
6211 AV.GeoPoint._validate(arg1, arg2);
6212 this.latitude = arg1;
6213 this.longitude = arg2;
6214 } else {
6215 this.latitude = 0;
6216 this.longitude = 0;
6217 }
6218
6219 // Add properties so that anyone using Webkit or Mozilla will get an error
6220 // if they try to set values that are out of bounds.
6221 var self = this;
6222 if (this.__defineGetter__ && this.__defineSetter__) {
6223 // Use _latitude and _longitude to actually store the values, and add
6224 // getters and setters for latitude and longitude.
6225 this._latitude = this.latitude;
6226 this._longitude = this.longitude;
6227 this.__defineGetter__("latitude", function () {
6228 return self._latitude;
6229 });
6230 this.__defineGetter__("longitude", function () {
6231 return self._longitude;
6232 });
6233 this.__defineSetter__("latitude", function (val) {
6234 AV.GeoPoint._validate(val, self.longitude);
6235 self._latitude = val;
6236 });
6237 this.__defineSetter__("longitude", function (val) {
6238 AV.GeoPoint._validate(self.latitude, val);
6239 self._longitude = val;
6240 });
6241 }
6242 };
6243
6244 /**
6245 * @lends AV.GeoPoint.prototype
6246 * @property {float} latitude North-south portion of the coordinate, in range
6247 * [-90, 90]. Throws an exception if set out of range in a modern browser.
6248 * @property {float} longitude East-west portion of the coordinate, in range
6249 * [-180, 180]. Throws if set out of range in a modern browser.
6250 */
6251
6252 /**
6253 * Throws an exception if the given lat-long is out of bounds.
6254 * @private
6255 */
6256 AV.GeoPoint._validate = function (latitude, longitude) {
6257 if (latitude < -90.0) {
6258 throw new Error("AV.GeoPoint latitude " + latitude + " < -90.0.");
6259 }
6260 if (latitude > 90.0) {
6261 throw new Error("AV.GeoPoint latitude " + latitude + " > 90.0.");
6262 }
6263 if (longitude < -180.0) {
6264 throw new Error("AV.GeoPoint longitude " + longitude + " < -180.0.");
6265 }
6266 if (longitude > 180.0) {
6267 throw new Error("AV.GeoPoint longitude " + longitude + " > 180.0.");
6268 }
6269 };
6270
6271 /**
6272 * Creates a GeoPoint with the user's current location, if available.
6273 * @return {Promise.<AV.GeoPoint>}
6274 */
6275 AV.GeoPoint.current = function () {
6276 return new AV.Promise(function (resolve, reject) {
6277 navigator.geolocation.getCurrentPosition(function (location) {
6278 resolve(new AV.GeoPoint({
6279 latitude: location.coords.latitude,
6280 longitude: location.coords.longitude
6281 }));
6282 }, reject);
6283 });
6284 };
6285
6286 AV.GeoPoint.prototype = {
6287 /**
6288 * Returns a JSON representation of the GeoPoint, suitable for AV.
6289 * @return {Object}
6290 */
6291 toJSON: function toJSON() {
6292 AV.GeoPoint._validate(this.latitude, this.longitude);
6293 return {
6294 "__type": "GeoPoint",
6295 latitude: this.latitude,
6296 longitude: this.longitude
6297 };
6298 },
6299
6300 /**
6301 * Returns the distance from this GeoPoint to another in radians.
6302 * @param {AV.GeoPoint} point the other AV.GeoPoint.
6303 * @return {Number}
6304 */
6305 radiansTo: function radiansTo(point) {
6306 var d2r = Math.PI / 180.0;
6307 var lat1rad = this.latitude * d2r;
6308 var long1rad = this.longitude * d2r;
6309 var lat2rad = point.latitude * d2r;
6310 var long2rad = point.longitude * d2r;
6311 var deltaLat = lat1rad - lat2rad;
6312 var deltaLong = long1rad - long2rad;
6313 var sinDeltaLatDiv2 = Math.sin(deltaLat / 2);
6314 var sinDeltaLongDiv2 = Math.sin(deltaLong / 2);
6315 // Square of half the straight line chord distance between both points.
6316 var a = sinDeltaLatDiv2 * sinDeltaLatDiv2 + Math.cos(lat1rad) * Math.cos(lat2rad) * sinDeltaLongDiv2 * sinDeltaLongDiv2;
6317 a = Math.min(1.0, a);
6318 return 2 * Math.asin(Math.sqrt(a));
6319 },
6320
6321 /**
6322 * Returns the distance from this GeoPoint to another in kilometers.
6323 * @param {AV.GeoPoint} point the other AV.GeoPoint.
6324 * @return {Number}
6325 */
6326 kilometersTo: function kilometersTo(point) {
6327 return this.radiansTo(point) * 6371.0;
6328 },
6329
6330 /**
6331 * Returns the distance from this GeoPoint to another in miles.
6332 * @param {AV.GeoPoint} point the other AV.GeoPoint.
6333 * @return {Number}
6334 */
6335 milesTo: function milesTo(point) {
6336 return this.radiansTo(point) * 3958.8;
6337 }
6338 };
6339};
6340
6341/***/ }),
6342/* 30 */
6343/***/ (function(module, exports, __webpack_require__) {
6344
6345"use strict";
6346
6347
6348var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
6349
6350var AV = __webpack_require__(6);
6351var request = __webpack_require__(2);
6352
6353var initialize = function initialize(appId, appKey, masterKey, hookKey) {
6354 if (AV.applicationId && appId !== AV.applicationId && appKey !== AV.applicationKey && masterKey !== AV.masterKey) {
6355 console.warn('LeanCloud SDK is already initialized, please do not reinitialize it.');
6356 }
6357 AV.applicationId = appId;
6358 AV.applicationKey = appKey;
6359 AV.masterKey = masterKey;
6360 if (false) {
6361 AV.hookKey = hookKey || process.env.LEANCLOUD_APP_HOOK_KEY;
6362 }
6363 AV._useMasterKey = false;
6364};
6365
6366var masterKeyWarn = function masterKeyWarn() {
6367 console.warn('MasterKey is not supposed to be used in browser.');
6368};
6369
6370/**
6371 * Call this method first to set up your authentication tokens for AV.
6372 * You can get your app keys from the LeanCloud dashboard on http://leancloud.cn .
6373 * @function AV.init
6374 * @param {Object} options
6375 * @param {String} options.appId application id
6376 * @param {String} options.appKey application key
6377 * @param {String} options.masterKey application master key
6378*/
6379
6380AV.init = function () {
6381 switch (arguments.length) {
6382 case 1:
6383 var options = arguments.length <= 0 ? undefined : arguments[0];
6384 if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {
6385 if ("Weapp" && options.masterKey) {
6386 masterKeyWarn();
6387 }
6388 initialize(options.appId, options.appKey, options.masterKey, options.hookKey);
6389 request.setServerUrlByRegion(options.region);
6390 AV._config.disableCurrentUser = options.disableCurrentUser;
6391 } else {
6392 throw new Error('AV.init(): Parameter is not correct.');
6393 }
6394 break;
6395 // 兼容旧版本的åˆå§‹åŒ–方法
6396 case 2:
6397 case 3:
6398 console.warn('Please use AV.init() to replace AV.initialize(), ' + 'AV.init() need an Object param, like { appId: \'YOUR_APP_ID\', appKey: \'YOUR_APP_KEY\' } . ' + 'Docs: https://leancloud.cn/docs/sdk_setup-js.html');
6399 if ("Weapp" && arguments.length === 3) {
6400 masterKeyWarn();
6401 }
6402 initialize.apply(undefined, arguments);
6403 request.setServerUrlByRegion('cn');
6404 break;
6405 }
6406};
6407
6408// If we're running in node.js, allow using the master key.
6409if (false) {
6410 AV.Cloud = AV.Cloud || {};
6411 /**
6412 * Switches the LeanCloud SDK to using the Master key. The Master key grants
6413 * priveleged access to the data in LeanCloud and can be used to bypass ACLs and
6414 * other restrictions that are applied to the client SDKs.
6415 * <p><strong><em>Available in Cloud Code and Node.js only.</em></strong>
6416 * </p>
6417 */
6418 AV.Cloud.useMasterKey = function () {
6419 AV._useMasterKey = true;
6420 };
6421}
6422
6423// 兼容è€ç‰ˆæœ¬çš„åˆå§‹åŒ–方法
6424AV.initialize = AV.init;
6425
6426/***/ }),
6427/* 31 */
6428/***/ (function(module, exports, __webpack_require__) {
6429
6430"use strict";
6431
6432
6433var _ = __webpack_require__(0);
6434var AVError = __webpack_require__(3);
6435var AVRequest = __webpack_require__(2).request;
6436
6437module.exports = function (AV) {
6438 /**
6439 * 包å«äº†ä½¿ç”¨äº† LeanCloud
6440 * <a href='/docs/leaninsight_guide.html'>离线数æ®åˆ†æžåŠŸèƒ½</a>的函数。
6441 * <p><strong><em>
6442 * 仅在云引擎è¿è¡ŒçŽ¯å¢ƒä¸‹æœ‰æ•ˆã€‚
6443 * </em></strong></p>
6444 * @namespace
6445 */
6446 AV.Insight = AV.Insight || {};
6447
6448 _.extend(AV.Insight, /** @lends AV.Insight */{
6449
6450 /**
6451 * 开始一个 Insight 任务。结果里将返回 Job idï¼Œä½ å¯ä»¥æ‹¿å¾—到的 id 使用
6452 * AV.Insight.JobQuery 查询任务状æ€å’Œç»“果。
6453 * @param {Object} jobConfig 任务é…置的 JSON 对象,例如:<code><pre>
6454 * { "sql" : "select count(*) as c,gender from _User group by gender",
6455 * "saveAs": {
6456 * "className" : "UserGender",
6457 * "limit": 1
6458 * }
6459 * }
6460 * </pre></code>
6461 * sql 指定任务执行的 SQL è¯å¥ï¼Œ saveAs(å¯é€‰ï¼‰ 指定将结果ä¿å˜åœ¨å“ªå¼ 表里,limit 最大 1000。
6462 * @param {AuthOptions} [options]
6463 * @return {Promise} A promise that will be resolved with the result
6464 * of the function.
6465 */
6466 startJob: function startJob(jobConfig, options) {
6467 if (!jobConfig || !jobConfig.sql) {
6468 throw new Error('Please provide the sql to run the job.');
6469 }
6470 var data = {
6471 jobConfig: jobConfig,
6472 appId: AV.applicationId
6473 };
6474 var request = AVRequest("bigquery", 'jobs', null, 'POST', AV._encode(data, null, true), options);
6475
6476 return request.then(function (resp) {
6477 return AV._decode(resp).id;
6478 });
6479 },
6480
6481 /**
6482 * ç›‘å¬ Insight 任务事件,目å‰ä»…æ”¯æŒ end 事件,表示任务完æˆã€‚
6483 * <p><strong><em>
6484 * 仅在云引擎è¿è¡ŒçŽ¯å¢ƒä¸‹æœ‰æ•ˆã€‚
6485 * </em></strong></p>
6486 * @param {String} event 监å¬çš„事件,目å‰ä»…æ”¯æŒ 'end' ,表示任务完æˆ
6487 * @param {Function} 监å¬å›žè°ƒå‡½æ•°ï¼ŒæŽ¥æ”¶ (err, id) ä¸¤ä¸ªå‚æ•°ï¼Œerr 表示错误信æ¯ï¼Œ
6488 * id 表示任务 id。接下æ¥ä½ å¯ä»¥æ‹¿è¿™ä¸ª id 使用AV.Insight.JobQuery 查询任务状æ€å’Œç»“果。
6489 *
6490 */
6491 on: function on(event, cb) {}
6492 });
6493
6494 /**
6495 * 创建一个对象,用于查询 Insight 任务状æ€å’Œç»“果。
6496 * @class
6497 * @param {String} id 任务 id
6498 * @since 0.5.5
6499 */
6500 AV.Insight.JobQuery = function (id, className) {
6501 if (!id) {
6502 throw new Error('Please provide the job id.');
6503 }
6504 this.id = id;
6505 this.className = className;
6506 this._skip = 0;
6507 this._limit = 100;
6508 };
6509
6510 AV.Insight.JobQuery.prototype = {
6511
6512 /**
6513 * Sets the number of results to skip before returning any results.
6514 * This is useful for pagination.
6515 * Default is to skip zero results.
6516 * @param {Number} n the number of results to skip.
6517 * @return {AV.Query} Returns the query, so you can chain this call.
6518 */
6519 skip: function skip(n) {
6520 this._skip = n;
6521 return this;
6522 },
6523
6524 /**
6525 * Sets the limit of the number of results to return. The default limit is
6526 * 100, with a maximum of 1000 results being returned at a time.
6527 * @param {Number} n the number of results to limit to.
6528 * @return {AV.Query} Returns the query, so you can chain this call.
6529 */
6530 limit: function limit(n) {
6531 this._limit = n;
6532 return this;
6533 },
6534
6535 /**
6536 * 查询任务状æ€å’Œç»“果,任务结果为一个 JSON 对象,包括 status 表示任务状æ€ï¼Œ totalCount 表示总数,
6537 * results 数组表示任务结果数组,previewCount 表示å¯ä»¥è¿”å›žçš„ç»“æžœæ€»æ•°ï¼Œä»»åŠ¡çš„å¼€å§‹å’Œæˆªæ¢æ—¶é—´
6538 * startTimeã€endTime ç‰ä¿¡æ¯ã€‚
6539 *
6540 * @param {AuthOptions} [options]
6541 * @return {Promise} A promise that will be resolved with the result
6542 * of the function.
6543 *
6544 */
6545 find: function find(options) {
6546 var params = {
6547 skip: this._skip,
6548 limit: this._limit
6549 };
6550
6551 var request = AVRequest("bigquery", 'jobs', this.id, "GET", params, options);
6552 var self = this;
6553 return request.then(function (response) {
6554 if (response.error) {
6555 return AV.Promise.reject(new AVError(response.code, response.error));
6556 }
6557 return AV.Promise.resolve(response);
6558 });
6559 }
6560
6561 };
6562};
6563
6564/***/ }),
6565/* 32 */
6566/***/ (function(module, exports, __webpack_require__) {
6567
6568"use strict";
6569
6570
6571var _ = __webpack_require__(0);
6572var AVError = __webpack_require__(3);
6573var AVRequest = __webpack_require__(2).request;
6574var utils = __webpack_require__(4);
6575
6576var RESERVED_KEYS = ['objectId', 'createdAt', 'updatedAt'];
6577var checkReservedKey = function checkReservedKey(key) {
6578 if (RESERVED_KEYS.indexOf(key) !== -1) {
6579 throw new Error('key[' + key + '] is reserved');
6580 }
6581};
6582
6583// AV.Object is analogous to the Java AVObject.
6584// It also implements the same interface as a Backbone model.
6585
6586module.exports = function (AV) {
6587 /**
6588 * Creates a new model with defined attributes. A client id (cid) is
6589 * automatically generated and assigned for you.
6590 *
6591 * <p>You won't normally call this method directly. It is recommended that
6592 * you use a subclass of <code>AV.Object</code> instead, created by calling
6593 * <code>extend</code>.</p>
6594 *
6595 * <p>However, if you don't want to use a subclass, or aren't sure which
6596 * subclass is appropriate, you can use this form:<pre>
6597 * var object = new AV.Object("ClassName");
6598 * </pre>
6599 * That is basically equivalent to:<pre>
6600 * var MyClass = AV.Object.extend("ClassName");
6601 * var object = new MyClass();
6602 * </pre></p>
6603 *
6604 * @param {Object} attributes The initial set of data to store in the object.
6605 * @param {Object} options A set of Backbone-like options for creating the
6606 * object. The only option currently supported is "collection".
6607 * @see AV.Object.extend
6608 *
6609 * @class
6610 *
6611 * <p>The fundamental unit of AV data, which implements the Backbone Model
6612 * interface.</p>
6613 */
6614 AV.Object = function (attributes, options) {
6615 // Allow new AV.Object("ClassName") as a shortcut to _create.
6616 if (_.isString(attributes)) {
6617 return AV.Object._create.apply(this, arguments);
6618 }
6619
6620 attributes = attributes || {};
6621 if (options && options.parse) {
6622 attributes = this.parse(attributes);
6623 attributes = this._mergeMagicFields(attributes);
6624 }
6625 var defaults = AV._getValue(this, 'defaults');
6626 if (defaults) {
6627 attributes = _.extend({}, defaults, attributes);
6628 }
6629 if (options && options.collection) {
6630 this.collection = options.collection;
6631 }
6632
6633 this._serverData = {}; // The last known data for this object from cloud.
6634 this._opSetQueue = [{}]; // List of sets of changes to the data.
6635 this._flags = {};
6636 this.attributes = {}; // The best estimate of this's current data.
6637
6638 this._hashedJSON = {}; // Hash of values of containers at last save.
6639 this._escapedAttributes = {};
6640 this.cid = _.uniqueId('c');
6641 this.changed = {};
6642 this._silent = {};
6643 this._pending = {};
6644 this.set(attributes, { silent: true });
6645 this.changed = {};
6646 this._silent = {};
6647 this._pending = {};
6648 this._hasData = true;
6649 this._previousAttributes = _.clone(this.attributes);
6650 this.initialize.apply(this, arguments);
6651 };
6652
6653 /**
6654 * @lends AV.Object.prototype
6655 * @property {String} id The objectId of the AV Object.
6656 */
6657
6658 /**
6659 * Saves the given list of AV.Object.
6660 * If any error is encountered, stops and calls the error handler.
6661 *
6662 * <pre>
6663 * AV.Object.saveAll([object1, object2, ...]).then(function(list) {
6664 * // All the objects were saved.
6665 * }, function(error) {
6666 * // An error occurred while saving one of the objects.
6667 * });
6668 *
6669 * @param {Array} list A list of <code>AV.Object</code>.
6670 */
6671 AV.Object.saveAll = function (list, options) {
6672 return AV.Object._deepSaveAsync(list, null, options);
6673 };
6674
6675 /**
6676 * Fetch the given list of AV.Object.
6677 *
6678 * @param {AV.Object[]} objects A list of <code>AV.Object</code>
6679 * @param {AuthOptions} options
6680 * @return {Promise.<AV.Object[]>} The given list of <code>AV.Object</code>, updated
6681 */
6682
6683 AV.Object.fetchAll = function (objects, options) {
6684 return AV.Promise.resolve().then(function () {
6685 return AVRequest('batch', null, null, 'POST', {
6686 requests: _.map(objects, function (object) {
6687 if (!object.className) throw new Error('object must have className to fetch');
6688 if (!object.id) throw new Error('object must have id to fetch');
6689 if (object.dirty()) throw new Error('object is modified but not saved');
6690 return {
6691 method: 'GET',
6692 path: '/1.1/classes/' + object.className + '/' + object.id
6693 };
6694 })
6695 }, options);
6696 }).then(function (response) {
6697 _.forEach(objects, function (object, i) {
6698 if (response[i].success) {
6699 object._finishFetch(object.parse(response[i].success));
6700 } else {
6701 var error = new Error(response[i].error.error);
6702 error.code = response[i].error.code;
6703 throw error;
6704 }
6705 });
6706 return objects;
6707 });
6708 };
6709
6710 // Attach all inheritable methods to the AV.Object prototype.
6711 _.extend(AV.Object.prototype, AV.Events,
6712 /** @lends AV.Object.prototype */{
6713 _fetchWhenSave: false,
6714
6715 /**
6716 * Initialize is an empty function by default. Override it with your own
6717 * initialization logic.
6718 */
6719 initialize: function initialize() {},
6720
6721 /**
6722 * Set whether to enable fetchWhenSave option when updating object.
6723 * When set true, SDK would fetch the latest object after saving.
6724 * Default is false.
6725 *
6726 * @deprecated use AV.Object#save with options.fetchWhenSave instead
6727 * @param {boolean} enable true to enable fetchWhenSave option.
6728 */
6729 fetchWhenSave: function fetchWhenSave(enable) {
6730 console.warn('AV.Object#fetchWhenSave is deprecated, use AV.Object#save with options.fetchWhenSave instead.');
6731 if (!_.isBoolean(enable)) {
6732 throw new Error('Expect boolean value for fetchWhenSave');
6733 }
6734 this._fetchWhenSave = enable;
6735 },
6736
6737 /**
6738 * Returns the object's objectId.
6739 * @return {String} the objectId.
6740 */
6741 getObjectId: function getObjectId() {
6742 return this.id;
6743 },
6744
6745 /**
6746 * Returns the object's createdAt attribute.
6747 * @return {Date}
6748 */
6749 getCreatedAt: function getCreatedAt() {
6750 return this.createdAt || this.get('createdAt');
6751 },
6752
6753 /**
6754 * Returns the object's updatedAt attribute.
6755 * @return {Date}
6756 */
6757 getUpdatedAt: function getUpdatedAt() {
6758 return this.updatedAt || this.get('updatedAt');
6759 },
6760
6761 /**
6762 * Returns a JSON version of the object suitable for saving to AV.
6763 * @return {Object}
6764 */
6765 toJSON: function toJSON() {
6766 var json = this._toFullJSON();
6767 AV._arrayEach(["__type", "className"], function (key) {
6768 delete json[key];
6769 });
6770 return json;
6771 },
6772
6773 _toFullJSON: function _toFullJSON(seenObjects) {
6774 var _this = this;
6775
6776 var json = _.clone(this.attributes);
6777 AV._objectEach(json, function (val, key) {
6778 json[key] = AV._encode(val, seenObjects);
6779 });
6780 AV._objectEach(this._operations, function (val, key) {
6781 json[key] = val;
6782 });
6783
6784 if (_.has(this, "id")) {
6785 json.objectId = this.id;
6786 }
6787 _(['createdAt', 'updatedAt']).each(function (key) {
6788 if (_.has(_this, key)) {
6789 var val = _this[key];
6790 json[key] = _.isDate(val) ? val.toJSON() : val;
6791 }
6792 });
6793 json.__type = "Object";
6794 json.className = this.className;
6795 return json;
6796 },
6797
6798 /**
6799 * Updates _hashedJSON to reflect the current state of this object.
6800 * Adds any changed hash values to the set of pending changes.
6801 * @private
6802 */
6803 _refreshCache: function _refreshCache() {
6804 var self = this;
6805 if (self._refreshingCache) {
6806 return;
6807 }
6808 self._refreshingCache = true;
6809 AV._objectEach(this.attributes, function (value, key) {
6810 if (value instanceof AV.Object) {
6811 value._refreshCache();
6812 } else if (_.isObject(value)) {
6813 if (self._resetCacheForKey(key)) {
6814 self.set(key, new AV.Op.Set(value), { silent: true });
6815 }
6816 }
6817 });
6818 delete self._refreshingCache;
6819 },
6820
6821 /**
6822 * Returns true if this object has been modified since its last
6823 * save/refresh. If an attribute is specified, it returns true only if that
6824 * particular attribute has been modified since the last save/refresh.
6825 * @param {String} attr An attribute name (optional).
6826 * @return {Boolean}
6827 */
6828 dirty: function dirty(attr) {
6829 this._refreshCache();
6830
6831 var currentChanges = _.last(this._opSetQueue);
6832
6833 if (attr) {
6834 return currentChanges[attr] ? true : false;
6835 }
6836 if (!this.id) {
6837 return true;
6838 }
6839 if (_.keys(currentChanges).length > 0) {
6840 return true;
6841 }
6842 return false;
6843 },
6844
6845 /**
6846 * Gets a Pointer referencing this Object.
6847 * @private
6848 */
6849 _toPointer: function _toPointer() {
6850 // if (!this.id) {
6851 // throw new Error("Can't serialize an unsaved AV.Object");
6852 // }
6853 return { __type: "Pointer",
6854 className: this.className,
6855 objectId: this.id };
6856 },
6857
6858 /**
6859 * Gets the value of an attribute.
6860 * @param {String} attr The string name of an attribute.
6861 */
6862 get: function get(attr) {
6863 switch (attr) {
6864 case 'objectId':
6865 return this.id;
6866 case 'createdAt':
6867 case 'updatedAt':
6868 return this[attr];
6869 default:
6870 return this.attributes[attr];
6871 }
6872 },
6873
6874 /**
6875 * Gets a relation on the given class for the attribute.
6876 * @param {String} attr The attribute to get the relation for.
6877 * @return {AV.Relation}
6878 */
6879 relation: function relation(attr) {
6880 var value = this.get(attr);
6881 if (value) {
6882 if (!(value instanceof AV.Relation)) {
6883 throw new Error("Called relation() on non-relation field " + attr);
6884 }
6885 value._ensureParentAndKey(this, attr);
6886 return value;
6887 } else {
6888 return new AV.Relation(this, attr);
6889 }
6890 },
6891
6892 /**
6893 * Gets the HTML-escaped value of an attribute.
6894 */
6895 escape: function escape(attr) {
6896 var html = this._escapedAttributes[attr];
6897 if (html) {
6898 return html;
6899 }
6900 var val = this.attributes[attr];
6901 var escaped;
6902 if (utils.isNullOrUndefined(val)) {
6903 escaped = '';
6904 } else {
6905 escaped = _.escape(val.toString());
6906 }
6907 this._escapedAttributes[attr] = escaped;
6908 return escaped;
6909 },
6910
6911 /**
6912 * Returns <code>true</code> if the attribute contains a value that is not
6913 * null or undefined.
6914 * @param {String} attr The string name of the attribute.
6915 * @return {Boolean}
6916 */
6917 has: function has(attr) {
6918 return !utils.isNullOrUndefined(this.attributes[attr]);
6919 },
6920
6921 /**
6922 * Pulls "special" fields like objectId, createdAt, etc. out of attrs
6923 * and puts them on "this" directly. Removes them from attrs.
6924 * @param attrs - A dictionary with the data for this AV.Object.
6925 * @private
6926 */
6927 _mergeMagicFields: function _mergeMagicFields(attrs) {
6928 // Check for changes of magic fields.
6929 var model = this;
6930 var specialFields = ["objectId", "createdAt", "updatedAt"];
6931 AV._arrayEach(specialFields, function (attr) {
6932 if (attrs[attr]) {
6933 if (attr === "objectId") {
6934 model.id = attrs[attr];
6935 } else if ((attr === "createdAt" || attr === "updatedAt") && !_.isDate(attrs[attr])) {
6936 model[attr] = AV._parseDate(attrs[attr]);
6937 } else {
6938 model[attr] = attrs[attr];
6939 }
6940 delete attrs[attr];
6941 }
6942 });
6943 return attrs;
6944 },
6945
6946 /**
6947 * Returns the json to be sent to the server.
6948 * @private
6949 */
6950 _startSave: function _startSave() {
6951 this._opSetQueue.push({});
6952 },
6953
6954 /**
6955 * Called when a save fails because of an error. Any changes that were part
6956 * of the save need to be merged with changes made after the save. This
6957 * might throw an exception is you do conflicting operations. For example,
6958 * if you do:
6959 * object.set("foo", "bar");
6960 * object.set("invalid field name", "baz");
6961 * object.save();
6962 * object.increment("foo");
6963 * then this will throw when the save fails and the client tries to merge
6964 * "bar" with the +1.
6965 * @private
6966 */
6967 _cancelSave: function _cancelSave() {
6968 var self = this;
6969 var failedChanges = _.first(this._opSetQueue);
6970 this._opSetQueue = _.rest(this._opSetQueue);
6971 var nextChanges = _.first(this._opSetQueue);
6972 AV._objectEach(failedChanges, function (op, key) {
6973 var op1 = failedChanges[key];
6974 var op2 = nextChanges[key];
6975 if (op1 && op2) {
6976 nextChanges[key] = op2._mergeWithPrevious(op1);
6977 } else if (op1) {
6978 nextChanges[key] = op1;
6979 }
6980 });
6981 this._saving = this._saving - 1;
6982 },
6983
6984 /**
6985 * Called when a save completes successfully. This merges the changes that
6986 * were saved into the known server data, and overrides it with any data
6987 * sent directly from the server.
6988 * @private
6989 */
6990 _finishSave: function _finishSave(serverData) {
6991 // Grab a copy of any object referenced by this object. These instances
6992 // may have already been fetched, and we don't want to lose their data.
6993 // Note that doing it like this means we will unify separate copies of the
6994 // same object, but that's a risk we have to take.
6995 var fetchedObjects = {};
6996 AV._traverse(this.attributes, function (object) {
6997 if (object instanceof AV.Object && object.id && object._hasData) {
6998 fetchedObjects[object.id] = object;
6999 }
7000 });
7001
7002 var savedChanges = _.first(this._opSetQueue);
7003 this._opSetQueue = _.rest(this._opSetQueue);
7004 this._applyOpSet(savedChanges, this._serverData);
7005 this._mergeMagicFields(serverData);
7006 var self = this;
7007 AV._objectEach(serverData, function (value, key) {
7008 self._serverData[key] = AV._decode(value, key);
7009
7010 // Look for any objects that might have become unfetched and fix them
7011 // by replacing their values with the previously observed values.
7012 var fetched = AV._traverse(self._serverData[key], function (object) {
7013 if (object instanceof AV.Object && fetchedObjects[object.id]) {
7014 return fetchedObjects[object.id];
7015 }
7016 });
7017 if (fetched) {
7018 self._serverData[key] = fetched;
7019 }
7020 });
7021 this._rebuildAllEstimatedData();
7022 this._saving = this._saving - 1;
7023 },
7024
7025 /**
7026 * Called when a fetch or login is complete to set the known server data to
7027 * the given object.
7028 * @private
7029 */
7030 _finishFetch: function _finishFetch(serverData, hasData) {
7031 // Clear out any changes the user might have made previously.
7032 this._opSetQueue = [{}];
7033
7034 // Bring in all the new server data.
7035 this._mergeMagicFields(serverData);
7036 var self = this;
7037 AV._objectEach(serverData, function (value, key) {
7038 self._serverData[key] = AV._decode(value, key);
7039 });
7040
7041 // Refresh the attributes.
7042 this._rebuildAllEstimatedData();
7043
7044 // Clear out the cache of mutable containers.
7045 this._refreshCache();
7046 this._opSetQueue = [{}];
7047
7048 this._hasData = hasData;
7049 },
7050
7051 /**
7052 * Applies the set of AV.Op in opSet to the object target.
7053 * @private
7054 */
7055 _applyOpSet: function _applyOpSet(opSet, target) {
7056 var self = this;
7057 AV._objectEach(opSet, function (change, key) {
7058 target[key] = change._estimate(target[key], self, key);
7059 if (target[key] === AV.Op._UNSET) {
7060 delete target[key];
7061 }
7062 });
7063 },
7064
7065 /**
7066 * Replaces the cached value for key with the current value.
7067 * Returns true if the new value is different than the old value.
7068 * @private
7069 */
7070 _resetCacheForKey: function _resetCacheForKey(key) {
7071 var value = this.attributes[key];
7072 if (_.isObject(value) && !(value instanceof AV.Object) && !(value instanceof AV.File)) {
7073
7074 value = value.toJSON ? value.toJSON() : value;
7075 var json = JSON.stringify(value);
7076 if (this._hashedJSON[key] !== json) {
7077 var wasSet = !!this._hashedJSON[key];
7078 this._hashedJSON[key] = json;
7079 return wasSet;
7080 }
7081 }
7082 return false;
7083 },
7084
7085 /**
7086 * Populates attributes[key] by starting with the last known data from the
7087 * server, and applying all of the local changes that have been made to that
7088 * key since then.
7089 * @private
7090 */
7091 _rebuildEstimatedDataForKey: function _rebuildEstimatedDataForKey(key) {
7092 var self = this;
7093 delete this.attributes[key];
7094 if (this._serverData[key]) {
7095 this.attributes[key] = this._serverData[key];
7096 }
7097 AV._arrayEach(this._opSetQueue, function (opSet) {
7098 var op = opSet[key];
7099 if (op) {
7100 self.attributes[key] = op._estimate(self.attributes[key], self, key);
7101 if (self.attributes[key] === AV.Op._UNSET) {
7102 delete self.attributes[key];
7103 } else {
7104 self._resetCacheForKey(key);
7105 }
7106 }
7107 });
7108 },
7109
7110 /**
7111 * Populates attributes by starting with the last known data from the
7112 * server, and applying all of the local changes that have been made since
7113 * then.
7114 * @private
7115 */
7116 _rebuildAllEstimatedData: function _rebuildAllEstimatedData() {
7117 var self = this;
7118
7119 var previousAttributes = _.clone(this.attributes);
7120
7121 this.attributes = _.clone(this._serverData);
7122 AV._arrayEach(this._opSetQueue, function (opSet) {
7123 self._applyOpSet(opSet, self.attributes);
7124 AV._objectEach(opSet, function (op, key) {
7125 self._resetCacheForKey(key);
7126 });
7127 });
7128
7129 // Trigger change events for anything that changed because of the fetch.
7130 AV._objectEach(previousAttributes, function (oldValue, key) {
7131 if (self.attributes[key] !== oldValue) {
7132 self.trigger('change:' + key, self, self.attributes[key], {});
7133 }
7134 });
7135 AV._objectEach(this.attributes, function (newValue, key) {
7136 if (!_.has(previousAttributes, key)) {
7137 self.trigger('change:' + key, self, newValue, {});
7138 }
7139 });
7140 },
7141
7142 /**
7143 * Sets a hash of model attributes on the object, firing
7144 * <code>"change"</code> unless you choose to silence it.
7145 *
7146 * <p>You can call it with an object containing keys and values, or with one
7147 * key and value. For example:<pre>
7148 * gameTurn.set({
7149 * player: player1,
7150 * diceRoll: 2
7151 * }, {
7152 * error: function(gameTurnAgain, error) {
7153 * // The set failed validation.
7154 * }
7155 * });
7156 *
7157 * game.set("currentPlayer", player2, {
7158 * error: function(gameTurnAgain, error) {
7159 * // The set failed validation.
7160 * }
7161 * });
7162 *
7163 * game.set("finished", true);</pre></p>
7164 *
7165 * @param {String} key The key to set.
7166 * @param {Any} value The value to give it.
7167 * @param {Object} [options]
7168 * @param {Boolean} [options.silent]
7169 * @return {AV.Object} self if succeeded, throws if the value is not valid.
7170 * @see AV.Object#validate
7171 */
7172 set: function set(key, value, options) {
7173 var attrs;
7174 if (_.isObject(key) || utils.isNullOrUndefined(key)) {
7175 attrs = _.mapObject(key, function (v, k) {
7176 checkReservedKey(k);
7177 return AV._decode(v, k);
7178 });
7179 options = value;
7180 } else {
7181 attrs = {};
7182 checkReservedKey(key);
7183 attrs[key] = AV._decode(value, key);
7184 }
7185
7186 // Extract attributes and options.
7187 options = options || {};
7188 if (!attrs) {
7189 return this;
7190 }
7191 if (attrs instanceof AV.Object) {
7192 attrs = attrs.attributes;
7193 }
7194
7195 // If the unset option is used, every attribute should be a Unset.
7196 if (options.unset) {
7197 AV._objectEach(attrs, function (unused_value, key) {
7198 attrs[key] = new AV.Op.Unset();
7199 });
7200 }
7201
7202 // Apply all the attributes to get the estimated values.
7203 var dataToValidate = _.clone(attrs);
7204 var self = this;
7205 AV._objectEach(dataToValidate, function (value, key) {
7206 if (value instanceof AV.Op) {
7207 dataToValidate[key] = value._estimate(self.attributes[key], self, key);
7208 if (dataToValidate[key] === AV.Op._UNSET) {
7209 delete dataToValidate[key];
7210 }
7211 }
7212 });
7213
7214 // Run validation.
7215 this._validate(attrs, options);
7216
7217 options.changes = {};
7218 var escaped = this._escapedAttributes;
7219 var prev = this._previousAttributes || {};
7220
7221 // Update attributes.
7222 AV._arrayEach(_.keys(attrs), function (attr) {
7223 var val = attrs[attr];
7224
7225 // If this is a relation object we need to set the parent correctly,
7226 // since the location where it was parsed does not have access to
7227 // this object.
7228 if (val instanceof AV.Relation) {
7229 val.parent = self;
7230 }
7231
7232 if (!(val instanceof AV.Op)) {
7233 val = new AV.Op.Set(val);
7234 }
7235
7236 // See if this change will actually have any effect.
7237 var isRealChange = true;
7238 if (val instanceof AV.Op.Set && _.isEqual(self.attributes[attr], val.value)) {
7239 isRealChange = false;
7240 }
7241
7242 if (isRealChange) {
7243 delete escaped[attr];
7244 if (options.silent) {
7245 self._silent[attr] = true;
7246 } else {
7247 options.changes[attr] = true;
7248 }
7249 }
7250
7251 var currentChanges = _.last(self._opSetQueue);
7252 currentChanges[attr] = val._mergeWithPrevious(currentChanges[attr]);
7253 self._rebuildEstimatedDataForKey(attr);
7254
7255 if (isRealChange) {
7256 self.changed[attr] = self.attributes[attr];
7257 if (!options.silent) {
7258 self._pending[attr] = true;
7259 }
7260 } else {
7261 delete self.changed[attr];
7262 delete self._pending[attr];
7263 }
7264 });
7265
7266 if (!options.silent) {
7267 this.change(options);
7268 }
7269 return this;
7270 },
7271
7272 /**
7273 * Remove an attribute from the model, firing <code>"change"</code> unless
7274 * you choose to silence it. This is a noop if the attribute doesn't
7275 * exist.
7276 */
7277 unset: function unset(attr, options) {
7278 options = options || {};
7279 options.unset = true;
7280 return this.set(attr, null, options);
7281 },
7282
7283 /**
7284 * Atomically increments the value of the given attribute the next time the
7285 * object is saved. If no amount is specified, 1 is used by default.
7286 *
7287 * @param attr {String} The key.
7288 * @param amount {Number} The amount to increment by.
7289 */
7290 increment: function increment(attr, amount) {
7291 if (_.isUndefined(amount) || _.isNull(amount)) {
7292 amount = 1;
7293 }
7294 return this.set(attr, new AV.Op.Increment(amount));
7295 },
7296
7297 /**
7298 * Atomically add an object to the end of the array associated with a given
7299 * key.
7300 * @param attr {String} The key.
7301 * @param item {} The item to add.
7302 */
7303 add: function add(attr, item) {
7304 return this.set(attr, new AV.Op.Add(utils.ensureArray(item)));
7305 },
7306
7307 /**
7308 * Atomically add an object to the array associated with a given key, only
7309 * if it is not already present in the array. The position of the insert is
7310 * not guaranteed.
7311 *
7312 * @param attr {String} The key.
7313 * @param item {} The object to add.
7314 */
7315 addUnique: function addUnique(attr, item) {
7316 return this.set(attr, new AV.Op.AddUnique(utils.ensureArray(item)));
7317 },
7318
7319 /**
7320 * Atomically remove all instances of an object from the array associated
7321 * with a given key.
7322 *
7323 * @param attr {String} The key.
7324 * @param item {} The object to remove.
7325 */
7326 remove: function remove(attr, item) {
7327 return this.set(attr, new AV.Op.Remove(utils.ensureArray(item)));
7328 },
7329
7330 /**
7331 * Returns an instance of a subclass of AV.Op describing what kind of
7332 * modification has been performed on this field since the last time it was
7333 * saved. For example, after calling object.increment("x"), calling
7334 * object.op("x") would return an instance of AV.Op.Increment.
7335 *
7336 * @param attr {String} The key.
7337 * @returns {AV.Op} The operation, or undefined if none.
7338 */
7339 op: function op(attr) {
7340 return _.last(this._opSetQueue)[attr];
7341 },
7342
7343 /**
7344 * Clear all attributes on the model, firing <code>"change"</code> unless
7345 * you choose to silence it.
7346 */
7347 clear: function clear(options) {
7348 options = options || {};
7349 options.unset = true;
7350 var keysToClear = _.extend(this.attributes, this._operations);
7351 return this.set(keysToClear, options);
7352 },
7353
7354 /**
7355 * Returns a JSON-encoded set of operations to be sent with the next save
7356 * request.
7357 * @private
7358 */
7359 _getSaveJSON: function _getSaveJSON() {
7360 var json = _.clone(_.first(this._opSetQueue));
7361 AV._objectEach(json, function (op, key) {
7362 json[key] = op.toJSON();
7363 });
7364 return json;
7365 },
7366
7367 /**
7368 * Returns true if this object can be serialized for saving.
7369 * @private
7370 */
7371 _canBeSerialized: function _canBeSerialized() {
7372 return AV.Object._canBeSerializedAsValue(this.attributes);
7373 },
7374
7375 /**
7376 * Fetch the model from the server. If the server's representation of the
7377 * model differs from its current attributes, they will be overriden,
7378 * triggering a <code>"change"</code> event.
7379 * @param {Object} fetchOptions Optional options to set 'keys' and
7380 * 'include' option.
7381 * @param {AuthOptions} options
7382 * @return {Promise} A promise that is fulfilled when the fetch
7383 * completes.
7384 */
7385 fetch: function fetch() {
7386 var fetchOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
7387 var options = arguments[1];
7388
7389 if (_.isArray(fetchOptions.keys)) {
7390 fetchOptions.keys = fetchOptions.keys.join(',');
7391 }
7392 if (_.isArray(fetchOptions.include)) {
7393 fetchOptions.include = fetchOptions.include.join(',');
7394 }
7395
7396 var self = this;
7397 var request = AVRequest('classes', this.className, this.id, 'GET', fetchOptions, options);
7398 return request.then(function (response) {
7399 self._finishFetch(self.parse(response), true);
7400 return self;
7401 });
7402 },
7403
7404 /**
7405 * Set a hash of model attributes, and save the model to the server.
7406 * updatedAt will be updated when the request returns.
7407 * You can either call it as:<pre>
7408 * object.save();</pre>
7409 * or<pre>
7410 * object.save(null, options);</pre>
7411 * or<pre>
7412 * object.save(attrs, options);</pre>
7413 * or<pre>
7414 * object.save(key, value, options);</pre>
7415 *
7416 * For example, <pre>
7417 * gameTurn.save({
7418 * player: "Jake Cutter",
7419 * diceRoll: 2
7420 * }).then(function(gameTurnAgain) {
7421 * // The save was successful.
7422 * }, function(error) {
7423 * // The save failed. Error is an instance of AVError.
7424 * });</pre>
7425 * @param {AuthOptions} options AuthOptions plus:
7426 * @param {Boolean} options.fetchWhenSave fetch and update object after save succeeded
7427 * @param {AV.Query} options.query Save object only when it matches the query
7428 * @return {AV.Promise} A promise that is fulfilled when the save
7429 * completes.
7430 * @see AVError
7431 */
7432 save: function save(arg1, arg2, arg3) {
7433 var i, attrs, current, options, saved;
7434 if (_.isObject(arg1) || utils.isNullOrUndefined(arg1)) {
7435 attrs = arg1;
7436 options = arg2;
7437 } else {
7438 attrs = {};
7439 attrs[arg1] = arg2;
7440 options = arg3;
7441 }
7442
7443 options = _.clone(options) || {};
7444 if (options.wait) {
7445 current = _.clone(this.attributes);
7446 }
7447
7448 var setOptions = _.clone(options) || {};
7449 if (setOptions.wait) {
7450 setOptions.silent = true;
7451 }
7452 if (attrs) {
7453 this.set(attrs, setOptions);
7454 }
7455
7456 var model = this;
7457
7458 // If there is any unsaved child, save it first.
7459 model._refreshCache();
7460
7461 var unsavedChildren = [];
7462 var unsavedFiles = [];
7463 AV.Object._findUnsavedChildren(model.attributes, unsavedChildren, unsavedFiles);
7464 if (unsavedChildren.length + unsavedFiles.length > 0) {
7465 return AV.Object._deepSaveAsync(this.attributes, model, options).then(function () {
7466 return model.save(null, options);
7467 });
7468 }
7469
7470 this._startSave();
7471 this._saving = (this._saving || 0) + 1;
7472
7473 this._allPreviousSaves = this._allPreviousSaves || AV.Promise.resolve();
7474 this._allPreviousSaves = this._allPreviousSaves.catch(function (e) {}).then(function () {
7475 var method = model.id ? 'PUT' : 'POST';
7476
7477 var json = model._getSaveJSON();
7478
7479 if (model._fetchWhenSave) {
7480 //Sepcial-case fetchWhenSave when updating object.
7481 json._fetchWhenSave = true;
7482 }
7483
7484 if (options.fetchWhenSave) {
7485 json._fetchWhenSave = true;
7486 }
7487 if (options.query) {
7488 var queryJSON;
7489 if (typeof options.query.toJSON === 'function') {
7490 queryJSON = options.query.toJSON();
7491 if (queryJSON) {
7492 json._where = queryJSON.where;
7493 }
7494 }
7495 if (!json._where) {
7496 var error = new Error('options.query is not an AV.Query');
7497 throw error;
7498 }
7499 }
7500
7501 _.extend(json, model._flags);
7502
7503 var route = "classes";
7504 var className = model.className;
7505 if (model.className === "_User" && !model.id) {
7506 // Special-case user sign-up.
7507 route = "users";
7508 className = null;
7509 }
7510 //hook makeRequest in options.
7511 var makeRequest = options._makeRequest || AVRequest;
7512 var request = makeRequest(route, className, model.id, method, json, options);
7513
7514 request = request.then(function (resp) {
7515 var serverAttrs = model.parse(resp);
7516 if (options.wait) {
7517 serverAttrs = _.extend(attrs || {}, serverAttrs);
7518 }
7519 model._finishSave(serverAttrs);
7520 if (options.wait) {
7521 model.set(current, setOptions);
7522 }
7523 return model;
7524 }, function (error) {
7525 model._cancelSave();
7526 throw error;
7527 });
7528
7529 return request;
7530 });
7531 return this._allPreviousSaves;
7532 },
7533
7534 /**
7535 * Destroy this model on the server if it was already persisted.
7536 * Optimistically removes the model from its collection, if it has one.
7537 * @param {AuthOptions} options AuthOptions plus:
7538 * @param {Boolean} [options.wait] wait for the server to respond
7539 * before removal.
7540 *
7541 * @return {Promise} A promise that is fulfilled when the destroy
7542 * completes.
7543 */
7544 destroy: function destroy(options) {
7545 options = options || {};
7546 var model = this;
7547
7548 var triggerDestroy = function triggerDestroy() {
7549 model.trigger('destroy', model, model.collection, options);
7550 };
7551
7552 if (!this.id) {
7553 return triggerDestroy();
7554 }
7555
7556 if (!options.wait) {
7557 triggerDestroy();
7558 }
7559
7560 var request = AVRequest('classes', this.className, this.id, 'DELETE', this._flags, options);
7561 return request.then(function () {
7562 if (options.wait) {
7563 triggerDestroy();
7564 }
7565 return model;
7566 });
7567 },
7568
7569 /**
7570 * Converts a response into the hash of attributes to be set on the model.
7571 * @ignore
7572 */
7573 parse: function parse(resp) {
7574 var output = _.clone(resp);
7575 _(["createdAt", "updatedAt"]).each(function (key) {
7576 if (output[key]) {
7577 output[key] = AV._parseDate(output[key]);
7578 }
7579 });
7580 if (!output.updatedAt) {
7581 output.updatedAt = output.createdAt;
7582 }
7583 return output;
7584 },
7585
7586 /**
7587 * Creates a new model with identical attributes to this one.
7588 * @return {AV.Object}
7589 */
7590 clone: function clone() {
7591 return new this.constructor(this.attributes);
7592 },
7593
7594 /**
7595 * Returns true if this object has never been saved to AV.
7596 * @return {Boolean}
7597 */
7598 isNew: function isNew() {
7599 return !this.id;
7600 },
7601
7602 /**
7603 * Call this method to manually fire a `"change"` event for this model and
7604 * a `"change:attribute"` event for each changed attribute.
7605 * Calling this will cause all objects observing the model to update.
7606 */
7607 change: function change(options) {
7608 options = options || {};
7609 var changing = this._changing;
7610 this._changing = true;
7611
7612 // Silent changes become pending changes.
7613 var self = this;
7614 AV._objectEach(this._silent, function (attr) {
7615 self._pending[attr] = true;
7616 });
7617
7618 // Silent changes are triggered.
7619 var changes = _.extend({}, options.changes, this._silent);
7620 this._silent = {};
7621 AV._objectEach(changes, function (unused_value, attr) {
7622 self.trigger('change:' + attr, self, self.get(attr), options);
7623 });
7624 if (changing) {
7625 return this;
7626 }
7627
7628 // This is to get around lint not letting us make a function in a loop.
7629 var deleteChanged = function deleteChanged(value, attr) {
7630 if (!self._pending[attr] && !self._silent[attr]) {
7631 delete self.changed[attr];
7632 }
7633 };
7634
7635 // Continue firing `"change"` events while there are pending changes.
7636 while (!_.isEmpty(this._pending)) {
7637 this._pending = {};
7638 this.trigger('change', this, options);
7639 // Pending and silent changes still remain.
7640 AV._objectEach(this.changed, deleteChanged);
7641 self._previousAttributes = _.clone(this.attributes);
7642 }
7643
7644 this._changing = false;
7645 return this;
7646 },
7647
7648 /**
7649 * Determine if the model has changed since the last <code>"change"</code>
7650 * event. If you specify an attribute name, determine if that attribute
7651 * has changed.
7652 * @param {String} attr Optional attribute name
7653 * @return {Boolean}
7654 */
7655 hasChanged: function hasChanged(attr) {
7656 if (!arguments.length) {
7657 return !_.isEmpty(this.changed);
7658 }
7659 return this.changed && _.has(this.changed, attr);
7660 },
7661
7662 /**
7663 * Returns an object containing all the attributes that have changed, or
7664 * false if there are no changed attributes. Useful for determining what
7665 * parts of a view need to be updated and/or what attributes need to be
7666 * persisted to the server. Unset attributes will be set to undefined.
7667 * You can also pass an attributes object to diff against the model,
7668 * determining if there *would be* a change.
7669 */
7670 changedAttributes: function changedAttributes(diff) {
7671 if (!diff) {
7672 return this.hasChanged() ? _.clone(this.changed) : false;
7673 }
7674 var changed = {};
7675 var old = this._previousAttributes;
7676 AV._objectEach(diff, function (diffVal, attr) {
7677 if (!_.isEqual(old[attr], diffVal)) {
7678 changed[attr] = diffVal;
7679 }
7680 });
7681 return changed;
7682 },
7683
7684 /**
7685 * Gets the previous value of an attribute, recorded at the time the last
7686 * <code>"change"</code> event was fired.
7687 * @param {String} attr Name of the attribute to get.
7688 */
7689 previous: function previous(attr) {
7690 if (!arguments.length || !this._previousAttributes) {
7691 return null;
7692 }
7693 return this._previousAttributes[attr];
7694 },
7695
7696 /**
7697 * Gets all of the attributes of the model at the time of the previous
7698 * <code>"change"</code> event.
7699 * @return {Object}
7700 */
7701 previousAttributes: function previousAttributes() {
7702 return _.clone(this._previousAttributes);
7703 },
7704
7705 /**
7706 * Checks if the model is currently in a valid state. It's only possible to
7707 * get into an *invalid* state if you're using silent changes.
7708 * @return {Boolean}
7709 */
7710 isValid: function isValid() {
7711 try {
7712 this.validate(this.attributes);
7713 } catch (error) {
7714 return false;
7715 }
7716 return true;
7717 },
7718
7719 /**
7720 * You should not call this function directly unless you subclass
7721 * <code>AV.Object</code>, in which case you can override this method
7722 * to provide additional validation on <code>set</code> and
7723 * <code>save</code>. Your implementation should throw an Error if
7724 * the attrs is invalid
7725 *
7726 * @param {Object} attrs The current data to validate.
7727 * @see AV.Object#set
7728 */
7729 validate: function validate(attrs) {
7730 if (_.has(attrs, "ACL") && !(attrs.ACL instanceof AV.ACL)) {
7731 throw new AVError(AVError.OTHER_CAUSE, "ACL must be a AV.ACL.");
7732 }
7733 },
7734
7735 /**
7736 * Run validation against a set of incoming attributes, returning `true`
7737 * if all is well. If a specific `error` callback has been passed,
7738 * call that instead of firing the general `"error"` event.
7739 * @private
7740 */
7741 _validate: function _validate(attrs, options) {
7742 if (options.silent || !this.validate) {
7743 return;
7744 }
7745 attrs = _.extend({}, this.attributes, attrs);
7746 this.validate(attrs);
7747 },
7748
7749 /**
7750 * Returns the ACL for this object.
7751 * @returns {AV.ACL} An instance of AV.ACL.
7752 * @see AV.Object#get
7753 */
7754 getACL: function getACL() {
7755 return this.get("ACL");
7756 },
7757
7758 /**
7759 * Sets the ACL to be used for this object.
7760 * @param {AV.ACL} acl An instance of AV.ACL.
7761 * @param {Object} options Optional Backbone-like options object to be
7762 * passed in to set.
7763 * @return {Boolean} Whether the set passed validation.
7764 * @see AV.Object#set
7765 */
7766 setACL: function setACL(acl, options) {
7767 return this.set("ACL", acl, options);
7768 },
7769
7770 disableBeforeHook: function disableBeforeHook() {
7771 this.ignoreHook('beforeSave');
7772 this.ignoreHook('beforeUpdate');
7773 this.ignoreHook('beforeDelete');
7774 },
7775
7776 disableAfterHook: function disableAfterHook() {
7777 this.ignoreHook('afterSave');
7778 this.ignoreHook('afterUpdate');
7779 this.ignoreHook('afterDelete');
7780 },
7781
7782 ignoreHook: function ignoreHook(hookName) {
7783 if (!_.contains(['beforeSave', 'afterSave', 'beforeUpdate', 'afterUpdate', 'beforeDelete', 'afterDelete'], hookName)) {
7784 console.trace('Unsupported hookName: ' + hookName);
7785 }
7786
7787 if (!AV.hookKey) {
7788 console.trace('ignoreHook required hookKey');
7789 }
7790
7791 if (!this._flags.__ignore_hooks) {
7792 this._flags.__ignore_hooks = [];
7793 }
7794
7795 this._flags.__ignore_hooks.push(hookName);
7796 }
7797 });
7798
7799 /**
7800 * Creates an instance of a subclass of AV.Object for the give classname
7801 * and id.
7802 * @param {String} className The name of the AV class backing this model.
7803 * @param {String} id The object id of this model.
7804 * @return {AV.Object} A new subclass instance of AV.Object.
7805 */
7806 AV.Object.createWithoutData = function (className, id, hasData) {
7807 var result = new AV.Object(className);
7808 result.id = id;
7809 result._hasData = hasData;
7810 return result;
7811 };
7812 /**
7813 * Delete objects in batch.
7814 * @param {AV.Object[]} objects The <code>AV.Object</code> array to be deleted.
7815 * @param {AuthOptions} options
7816 * @return {Promise} A promise that is fulfilled when the save
7817 * completes.
7818 */
7819 AV.Object.destroyAll = function (objects) {
7820 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7821
7822 if (!objects || objects.length === 0) {
7823 return AV.Promise.resolve();
7824 }
7825 var objectsByClassNameAndFlags = _.groupBy(objects, function (object) {
7826 return JSON.stringify({
7827 className: object.className,
7828 flags: object._flags
7829 });
7830 });
7831 var body = {
7832 requests: _.map(objectsByClassNameAndFlags, function (objects) {
7833 var ids = _.map(objects, 'id').join(',');
7834 return {
7835 method: 'DELETE',
7836 path: '/1.1/classes/' + objects[0].className + '/' + ids,
7837 body: objects[0]._flags
7838 };
7839 })
7840 };
7841 return AVRequest('batch', null, null, 'POST', body, options);
7842 };
7843
7844 /**
7845 * Returns the appropriate subclass for making new instances of the given
7846 * className string.
7847 * @private
7848 */
7849 AV.Object._getSubclass = function (className) {
7850 if (!_.isString(className)) {
7851 throw new Error('AV.Object._getSubclass requires a string argument.');
7852 }
7853 var ObjectClass = AV.Object._classMap[className];
7854 if (!ObjectClass) {
7855 ObjectClass = AV.Object.extend(className);
7856 AV.Object._classMap[className] = ObjectClass;
7857 }
7858 return ObjectClass;
7859 };
7860
7861 /**
7862 * Creates an instance of a subclass of AV.Object for the given classname.
7863 * @private
7864 */
7865 AV.Object._create = function (className, attributes, options) {
7866 var ObjectClass = AV.Object._getSubclass(className);
7867 return new ObjectClass(attributes, options);
7868 };
7869
7870 // Set up a map of className to class so that we can create new instances of
7871 // AV Objects from JSON automatically.
7872 AV.Object._classMap = {};
7873
7874 AV.Object._extend = AV._extend;
7875
7876 /**
7877 * Creates a new model with defined attributes,
7878 * It's the same with
7879 * <pre>
7880 * new AV.Object(attributes, options);
7881 * </pre>
7882 * @param {Object} attributes The initial set of data to store in the object.
7883 * @param {Object} options A set of Backbone-like options for creating the
7884 * object. The only option currently supported is "collection".
7885 * @return {AV.Object}
7886 * @since v0.4.4
7887 * @see AV.Object
7888 * @see AV.Object.extend
7889 */
7890 AV.Object['new'] = function (attributes, options) {
7891 return new AV.Object(attributes, options);
7892 };
7893
7894 /**
7895 * Creates a new subclass of AV.Object for the given AV class name.
7896 *
7897 * <p>Every extension of a AV class will inherit from the most recent
7898 * previous extension of that class. When a AV.Object is automatically
7899 * created by parsing JSON, it will use the most recent extension of that
7900 * class.</p>
7901 *
7902 * <p>You should call either:<pre>
7903 * var MyClass = AV.Object.extend("MyClass", {
7904 * <i>Instance properties</i>
7905 * }, {
7906 * <i>Class properties</i>
7907 * });</pre>
7908 * or, for Backbone compatibility:<pre>
7909 * var MyClass = AV.Object.extend({
7910 * className: "MyClass",
7911 * <i>Other instance properties</i>
7912 * }, {
7913 * <i>Class properties</i>
7914 * });</pre></p>
7915 *
7916 * @param {String} className The name of the AV class backing this model.
7917 * @param {Object} protoProps Instance properties to add to instances of the
7918 * class returned from this method.
7919 * @param {Object} classProps Class properties to add the class returned from
7920 * this method.
7921 * @return {Class} A new subclass of AV.Object.
7922 */
7923 AV.Object.extend = function (className, protoProps, classProps) {
7924 // Handle the case with only two args.
7925 if (!_.isString(className)) {
7926 if (className && _.has(className, "className")) {
7927 return AV.Object.extend(className.className, className, protoProps);
7928 } else {
7929 throw new Error("AV.Object.extend's first argument should be the className.");
7930 }
7931 }
7932
7933 // If someone tries to subclass "User", coerce it to the right type.
7934 if (className === "User") {
7935 className = "_User";
7936 }
7937
7938 var NewClassObject = null;
7939 if (_.has(AV.Object._classMap, className)) {
7940 var OldClassObject = AV.Object._classMap[className];
7941 // This new subclass has been told to extend both from "this" and from
7942 // OldClassObject. This is multiple inheritance, which isn't supported.
7943 // For now, let's just pick one.
7944 if (protoProps || classProps) {
7945 NewClassObject = OldClassObject._extend(protoProps, classProps);
7946 } else {
7947 return OldClassObject;
7948 }
7949 } else {
7950 protoProps = protoProps || {};
7951 protoProps._className = className;
7952 NewClassObject = this._extend(protoProps, classProps);
7953 }
7954 // Extending a subclass should reuse the classname automatically.
7955 NewClassObject.extend = function (arg0) {
7956 if (_.isString(arg0) || arg0 && _.has(arg0, "className")) {
7957 return AV.Object.extend.apply(NewClassObject, arguments);
7958 }
7959 var newArguments = [className].concat(_.toArray(arguments));
7960 return AV.Object.extend.apply(NewClassObject, newArguments);
7961 };
7962 NewClassObject['new'] = function (attributes, options) {
7963 return new NewClassObject(attributes, options);
7964 };
7965 AV.Object._classMap[className] = NewClassObject;
7966 return NewClassObject;
7967 };
7968
7969 // ES6 class syntax support
7970 Object.defineProperty(AV.Object.prototype, 'className', {
7971 get: function get() {
7972 var className = this._className || this.constructor._LCClassName || this.constructor.name;
7973 // If someone tries to subclass "User", coerce it to the right type.
7974 if (className === "User") {
7975 return "_User";
7976 }
7977 return className;
7978 }
7979 });
7980
7981 /**
7982 * Register a class.
7983 * If a subclass of <code>AV.Object</code> is defined with your own implement
7984 * rather then <code>AV.Object.extend</code>, the subclass must be registered.
7985 * @param {Function} klass A subclass of <code>AV.Object</code>
7986 * @param {String} [name] Specify the name of the class. Useful when the class might be uglified.
7987 * @example
7988 * class Person extend AV.Object {}
7989 * AV.Object.register(Person);
7990 */
7991 AV.Object.register = function (klass, name) {
7992 if (!(klass.prototype instanceof AV.Object)) {
7993 throw new Error('registered class is not a subclass of AV.Object');
7994 }
7995 var className = name || klass.name;
7996 if (!className.length) {
7997 throw new Error('registered class must be named');
7998 }
7999 if (name) {
8000 klass._LCClassName = name;
8001 }
8002 AV.Object._classMap[className] = klass;
8003 };
8004
8005 AV.Object._findUnsavedChildren = function (object, children, files) {
8006 AV._traverse(object, function (object) {
8007 if (object instanceof AV.Object) {
8008 object._refreshCache();
8009 if (object.dirty()) {
8010 children.push(object);
8011 }
8012 return;
8013 }
8014
8015 if (object instanceof AV.File) {
8016 if (!object.url() && !object.id) {
8017 files.push(object);
8018 }
8019 return;
8020 }
8021 });
8022 };
8023
8024 AV.Object._canBeSerializedAsValue = function (object) {
8025 var canBeSerializedAsValue = true;
8026
8027 if (object instanceof AV.Object || object instanceof AV.File) {
8028 canBeSerializedAsValue = !!object.id;
8029 } else if (_.isArray(object)) {
8030 AV._arrayEach(object, function (child) {
8031 if (!AV.Object._canBeSerializedAsValue(child)) {
8032 canBeSerializedAsValue = false;
8033 }
8034 });
8035 } else if (_.isObject(object)) {
8036 AV._objectEach(object, function (child) {
8037 if (!AV.Object._canBeSerializedAsValue(child)) {
8038 canBeSerializedAsValue = false;
8039 }
8040 });
8041 }
8042
8043 return canBeSerializedAsValue;
8044 };
8045
8046 AV.Object._deepSaveAsync = function (object, model, options) {
8047 var unsavedChildren = [];
8048 var unsavedFiles = [];
8049 AV.Object._findUnsavedChildren(object, unsavedChildren, unsavedFiles);
8050 if (model) {
8051 unsavedChildren = _.filter(unsavedChildren, function (object) {
8052 return object != model;
8053 });
8054 }
8055
8056 var promise = AV.Promise.resolve();
8057 _.each(unsavedFiles, function (file) {
8058 promise = promise.then(function () {
8059 return file.save();
8060 });
8061 });
8062
8063 var objects = _.uniq(unsavedChildren);
8064 var remaining = _.uniq(objects);
8065
8066 return promise.then(function () {
8067 return AV.Promise._continueWhile(function () {
8068 return remaining.length > 0;
8069 }, function () {
8070
8071 // Gather up all the objects that can be saved in this batch.
8072 var batch = [];
8073 var newRemaining = [];
8074 AV._arrayEach(remaining, function (object) {
8075 // Limit batches to 20 objects.
8076 if (batch.length > 20) {
8077 newRemaining.push(object);
8078 return;
8079 }
8080
8081 if (object._canBeSerialized()) {
8082 batch.push(object);
8083 } else {
8084 newRemaining.push(object);
8085 }
8086 });
8087 remaining = newRemaining;
8088
8089 // If we can't save any objects, there must be a circular reference.
8090 if (batch.length === 0) {
8091 return AV.Promise.reject(new AVError(AVError.OTHER_CAUSE, "Tried to save a batch with a cycle."));
8092 }
8093
8094 // Reserve a spot in every object's save queue.
8095 var readyToStart = AV.Promise.resolve(_.map(batch, function (object) {
8096 return object._allPreviousSaves || AV.Promise.resolve();
8097 }));
8098
8099 // Save a single batch, whether previous saves succeeded or failed.
8100 var bathSavePromise = readyToStart.then(function () {
8101 return AVRequest("batch", null, null, "POST", {
8102 requests: _.map(batch, function (object) {
8103 var json = object._getSaveJSON();
8104 _.extend(json, object._flags);
8105 var method = "POST";
8106
8107 var path = "/1.1/classes/" + object.className;
8108 if (object.id) {
8109 path = path + "/" + object.id;
8110 method = "PUT";
8111 }
8112
8113 object._startSave();
8114
8115 return {
8116 method: method,
8117 path: path,
8118 body: json
8119 };
8120 })
8121
8122 }, options).then(function (response) {
8123 var error;
8124 AV._arrayEach(batch, function (object, i) {
8125 if (response[i].success) {
8126 object._finishSave(object.parse(response[i].success));
8127 } else {
8128 error = error || response[i].error;
8129 object._cancelSave();
8130 }
8131 });
8132 if (error) {
8133 return AV.Promise.reject(new AVError(error.code, error.error));
8134 }
8135 });
8136 });
8137 AV._arrayEach(batch, function (object) {
8138 object._allPreviousSaves = bathSavePromise;
8139 });
8140 return bathSavePromise;
8141 });
8142 }).then(function () {
8143 return object;
8144 });
8145 };
8146};
8147
8148/***/ }),
8149/* 33 */
8150/***/ (function(module, exports, __webpack_require__) {
8151
8152"use strict";
8153
8154
8155var _ = __webpack_require__(0);
8156
8157module.exports = function (AV) {
8158
8159 /**
8160 * @private
8161 * @class
8162 * A AV.Op is an atomic operation that can be applied to a field in a
8163 * AV.Object. For example, calling <code>object.set("foo", "bar")</code>
8164 * is an example of a AV.Op.Set. Calling <code>object.unset("foo")</code>
8165 * is a AV.Op.Unset. These operations are stored in a AV.Object and
8166 * sent to the server as part of <code>object.save()</code> operations.
8167 * Instances of AV.Op should be immutable.
8168 *
8169 * You should not create subclasses of AV.Op or instantiate AV.Op
8170 * directly.
8171 */
8172 AV.Op = function () {
8173 this._initialize.apply(this, arguments);
8174 };
8175
8176 AV.Op.prototype = {
8177 _initialize: function _initialize() {}
8178 };
8179
8180 _.extend(AV.Op, {
8181 /**
8182 * To create a new Op, call AV.Op._extend();
8183 * @private
8184 */
8185 _extend: AV._extend,
8186
8187 // A map of __op string to decoder function.
8188 _opDecoderMap: {},
8189
8190 /**
8191 * Registers a function to convert a json object with an __op field into an
8192 * instance of a subclass of AV.Op.
8193 * @private
8194 */
8195 _registerDecoder: function _registerDecoder(opName, decoder) {
8196 AV.Op._opDecoderMap[opName] = decoder;
8197 },
8198
8199 /**
8200 * Converts a json object into an instance of a subclass of AV.Op.
8201 * @private
8202 */
8203 _decode: function _decode(json) {
8204 var decoder = AV.Op._opDecoderMap[json.__op];
8205 if (decoder) {
8206 return decoder(json);
8207 } else {
8208 return undefined;
8209 }
8210 }
8211 });
8212
8213 /*
8214 * Add a handler for Batch ops.
8215 */
8216 AV.Op._registerDecoder("Batch", function (json) {
8217 var op = null;
8218 AV._arrayEach(json.ops, function (nextOp) {
8219 nextOp = AV.Op._decode(nextOp);
8220 op = nextOp._mergeWithPrevious(op);
8221 });
8222 return op;
8223 });
8224
8225 /**
8226 * @private
8227 * @class
8228 * A Set operation indicates that either the field was changed using
8229 * AV.Object.set, or it is a mutable container that was detected as being
8230 * changed.
8231 */
8232 AV.Op.Set = AV.Op._extend( /** @lends AV.Op.Set.prototype */{
8233 _initialize: function _initialize(value) {
8234 this._value = value;
8235 },
8236
8237 /**
8238 * Returns the new value of this field after the set.
8239 */
8240 value: function value() {
8241 return this._value;
8242 },
8243
8244 /**
8245 * Returns a JSON version of the operation suitable for sending to AV.
8246 * @return {Object}
8247 */
8248 toJSON: function toJSON() {
8249 return AV._encode(this.value());
8250 },
8251
8252 _mergeWithPrevious: function _mergeWithPrevious(previous) {
8253 return this;
8254 },
8255
8256 _estimate: function _estimate(oldValue) {
8257 return this.value();
8258 }
8259 });
8260
8261 /**
8262 * A sentinel value that is returned by AV.Op.Unset._estimate to
8263 * indicate the field should be deleted. Basically, if you find _UNSET as a
8264 * value in your object, you should remove that key.
8265 */
8266 AV.Op._UNSET = {};
8267
8268 /**
8269 * @private
8270 * @class
8271 * An Unset operation indicates that this field has been deleted from the
8272 * object.
8273 */
8274 AV.Op.Unset = AV.Op._extend( /** @lends AV.Op.Unset.prototype */{
8275 /**
8276 * Returns a JSON version of the operation suitable for sending to AV.
8277 * @return {Object}
8278 */
8279 toJSON: function toJSON() {
8280 return { __op: "Delete" };
8281 },
8282
8283 _mergeWithPrevious: function _mergeWithPrevious(previous) {
8284 return this;
8285 },
8286
8287 _estimate: function _estimate(oldValue) {
8288 return AV.Op._UNSET;
8289 }
8290 });
8291
8292 AV.Op._registerDecoder("Delete", function (json) {
8293 return new AV.Op.Unset();
8294 });
8295
8296 /**
8297 * @private
8298 * @class
8299 * An Increment is an atomic operation where the numeric value for the field
8300 * will be increased by a given amount.
8301 */
8302 AV.Op.Increment = AV.Op._extend(
8303 /** @lends AV.Op.Increment.prototype */{
8304
8305 _initialize: function _initialize(amount) {
8306 this._amount = amount;
8307 },
8308
8309 /**
8310 * Returns the amount to increment by.
8311 * @return {Number} the amount to increment by.
8312 */
8313 amount: function amount() {
8314 return this._amount;
8315 },
8316
8317 /**
8318 * Returns a JSON version of the operation suitable for sending to AV.
8319 * @return {Object}
8320 */
8321 toJSON: function toJSON() {
8322 return { __op: "Increment", amount: this._amount };
8323 },
8324
8325 _mergeWithPrevious: function _mergeWithPrevious(previous) {
8326 if (!previous) {
8327 return this;
8328 } else if (previous instanceof AV.Op.Unset) {
8329 return new AV.Op.Set(this.amount());
8330 } else if (previous instanceof AV.Op.Set) {
8331 return new AV.Op.Set(previous.value() + this.amount());
8332 } else if (previous instanceof AV.Op.Increment) {
8333 return new AV.Op.Increment(this.amount() + previous.amount());
8334 } else {
8335 throw new Error('Op is invalid after previous op.');
8336 }
8337 },
8338
8339 _estimate: function _estimate(oldValue) {
8340 if (!oldValue) {
8341 return this.amount();
8342 }
8343 return oldValue + this.amount();
8344 }
8345 });
8346
8347 AV.Op._registerDecoder("Increment", function (json) {
8348 return new AV.Op.Increment(json.amount);
8349 });
8350
8351 /**
8352 * @private
8353 * @class
8354 * Add is an atomic operation where the given objects will be appended to the
8355 * array that is stored in this field.
8356 */
8357 AV.Op.Add = AV.Op._extend( /** @lends AV.Op.Add.prototype */{
8358 _initialize: function _initialize(objects) {
8359 this._objects = objects;
8360 },
8361
8362 /**
8363 * Returns the objects to be added to the array.
8364 * @return {Array} The objects to be added to the array.
8365 */
8366 objects: function objects() {
8367 return this._objects;
8368 },
8369
8370 /**
8371 * Returns a JSON version of the operation suitable for sending to AV.
8372 * @return {Object}
8373 */
8374 toJSON: function toJSON() {
8375 return { __op: "Add", objects: AV._encode(this.objects()) };
8376 },
8377
8378 _mergeWithPrevious: function _mergeWithPrevious(previous) {
8379 if (!previous) {
8380 return this;
8381 } else if (previous instanceof AV.Op.Unset) {
8382 return new AV.Op.Set(this.objects());
8383 } else if (previous instanceof AV.Op.Set) {
8384 return new AV.Op.Set(this._estimate(previous.value()));
8385 } else if (previous instanceof AV.Op.Add) {
8386 return new AV.Op.Add(previous.objects().concat(this.objects()));
8387 } else {
8388 throw new Error('Op is invalid after previous op.');
8389 }
8390 },
8391
8392 _estimate: function _estimate(oldValue) {
8393 if (!oldValue) {
8394 return _.clone(this.objects());
8395 } else {
8396 return oldValue.concat(this.objects());
8397 }
8398 }
8399 });
8400
8401 AV.Op._registerDecoder("Add", function (json) {
8402 return new AV.Op.Add(AV._decode(json.objects));
8403 });
8404
8405 /**
8406 * @private
8407 * @class
8408 * AddUnique is an atomic operation where the given items will be appended to
8409 * the array that is stored in this field only if they were not already
8410 * present in the array.
8411 */
8412 AV.Op.AddUnique = AV.Op._extend(
8413 /** @lends AV.Op.AddUnique.prototype */{
8414
8415 _initialize: function _initialize(objects) {
8416 this._objects = _.uniq(objects);
8417 },
8418
8419 /**
8420 * Returns the objects to be added to the array.
8421 * @return {Array} The objects to be added to the array.
8422 */
8423 objects: function objects() {
8424 return this._objects;
8425 },
8426
8427 /**
8428 * Returns a JSON version of the operation suitable for sending to AV.
8429 * @return {Object}
8430 */
8431 toJSON: function toJSON() {
8432 return { __op: "AddUnique", objects: AV._encode(this.objects()) };
8433 },
8434
8435 _mergeWithPrevious: function _mergeWithPrevious(previous) {
8436 if (!previous) {
8437 return this;
8438 } else if (previous instanceof AV.Op.Unset) {
8439 return new AV.Op.Set(this.objects());
8440 } else if (previous instanceof AV.Op.Set) {
8441 return new AV.Op.Set(this._estimate(previous.value()));
8442 } else if (previous instanceof AV.Op.AddUnique) {
8443 return new AV.Op.AddUnique(this._estimate(previous.objects()));
8444 } else {
8445 throw new Error('Op is invalid after previous op.');
8446 }
8447 },
8448
8449 _estimate: function _estimate(oldValue) {
8450 if (!oldValue) {
8451 return _.clone(this.objects());
8452 } else {
8453 // We can't just take the _.uniq(_.union(...)) of oldValue and
8454 // this.objects, because the uniqueness may not apply to oldValue
8455 // (especially if the oldValue was set via .set())
8456 var newValue = _.clone(oldValue);
8457 AV._arrayEach(this.objects(), function (obj) {
8458 if (obj instanceof AV.Object && obj.id) {
8459 var matchingObj = _.find(newValue, function (anObj) {
8460 return anObj instanceof AV.Object && anObj.id === obj.id;
8461 });
8462 if (!matchingObj) {
8463 newValue.push(obj);
8464 } else {
8465 var index = _.indexOf(newValue, matchingObj);
8466 newValue[index] = obj;
8467 }
8468 } else if (!_.contains(newValue, obj)) {
8469 newValue.push(obj);
8470 }
8471 });
8472 return newValue;
8473 }
8474 }
8475 });
8476
8477 AV.Op._registerDecoder("AddUnique", function (json) {
8478 return new AV.Op.AddUnique(AV._decode(json.objects));
8479 });
8480
8481 /**
8482 * @private
8483 * @class
8484 * Remove is an atomic operation where the given objects will be removed from
8485 * the array that is stored in this field.
8486 */
8487 AV.Op.Remove = AV.Op._extend( /** @lends AV.Op.Remove.prototype */{
8488 _initialize: function _initialize(objects) {
8489 this._objects = _.uniq(objects);
8490 },
8491
8492 /**
8493 * Returns the objects to be removed from the array.
8494 * @return {Array} The objects to be removed from the array.
8495 */
8496 objects: function objects() {
8497 return this._objects;
8498 },
8499
8500 /**
8501 * Returns a JSON version of the operation suitable for sending to AV.
8502 * @return {Object}
8503 */
8504 toJSON: function toJSON() {
8505 return { __op: "Remove", objects: AV._encode(this.objects()) };
8506 },
8507
8508 _mergeWithPrevious: function _mergeWithPrevious(previous) {
8509 if (!previous) {
8510 return this;
8511 } else if (previous instanceof AV.Op.Unset) {
8512 return previous;
8513 } else if (previous instanceof AV.Op.Set) {
8514 return new AV.Op.Set(this._estimate(previous.value()));
8515 } else if (previous instanceof AV.Op.Remove) {
8516 return new AV.Op.Remove(_.union(previous.objects(), this.objects()));
8517 } else {
8518 throw new Error('Op is invalid after previous op.');
8519 }
8520 },
8521
8522 _estimate: function _estimate(oldValue) {
8523 if (!oldValue) {
8524 return [];
8525 } else {
8526 var newValue = _.difference(oldValue, this.objects());
8527 // If there are saved AV Objects being removed, also remove them.
8528 AV._arrayEach(this.objects(), function (obj) {
8529 if (obj instanceof AV.Object && obj.id) {
8530 newValue = _.reject(newValue, function (other) {
8531 return other instanceof AV.Object && other.id === obj.id;
8532 });
8533 }
8534 });
8535 return newValue;
8536 }
8537 }
8538 });
8539
8540 AV.Op._registerDecoder("Remove", function (json) {
8541 return new AV.Op.Remove(AV._decode(json.objects));
8542 });
8543
8544 /**
8545 * @private
8546 * @class
8547 * A Relation operation indicates that the field is an instance of
8548 * AV.Relation, and objects are being added to, or removed from, that
8549 * relation.
8550 */
8551 AV.Op.Relation = AV.Op._extend(
8552 /** @lends AV.Op.Relation.prototype */{
8553
8554 _initialize: function _initialize(adds, removes) {
8555 this._targetClassName = null;
8556
8557 var self = this;
8558
8559 var pointerToId = function pointerToId(object) {
8560 if (object instanceof AV.Object) {
8561 if (!object.id) {
8562 throw new Error('You can\'t add an unsaved AV.Object to a relation.');
8563 }
8564 if (!self._targetClassName) {
8565 self._targetClassName = object.className;
8566 }
8567 if (self._targetClassName !== object.className) {
8568 throw new Error("Tried to create a AV.Relation with 2 different types: " + self._targetClassName + " and " + object.className + ".");
8569 }
8570 return object.id;
8571 }
8572 return object;
8573 };
8574
8575 this.relationsToAdd = _.uniq(_.map(adds, pointerToId));
8576 this.relationsToRemove = _.uniq(_.map(removes, pointerToId));
8577 },
8578
8579 /**
8580 * Returns an array of unfetched AV.Object that are being added to the
8581 * relation.
8582 * @return {Array}
8583 */
8584 added: function added() {
8585 var self = this;
8586 return _.map(this.relationsToAdd, function (objectId) {
8587 var object = AV.Object._create(self._targetClassName);
8588 object.id = objectId;
8589 return object;
8590 });
8591 },
8592
8593 /**
8594 * Returns an array of unfetched AV.Object that are being removed from
8595 * the relation.
8596 * @return {Array}
8597 */
8598 removed: function removed() {
8599 var self = this;
8600 return _.map(this.relationsToRemove, function (objectId) {
8601 var object = AV.Object._create(self._targetClassName);
8602 object.id = objectId;
8603 return object;
8604 });
8605 },
8606
8607 /**
8608 * Returns a JSON version of the operation suitable for sending to AV.
8609 * @return {Object}
8610 */
8611 toJSON: function toJSON() {
8612 var adds = null;
8613 var removes = null;
8614 var self = this;
8615 var idToPointer = function idToPointer(id) {
8616 return { __type: 'Pointer',
8617 className: self._targetClassName,
8618 objectId: id };
8619 };
8620 var pointers = null;
8621 if (this.relationsToAdd.length > 0) {
8622 pointers = _.map(this.relationsToAdd, idToPointer);
8623 adds = { "__op": "AddRelation", "objects": pointers };
8624 }
8625
8626 if (this.relationsToRemove.length > 0) {
8627 pointers = _.map(this.relationsToRemove, idToPointer);
8628 removes = { "__op": "RemoveRelation", "objects": pointers };
8629 }
8630
8631 if (adds && removes) {
8632 return { "__op": "Batch", "ops": [adds, removes] };
8633 }
8634
8635 return adds || removes || {};
8636 },
8637
8638 _mergeWithPrevious: function _mergeWithPrevious(previous) {
8639 if (!previous) {
8640 return this;
8641 } else if (previous instanceof AV.Op.Unset) {
8642 throw new Error('You can\'t modify a relation after deleting it.');
8643 } else if (previous instanceof AV.Op.Relation) {
8644 if (previous._targetClassName && previous._targetClassName !== this._targetClassName) {
8645 throw new Error("Related object must be of class " + previous._targetClassName + ", but " + this._targetClassName + " was passed in.");
8646 }
8647 var newAdd = _.union(_.difference(previous.relationsToAdd, this.relationsToRemove), this.relationsToAdd);
8648 var newRemove = _.union(_.difference(previous.relationsToRemove, this.relationsToAdd), this.relationsToRemove);
8649
8650 var newRelation = new AV.Op.Relation(newAdd, newRemove);
8651 newRelation._targetClassName = this._targetClassName;
8652 return newRelation;
8653 } else {
8654 throw new Error('Op is invalid after previous op.');
8655 }
8656 },
8657
8658 _estimate: function _estimate(oldValue, object, key) {
8659 if (!oldValue) {
8660 var relation = new AV.Relation(object, key);
8661 relation.targetClassName = this._targetClassName;
8662 } else if (oldValue instanceof AV.Relation) {
8663 if (this._targetClassName) {
8664 if (oldValue.targetClassName) {
8665 if (oldValue.targetClassName !== this._targetClassName) {
8666 throw new Error("Related object must be a " + oldValue.targetClassName + ", but a " + this._targetClassName + " was passed in.");
8667 }
8668 } else {
8669 oldValue.targetClassName = this._targetClassName;
8670 }
8671 }
8672 return oldValue;
8673 } else {
8674 throw new Error('Op is invalid after previous op.');
8675 }
8676 }
8677 });
8678
8679 AV.Op._registerDecoder("AddRelation", function (json) {
8680 return new AV.Op.Relation(AV._decode(json.objects), []);
8681 });
8682 AV.Op._registerDecoder("RemoveRelation", function (json) {
8683 return new AV.Op.Relation([], AV._decode(json.objects));
8684 });
8685};
8686
8687/***/ }),
8688/* 34 */
8689/***/ (function(module, exports, __webpack_require__) {
8690
8691"use strict";
8692
8693
8694var AVRequest = __webpack_require__(2).request;
8695
8696module.exports = function (AV) {
8697 AV.Installation = AV.Object.extend("_Installation");
8698
8699 /**
8700 * @namespace
8701 */
8702 AV.Push = AV.Push || {};
8703
8704 /**
8705 * Sends a push notification.
8706 * @param {Object} data The data of the push notification.
8707 * @param {String[]} [data.channels] An Array of channels to push to.
8708 * @param {Date} [data.push_time] A Date object for when to send the push.
8709 * @param {Date} [data.expiration_time] A Date object for when to expire
8710 * the push.
8711 * @param {Number} [data.expiration_interval] The seconds from now to expire the push.
8712 * @param {AV.Query} [data.where] An AV.Query over AV.Installation that is used to match
8713 * a set of installations to push to.
8714 * @param {String} [data.cql] A CQL statement over AV.Installation that is used to match
8715 * a set of installations to push to.
8716 * @param {Date} data.data The data to send as part of the push
8717 * @param {AuthOptions} [options]
8718 * @return {Promise}
8719 */
8720 AV.Push.send = function (data, options) {
8721 if (data.where) {
8722 data.where = data.where.toJSON().where;
8723 }
8724
8725 if (data.where && data.cql) {
8726 throw new Error("Both where and cql can't be set");
8727 }
8728
8729 if (data.push_time) {
8730 data.push_time = data.push_time.toJSON();
8731 }
8732
8733 if (data.expiration_time) {
8734 data.expiration_time = data.expiration_time.toJSON();
8735 }
8736
8737 if (data.expiration_time && data.expiration_time_interval) {
8738 throw new Error("Both expiration_time and expiration_time_interval can't be set");
8739 }
8740
8741 var request = AVRequest('push', null, null, 'POST', data, options);
8742 return request;
8743 };
8744};
8745
8746/***/ }),
8747/* 35 */
8748/***/ (function(module, exports, __webpack_require__) {
8749
8750"use strict";
8751
8752
8753var _ = __webpack_require__(0);
8754var debug = __webpack_require__(5)('leancloud:query');
8755var Promise = __webpack_require__(1);
8756var AVError = __webpack_require__(3);
8757var AVRequest = __webpack_require__(2).request;
8758
8759var _require = __webpack_require__(4),
8760 ensureArray = _require.ensureArray;
8761
8762var requires = function requires(value, message) {
8763 if (value === undefined) {
8764 throw new Error(message);
8765 }
8766};
8767
8768// AV.Query is a way to create a list of AV.Objects.
8769module.exports = function (AV) {
8770 /**
8771 * Creates a new AV.Query for the given AV.Object subclass.
8772 * @param {Class|String} objectClass An instance of a subclass of AV.Object, or a AV className string.
8773 * @class
8774 *
8775 * <p>AV.Query defines a query that is used to fetch AV.Objects. The
8776 * most common use case is finding all objects that match a query through the
8777 * <code>find</code> method. For example, this sample code fetches all objects
8778 * of class <code>MyClass</code>. It calls a different function depending on
8779 * whether the fetch succeeded or not.
8780 *
8781 * <pre>
8782 * var query = new AV.Query(MyClass);
8783 * query.find().then(function(results) {
8784 * // results is an array of AV.Object.
8785 * }, function(error) {
8786 * // error is an instance of AVError.
8787 * });</pre></p>
8788 *
8789 * <p>An AV.Query can also be used to retrieve a single object whose id is
8790 * known, through the get method. For example, this sample code fetches an
8791 * object of class <code>MyClass</code> and id <code>myId</code>. It calls a
8792 * different function depending on whether the fetch succeeded or not.
8793 *
8794 * <pre>
8795 * var query = new AV.Query(MyClass);
8796 * query.get(myId).then(function(object) {
8797 * // object is an instance of AV.Object.
8798 * }, function(error) {
8799 * // error is an instance of AVError.
8800 * });</pre></p>
8801 *
8802 * <p>An AV.Query can also be used to count the number of objects that match
8803 * the query without retrieving all of those objects. For example, this
8804 * sample code counts the number of objects of the class <code>MyClass</code>
8805 * <pre>
8806 * var query = new AV.Query(MyClass);
8807 * query.count().then(function(number) {
8808 * // There are number instances of MyClass.
8809 * }, function(error) {
8810 * // error is an instance of AVError.
8811 * });</pre></p>
8812 */
8813 AV.Query = function (objectClass) {
8814 if (_.isString(objectClass)) {
8815 objectClass = AV.Object._getSubclass(objectClass);
8816 }
8817
8818 this.objectClass = objectClass;
8819
8820 this.className = objectClass.prototype.className;
8821
8822 this._where = {};
8823 this._include = [];
8824 this._select = [];
8825 this._limit = -1; // negative limit means, do not send a limit
8826 this._skip = 0;
8827 this._extraOptions = {};
8828 };
8829
8830 /**
8831 * Constructs a AV.Query that is the OR of the passed in queries. For
8832 * example:
8833 * <pre>var compoundQuery = AV.Query.or(query1, query2, query3);</pre>
8834 *
8835 * will create a compoundQuery that is an or of the query1, query2, and
8836 * query3.
8837 * @param {...AV.Query} var_args The list of queries to OR.
8838 * @return {AV.Query} The query that is the OR of the passed in queries.
8839 */
8840 AV.Query.or = function () {
8841 var queries = _.toArray(arguments);
8842 var className = null;
8843 AV._arrayEach(queries, function (q) {
8844 if (_.isNull(className)) {
8845 className = q.className;
8846 }
8847
8848 if (className !== q.className) {
8849 throw new Error('All queries must be for the same class');
8850 }
8851 });
8852 var query = new AV.Query(className);
8853 query._orQuery(queries);
8854 return query;
8855 };
8856
8857 /**
8858 * Constructs a AV.Query that is the AND of the passed in queries. For
8859 * example:
8860 * <pre>var compoundQuery = AV.Query.and(query1, query2, query3);</pre>
8861 *
8862 * will create a compoundQuery that is an 'and' of the query1, query2, and
8863 * query3.
8864 * @param {...AV.Query} var_args The list of queries to AND.
8865 * @return {AV.Query} The query that is the AND of the passed in queries.
8866 */
8867 AV.Query.and = function () {
8868 var queries = _.toArray(arguments);
8869 var className = null;
8870 AV._arrayEach(queries, function (q) {
8871 if (_.isNull(className)) {
8872 className = q.className;
8873 }
8874
8875 if (className !== q.className) {
8876 throw new Error('All queries must be for the same class');
8877 }
8878 });
8879 var query = new AV.Query(className);
8880 query._andQuery(queries);
8881 return query;
8882 };
8883
8884 /**
8885 * Retrieves a list of AVObjects that satisfy the CQL.
8886 * CQL syntax please see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}.
8887 *
8888 * @param {String} cql A CQL string, see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}.
8889 * @param {Array} pvalues An array contains placeholder values.
8890 * @param {AuthOptions} options
8891 * @return {Promise} A promise that is resolved with the results when
8892 * the query completes.
8893 */
8894 AV.Query.doCloudQuery = function (cql, pvalues, options) {
8895 var params = { cql: cql };
8896 if (_.isArray(pvalues)) {
8897 params.pvalues = pvalues;
8898 } else {
8899 options = pvalues;
8900 }
8901
8902 var request = AVRequest('cloudQuery', null, null, 'GET', params, options);
8903 return request.then(function (response) {
8904 //query to process results.
8905 var query = new AV.Query(response.className);
8906 var results = _.map(response.results, function (json) {
8907 var obj = query._newObject(response);
8908 if (obj._finishFetch) {
8909 obj._finishFetch(query._processResult(json), true);
8910 }
8911 return obj;
8912 });
8913 return {
8914 results: results,
8915 count: response.count,
8916 className: response.className
8917 };
8918 });
8919 };
8920
8921 AV.Query._extend = AV._extend;
8922
8923 AV.Query.prototype = {
8924 //hook to iterate result. Added by dennis<xzhuang@avoscloud.com>.
8925 _processResult: function _processResult(obj) {
8926 return obj;
8927 },
8928
8929 /**
8930 * Constructs an AV.Object whose id is already known by fetching data from
8931 * the server.
8932 *
8933 * @param {String} objectId The id of the object to be fetched.
8934 * @param {AuthOptions} options
8935 * @return {Promise.<AV.Object>}
8936 */
8937 get: function get(objectId, options) {
8938 if (!objectId) {
8939 var errorObject = new AVError(AVError.OBJECT_NOT_FOUND, "Object not found.");
8940 throw errorObject;
8941 }
8942
8943 var self = this;
8944
8945 var obj = self._newObject();
8946 obj.id = objectId;
8947
8948 var queryJSON = self.toJSON();
8949 var fetchOptions = {};
8950
8951 if (queryJSON.keys) fetchOptions.keys = queryJSON.keys;
8952 if (queryJSON.include) fetchOptions.include = queryJSON.include;
8953
8954 return obj.fetch(fetchOptions, options);
8955 },
8956
8957 /**
8958 * Returns a JSON representation of this query.
8959 * @return {Object}
8960 */
8961 toJSON: function toJSON() {
8962 var params = {
8963 where: this._where
8964 };
8965
8966 if (this._include.length > 0) {
8967 params.include = this._include.join(",");
8968 }
8969 if (this._select.length > 0) {
8970 params.keys = this._select.join(",");
8971 }
8972 if (this._limit >= 0) {
8973 params.limit = this._limit;
8974 }
8975 if (this._skip > 0) {
8976 params.skip = this._skip;
8977 }
8978 if (this._order !== undefined) {
8979 params.order = this._order;
8980 }
8981
8982 AV._objectEach(this._extraOptions, function (v, k) {
8983 params[k] = v;
8984 });
8985
8986 return params;
8987 },
8988
8989 _newObject: function _newObject(response) {
8990 var obj;
8991 if (response && response.className) {
8992 obj = new AV.Object(response.className);
8993 } else {
8994 obj = new this.objectClass();
8995 }
8996 return obj;
8997 },
8998 _createRequest: function _createRequest() {
8999 var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.toJSON();
9000 var options = arguments[1];
9001
9002 if (JSON.stringify(params).length > 2000) {
9003 var body = {
9004 requests: [{
9005 method: 'GET',
9006 path: '/1.1/classes/' + this.className,
9007 params: params
9008 }]
9009 };
9010 return AVRequest('batch', null, null, 'POST', body, options).then(function (response) {
9011 var result = response[0];
9012 if (result.success) {
9013 return result.success;
9014 }
9015 var error = new Error(result.error.error || 'Unknown batch error');
9016 error.code = result.error.code;
9017 throw error;
9018 });
9019 }
9020 return AVRequest('classes', this.className, null, "GET", params, options);
9021 },
9022 _parseResponse: function _parseResponse(response) {
9023 var _this = this;
9024
9025 return _.map(response.results, function (json) {
9026 var obj = _this._newObject(response);
9027 if (obj._finishFetch) {
9028 obj._finishFetch(_this._processResult(json), true);
9029 }
9030 return obj;
9031 });
9032 },
9033
9034
9035 /**
9036 * Retrieves a list of AVObjects that satisfy this query.
9037 *
9038 * @param {AuthOptions} options
9039 * @return {Promise} A promise that is resolved with the results when
9040 * the query completes.
9041 */
9042 find: function find(options) {
9043 var request = this._createRequest(undefined, options);
9044 return request.then(this._parseResponse.bind(this));
9045 },
9046
9047
9048 /**
9049 * scan a Query. masterKey required.
9050 *
9051 * @since 2.1.0
9052 * @param {object} [options]
9053 * @param {string} [options.orderedBy] specify the key to sort
9054 * @param {number} [options.batchSize] specify the batch size for each request
9055 * @param {AuthOptions} [authOptions]
9056 * @return {AsyncIterator.<AV.Object>}
9057 * @example const scan = new AV.Query(TestClass).scan({
9058 * orderedBy: 'objectId',
9059 * batchSize: 10,
9060 * }, {
9061 * useMasterKey: true,
9062 * });
9063 * const getTen = () => Promise.all(new Array(10).fill(0).map(() => scan.next()));
9064 * getTen().then(results => {
9065 * // results are fisrt 10 instances of TestClass
9066 * return getTen();
9067 * }).then(results => {
9068 * // 11 - 20
9069 * });
9070 */
9071 scan: function scan() {
9072 var _this2 = this;
9073
9074 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
9075 orderedBy = _ref.orderedBy,
9076 batchSize = _ref.batchSize;
9077
9078 var authOptions = arguments[1];
9079
9080 var condition = this.toJSON();
9081 debug('scan %O', condition);
9082 if (condition.order) {
9083 console.warn('The order of the query is ignored for Query#scan. Checkout the orderedBy option of Query#scan.');
9084 delete condition.order;
9085 }
9086 if (condition.skip) {
9087 console.warn('The skip option of the query is ignored for Query#scan.');
9088 delete condition.skip;
9089 }
9090 if (condition.limit) {
9091 console.warn('The limit option of the query is ignored for Query#scan.');
9092 delete condition.limit;
9093 }
9094 if (orderedBy) condition.scan_key = orderedBy;
9095 if (batchSize) condition.limit = batchSize;
9096 var promise = Promise.resolve([]);
9097 var cursor = void 0;
9098 var done = false;
9099 return {
9100 next: function next() {
9101 promise = promise.then(function (remainResults) {
9102 if (done) return [];
9103 if (remainResults.length > 1) return remainResults;
9104 // no cursor means we have reached the end
9105 // except for the first time
9106 if (!cursor && remainResults.length !== 0) {
9107 done = true;
9108 return remainResults;
9109 }
9110 // when only 1 item left in queue
9111 // start the next request to see if it is the last one
9112 return AVRequest('scan/classes', _this2.className, null, 'GET', cursor ? _.extend({}, condition, { cursor: cursor }) : condition, authOptions).then(function (response) {
9113 cursor = response.cursor;
9114 return _this2._parseResponse(response);
9115 }).then(function (results) {
9116 if (!results.length) done = true;
9117 return remainResults.concat(results);
9118 });
9119 });
9120 return promise.then(function (remainResults) {
9121 return remainResults.shift();
9122 }).then(function (result) {
9123 return {
9124 value: result,
9125 done: done
9126 };
9127 });
9128 }
9129 };
9130 },
9131
9132
9133 /**
9134 * Delete objects retrieved by this query.
9135 * @param {AuthOptions} options
9136 * @return {Promise} A promise that is fulfilled when the save
9137 * completes.
9138 */
9139 destroyAll: function destroyAll(options) {
9140 var self = this;
9141 return self.find(options).then(function (objects) {
9142 return AV.Object.destroyAll(objects);
9143 });
9144 },
9145
9146 /**
9147 * Counts the number of objects that match this query.
9148 *
9149 * @param {AuthOptions} options
9150 * @return {Promise} A promise that is resolved with the count when
9151 * the query completes.
9152 */
9153 count: function count(options) {
9154 var params = this.toJSON();
9155 params.limit = 0;
9156 params.count = 1;
9157 var request = this._createRequest(params, options);
9158
9159 return request.then(function (response) {
9160 return response.count;
9161 });
9162 },
9163
9164 /**
9165 * Retrieves at most one AV.Object that satisfies this query.
9166 *
9167 * @param {AuthOptions} options
9168 * @return {Promise} A promise that is resolved with the object when
9169 * the query completes.
9170 */
9171 first: function first(options) {
9172 var self = this;
9173
9174 var params = this.toJSON();
9175 params.limit = 1;
9176 var request = this._createRequest(params, options);
9177
9178 return request.then(function (response) {
9179 return _.map(response.results, function (json) {
9180 var obj = self._newObject();
9181 if (obj._finishFetch) {
9182 obj._finishFetch(self._processResult(json), true);
9183 }
9184 return obj;
9185 })[0];
9186 });
9187 },
9188
9189 /**
9190 * Sets the number of results to skip before returning any results.
9191 * This is useful for pagination.
9192 * Default is to skip zero results.
9193 * @param {Number} n the number of results to skip.
9194 * @return {AV.Query} Returns the query, so you can chain this call.
9195 */
9196 skip: function skip(n) {
9197 requires(n, 'undefined is not a valid skip value');
9198 this._skip = n;
9199 return this;
9200 },
9201
9202 /**
9203 * Sets the limit of the number of results to return. The default limit is
9204 * 100, with a maximum of 1000 results being returned at a time.
9205 * @param {Number} n the number of results to limit to.
9206 * @return {AV.Query} Returns the query, so you can chain this call.
9207 */
9208 limit: function limit(n) {
9209 requires(n, 'undefined is not a valid limit value');
9210 this._limit = n;
9211 return this;
9212 },
9213
9214 /**
9215 * Add a constraint to the query that requires a particular key's value to
9216 * be equal to the provided value.
9217 * @param {String} key The key to check.
9218 * @param value The value that the AV.Object must contain.
9219 * @return {AV.Query} Returns the query, so you can chain this call.
9220 */
9221 equalTo: function equalTo(key, value) {
9222 requires(key, 'undefined is not a valid key');
9223 requires(value, 'undefined is not a valid value');
9224 this._where[key] = AV._encode(value);
9225 return this;
9226 },
9227
9228 /**
9229 * Helper for condition queries
9230 * @private
9231 */
9232 _addCondition: function _addCondition(key, condition, value) {
9233 requires(key, 'undefined is not a valid condition key');
9234 requires(condition, 'undefined is not a valid condition');
9235 requires(value, 'undefined is not a valid condition value');
9236
9237 // Check if we already have a condition
9238 if (!this._where[key]) {
9239 this._where[key] = {};
9240 }
9241 this._where[key][condition] = AV._encode(value);
9242 return this;
9243 },
9244
9245 /**
9246 * Add a constraint to the query that requires a particular
9247 * <strong>array</strong> key's length to be equal to the provided value.
9248 * @param {String} key The array key to check.
9249 * @param value The length value.
9250 * @return {AV.Query} Returns the query, so you can chain this call.
9251 */
9252 sizeEqualTo: function sizeEqualTo(key, value) {
9253 this._addCondition(key, "$size", value);
9254 },
9255
9256 /**
9257 * Add a constraint to the query that requires a particular key's value to
9258 * be not equal to the provided value.
9259 * @param {String} key The key to check.
9260 * @param value The value that must not be equalled.
9261 * @return {AV.Query} Returns the query, so you can chain this call.
9262 */
9263 notEqualTo: function notEqualTo(key, value) {
9264 this._addCondition(key, "$ne", value);
9265 return this;
9266 },
9267
9268 /**
9269 * Add a constraint to the query that requires a particular key's value to
9270 * be less than the provided value.
9271 * @param {String} key The key to check.
9272 * @param value The value that provides an upper bound.
9273 * @return {AV.Query} Returns the query, so you can chain this call.
9274 */
9275 lessThan: function lessThan(key, value) {
9276 this._addCondition(key, "$lt", value);
9277 return this;
9278 },
9279
9280 /**
9281 * Add a constraint to the query that requires a particular key's value to
9282 * be greater than the provided value.
9283 * @param {String} key The key to check.
9284 * @param value The value that provides an lower bound.
9285 * @return {AV.Query} Returns the query, so you can chain this call.
9286 */
9287 greaterThan: function greaterThan(key, value) {
9288 this._addCondition(key, "$gt", value);
9289 return this;
9290 },
9291
9292 /**
9293 * Add a constraint to the query that requires a particular key's value to
9294 * be less than or equal to the provided value.
9295 * @param {String} key The key to check.
9296 * @param value The value that provides an upper bound.
9297 * @return {AV.Query} Returns the query, so you can chain this call.
9298 */
9299 lessThanOrEqualTo: function lessThanOrEqualTo(key, value) {
9300 this._addCondition(key, "$lte", value);
9301 return this;
9302 },
9303
9304 /**
9305 * Add a constraint to the query that requires a particular key's value to
9306 * be greater than or equal to the provided value.
9307 * @param {String} key The key to check.
9308 * @param value The value that provides an lower bound.
9309 * @return {AV.Query} Returns the query, so you can chain this call.
9310 */
9311 greaterThanOrEqualTo: function greaterThanOrEqualTo(key, value) {
9312 this._addCondition(key, "$gte", value);
9313 return this;
9314 },
9315
9316 /**
9317 * Add a constraint to the query that requires a particular key's value to
9318 * be contained in the provided list of values.
9319 * @param {String} key The key to check.
9320 * @param {Array} values The values that will match.
9321 * @return {AV.Query} Returns the query, so you can chain this call.
9322 */
9323 containedIn: function containedIn(key, values) {
9324 this._addCondition(key, "$in", values);
9325 return this;
9326 },
9327
9328 /**
9329 * Add a constraint to the query that requires a particular key's value to
9330 * not be contained in the provided list of values.
9331 * @param {String} key The key to check.
9332 * @param {Array} values The values that will not match.
9333 * @return {AV.Query} Returns the query, so you can chain this call.
9334 */
9335 notContainedIn: function notContainedIn(key, values) {
9336 this._addCondition(key, "$nin", values);
9337 return this;
9338 },
9339
9340 /**
9341 * Add a constraint to the query that requires a particular key's value to
9342 * contain each one of the provided list of values.
9343 * @param {String} key The key to check. This key's value must be an array.
9344 * @param {Array} values The values that will match.
9345 * @return {AV.Query} Returns the query, so you can chain this call.
9346 */
9347 containsAll: function containsAll(key, values) {
9348 this._addCondition(key, "$all", values);
9349 return this;
9350 },
9351
9352 /**
9353 * Add a constraint for finding objects that contain the given key.
9354 * @param {String} key The key that should exist.
9355 * @return {AV.Query} Returns the query, so you can chain this call.
9356 */
9357 exists: function exists(key) {
9358 this._addCondition(key, "$exists", true);
9359 return this;
9360 },
9361
9362 /**
9363 * Add a constraint for finding objects that do not contain a given key.
9364 * @param {String} key The key that should not exist
9365 * @return {AV.Query} Returns the query, so you can chain this call.
9366 */
9367 doesNotExist: function doesNotExist(key) {
9368 this._addCondition(key, "$exists", false);
9369 return this;
9370 },
9371
9372 /**
9373 * Add a regular expression constraint for finding string values that match
9374 * the provided regular expression.
9375 * This may be slow for large datasets.
9376 * @param {String} key The key that the string to match is stored in.
9377 * @param {RegExp} regex The regular expression pattern to match.
9378 * @return {AV.Query} Returns the query, so you can chain this call.
9379 */
9380 matches: function matches(key, regex, modifiers) {
9381 this._addCondition(key, "$regex", regex);
9382 if (!modifiers) {
9383 modifiers = "";
9384 }
9385 // Javascript regex options support mig as inline options but store them
9386 // as properties of the object. We support mi & should migrate them to
9387 // modifiers
9388 if (regex.ignoreCase) {
9389 modifiers += 'i';
9390 }
9391 if (regex.multiline) {
9392 modifiers += 'm';
9393 }
9394
9395 if (modifiers && modifiers.length) {
9396 this._addCondition(key, "$options", modifiers);
9397 }
9398 return this;
9399 },
9400
9401 /**
9402 * Add a constraint that requires that a key's value matches a AV.Query
9403 * constraint.
9404 * @param {String} key The key that the contains the object to match the
9405 * query.
9406 * @param {AV.Query} query The query that should match.
9407 * @return {AV.Query} Returns the query, so you can chain this call.
9408 */
9409 matchesQuery: function matchesQuery(key, query) {
9410 var queryJSON = query.toJSON();
9411 queryJSON.className = query.className;
9412 this._addCondition(key, "$inQuery", queryJSON);
9413 return this;
9414 },
9415
9416 /**
9417 * Add a constraint that requires that a key's value not matches a
9418 * AV.Query constraint.
9419 * @param {String} key The key that the contains the object to match the
9420 * query.
9421 * @param {AV.Query} query The query that should not match.
9422 * @return {AV.Query} Returns the query, so you can chain this call.
9423 */
9424 doesNotMatchQuery: function doesNotMatchQuery(key, query) {
9425 var queryJSON = query.toJSON();
9426 queryJSON.className = query.className;
9427 this._addCondition(key, "$notInQuery", queryJSON);
9428 return this;
9429 },
9430
9431 /**
9432 * Add a constraint that requires that a key's value matches a value in
9433 * an object returned by a different AV.Query.
9434 * @param {String} key The key that contains the value that is being
9435 * matched.
9436 * @param {String} queryKey The key in the objects returned by the query to
9437 * match against.
9438 * @param {AV.Query} query The query to run.
9439 * @return {AV.Query} Returns the query, so you can chain this call.
9440 */
9441 matchesKeyInQuery: function matchesKeyInQuery(key, queryKey, query) {
9442 var queryJSON = query.toJSON();
9443 queryJSON.className = query.className;
9444 this._addCondition(key, "$select", { key: queryKey, query: queryJSON });
9445 return this;
9446 },
9447
9448 /**
9449 * Add a constraint that requires that a key's value not match a value in
9450 * an object returned by a different AV.Query.
9451 * @param {String} key The key that contains the value that is being
9452 * excluded.
9453 * @param {String} queryKey The key in the objects returned by the query to
9454 * match against.
9455 * @param {AV.Query} query The query to run.
9456 * @return {AV.Query} Returns the query, so you can chain this call.
9457 */
9458 doesNotMatchKeyInQuery: function doesNotMatchKeyInQuery(key, queryKey, query) {
9459 var queryJSON = query.toJSON();
9460 queryJSON.className = query.className;
9461 this._addCondition(key, "$dontSelect", { key: queryKey, query: queryJSON });
9462 return this;
9463 },
9464
9465 /**
9466 * Add constraint that at least one of the passed in queries matches.
9467 * @param {Array} queries
9468 * @return {AV.Query} Returns the query, so you can chain this call.
9469 * @private
9470 */
9471 _orQuery: function _orQuery(queries) {
9472 var queryJSON = _.map(queries, function (q) {
9473 return q.toJSON().where;
9474 });
9475
9476 this._where.$or = queryJSON;
9477 return this;
9478 },
9479
9480 /**
9481 * Add constraint that both of the passed in queries matches.
9482 * @param {Array} queries
9483 * @return {AV.Query} Returns the query, so you can chain this call.
9484 * @private
9485 */
9486 _andQuery: function _andQuery(queries) {
9487 var queryJSON = _.map(queries, function (q) {
9488 return q.toJSON().where;
9489 });
9490
9491 this._where.$and = queryJSON;
9492 return this;
9493 },
9494
9495 /**
9496 * Converts a string into a regex that matches it.
9497 * Surrounding with \Q .. \E does this, we just need to escape \E's in
9498 * the text separately.
9499 * @private
9500 */
9501 _quote: function _quote(s) {
9502 return "\\Q" + s.replace("\\E", "\\E\\\\E\\Q") + "\\E";
9503 },
9504
9505 /**
9506 * Add a constraint for finding string values that contain a provided
9507 * string. This may be slow for large datasets.
9508 * @param {String} key The key that the string to match is stored in.
9509 * @param {String} substring The substring that the value must contain.
9510 * @return {AV.Query} Returns the query, so you can chain this call.
9511 */
9512 contains: function contains(key, value) {
9513 this._addCondition(key, "$regex", this._quote(value));
9514 return this;
9515 },
9516
9517 /**
9518 * Add a constraint for finding string values that start with a provided
9519 * string. This query will use the backend index, so it will be fast even
9520 * for large datasets.
9521 * @param {String} key The key that the string to match is stored in.
9522 * @param {String} prefix The substring that the value must start with.
9523 * @return {AV.Query} Returns the query, so you can chain this call.
9524 */
9525 startsWith: function startsWith(key, value) {
9526 this._addCondition(key, "$regex", "^" + this._quote(value));
9527 return this;
9528 },
9529
9530 /**
9531 * Add a constraint for finding string values that end with a provided
9532 * string. This will be slow for large datasets.
9533 * @param {String} key The key that the string to match is stored in.
9534 * @param {String} suffix The substring that the value must end with.
9535 * @return {AV.Query} Returns the query, so you can chain this call.
9536 */
9537 endsWith: function endsWith(key, value) {
9538 this._addCondition(key, "$regex", this._quote(value) + "$");
9539 return this;
9540 },
9541
9542 /**
9543 * Sorts the results in ascending order by the given key.
9544 *
9545 * @param {String} key The key to order by.
9546 * @return {AV.Query} Returns the query, so you can chain this call.
9547 */
9548 ascending: function ascending(key) {
9549 requires(key, 'undefined is not a valid key');
9550 this._order = key;
9551 return this;
9552 },
9553
9554 /**
9555 * Also sorts the results in ascending order by the given key. The previous sort keys have
9556 * precedence over this key.
9557 *
9558 * @param {String} key The key to order by
9559 * @return {AV.Query} Returns the query so you can chain this call.
9560 */
9561 addAscending: function addAscending(key) {
9562 requires(key, 'undefined is not a valid key');
9563 if (this._order) this._order += ',' + key;else this._order = key;
9564 return this;
9565 },
9566
9567 /**
9568 * Sorts the results in descending order by the given key.
9569 *
9570 * @param {String} key The key to order by.
9571 * @return {AV.Query} Returns the query, so you can chain this call.
9572 */
9573 descending: function descending(key) {
9574 requires(key, 'undefined is not a valid key');
9575 this._order = "-" + key;
9576 return this;
9577 },
9578
9579 /**
9580 * Also sorts the results in descending order by the given key. The previous sort keys have
9581 * precedence over this key.
9582 *
9583 * @param {String} key The key to order by
9584 * @return {AV.Query} Returns the query so you can chain this call.
9585 */
9586 addDescending: function addDescending(key) {
9587 requires(key, 'undefined is not a valid key');
9588 if (this._order) this._order += ',-' + key;else this._order = '-' + key;
9589 return this;
9590 },
9591
9592 /**
9593 * Add a proximity based constraint for finding objects with key point
9594 * values near the point given.
9595 * @param {String} key The key that the AV.GeoPoint is stored in.
9596 * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.
9597 * @return {AV.Query} Returns the query, so you can chain this call.
9598 */
9599 near: function near(key, point) {
9600 if (!(point instanceof AV.GeoPoint)) {
9601 // Try to cast it to a GeoPoint, so that near("loc", [20,30]) works.
9602 point = new AV.GeoPoint(point);
9603 }
9604 this._addCondition(key, "$nearSphere", point);
9605 return this;
9606 },
9607
9608 /**
9609 * Add a proximity based constraint for finding objects with key point
9610 * values near the point given and within the maximum distance given.
9611 * @param {String} key The key that the AV.GeoPoint is stored in.
9612 * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.
9613 * @param maxDistance Maximum distance (in radians) of results to return.
9614 * @return {AV.Query} Returns the query, so you can chain this call.
9615 */
9616 withinRadians: function withinRadians(key, point, distance) {
9617 this.near(key, point);
9618 this._addCondition(key, "$maxDistance", distance);
9619 return this;
9620 },
9621
9622 /**
9623 * Add a proximity based constraint for finding objects with key point
9624 * values near the point given and within the maximum distance given.
9625 * Radius of earth used is 3958.8 miles.
9626 * @param {String} key The key that the AV.GeoPoint is stored in.
9627 * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.
9628 * @param {Number} maxDistance Maximum distance (in miles) of results to
9629 * return.
9630 * @return {AV.Query} Returns the query, so you can chain this call.
9631 */
9632 withinMiles: function withinMiles(key, point, distance) {
9633 return this.withinRadians(key, point, distance / 3958.8);
9634 },
9635
9636 /**
9637 * Add a proximity based constraint for finding objects with key point
9638 * values near the point given and within the maximum distance given.
9639 * Radius of earth used is 6371.0 kilometers.
9640 * @param {String} key The key that the AV.GeoPoint is stored in.
9641 * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.
9642 * @param {Number} maxDistance Maximum distance (in kilometers) of results
9643 * to return.
9644 * @return {AV.Query} Returns the query, so you can chain this call.
9645 */
9646 withinKilometers: function withinKilometers(key, point, distance) {
9647 return this.withinRadians(key, point, distance / 6371.0);
9648 },
9649
9650 /**
9651 * Add a constraint to the query that requires a particular key's
9652 * coordinates be contained within a given rectangular geographic bounding
9653 * box.
9654 * @param {String} key The key to be constrained.
9655 * @param {AV.GeoPoint} southwest
9656 * The lower-left inclusive corner of the box.
9657 * @param {AV.GeoPoint} northeast
9658 * The upper-right inclusive corner of the box.
9659 * @return {AV.Query} Returns the query, so you can chain this call.
9660 */
9661 withinGeoBox: function withinGeoBox(key, southwest, northeast) {
9662 if (!(southwest instanceof AV.GeoPoint)) {
9663 southwest = new AV.GeoPoint(southwest);
9664 }
9665 if (!(northeast instanceof AV.GeoPoint)) {
9666 northeast = new AV.GeoPoint(northeast);
9667 }
9668 this._addCondition(key, '$within', { '$box': [southwest, northeast] });
9669 return this;
9670 },
9671
9672 /**
9673 * Include nested AV.Objects for the provided key. You can use dot
9674 * notation to specify which fields in the included object are also fetch.
9675 * @param {String[]} keys The name of the key to include.
9676 * @return {AV.Query} Returns the query, so you can chain this call.
9677 */
9678 include: function include(keys) {
9679 var _this3 = this;
9680
9681 requires(keys, 'undefined is not a valid key');
9682 _(arguments).forEach(function (keys) {
9683 _this3._include = _this3._include.concat(ensureArray(keys));
9684 });
9685 return this;
9686 },
9687
9688 /**
9689 * Restrict the fields of the returned AV.Objects to include only the
9690 * provided keys. If this is called multiple times, then all of the keys
9691 * specified in each of the calls will be included.
9692 * @param {String[]} keys The names of the keys to include.
9693 * @return {AV.Query} Returns the query, so you can chain this call.
9694 */
9695 select: function select(keys) {
9696 var _this4 = this;
9697
9698 requires(keys, 'undefined is not a valid key');
9699 _(arguments).forEach(function (keys) {
9700 _this4._select = _this4._select.concat(ensureArray(keys));
9701 });
9702 return this;
9703 },
9704
9705 /**
9706 * Iterates over each result of a query, calling a callback for each one. If
9707 * the callback returns a promise, the iteration will not continue until
9708 * that promise has been fulfilled. If the callback returns a rejected
9709 * promise, then iteration will stop with that error. The items are
9710 * processed in an unspecified order. The query may not have any sort order,
9711 * and may not use limit or skip.
9712 * @param callback {Function} Callback that will be called with each result
9713 * of the query.
9714 * @return {Promise} A promise that will be fulfilled once the
9715 * iteration has completed.
9716 */
9717 each: function each(callback) {
9718 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
9719
9720
9721 if (this._order || this._skip || this._limit >= 0) {
9722 var error = new Error("Cannot iterate on a query with sort, skip, or limit.");
9723 return AV.Promise.reject(error);
9724 }
9725
9726 var query = new AV.Query(this.objectClass);
9727 // We can override the batch size from the options.
9728 // This is undocumented, but useful for testing.
9729 query._limit = options.batchSize || 100;
9730 query._where = _.clone(this._where);
9731 query._include = _.clone(this._include);
9732
9733 query.ascending('objectId');
9734
9735 var finished = false;
9736 return AV.Promise._continueWhile(function () {
9737 return !finished;
9738 }, function () {
9739 return query.find(options).then(function (results) {
9740 var callbacksDone = AV.Promise.resolve();
9741 _.each(results, function (result) {
9742 callbacksDone = callbacksDone.then(function () {
9743 return callback(result);
9744 });
9745 });
9746
9747 return callbacksDone.then(function () {
9748 if (results.length >= query._limit) {
9749 query.greaterThan("objectId", results[results.length - 1].id);
9750 } else {
9751 finished = true;
9752 }
9753 });
9754 });
9755 });
9756 }
9757 };
9758
9759 AV.FriendShipQuery = AV.Query._extend({
9760 _objectClass: AV.User,
9761 _newObject: function _newObject() {
9762 return new AV.User();
9763 },
9764 _processResult: function _processResult(json) {
9765 if (json && json[this._friendshipTag]) {
9766 var user = json[this._friendshipTag];
9767 if (user.__type === 'Pointer' && user.className === '_User') {
9768 delete user.__type;
9769 delete user.className;
9770 }
9771 return user;
9772 } else {
9773 return null;
9774 }
9775 }
9776 });
9777};
9778
9779/***/ }),
9780/* 36 */
9781/***/ (function(module, exports, __webpack_require__) {
9782
9783"use strict";
9784
9785
9786var _ = __webpack_require__(0);
9787
9788module.exports = function (AV) {
9789 /**
9790 * Creates a new Relation for the given parent object and key. This
9791 * constructor should rarely be used directly, but rather created by
9792 * {@link AV.Object#relation}.
9793 * @param {AV.Object} parent The parent of this relation.
9794 * @param {String} key The key for this relation on the parent.
9795 * @see AV.Object#relation
9796 * @class
9797 *
9798 * <p>
9799 * A class that is used to access all of the children of a many-to-many
9800 * relationship. Each instance of AV.Relation is associated with a
9801 * particular parent object and key.
9802 * </p>
9803 */
9804 AV.Relation = function (parent, key) {
9805 if (!_.isString(key)) {
9806 throw new TypeError('key must be a string');
9807 }
9808 this.parent = parent;
9809 this.key = key;
9810 this.targetClassName = null;
9811 };
9812
9813 /**
9814 * Creates a query that can be used to query the parent objects in this relation.
9815 * @param {String} parentClass The parent class or name.
9816 * @param {String} relationKey The relation field key in parent.
9817 * @param {AV.Object} child The child object.
9818 * @return {AV.Query}
9819 */
9820 AV.Relation.reverseQuery = function (parentClass, relationKey, child) {
9821 var query = new AV.Query(parentClass);
9822 query.equalTo(relationKey, child._toPointer());
9823 return query;
9824 };
9825
9826 AV.Relation.prototype = {
9827 /**
9828 * Makes sure that this relation has the right parent and key.
9829 * @private
9830 */
9831 _ensureParentAndKey: function _ensureParentAndKey(parent, key) {
9832 this.parent = this.parent || parent;
9833 this.key = this.key || key;
9834 if (this.parent !== parent) {
9835 throw new Error("Internal Error. Relation retrieved from two different Objects.");
9836 }
9837 if (this.key !== key) {
9838 throw new Error("Internal Error. Relation retrieved from two different keys.");
9839 }
9840 },
9841
9842 /**
9843 * Adds a AV.Object or an array of AV.Objects to the relation.
9844 * @param {AV.Object|AV.Object[]} objects The item or items to add.
9845 */
9846 add: function add(objects) {
9847 if (!_.isArray(objects)) {
9848 objects = [objects];
9849 }
9850
9851 var change = new AV.Op.Relation(objects, []);
9852 this.parent.set(this.key, change);
9853 this.targetClassName = change._targetClassName;
9854 },
9855
9856 /**
9857 * Removes a AV.Object or an array of AV.Objects from this relation.
9858 * @param {AV.Object|AV.Object[]} objects The item or items to remove.
9859 */
9860 remove: function remove(objects) {
9861 if (!_.isArray(objects)) {
9862 objects = [objects];
9863 }
9864
9865 var change = new AV.Op.Relation([], objects);
9866 this.parent.set(this.key, change);
9867 this.targetClassName = change._targetClassName;
9868 },
9869
9870 /**
9871 * Returns a JSON version of the object suitable for saving to disk.
9872 * @return {Object}
9873 */
9874 toJSON: function toJSON() {
9875 return { "__type": "Relation", "className": this.targetClassName };
9876 },
9877
9878 /**
9879 * Returns a AV.Query that is limited to objects in this
9880 * relation.
9881 * @return {AV.Query}
9882 */
9883 query: function query() {
9884 var targetClass;
9885 var query;
9886 if (!this.targetClassName) {
9887 targetClass = AV.Object._getSubclass(this.parent.className);
9888 query = new AV.Query(targetClass);
9889 query._extraOptions.redirectClassNameForKey = this.key;
9890 } else {
9891 targetClass = AV.Object._getSubclass(this.targetClassName);
9892 query = new AV.Query(targetClass);
9893 }
9894 query._addCondition("$relatedTo", "object", this.parent._toPointer());
9895 query._addCondition("$relatedTo", "key", this.key);
9896
9897 return query;
9898 }
9899 };
9900};
9901
9902/***/ }),
9903/* 37 */
9904/***/ (function(module, exports, __webpack_require__) {
9905
9906"use strict";
9907
9908
9909var _ = __webpack_require__(0);
9910var AVError = __webpack_require__(3);
9911
9912module.exports = function (AV) {
9913 AV.Role = AV.Object.extend("_Role", /** @lends AV.Role.prototype */{
9914 // Instance Methods
9915
9916 /**
9917 * Represents a Role on the AV server. Roles represent groupings of
9918 * Users for the purposes of granting permissions (e.g. specifying an ACL
9919 * for an Object). Roles are specified by their sets of child users and
9920 * child roles, all of which are granted any permissions that the parent
9921 * role has.
9922 *
9923 * <p>Roles must have a name (which cannot be changed after creation of the
9924 * role), and must specify an ACL.</p>
9925 * An AV.Role is a local representation of a role persisted to the AV
9926 * cloud.
9927 * @class AV.Role
9928 * @param {String} name The name of the Role to create.
9929 * @param {AV.ACL} [acl] The ACL for this role. if absent, the default ACL
9930 * `{'*': { read: true }}` will be used.
9931 */
9932 constructor: function constructor(name, acl) {
9933 if (_.isString(name)) {
9934 AV.Object.prototype.constructor.call(this, null, null);
9935 this.setName(name);
9936 } else {
9937 AV.Object.prototype.constructor.call(this, name, acl);
9938 }
9939 if (acl === undefined) {
9940 var defaultAcl = new AV.ACL();
9941 defaultAcl.setPublicReadAccess(true);
9942 if (!this.getACL()) {
9943 this.setACL(defaultAcl);
9944 }
9945 } else if (!(acl instanceof AV.ACL)) {
9946 throw new TypeError('acl must be an instance of AV.ACL');
9947 } else {
9948 this.setACL(acl);
9949 }
9950 },
9951
9952 /**
9953 * Gets the name of the role. You can alternatively call role.get("name")
9954 *
9955 * @return {String} the name of the role.
9956 */
9957 getName: function getName() {
9958 return this.get("name");
9959 },
9960
9961 /**
9962 * Sets the name for a role. This value must be set before the role has
9963 * been saved to the server, and cannot be set once the role has been
9964 * saved.
9965 *
9966 * <p>
9967 * A role's name can only contain alphanumeric characters, _, -, and
9968 * spaces.
9969 * </p>
9970 *
9971 * <p>This is equivalent to calling role.set("name", name)</p>
9972 *
9973 * @param {String} name The name of the role.
9974 */
9975 setName: function setName(name, options) {
9976 return this.set("name", name, options);
9977 },
9978
9979 /**
9980 * Gets the AV.Relation for the AV.Users that are direct
9981 * children of this role. These users are granted any privileges that this
9982 * role has been granted (e.g. read or write access through ACLs). You can
9983 * add or remove users from the role through this relation.
9984 *
9985 * <p>This is equivalent to calling role.relation("users")</p>
9986 *
9987 * @return {AV.Relation} the relation for the users belonging to this
9988 * role.
9989 */
9990 getUsers: function getUsers() {
9991 return this.relation("users");
9992 },
9993
9994 /**
9995 * Gets the AV.Relation for the AV.Roles that are direct
9996 * children of this role. These roles' users are granted any privileges that
9997 * this role has been granted (e.g. read or write access through ACLs). You
9998 * can add or remove child roles from this role through this relation.
9999 *
10000 * <p>This is equivalent to calling role.relation("roles")</p>
10001 *
10002 * @return {AV.Relation} the relation for the roles belonging to this
10003 * role.
10004 */
10005 getRoles: function getRoles() {
10006 return this.relation("roles");
10007 },
10008
10009 /**
10010 * @ignore
10011 */
10012 validate: function validate(attrs, options) {
10013 if ("name" in attrs && attrs.name !== this.getName()) {
10014 var newName = attrs.name;
10015 if (this.id && this.id !== attrs.objectId) {
10016 // Check to see if the objectId being set matches this.id.
10017 // This happens during a fetch -- the id is set before calling fetch.
10018 // Let the name be set in this case.
10019 return new AVError(AVError.OTHER_CAUSE, "A role's name can only be set before it has been saved.");
10020 }
10021 if (!_.isString(newName)) {
10022 return new AVError(AVError.OTHER_CAUSE, "A role's name must be a String.");
10023 }
10024 if (!/^[0-9a-zA-Z\-_ ]+$/.test(newName)) {
10025 return new AVError(AVError.OTHER_CAUSE, "A role's name can only contain alphanumeric characters, _," + " -, and spaces.");
10026 }
10027 }
10028 if (AV.Object.prototype.validate) {
10029 return AV.Object.prototype.validate.call(this, attrs, options);
10030 }
10031 return false;
10032 }
10033 });
10034};
10035
10036/***/ }),
10037/* 38 */
10038/***/ (function(module, exports, __webpack_require__) {
10039
10040"use strict";
10041
10042
10043var _ = __webpack_require__(0);
10044var AVRequest = __webpack_require__(2).request;
10045
10046module.exports = function (AV) {
10047 /**
10048 * A builder to generate sort string for app searching.For example:
10049 * @class
10050 * @since 0.5.1
10051 * @example
10052 * var builder = new AV.SearchSortBuilder();
10053 * builder.ascending('key1').descending('key2','max');
10054 * var query = new AV.SearchQuery('Player');
10055 * query.sortBy(builder);
10056 * query.find().then();
10057 */
10058 AV.SearchSortBuilder = function () {
10059 this._sortFields = [];
10060 };
10061
10062 AV.SearchSortBuilder.prototype = {
10063 _addField: function _addField(key, order, mode, missing) {
10064 var field = {};
10065 field[key] = {
10066 order: order || 'asc',
10067 mode: mode || 'avg',
10068 missing: '_' + (missing || 'last')
10069 };
10070 this._sortFields.push(field);
10071 return this;
10072 },
10073
10074 /**
10075 * Sorts the results in ascending order by the given key and options.
10076 *
10077 * @param {String} key The key to order by.
10078 * @param {String} mode The sort mode, default is 'avg', you can choose
10079 * 'max' or 'min' too.
10080 * @param {String} missing The missing key behaviour, default is 'last',
10081 * you can choose 'first' too.
10082 * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.
10083 */
10084 ascending: function ascending(key, mode, missing) {
10085 return this._addField(key, 'asc', mode, missing);
10086 },
10087
10088 /**
10089 * Sorts the results in descending order by the given key and options.
10090 *
10091 * @param {String} key The key to order by.
10092 * @param {String} mode The sort mode, default is 'avg', you can choose
10093 * 'max' or 'min' too.
10094 * @param {String} missing The missing key behaviour, default is 'last',
10095 * you can choose 'first' too.
10096 * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.
10097 */
10098 descending: function descending(key, mode, missing) {
10099 return this._addField(key, 'desc', mode, missing);
10100 },
10101
10102 /**
10103 * Add a proximity based constraint for finding objects with key point
10104 * values near the point given.
10105 * @param {String} key The key that the AV.GeoPoint is stored in.
10106 * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.
10107 * @param {Object} options The other options such as mode,order, unit etc.
10108 * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.
10109 */
10110 whereNear: function whereNear(key, point, options) {
10111 options = options || {};
10112 var field = {};
10113 var geo = {
10114 lat: point.latitude,
10115 lon: point.longitude
10116 };
10117 var m = {
10118 order: options.order || 'asc',
10119 mode: options.mode || 'avg',
10120 unit: options.unit || 'km'
10121 };
10122 m[key] = geo;
10123 field['_geo_distance'] = m;
10124
10125 this._sortFields.push(field);
10126 return this;
10127 },
10128
10129 /**
10130 * Build a sort string by configuration.
10131 * @return {String} the sort string.
10132 */
10133 build: function build() {
10134 return JSON.stringify(AV._encode(this._sortFields));
10135 }
10136 };
10137
10138 /**
10139 * App searching query.Use just like AV.Query:
10140 *
10141 * Visit <a href='https://leancloud.cn/docs/app_search_guide.html'>App Searching Guide</a>
10142 * for more details.
10143 * @class
10144 * @since 0.5.1
10145 * @example
10146 * var query = new AV.SearchQuery('Player');
10147 * query.queryString('*');
10148 * query.find().then(function(results) {
10149 * console.log('Found %d objects', query.hits());
10150 * //Process results
10151 * });
10152 */
10153 AV.SearchQuery = AV.Query._extend( /** @lends AV.SearchQuery.prototype */{
10154 _sid: null,
10155 _hits: 0,
10156 _queryString: null,
10157 _highlights: null,
10158 _sortBuilder: null,
10159 _createRequest: function _createRequest(params, options) {
10160 return AVRequest('search/select', null, null, 'GET', params || this.toJSON(), options);
10161 },
10162
10163 /**
10164 * Sets the sid of app searching query.Default is null.
10165 * @param {String} sid Scroll id for searching.
10166 * @return {AV.SearchQuery} Returns the query, so you can chain this call.
10167 */
10168 sid: function sid(_sid) {
10169 this._sid = _sid;
10170 return this;
10171 },
10172
10173 /**
10174 * Sets the query string of app searching.
10175 * @param {String} q The query string.
10176 * @return {AV.SearchQuery} Returns the query, so you can chain this call.
10177 */
10178 queryString: function queryString(q) {
10179 this._queryString = q;
10180 return this;
10181 },
10182
10183 /**
10184 * Sets the highlight fields. Such as
10185 * <pre><code>
10186 * query.highlights('title');
10187 * //or pass an array.
10188 * query.highlights(['title', 'content'])
10189 * </code></pre>
10190 * @param {String[]} highlights a list of fields.
10191 * @return {AV.SearchQuery} Returns the query, so you can chain this call.
10192 */
10193 highlights: function highlights(_highlights) {
10194 var objects;
10195 if (_highlights && _.isString(_highlights)) {
10196 objects = arguments;
10197 } else {
10198 objects = _highlights;
10199 }
10200 this._highlights = objects;
10201 return this;
10202 },
10203
10204 /**
10205 * Sets the sort builder for this query.
10206 * @see AV.SearchSortBuilder
10207 * @param { AV.SearchSortBuilder} builder The sort builder.
10208 * @return {AV.SearchQuery} Returns the query, so you can chain this call.
10209 *
10210 */
10211 sortBy: function sortBy(builder) {
10212 this._sortBuilder = builder;
10213 return this;
10214 },
10215
10216 /**
10217 * Returns the number of objects that match this query.
10218 * @return {Number}
10219 */
10220 hits: function hits() {
10221 if (!this._hits) {
10222 this._hits = 0;
10223 }
10224 return this._hits;
10225 },
10226
10227 _processResult: function _processResult(json) {
10228 delete json['className'];
10229 delete json['_app_url'];
10230 delete json['_deeplink'];
10231 return json;
10232 },
10233
10234 /**
10235 * Returns true when there are more documents can be retrieved by this
10236 * query instance, you can call find function to get more results.
10237 * @see AV.SearchQuery#find
10238 * @return {Boolean}
10239 */
10240 hasMore: function hasMore() {
10241 return !this._hitEnd;
10242 },
10243
10244 /**
10245 * Reset current query instance state(such as sid, hits etc) except params
10246 * for a new searching. After resetting, hasMore() will return true.
10247 */
10248 reset: function reset() {
10249 this._hitEnd = false;
10250 this._sid = null;
10251 this._hits = 0;
10252 },
10253
10254 /**
10255 * Retrieves a list of AVObjects that satisfy this query.
10256 * Either options.success or options.error is called when the find
10257 * completes.
10258 *
10259 * @see AV.Query#find
10260 * @return {AV.Promise} A promise that is resolved with the results when
10261 * the query completes.
10262 */
10263 find: function find() {
10264 var self = this;
10265
10266 var request = this._createRequest();
10267
10268 return request.then(function (response) {
10269 //update sid for next querying.
10270 if (response.sid) {
10271 self._oldSid = self._sid;
10272 self._sid = response.sid;
10273 } else {
10274 self._sid = null;
10275 self._hitEnd = true;
10276 }
10277 self._hits = response.hits || 0;
10278
10279 return _.map(response.results, function (json) {
10280 if (json.className) {
10281 response.className = json.className;
10282 }
10283 var obj = self._newObject(response);
10284 obj.appURL = json['_app_url'];
10285 obj._finishFetch(self._processResult(json), true);
10286 return obj;
10287 });
10288 });
10289 },
10290
10291 toJSON: function toJSON() {
10292 var params = AV.SearchQuery.__super__.toJSON.call(this);
10293 delete params.where;
10294 if (this.className) {
10295 params.clazz = this.className;
10296 }
10297 if (this._sid) {
10298 params.sid = this._sid;
10299 }
10300 if (!this._queryString) {
10301 throw new Error('Please set query string.');
10302 } else {
10303 params.q = this._queryString;
10304 }
10305 if (this._highlights) {
10306 params.highlights = this._highlights.join(',');
10307 }
10308 if (this._sortBuilder && params.order) {
10309 throw new Error('sort and order can not be set at same time.');
10310 }
10311 if (this._sortBuilder) {
10312 params.sort = this._sortBuilder.build();
10313 }
10314
10315 return params;
10316 }
10317 });
10318};
10319
10320/***/ }),
10321/* 39 */
10322/***/ (function(module, exports, __webpack_require__) {
10323
10324"use strict";
10325
10326
10327var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
10328
10329var _ = __webpack_require__(0);
10330var AVRequest = __webpack_require__(2).request;
10331
10332module.exports = function (AV) {
10333 var getUser = function getUser() {
10334 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10335 return AV.User.currentAsync().then(function (currUser) {
10336 return currUser || AV.User._fetchUserBySessionToken(options.sessionToken);
10337 });
10338 };
10339
10340 var getUserPointer = function getUserPointer(options) {
10341 return getUser(options).then(function (currUser) {
10342 return AV.Object.createWithoutData('_User', currUser.id)._toPointer();
10343 });
10344 };
10345
10346 /**
10347 * Contains functions to deal with Status in LeanCloud.
10348 * @class
10349 */
10350 AV.Status = function (imageUrl, message) {
10351 this.data = {};
10352 this.inboxType = 'default';
10353 this.query = null;
10354 if (imageUrl && (typeof imageUrl === 'undefined' ? 'undefined' : _typeof(imageUrl)) === 'object') {
10355 this.data = imageUrl;
10356 } else {
10357 if (imageUrl) {
10358 this.data.image = imageUrl;
10359 }
10360 if (message) {
10361 this.data.message = message;
10362 }
10363 }
10364 return this;
10365 };
10366
10367 AV.Status.prototype = {
10368 /**
10369 * Gets the value of an attribute in status data.
10370 * @param {String} attr The string name of an attribute.
10371 */
10372 get: function get(attr) {
10373 return this.data[attr];
10374 },
10375 /**
10376 * Sets a hash of model attributes on the status data.
10377 * @param {String} key The key to set.
10378 * @param {} value The value to give it.
10379 */
10380 set: function set(key, value) {
10381 this.data[key] = value;
10382 return this;
10383 },
10384 /**
10385 * Destroy this status,then it will not be avaiable in other user's inboxes.
10386 * @param {AuthOptions} options
10387 * @return {Promise} A promise that is fulfilled when the destroy
10388 * completes.
10389 */
10390 destroy: function destroy(options) {
10391 if (!this.id) return AV.Promise.reject(new Error('The status id is not exists.'));
10392 var request = AVRequest('statuses', null, this.id, 'DELETE', options);
10393 return request;
10394 },
10395 /**
10396 * Cast the AV.Status object to an AV.Object pointer.
10397 * @return {AV.Object} A AV.Object pointer.
10398 */
10399 toObject: function toObject() {
10400 if (!this.id) return null;
10401 return AV.Object.createWithoutData('_Status', this.id);
10402 },
10403 _getDataJSON: function _getDataJSON() {
10404 var json = _.clone(this.data);
10405 return AV._encode(json);
10406 },
10407 /**
10408 * Send a status by a AV.Query object.
10409 * @since 0.3.0
10410 * @param {AuthOptions} options
10411 * @return {Promise} A promise that is fulfilled when the send
10412 * completes.
10413 * @example
10414 * // send a status to male users
10415 * var status = new AVStatus('image url', 'a message');
10416 * status.query = new AV.Query('_User');
10417 * status.query.equalTo('gender', 'male');
10418 * status.send().then(function(){
10419 * //send status successfully.
10420 * }, function(err){
10421 * //an error threw.
10422 * console.dir(err);
10423 * });
10424 */
10425 send: function send() {
10426 var _this = this;
10427
10428 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10429
10430 if (!options.sessionToken && !AV.User.current()) {
10431 throw new Error('Please signin an user.');
10432 }
10433 if (!this.query) {
10434 return AV.Status.sendStatusToFollowers(this, options);
10435 }
10436
10437 return getUserPointer(options).then(function (currUser) {
10438 var query = _this.query.toJSON();
10439 query.className = _this.query.className;
10440 var data = {};
10441 data.query = query;
10442 _this.data = _this.data || {};
10443 _this.data.source = _this.data.source || currUser;
10444 data.data = _this._getDataJSON();
10445 data.inboxType = _this.inboxType || 'default';
10446
10447 return AVRequest('statuses', null, null, 'POST', data, options);
10448 }).then(function (response) {
10449 _this.id = response.objectId;
10450 _this.createdAt = AV._parseDate(response.createdAt);
10451 return _this;
10452 });
10453 },
10454
10455 _finishFetch: function _finishFetch(serverData) {
10456 this.id = serverData.objectId;
10457 this.createdAt = AV._parseDate(serverData.createdAt);
10458 this.updatedAt = AV._parseDate(serverData.updatedAt);
10459 this.messageId = serverData.messageId;
10460 delete serverData.messageId;
10461 delete serverData.objectId;
10462 delete serverData.createdAt;
10463 delete serverData.updatedAt;
10464 this.data = AV._decode(serverData);
10465 }
10466 };
10467
10468 /**
10469 * Send a status to current signined user's followers.
10470 * @since 0.3.0
10471 * @param {AV.Status} status A status object to be send to followers.
10472 * @param {AuthOptions} options
10473 * @return {Promise} A promise that is fulfilled when the send
10474 * completes.
10475 * @example
10476 * var status = new AVStatus('image url', 'a message');
10477 * AV.Status.sendStatusToFollowers(status).then(function(){
10478 * //send status successfully.
10479 * }, function(err){
10480 * //an error threw.
10481 * console.dir(err);
10482 * });
10483 */
10484 AV.Status.sendStatusToFollowers = function (status) {
10485 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
10486
10487 if (!options.sessionToken && !AV.User.current()) {
10488 throw new Error('Please signin an user.');
10489 }
10490 return getUserPointer(options).then(function (currUser) {
10491 var query = {};
10492 query.className = '_Follower';
10493 query.keys = 'follower';
10494 query.where = { user: currUser };
10495 var data = {};
10496 data.query = query;
10497 status.data = status.data || {};
10498 status.data.source = status.data.source || currUser;
10499 data.data = status._getDataJSON();
10500 data.inboxType = status.inboxType || 'default';
10501
10502 var request = AVRequest('statuses', null, null, 'POST', data, options);
10503 return request.then(function (response) {
10504 status.id = response.objectId;
10505 status.createdAt = AV._parseDate(response.createdAt);
10506 return status;
10507 });
10508 });
10509 };
10510
10511 /**
10512 * <p>Send a status from current signined user to other user's private status inbox.</p>
10513 * @since 0.3.0
10514 * @param {AV.Status} status A status object to be send to followers.
10515 * @param {String} target The target user or user's objectId.
10516 * @param {AuthOptions} options
10517 * @return {Promise} A promise that is fulfilled when the send
10518 * completes.
10519 * @example
10520 * // send a private status to user '52e84e47e4b0f8de283b079b'
10521 * var status = new AVStatus('image url', 'a message');
10522 * AV.Status.sendPrivateStatus(status, '52e84e47e4b0f8de283b079b').then(function(){
10523 * //send status successfully.
10524 * }, function(err){
10525 * //an error threw.
10526 * console.dir(err);
10527 * });
10528 */
10529 AV.Status.sendPrivateStatus = function (status, target) {
10530 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
10531
10532 if (!options.sessionToken && !AV.User.current()) {
10533 throw new Error('Please signin an user.');
10534 }
10535 if (!target) {
10536 throw new Error("Invalid target user.");
10537 }
10538 var userObjectId = _.isString(target) ? target : target.id;
10539 if (!userObjectId) {
10540 throw new Error("Invalid target user.");
10541 }
10542 return getUserPointer(options).then(function (currUser) {
10543 var query = {};
10544 query.className = '_User';
10545 query.where = { objectId: userObjectId };
10546 var data = {};
10547 data.query = query;
10548 status.data = status.data || {};
10549 status.data.source = status.data.source || currUser;
10550 data.data = status._getDataJSON();
10551 data.inboxType = 'private';
10552 status.inboxType = 'private';
10553
10554 var request = AVRequest('statuses', null, null, 'POST', data, options);
10555 return request.then(function (response) {
10556 status.id = response.objectId;
10557 status.createdAt = AV._parseDate(response.createdAt);
10558 return status;
10559 });
10560 });
10561 };
10562
10563 /**
10564 * Count unread statuses in someone's inbox.
10565 * @since 0.3.0
10566 * @param {Object} owner The status owner.
10567 * @param {String} inboxType The inbox type, 'default' by default.
10568 * @param {AuthOptions} options
10569 * @return {Promise} A promise that is fulfilled when the count
10570 * completes.
10571 * @example
10572 * AV.Status.countUnreadStatuses(AV.User.current()).then(function(response){
10573 * console.log(response.unread); //unread statuses number.
10574 * console.log(response.total); //total statuses number.
10575 * });
10576 */
10577 AV.Status.countUnreadStatuses = function (owner) {
10578 var inboxType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default';
10579 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
10580
10581 if (!_.isString(inboxType)) options = inboxType;
10582 if (!options.sessionToken && owner == null && !AV.User.current()) {
10583 throw new Error('Please signin an user or pass the owner objectId.');
10584 }
10585 return getUser(options).then(function (owner) {
10586 var params = {};
10587 params.inboxType = AV._encode(inboxType);
10588 params.owner = AV._encode(owner);
10589 return AVRequest('subscribe/statuses/count', null, null, 'GET', params, options);
10590 });
10591 };
10592
10593 /**
10594 * reset unread statuses count in someone's inbox.
10595 * @since 2.1.0
10596 * @param {Object} owner The status owner.
10597 * @param {String} inboxType The inbox type, 'default' by default.
10598 * @param {AuthOptions} options
10599 * @return {Promise} A promise that is fulfilled when the reset
10600 * completes.
10601 * @example
10602 * AV.Status.resetUnreadCount(AV.User.current()).then(function(response){
10603 * console.log(response.unread); //unread statuses number.
10604 * console.log(response.total); //total statuses number.
10605 * });
10606 */
10607 AV.Status.resetUnreadCount = function (owner) {
10608 var inboxType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default';
10609 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
10610
10611 if (!_.isString(inboxType)) options = inboxType;
10612 if (!options.sessionToken && owner == null && !AV.User.current()) {
10613 throw new Error('Please signin an user or pass the owner objectId.');
10614 }
10615 return getUser(options).then(function (owner) {
10616 var params = {};
10617 params.inboxType = AV._encode(inboxType);
10618 params.owner = AV._encode(owner);
10619 return AVRequest('subscribe/statuses/resetUnreadCount', null, null, 'POST', params, options);
10620 });
10621 };
10622
10623 /**
10624 * Create a status query to find someone's published statuses.
10625 * @since 0.3.0
10626 * @param {Object} source The status source.
10627 * @return {AV.Query} The query object for status.
10628 * @example
10629 * //Find current user's published statuses.
10630 * var query = AV.Status.statusQuery(AV.User.current());
10631 * query.find().then(function(statuses){
10632 * //process statuses
10633 * });
10634 */
10635 AV.Status.statusQuery = function (source) {
10636 var query = new AV.Query('_Status');
10637 if (source) {
10638 query.equalTo('source', source);
10639 }
10640 return query;
10641 };
10642
10643 /**
10644 * <p>AV.InboxQuery defines a query that is used to fetch somebody's inbox statuses.</p>
10645 * @class
10646 */
10647 AV.InboxQuery = AV.Query._extend( /** @lends AV.InboxQuery.prototype */{
10648 _objectClass: AV.Status,
10649 _sinceId: 0,
10650 _maxId: 0,
10651 _inboxType: 'default',
10652 _owner: null,
10653 _newObject: function _newObject() {
10654 return new AV.Status();
10655 },
10656 _createRequest: function _createRequest(params, options) {
10657 return AVRequest('subscribe/statuses', null, null, 'GET', params || this.toJSON(), options);
10658 },
10659
10660 /**
10661 * Sets the messageId of results to skip before returning any results.
10662 * This is useful for pagination.
10663 * Default is zero.
10664 * @param {Number} n the mesage id.
10665 * @return {AV.InboxQuery} Returns the query, so you can chain this call.
10666 */
10667 sinceId: function sinceId(id) {
10668 this._sinceId = id;
10669 return this;
10670 },
10671 /**
10672 * Sets the maximal messageId of results。
10673 * This is useful for pagination.
10674 * Default is zero that is no limition.
10675 * @param {Number} n the mesage id.
10676 * @return {AV.InboxQuery} Returns the query, so you can chain this call.
10677 */
10678 maxId: function maxId(id) {
10679 this._maxId = id;
10680 return this;
10681 },
10682 /**
10683 * Sets the owner of the querying inbox.
10684 * @param {Object} owner The inbox owner.
10685 * @return {AV.InboxQuery} Returns the query, so you can chain this call.
10686 */
10687 owner: function owner(_owner) {
10688 this._owner = _owner;
10689 return this;
10690 },
10691 /**
10692 * Sets the querying inbox type.default is 'default'.
10693 * @param {Object} owner The inbox type.
10694 * @return {AV.InboxQuery} Returns the query, so you can chain this call.
10695 */
10696 inboxType: function inboxType(type) {
10697 this._inboxType = type;
10698 return this;
10699 },
10700 toJSON: function toJSON() {
10701 var params = AV.InboxQuery.__super__.toJSON.call(this);
10702 params.owner = AV._encode(this._owner);
10703 params.inboxType = AV._encode(this._inboxType);
10704 params.sinceId = AV._encode(this._sinceId);
10705 params.maxId = AV._encode(this._maxId);
10706 return params;
10707 }
10708 });
10709
10710 /**
10711 * Create a inbox status query to find someone's inbox statuses.
10712 * @since 0.3.0
10713 * @param {Object} owner The inbox's owner
10714 * @param {String} inboxType The inbox type,'default' by default.
10715 * @return {AV.InboxQuery} The inbox query object.
10716 * @see AV.InboxQuery
10717 * @example
10718 * //Find current user's default inbox statuses.
10719 * var query = AV.Status.inboxQuery(AV.User.current());
10720 * //find the statuses after the last message id
10721 * query.sinceId(lastMessageId);
10722 * query.find().then(function(statuses){
10723 * //process statuses
10724 * });
10725 */
10726 AV.Status.inboxQuery = function (owner, inboxType) {
10727 var query = new AV.InboxQuery(AV.Status);
10728 if (owner) {
10729 query._owner = owner;
10730 }
10731 if (inboxType) {
10732 query._inboxType = inboxType;
10733 }
10734 return query;
10735 };
10736};
10737
10738/***/ }),
10739/* 40 */
10740/***/ (function(module, exports, __webpack_require__) {
10741
10742"use strict";
10743
10744
10745module.exports = [];
10746
10747/***/ }),
10748/* 41 */
10749/***/ (function(module, exports, __webpack_require__) {
10750
10751"use strict";
10752
10753
10754var version = __webpack_require__(18);
10755var comments = ["Weapp" || 'Node.js'].concat(__webpack_require__(40));
10756
10757module.exports = 'LeanCloud-JS-SDK/' + version + ' (' + comments.join('; ') + ')';
10758
10759/***/ }),
10760/* 42 */
10761/***/ (function(module, exports, __webpack_require__) {
10762
10763"use strict";
10764
10765
10766var request = __webpack_require__(7);
10767var debug = __webpack_require__(5)('cos');
10768var Promise = __webpack_require__(1);
10769
10770module.exports = function upload(uploadInfo, data, file) {
10771 var saveOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
10772
10773 file.attributes.url = uploadInfo.url;
10774 file._bucket = uploadInfo.bucket;
10775 file.id = uploadInfo.objectId;
10776 var uploadUrl = uploadInfo.upload_url + "?sign=" + encodeURIComponent(uploadInfo.token);
10777
10778 return new Promise(function (resolve, reject) {
10779 var req = request('POST', uploadUrl).field('fileContent', data).field('op', 'upload');
10780 if (saveOptions.onprogress) {
10781 req.on('progress', saveOptions.onprogress);
10782 }
10783 req.end(function (err, res) {
10784 if (res) {
10785 debug(res.status, res.body, res.text);
10786 }
10787 if (err) {
10788 if (res) {
10789 err.statusCode = res.status;
10790 err.responseText = res.text;
10791 err.response = res.body;
10792 }
10793 return reject(err);
10794 }
10795 resolve(file);
10796 });
10797 });
10798};
10799
10800/***/ }),
10801/* 43 */
10802/***/ (function(module, exports, __webpack_require__) {
10803
10804"use strict";
10805
10806
10807var request = __webpack_require__(7);
10808var Promise = __webpack_require__(1);
10809var debug = __webpack_require__(5)('qiniu');
10810
10811module.exports = function upload(uploadInfo, data, file) {
10812 var saveOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
10813
10814 file.attributes.url = uploadInfo.url;
10815 file._bucket = uploadInfo.bucket;
10816 file.id = uploadInfo.objectId;
10817 // Get the uptoken to upload files to qiniu.
10818 var uptoken = uploadInfo.token;
10819 return new Promise(function (resolve, reject) {
10820 var req = request('POST', 'https://up.qbox.me').field('file', data).field('name', file.attributes.name).field('key', file._qiniu_key).field('token', uptoken);
10821 if (saveOptions.onprogress) {
10822 req.on('progress', saveOptions.onprogress);
10823 }
10824 req.end(function (err, res) {
10825 if (res) {
10826 debug(res.status, res.body, res.text);
10827 }
10828 if (err) {
10829 if (res) {
10830 err.statusCode = res.status;
10831 err.responseText = res.text;
10832 err.response = res.body;
10833 }
10834 return reject(err);
10835 }
10836 resolve(file);
10837 });
10838 });
10839};
10840
10841/***/ }),
10842/* 44 */
10843/***/ (function(module, exports, __webpack_require__) {
10844
10845"use strict";
10846
10847
10848var request = __webpack_require__(7);
10849var AVPromise = __webpack_require__(1);
10850
10851module.exports = function upload(uploadInfo, data, file) {
10852 var saveOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
10853
10854 file.attributes.url = uploadInfo.url;
10855 file._bucket = uploadInfo.bucket;
10856 file.id = uploadInfo.objectId;
10857 return new Promise(function (resolve, reject) {
10858 // 海外节点,针对 S3 æ‰ä¼šè¿”回 upload_url
10859 var req = request('PUT', uploadInfo.upload_url).set('Content-Type', file.get('mime_type')).send(data);
10860 if (saveOptions.onprogress) {
10861 req.on('progress', saveOptions.onprogress);
10862 }
10863 req.end(function (err, res) {
10864 if (err) {
10865 if (res) {
10866 err.statusCode = res.status;
10867 err.responseText = res.text;
10868 err.response = res.body;
10869 }
10870 return reject(err);
10871 }
10872 resolve(file);
10873 });
10874 });
10875};
10876
10877/***/ }),
10878/* 45 */
10879/***/ (function(module, exports, __webpack_require__) {
10880
10881"use strict";
10882
10883
10884var _ = __webpack_require__(0);
10885var AVError = __webpack_require__(3);
10886var AVRequest = __webpack_require__(2).request;
10887var Promise = __webpack_require__(1);
10888
10889var getWeappLoginCode = function getWeappLoginCode() {
10890 if (typeof wx === 'undefined' || typeof wx.login !== 'function') {
10891 throw new Error('Weapp Login is only available in Weapp');
10892 }
10893 return new Promise(function (resolve, reject) {
10894 wx.login({
10895 success: function success(_ref) {
10896 var code = _ref.code,
10897 errMsg = _ref.errMsg;
10898
10899 if (code) {
10900 resolve(code);
10901 } else {
10902 reject(new Error(errMsg));
10903 }
10904 }
10905 });
10906 });
10907};
10908
10909module.exports = function (AV) {
10910 /**
10911 * @class
10912 *
10913 * <p>An AV.User object is a local representation of a user persisted to the
10914 * LeanCloud server. This class is a subclass of an AV.Object, and retains the
10915 * same functionality of an AV.Object, but also extends it with various
10916 * user specific methods, like authentication, signing up, and validation of
10917 * uniqueness.</p>
10918 */
10919 AV.User = AV.Object.extend("_User", /** @lends AV.User.prototype */{
10920 // Instance Variables
10921 _isCurrentUser: false,
10922
10923 // Instance Methods
10924
10925 /**
10926 * Internal method to handle special fields in a _User response.
10927 * @private
10928 */
10929 _mergeMagicFields: function _mergeMagicFields(attrs) {
10930 if (attrs.sessionToken) {
10931 this._sessionToken = attrs.sessionToken;
10932 delete attrs.sessionToken;
10933 }
10934 AV.User.__super__._mergeMagicFields.call(this, attrs);
10935 },
10936
10937 /**
10938 * Removes null values from authData (which exist temporarily for
10939 * unlinking)
10940 * @private
10941 */
10942 _cleanupAuthData: function _cleanupAuthData() {
10943 if (!this.isCurrent()) {
10944 return;
10945 }
10946 var authData = this.get('authData');
10947 if (!authData) {
10948 return;
10949 }
10950 AV._objectEach(this.get('authData'), function (value, key) {
10951 if (!authData[key]) {
10952 delete authData[key];
10953 }
10954 });
10955 },
10956
10957 /**
10958 * Synchronizes authData for all providers.
10959 * @private
10960 */
10961 _synchronizeAllAuthData: function _synchronizeAllAuthData() {
10962 var authData = this.get('authData');
10963 if (!authData) {
10964 return;
10965 }
10966
10967 var self = this;
10968 AV._objectEach(this.get('authData'), function (value, key) {
10969 self._synchronizeAuthData(key);
10970 });
10971 },
10972
10973 /**
10974 * Synchronizes auth data for a provider (e.g. puts the access token in the
10975 * right place to be used by the Facebook SDK).
10976 * @private
10977 */
10978 _synchronizeAuthData: function _synchronizeAuthData(provider) {
10979 if (!this.isCurrent()) {
10980 return;
10981 }
10982 var authType;
10983 if (_.isString(provider)) {
10984 authType = provider;
10985 provider = AV.User._authProviders[authType];
10986 } else {
10987 authType = provider.getAuthType();
10988 }
10989 var authData = this.get('authData');
10990 if (!authData || !provider) {
10991 return;
10992 }
10993 var success = provider.restoreAuthentication(authData[authType]);
10994 if (!success) {
10995 this._unlinkFrom(provider);
10996 }
10997 },
10998
10999 _handleSaveResult: function _handleSaveResult(makeCurrent) {
11000 // Clean up and synchronize the authData object, removing any unset values
11001 if (makeCurrent && !AV._config.disableCurrentUser) {
11002 this._isCurrentUser = true;
11003 }
11004 this._cleanupAuthData();
11005 this._synchronizeAllAuthData();
11006 // Don't keep the password around.
11007 delete this._serverData.password;
11008 this._rebuildEstimatedDataForKey("password");
11009 this._refreshCache();
11010 if ((makeCurrent || this.isCurrent()) && !AV._config.disableCurrentUser) {
11011 // Some old version of leanengine-node-sdk will overwrite
11012 // AV.User._saveCurrentUser which returns no Promise.
11013 // So we need a Promise wrapper.
11014 return Promise.resolve(AV.User._saveCurrentUser(this));
11015 } else {
11016 return Promise.resolve();
11017 }
11018 },
11019
11020 /**
11021 * Unlike in the Android/iOS SDKs, logInWith is unnecessary, since you can
11022 * call linkWith on the user (even if it doesn't exist yet on the server).
11023 * @private
11024 */
11025 _linkWith: function _linkWith(provider, data) {
11026 var _this = this;
11027
11028 var authType;
11029 if (_.isString(provider)) {
11030 authType = provider;
11031 provider = AV.User._authProviders[provider];
11032 } else {
11033 authType = provider.getAuthType();
11034 }
11035 if (data) {
11036 var authData = this.get('authData') || {};
11037 authData[authType] = data;
11038 return this.save({ authData: authData }).then(function (model) {
11039 return model._handleSaveResult(true).then(function () {
11040 return model;
11041 });
11042 });
11043 } else {
11044 return provider.authenticate().then(function (result) {
11045 return _this._linkWith(provider, result);
11046 });
11047 }
11048 },
11049
11050 /**
11051 * 将用户与å°ç¨‹åºç”¨æˆ·è¿›è¡Œå…³è”。适用于为已ç»åœ¨ç”¨æˆ·ç³»ç»Ÿä¸å˜åœ¨çš„用户关è”当å‰ä½¿ç”¨å°ç¨‹åºçš„微信å¸å·ã€‚
11052 * 仅在å°ç¨‹åºä¸å¯ç”¨ã€‚
11053 *
11054 * @return {AV.User}
11055 */
11056 linkWithWeapp: function linkWithWeapp() {
11057 var _this2 = this;
11058
11059 return getWeappLoginCode().then(function (code) {
11060 return _this2._linkWith('lc_weapp', { code: code });
11061 });
11062 },
11063
11064
11065 /**
11066 * Unlinks a user from a service.
11067 * @private
11068 */
11069 _unlinkFrom: function _unlinkFrom(provider) {
11070 var _this3 = this;
11071
11072 if (_.isString(provider)) {
11073 provider = AV.User._authProviders[provider];
11074 }
11075 return this._linkWith(provider, null).then(function (model) {
11076 _this3._synchronizeAuthData(provider);
11077 return model;
11078 });
11079 },
11080
11081 /**
11082 * Checks whether a user is linked to a service.
11083 * @private
11084 */
11085 _isLinked: function _isLinked(provider) {
11086 var authType;
11087 if (_.isString(provider)) {
11088 authType = provider;
11089 } else {
11090 authType = provider.getAuthType();
11091 }
11092 var authData = this.get('authData') || {};
11093 return !!authData[authType];
11094 },
11095
11096 logOut: function logOut() {
11097 this._logOutWithAll();
11098 this._isCurrentUser = false;
11099 },
11100
11101 /**
11102 * Deauthenticates all providers.
11103 * @private
11104 */
11105 _logOutWithAll: function _logOutWithAll() {
11106 var authData = this.get('authData');
11107 if (!authData) {
11108 return;
11109 }
11110 var self = this;
11111 AV._objectEach(this.get('authData'), function (value, key) {
11112 self._logOutWith(key);
11113 });
11114 },
11115
11116 /**
11117 * Deauthenticates a single provider (e.g. removing access tokens from the
11118 * Facebook SDK).
11119 * @private
11120 */
11121 _logOutWith: function _logOutWith(provider) {
11122 if (!this.isCurrent()) {
11123 return;
11124 }
11125 if (_.isString(provider)) {
11126 provider = AV.User._authProviders[provider];
11127 }
11128 if (provider && provider.deauthenticate) {
11129 provider.deauthenticate();
11130 }
11131 },
11132
11133 /**
11134 * Signs up a new user. You should call this instead of save for
11135 * new AV.Users. This will create a new AV.User on the server, and
11136 * also persist the session on disk so that you can access the user using
11137 * <code>current</code>.
11138 *
11139 * <p>A username and password must be set before calling signUp.</p>
11140 *
11141 * @param {Object} attrs Extra fields to set on the new user, or null.
11142 * @param {AuthOptions} options
11143 * @return {Promise} A promise that is fulfilled when the signup
11144 * finishes.
11145 * @see AV.User.signUp
11146 */
11147 signUp: function signUp(attrs, options) {
11148 var error;
11149
11150 var username = attrs && attrs.username || this.get("username");
11151 if (!username || username === "") {
11152 error = new AVError(AVError.OTHER_CAUSE, "Cannot sign up user with an empty name.");
11153 throw error;
11154 }
11155
11156 var password = attrs && attrs.password || this.get("password");
11157 if (!password || password === "") {
11158 error = new AVError(AVError.OTHER_CAUSE, "Cannot sign up user with an empty password.");
11159 throw error;
11160 }
11161
11162 return this.save(attrs, options).then(function (model) {
11163 return model._handleSaveResult(true).then(function () {
11164 return model;
11165 });
11166 });
11167 },
11168
11169 /**
11170 * Signs up a new user with mobile phone and sms code.
11171 * You should call this instead of save for
11172 * new AV.Users. This will create a new AV.User on the server, and
11173 * also persist the session on disk so that you can access the user using
11174 * <code>current</code>.
11175 *
11176 * <p>A username and password must be set before calling signUp.</p>
11177 *
11178 * @param {Object} attrs Extra fields to set on the new user, or null.
11179 * @param {AuthOptions} options
11180 * @return {Promise} A promise that is fulfilled when the signup
11181 * finishes.
11182 * @see AV.User.signUpOrlogInWithMobilePhone
11183 * @see AV.Cloud.requestSmsCode
11184 */
11185 signUpOrlogInWithMobilePhone: function signUpOrlogInWithMobilePhone(attrs) {
11186 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
11187
11188 var error;
11189
11190 var mobilePhoneNumber = attrs && attrs.mobilePhoneNumber || this.get("mobilePhoneNumber");
11191 if (!mobilePhoneNumber || mobilePhoneNumber === "") {
11192 error = new AVError(AVError.OTHER_CAUSE, "Cannot sign up or login user by mobilePhoneNumber " + "with an empty mobilePhoneNumber.");
11193 throw error;
11194 }
11195
11196 var smsCode = attrs && attrs.smsCode || this.get("smsCode");
11197 if (!smsCode || smsCode === "") {
11198 error = new AVError(AVError.OTHER_CAUSE, "Cannot sign up or login user by mobilePhoneNumber " + "with an empty smsCode.");
11199 throw error;
11200 }
11201
11202 options._makeRequest = function (route, className, id, method, json) {
11203 return AVRequest('usersByMobilePhone', null, null, "POST", json);
11204 };
11205 return this.save(attrs, options).then(function (model) {
11206 delete model.attributes.smsCode;
11207 delete model._serverData.smsCode;
11208 return model._handleSaveResult(true).then(function () {
11209 return model;
11210 });
11211 });
11212 },
11213
11214 /**
11215 * Logs in a AV.User. On success, this saves the session to localStorage,
11216 * so you can retrieve the currently logged in user using
11217 * <code>current</code>.
11218 *
11219 * <p>A username and password must be set before calling logIn.</p>
11220 *
11221 * @see AV.User.logIn
11222 * @return {Promise} A promise that is fulfilled with the user when
11223 * the login is complete.
11224 */
11225 logIn: function logIn() {
11226 var model = this;
11227 var request = AVRequest('login', null, null, 'POST', this.toJSON());
11228 return request.then(function (resp) {
11229 var serverAttrs = model.parse(resp);
11230 model._finishFetch(serverAttrs);
11231 return model._handleSaveResult(true).then(function () {
11232 if (!serverAttrs.smsCode) delete model.attributes['smsCode'];
11233 return model;
11234 });
11235 });
11236 },
11237 /**
11238 * @see AV.Object#save
11239 */
11240 save: function save(arg1, arg2, arg3) {
11241 var i, attrs, current, options, saved;
11242 if (_.isObject(arg1) || _.isNull(arg1) || _.isUndefined(arg1)) {
11243 attrs = arg1;
11244 options = arg2;
11245 } else {
11246 attrs = {};
11247 attrs[arg1] = arg2;
11248 options = arg3;
11249 }
11250 options = options || {};
11251
11252 return AV.Object.prototype.save.call(this, attrs, options).then(function (model) {
11253 return model._handleSaveResult(false).then(function () {
11254 return model;
11255 });
11256 });
11257 },
11258
11259 /**
11260 * Follow a user
11261 * @since 0.3.0
11262 * @param {AV.User | String} target The target user or user's objectId to follow.
11263 * @param {AuthOptions} options
11264 */
11265 follow: function follow(target, options) {
11266 if (!this.id) {
11267 throw new Error('Please signin.');
11268 }
11269 if (!target) {
11270 throw new Error('Invalid target user.');
11271 }
11272 var userObjectId = _.isString(target) ? target : target.id;
11273 if (!userObjectId) {
11274 throw new Error('Invalid target user.');
11275 }
11276 var route = 'users/' + this.id + '/friendship/' + userObjectId;
11277 var request = AVRequest(route, null, null, 'POST', null, options);
11278 return request;
11279 },
11280
11281 /**
11282 * Unfollow a user.
11283 * @since 0.3.0
11284 * @param {AV.User | String} target The target user or user's objectId to unfollow.
11285 * @param {AuthOptions} options
11286 */
11287 unfollow: function unfollow(target, options) {
11288 if (!this.id) {
11289 throw new Error('Please signin.');
11290 }
11291 if (!target) {
11292 throw new Error('Invalid target user.');
11293 }
11294 var userObjectId = _.isString(target) ? target : target.id;
11295 if (!userObjectId) {
11296 throw new Error('Invalid target user.');
11297 }
11298 var route = 'users/' + this.id + '/friendship/' + userObjectId;
11299 var request = AVRequest(route, null, null, 'DELETE', null, options);
11300 return request;
11301 },
11302
11303 /**
11304 *Create a follower query to query the user's followers.
11305 * @since 0.3.0
11306 * @see AV.User#followerQuery
11307 */
11308 followerQuery: function followerQuery() {
11309 return AV.User.followerQuery(this.id);
11310 },
11311
11312 /**
11313 *Create a followee query to query the user's followees.
11314 * @since 0.3.0
11315 * @see AV.User#followeeQuery
11316 */
11317 followeeQuery: function followeeQuery() {
11318 return AV.User.followeeQuery(this.id);
11319 },
11320
11321 /**
11322 * @see AV.Object#fetch
11323 */
11324 fetch: function fetch(fetchOptions, options) {
11325 return AV.Object.prototype.fetch.call(this, fetchOptions, options).then(function (model) {
11326 return model._handleSaveResult(false).then(function () {
11327 return model;
11328 });
11329 });
11330 },
11331
11332 /**
11333 * Update user's new password safely based on old password.
11334 * @param {String} oldPassword the old password.
11335 * @param {String} newPassword the new password.
11336 * @param {AuthOptions} options
11337 */
11338 updatePassword: function updatePassword(oldPassword, newPassword, options) {
11339 var route = 'users/' + this.id + '/updatePassword';
11340 var params = {
11341 old_password: oldPassword,
11342 new_password: newPassword
11343 };
11344 var request = AVRequest(route, null, null, 'PUT', params, options);
11345 return request;
11346 },
11347
11348 /**
11349 * Returns true if <code>current</code> would return this user.
11350 * @see AV.User#current
11351 */
11352 isCurrent: function isCurrent() {
11353 return this._isCurrentUser;
11354 },
11355
11356 /**
11357 * Returns get("username").
11358 * @return {String}
11359 * @see AV.Object#get
11360 */
11361 getUsername: function getUsername() {
11362 return this.get("username");
11363 },
11364
11365 /**
11366 * Returns get("mobilePhoneNumber").
11367 * @return {String}
11368 * @see AV.Object#get
11369 */
11370 getMobilePhoneNumber: function getMobilePhoneNumber() {
11371 return this.get("mobilePhoneNumber");
11372 },
11373
11374 /**
11375 * Calls set("mobilePhoneNumber", phoneNumber, options) and returns the result.
11376 * @param {String} mobilePhoneNumber
11377 * @param {AuthOptions} options
11378 * @return {Boolean}
11379 * @see AV.Object#set
11380 */
11381 setMobilePhoneNumber: function setMobilePhoneNumber(phone, options) {
11382 return this.set("mobilePhoneNumber", phone, options);
11383 },
11384
11385 /**
11386 * Calls set("username", username, options) and returns the result.
11387 * @param {String} username
11388 * @param {AuthOptions} options
11389 * @return {Boolean}
11390 * @see AV.Object#set
11391 */
11392 setUsername: function setUsername(username, options) {
11393 return this.set("username", username, options);
11394 },
11395
11396 /**
11397 * Calls set("password", password, options) and returns the result.
11398 * @param {String} password
11399 * @param {AuthOptions} options
11400 * @return {Boolean}
11401 * @see AV.Object#set
11402 */
11403 setPassword: function setPassword(password, options) {
11404 return this.set("password", password, options);
11405 },
11406
11407 /**
11408 * Returns get("email").
11409 * @return {String}
11410 * @see AV.Object#get
11411 */
11412 getEmail: function getEmail() {
11413 return this.get("email");
11414 },
11415
11416 /**
11417 * Calls set("email", email, options) and returns the result.
11418 * @param {String} email
11419 * @param {AuthOptions} options
11420 * @return {Boolean}
11421 * @see AV.Object#set
11422 */
11423 setEmail: function setEmail(email, options) {
11424 return this.set("email", email, options);
11425 },
11426
11427 /**
11428 * Checks whether this user is the current user and has been authenticated.
11429 * @deprecated 如果è¦åˆ¤æ–当å‰ç”¨æˆ·çš„ç™»å½•çŠ¶æ€æ˜¯å¦æœ‰æ•ˆï¼Œè¯·ä½¿ç”¨ currentUser.isAuthenticated().then(),
11430 * 如果è¦åˆ¤æ–è¯¥ç”¨æˆ·æ˜¯å¦æ˜¯å½“å‰ç™»å½•用户,请使用 user.id === currentUser.id
11431 * @return (Boolean) whether this user is the current user and is logged in.
11432 */
11433 authenticated: function authenticated() {
11434 console.warn('DEPRECATED: 如果è¦åˆ¤æ–当å‰ç”¨æˆ·çš„ç™»å½•çŠ¶æ€æ˜¯å¦æœ‰æ•ˆï¼Œè¯·ä½¿ç”¨ currentUser.isAuthenticated().then(),如果è¦åˆ¤æ–è¯¥ç”¨æˆ·æ˜¯å¦æ˜¯å½“å‰ç™»å½•用户,请使用 user.id === currentUser.id。');
11435 return !!this._sessionToken && !AV._config.disableCurrentUser && AV.User.current() && AV.User.current().id === this.id;
11436 },
11437
11438 /**
11439 * æ£€æŸ¥è¯¥ç”¨æˆ·çš„ç™»å½•çŠ¶æ€æ˜¯å¦æœ‰æ•ˆï¼Œè¯·æ³¨æ„è¯¥æ–¹æ³•ä¼šæ ¡éªŒ sessionToken çš„æœ‰æ•ˆæ€§ï¼Œæ˜¯ä¸ªå¼‚æ¥æ–¹æ³•。
11440 *
11441 * @since 2.0.0
11442 * @return Promise.<Boolean>
11443 */
11444 isAuthenticated: function isAuthenticated() {
11445 var _this4 = this;
11446
11447 return Promise.resolve().then(function () {
11448 return !!_this4._sessionToken && AV.User._fetchUserBySessionToken(_this4._sessionToken).then(function () {
11449 return true;
11450 }, function (error) {
11451 if (error.code === 211) {
11452 return false;
11453 }
11454 throw error;
11455 });
11456 });
11457 },
11458
11459
11460 /**
11461 * Get sessionToken of current user.
11462 * @return {String} sessionToken
11463 */
11464 getSessionToken: function getSessionToken() {
11465 return this._sessionToken;
11466 },
11467
11468
11469 /**
11470 * Refresh sessionToken of current user.
11471 * @since 2.1.0
11472 * @param {AuthOptions} [options]
11473 * @return {Promise.<AV.User>} user with refreshed sessionToken
11474 */
11475 refreshSessionToken: function refreshSessionToken(options) {
11476 var _this5 = this;
11477
11478 return AVRequest('users/' + this.id + '/refreshSessionToken', null, null, 'PUT', null, options).then(function (response) {
11479 _this5._finishFetch(response);
11480 return _this5;
11481 });
11482 },
11483
11484
11485 /**
11486 * Get this user's Roles.
11487 * @param {AuthOptions} [options]
11488 * @return {Promise} A promise that is fulfilled with the roles when
11489 * the query is complete.
11490 */
11491 getRoles: function getRoles(options) {
11492 return AV.Relation.reverseQuery("_Role", "users", this).find(options);
11493 }
11494 }, /** @lends AV.User */{
11495 // Class Variables
11496
11497 // The currently logged-in user.
11498 _currentUser: null,
11499
11500 // Whether currentUser is known to match the serialized version on disk.
11501 // This is useful for saving a localstorage check if you try to load
11502 // _currentUser frequently while there is none stored.
11503 _currentUserMatchesDisk: false,
11504
11505 // The localStorage key suffix that the current user is stored under.
11506 _CURRENT_USER_KEY: "currentUser",
11507
11508 // The mapping of auth provider names to actual providers
11509 _authProviders: {},
11510
11511 // Class Methods
11512
11513 /**
11514 * Signs up a new user with a username (or email) and password.
11515 * This will create a new AV.User on the server, and also persist the
11516 * session in localStorage so that you can access the user using
11517 * {@link #current}.
11518 *
11519 * @param {String} username The username (or email) to sign up with.
11520 * @param {String} password The password to sign up with.
11521 * @param {Object} attrs Extra fields to set on the new user.
11522 * @param {AuthOptions} options
11523 * @return {Promise} A promise that is fulfilled with the user when
11524 * the signup completes.
11525 * @see AV.User#signUp
11526 */
11527 signUp: function signUp(username, password, attrs, options) {
11528 attrs = attrs || {};
11529 attrs.username = username;
11530 attrs.password = password;
11531 var user = AV.Object._create("_User");
11532 return user.signUp(attrs, options);
11533 },
11534
11535 /**
11536 * Logs in a user with a username (or email) and password. On success, this
11537 * saves the session to disk, so you can retrieve the currently logged in
11538 * user using <code>current</code>.
11539 *
11540 * @param {String} username The username (or email) to log in with.
11541 * @param {String} password The password to log in with.
11542 * @param {AuthOptions} options
11543 * @return {Promise} A promise that is fulfilled with the user when
11544 * the login completes.
11545 * @see AV.User#logIn
11546 */
11547 logIn: function logIn(username, password, options) {
11548 var user = AV.Object._create("_User");
11549 user._finishFetch({ username: username, password: password });
11550 return user.logIn(options);
11551 },
11552
11553 /**
11554 * Logs in a user with a session token. On success, this saves the session
11555 * to disk, so you can retrieve the currently logged in user using
11556 * <code>current</code>.
11557 *
11558 * @param {String} sessionToken The sessionToken to log in with.
11559 * @return {Promise} A promise that is fulfilled with the user when
11560 * the login completes.
11561 */
11562 become: function become(sessionToken) {
11563 return this._fetchUserBySessionToken(sessionToken).then(function (user) {
11564 return user._handleSaveResult(true).then(function () {
11565 return user;
11566 });
11567 });
11568 },
11569
11570 _fetchUserBySessionToken: function _fetchUserBySessionToken(sessionToken) {
11571 var user = AV.Object._create("_User");
11572 return AVRequest("users", "me", null, "GET", {
11573 session_token: sessionToken
11574 }).then(function (resp) {
11575 var serverAttrs = user.parse(resp);
11576 user._finishFetch(serverAttrs);
11577 return user;
11578 });
11579 },
11580
11581 /**
11582 * Logs in a user with a mobile phone number and sms code sent by
11583 * AV.User.requestLoginSmsCode.On success, this
11584 * saves the session to disk, so you can retrieve the currently logged in
11585 * user using <code>current</code>.
11586 *
11587 * @param {String} mobilePhone The user's mobilePhoneNumber
11588 * @param {String} smsCode The sms code sent by AV.User.requestLoginSmsCode
11589 * @param {AuthOptions} options
11590 * @return {Promise} A promise that is fulfilled with the user when
11591 * the login completes.
11592 * @see AV.User#logIn
11593 */
11594 logInWithMobilePhoneSmsCode: function logInWithMobilePhoneSmsCode(mobilePhone, smsCode, options) {
11595 var user = AV.Object._create("_User");
11596 user._finishFetch({ mobilePhoneNumber: mobilePhone, smsCode: smsCode });
11597 return user.logIn(options);
11598 },
11599
11600 /**
11601 * Sign up or logs in a user with a mobilePhoneNumber and smsCode.
11602 * On success, this saves the session to disk, so you can retrieve the currently
11603 * logged in user using <code>current</code>.
11604 *
11605 * @param {String} mobilePhoneNumber The user's mobilePhoneNumber.
11606 * @param {String} smsCode The sms code sent by AV.Cloud.requestSmsCode
11607 * @param {Object} attributes The user's other attributes such as username etc.
11608 * @param {AuthOptions} options
11609 * @return {Promise} A promise that is fulfilled with the user when
11610 * the login completes.
11611 * @see AV.User#signUpOrlogInWithMobilePhone
11612 * @see AV.Cloud.requestSmsCode
11613 */
11614 signUpOrlogInWithMobilePhone: function signUpOrlogInWithMobilePhone(mobilePhoneNumber, smsCode, attrs, options) {
11615 attrs = attrs || {};
11616 attrs.mobilePhoneNumber = mobilePhoneNumber;
11617 attrs.smsCode = smsCode;
11618 var user = AV.Object._create("_User");
11619 return user.signUpOrlogInWithMobilePhone(attrs, options);
11620 },
11621
11622 /**
11623 * Logs in a user with a mobile phone number and password. On success, this
11624 * saves the session to disk, so you can retrieve the currently logged in
11625 * user using <code>current</code>.
11626 *
11627 * @param {String} mobilePhone The user's mobilePhoneNumber
11628 * @param {String} password The password to log in with.
11629 * @param {AuthOptions} options
11630 * @return {Promise} A promise that is fulfilled with the user when
11631 * the login completes.
11632 * @see AV.User#logIn
11633 */
11634 logInWithMobilePhone: function logInWithMobilePhone(mobilePhone, password, options) {
11635 var user = AV.Object._create("_User");
11636 user._finishFetch({ mobilePhoneNumber: mobilePhone, password: password });
11637 return user.logIn(options);
11638 },
11639
11640 /**
11641 * Sign up or logs in a user with a third party auth data(AccessToken).
11642 * On success, this saves the session to disk, so you can retrieve the currently
11643 * logged in user using <code>current</code>.
11644 *
11645 * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }
11646 * @param {string} platform Available platform for sign up.
11647 * @return {Promise} A promise that is fulfilled with the user when
11648 * the login completes.
11649 * @example AV.User.signUpOrlogInWithAuthData(authData, platform).then(function(user) {
11650 * //Access user here
11651 * }).catch(function(error) {
11652 * //console.error("error: ", error);
11653 * });
11654 * @see {@link https://leancloud.cn/docs/js_guide.html#绑定第三方平å°è´¦æˆ·}
11655 */
11656 signUpOrlogInWithAuthData: function signUpOrlogInWithAuthData(authData, platform) {
11657 return AV.User._logInWith(platform, authData);
11658 },
11659
11660
11661 /**
11662 * 使用当å‰ä½¿ç”¨å°ç¨‹åºçš„微信用户身份注册或登录,æˆåŠŸåŽç”¨æˆ·çš„ session 会在设备上æŒä¹…化ä¿å˜ï¼Œä¹‹åŽå¯ä»¥ä½¿ç”¨ AV.User.current() 获å–当å‰ç™»å½•用户。
11663 * 仅在å°ç¨‹åºä¸å¯ç”¨ã€‚
11664 *
11665 * @since 2.0.0
11666 * @return {AV.User}
11667 */
11668 loginWithWeapp: function loginWithWeapp() {
11669 var _this6 = this;
11670
11671 return getWeappLoginCode().then(function (code) {
11672 return _this6.signUpOrlogInWithAuthData({ code: code }, 'lc_weapp');
11673 });
11674 },
11675
11676
11677 /**
11678 * Associate a user with a third party auth data(AccessToken).
11679 *
11680 * @param {AV.User} userObj A user which you want to associate.
11681 * @param {string} platform Available platform for sign up.
11682 * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }
11683 * @return {Promise} A promise that is fulfilled with the user when completed.
11684 * @example AV.User.associateWithAuthData(loginUser, 'weixin', {
11685 * openid: 'abc123',
11686 * access_token: '123abc',
11687 * expires_in: 1382686496
11688 * }).then(function(user) {
11689 * //Access user here
11690 * }).catch(function(error) {
11691 * //console.error("error: ", error);
11692 * });
11693 */
11694 associateWithAuthData: function associateWithAuthData(userObj, platform, authData) {
11695 return userObj._linkWith(platform, authData);
11696 },
11697
11698 /**
11699 * Logs out the currently logged in user session. This will remove the
11700 * session from disk, log out of linked services, and future calls to
11701 * <code>current</code> will return <code>null</code>.
11702 * @return {Promise}
11703 */
11704 logOut: function logOut() {
11705 if (AV._config.disableCurrentUser) {
11706 console.warn('AV.User.current() was disabled in multi-user environment, call logOut() from user object instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html');
11707 return Promise.resolve(null);
11708 }
11709
11710 if (AV.User._currentUser !== null) {
11711 AV.User._currentUser._logOutWithAll();
11712 AV.User._currentUser._isCurrentUser = false;
11713 }
11714 AV.User._currentUserMatchesDisk = true;
11715 AV.User._currentUser = null;
11716 return AV.localStorage.removeItemAsync(AV._getAVPath(AV.User._CURRENT_USER_KEY));
11717 },
11718
11719 /**
11720 *Create a follower query for special user to query the user's followers.
11721 * @param {String} userObjectId The user object id.
11722 * @return {AV.FriendShipQuery}
11723 * @since 0.3.0
11724 */
11725 followerQuery: function followerQuery(userObjectId) {
11726 if (!userObjectId || !_.isString(userObjectId)) {
11727 throw new Error('Invalid user object id.');
11728 }
11729 var query = new AV.FriendShipQuery('_Follower');
11730 query._friendshipTag = 'follower';
11731 query.equalTo('user', AV.Object.createWithoutData('_User', userObjectId));
11732 return query;
11733 },
11734
11735 /**
11736 *Create a followee query for special user to query the user's followees.
11737 * @param {String} userObjectId The user object id.
11738 * @return {AV.FriendShipQuery}
11739 * @since 0.3.0
11740 */
11741 followeeQuery: function followeeQuery(userObjectId) {
11742 if (!userObjectId || !_.isString(userObjectId)) {
11743 throw new Error('Invalid user object id.');
11744 }
11745 var query = new AV.FriendShipQuery('_Followee');
11746 query._friendshipTag = 'followee';
11747 query.equalTo('user', AV.Object.createWithoutData('_User', userObjectId));
11748 return query;
11749 },
11750
11751 /**
11752 * Requests a password reset email to be sent to the specified email address
11753 * associated with the user account. This email allows the user to securely
11754 * reset their password on the AV site.
11755 *
11756 * @param {String} email The email address associated with the user that
11757 * forgot their password.
11758 * @return {Promise}
11759 */
11760 requestPasswordReset: function requestPasswordReset(email) {
11761 var json = { email: email };
11762 var request = AVRequest("requestPasswordReset", null, null, "POST", json);
11763 return request;
11764 },
11765
11766 /**
11767 * Requests a verify email to be sent to the specified email address
11768 * associated with the user account. This email allows the user to securely
11769 * verify their email address on the AV site.
11770 *
11771 * @param {String} email The email address associated with the user that
11772 * doesn't verify their email address.
11773 * @return {Promise}
11774 */
11775 requestEmailVerify: function requestEmailVerify(email) {
11776 var json = { email: email };
11777 var request = AVRequest("requestEmailVerify", null, null, "POST", json);
11778 return request;
11779 },
11780
11781 /**
11782 * Requests a verify sms code to be sent to the specified mobile phone
11783 * number associated with the user account. This sms code allows the user to
11784 * verify their mobile phone number by calling AV.User.verifyMobilePhone
11785 *
11786 * @param {String} mobilePhone The mobile phone number associated with the
11787 * user that doesn't verify their mobile phone number.
11788 * @return {Promise}
11789 */
11790 requestMobilePhoneVerify: function requestMobilePhoneVerify(mobilePhone) {
11791 var json = { mobilePhoneNumber: mobilePhone };
11792 var request = AVRequest("requestMobilePhoneVerify", null, null, "POST", json);
11793 return request;
11794 },
11795
11796 /**
11797 * Requests a reset password sms code to be sent to the specified mobile phone
11798 * number associated with the user account. This sms code allows the user to
11799 * reset their account's password by calling AV.User.resetPasswordBySmsCode
11800 *
11801 * @param {String} mobilePhone The mobile phone number associated with the
11802 * user that doesn't verify their mobile phone number.
11803 * @return {Promise}
11804 */
11805 requestPasswordResetBySmsCode: function requestPasswordResetBySmsCode(mobilePhone) {
11806 var json = { mobilePhoneNumber: mobilePhone };
11807 var request = AVRequest("requestPasswordResetBySmsCode", null, null, "POST", json);
11808 return request;
11809 },
11810
11811 /**
11812 * Makes a call to reset user's account password by sms code and new password.
11813 * The sms code is sent by AV.User.requestPasswordResetBySmsCode.
11814 * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode
11815 * @param {String} password The new password.
11816 * @return {Promise} A promise that will be resolved with the result
11817 * of the function.
11818 */
11819 resetPasswordBySmsCode: function resetPasswordBySmsCode(code, password) {
11820 var json = { password: password };
11821 var request = AVRequest("resetPasswordBySmsCode", null, code, "PUT", json);
11822 return request;
11823 },
11824
11825 /**
11826 * Makes a call to verify sms code that sent by AV.User.Cloud.requestSmsCode
11827 * If verify successfully,the user mobilePhoneVerified attribute will be true.
11828 * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode
11829 * @return {Promise} A promise that will be resolved with the result
11830 * of the function.
11831 */
11832 verifyMobilePhone: function verifyMobilePhone(code) {
11833 var request = AVRequest("verifyMobilePhone", null, code, "POST", null);
11834 return request;
11835 },
11836
11837 /**
11838 * Requests a logIn sms code to be sent to the specified mobile phone
11839 * number associated with the user account. This sms code allows the user to
11840 * login by AV.User.logInWithMobilePhoneSmsCode function.
11841 *
11842 * @param {String} mobilePhone The mobile phone number associated with the
11843 * user that want to login by AV.User.logInWithMobilePhoneSmsCode
11844 * @return {Promise}
11845 */
11846 requestLoginSmsCode: function requestLoginSmsCode(mobilePhone) {
11847 var json = { mobilePhoneNumber: mobilePhone };
11848 var request = AVRequest("requestLoginSmsCode", null, null, "POST", json);
11849 return request;
11850 },
11851
11852 /**
11853 * Retrieves the currently logged in AVUser with a valid session,
11854 * either from memory or localStorage, if necessary.
11855 * @return {Promise.<AV.User>} resolved with the currently logged in AV.User.
11856 */
11857 currentAsync: function currentAsync() {
11858 if (AV._config.disableCurrentUser) {
11859 console.warn('AV.User.currentAsync() was disabled in multi-user environment, access user from request instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html');
11860 return Promise.resolve(null);
11861 }
11862
11863 if (AV.User._currentUser) {
11864 return Promise.resolve(AV.User._currentUser);
11865 }
11866
11867 if (AV.User._currentUserMatchesDisk) {
11868
11869 return Promise.resolve(AV.User._currentUser);
11870 }
11871
11872 return AV.localStorage.getItemAsync(AV._getAVPath(AV.User._CURRENT_USER_KEY)).then(function (userData) {
11873 if (!userData) {
11874 return null;
11875 }
11876
11877 // Load the user from local storage.
11878 AV.User._currentUserMatchesDisk = true;
11879
11880 AV.User._currentUser = AV.Object._create("_User");
11881 AV.User._currentUser._isCurrentUser = true;
11882
11883 var json = JSON.parse(userData);
11884 AV.User._currentUser.id = json._id;
11885 delete json._id;
11886 AV.User._currentUser._sessionToken = json._sessionToken;
11887 delete json._sessionToken;
11888 AV.User._currentUser._finishFetch(json);
11889 //AV.User._currentUser.set(json);
11890
11891 AV.User._currentUser._synchronizeAllAuthData();
11892 AV.User._currentUser._refreshCache();
11893 AV.User._currentUser._opSetQueue = [{}];
11894 return AV.User._currentUser;
11895 });
11896 },
11897
11898 /**
11899 * Retrieves the currently logged in AVUser with a valid session,
11900 * either from memory or localStorage, if necessary.
11901 * @return {AV.User} The currently logged in AV.User.
11902 */
11903 current: function current() {
11904 if (AV._config.disableCurrentUser) {
11905 console.warn('AV.User.current() was disabled in multi-user environment, access user from request instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html');
11906 return null;
11907 }
11908
11909 if (AV.User._currentUser) {
11910 return AV.User._currentUser;
11911 }
11912
11913 if (AV.User._currentUserMatchesDisk) {
11914
11915 return AV.User._currentUser;
11916 }
11917
11918 // Load the user from local storage.
11919 AV.User._currentUserMatchesDisk = true;
11920
11921 var userData = AV.localStorage.getItem(AV._getAVPath(AV.User._CURRENT_USER_KEY));
11922 if (!userData) {
11923
11924 return null;
11925 }
11926 AV.User._currentUser = AV.Object._create("_User");
11927 AV.User._currentUser._isCurrentUser = true;
11928
11929 var json = JSON.parse(userData);
11930 AV.User._currentUser.id = json._id;
11931 delete json._id;
11932 AV.User._currentUser._sessionToken = json._sessionToken;
11933 delete json._sessionToken;
11934 AV.User._currentUser._finishFetch(json);
11935 //AV.User._currentUser.set(json);
11936
11937 AV.User._currentUser._synchronizeAllAuthData();
11938 AV.User._currentUser._refreshCache();
11939 AV.User._currentUser._opSetQueue = [{}];
11940 return AV.User._currentUser;
11941 },
11942
11943 /**
11944 * Persists a user as currentUser to localStorage, and into the singleton.
11945 * @private
11946 */
11947 _saveCurrentUser: function _saveCurrentUser(user) {
11948 var promise;
11949 if (AV.User._currentUser !== user) {
11950 promise = AV.User.logOut();
11951 } else {
11952 promise = Promise.resolve();
11953 }
11954 return promise.then(function () {
11955 user._isCurrentUser = true;
11956 AV.User._currentUser = user;
11957
11958 var json = user.toJSON();
11959 json._id = user.id;
11960 json._sessionToken = user._sessionToken;
11961 return AV.localStorage.setItemAsync(AV._getAVPath(AV.User._CURRENT_USER_KEY), JSON.stringify(json)).then(function () {
11962 AV.User._currentUserMatchesDisk = true;
11963 });
11964 });
11965 },
11966
11967 _registerAuthenticationProvider: function _registerAuthenticationProvider(provider) {
11968 AV.User._authProviders[provider.getAuthType()] = provider;
11969 // Synchronize the current user with the auth provider.
11970 if (!AV._config.disableCurrentUser && AV.User.current()) {
11971 AV.User.current()._synchronizeAuthData(provider.getAuthType());
11972 }
11973 },
11974
11975 _logInWith: function _logInWith(provider, options) {
11976 var user = AV.Object._create("_User");
11977 return user._linkWith(provider, options);
11978 }
11979
11980 });
11981};
11982
11983/***/ }),
11984/* 46 */
11985/***/ (function(module, exports, __webpack_require__) {
11986
11987"use strict";
11988/* WEBPACK VAR INJECTION */(function(global) {
11989
11990var _ = __webpack_require__(0);
11991var Promise = __webpack_require__(1);
11992
11993// interface Storage {
11994// readonly attribute boolean async;
11995// string getItem(string key);
11996// void setItem(string key, string value);
11997// void removeItem(string key);
11998// void clear();
11999// Promise getItemAsync(string key);
12000// Promise setItemAsync(string key, string value);
12001// Promise removeItemAsync(string key);
12002// Promise clearAsync();
12003// }
12004var Storage = {};
12005var apiNames = ['getItem', 'setItem', 'removeItem', 'clear'];
12006
12007var localStorage = global.localStorage;
12008
12009try {
12010 var testKey = '__storejs__';
12011 localStorage.setItem(testKey, testKey);
12012 if (localStorage.getItem(testKey) != testKey) {
12013 throw new Error();
12014 }
12015 localStorage.removeItem(testKey);
12016} catch (e) {
12017 localStorage = __webpack_require__(55);
12018}
12019
12020// in browser, `localStorage.async = false` will excute `localStorage.setItem('async', false)`
12021_(apiNames).each(function (apiName) {
12022 Storage[apiName] = function () {
12023 return global.localStorage[apiName].apply(global.localStorage, arguments);
12024 };
12025});
12026Storage.async = false;
12027
12028module.exports = Storage;
12029/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8)))
12030
12031/***/ }),
12032/* 47 */
12033/***/ (function(module, exports, __webpack_require__) {
12034
12035"use strict";
12036
12037
12038var dataURItoBlob = function dataURItoBlob(dataURI, type) {
12039 var byteString;
12040
12041 // ä¼ å…¥çš„ base64ï¼Œä¸æ˜¯ dataURL
12042 if (dataURI.indexOf('base64') < 0) {
12043 byteString = atob(dataURI);
12044 } else if (dataURI.split(',')[0].indexOf('base64') >= 0) {
12045 type = type || dataURI.split(',')[0].split(':')[1].split(';')[0];
12046 byteString = atob(dataURI.split(',')[1]);
12047 } else {
12048 byteString = unescape(dataURI.split(',')[1]);
12049 }
12050 var ia = new Uint8Array(byteString.length);
12051 for (var i = 0; i < byteString.length; i++) {
12052 ia[i] = byteString.charCodeAt(i);
12053 }
12054 return new Blob([ia], { type: type });
12055};
12056
12057module.exports = dataURItoBlob;
12058
12059/***/ }),
12060/* 48 */
12061/***/ (function(module, exports, __webpack_require__) {
12062
12063
12064/**
12065 * Expose `Emitter`.
12066 */
12067
12068if (true) {
12069 module.exports = Emitter;
12070}
12071
12072/**
12073 * Initialize a new `Emitter`.
12074 *
12075 * @api public
12076 */
12077
12078function Emitter(obj) {
12079 if (obj) return mixin(obj);
12080};
12081
12082/**
12083 * Mixin the emitter properties.
12084 *
12085 * @param {Object} obj
12086 * @return {Object}
12087 * @api private
12088 */
12089
12090function mixin(obj) {
12091 for (var key in Emitter.prototype) {
12092 obj[key] = Emitter.prototype[key];
12093 }
12094 return obj;
12095}
12096
12097/**
12098 * Listen on the given `event` with `fn`.
12099 *
12100 * @param {String} event
12101 * @param {Function} fn
12102 * @return {Emitter}
12103 * @api public
12104 */
12105
12106Emitter.prototype.on =
12107Emitter.prototype.addEventListener = function(event, fn){
12108 this._callbacks = this._callbacks || {};
12109 (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
12110 .push(fn);
12111 return this;
12112};
12113
12114/**
12115 * Adds an `event` listener that will be invoked a single
12116 * time then automatically removed.
12117 *
12118 * @param {String} event
12119 * @param {Function} fn
12120 * @return {Emitter}
12121 * @api public
12122 */
12123
12124Emitter.prototype.once = function(event, fn){
12125 function on() {
12126 this.off(event, on);
12127 fn.apply(this, arguments);
12128 }
12129
12130 on.fn = fn;
12131 this.on(event, on);
12132 return this;
12133};
12134
12135/**
12136 * Remove the given callback for `event` or all
12137 * registered callbacks.
12138 *
12139 * @param {String} event
12140 * @param {Function} fn
12141 * @return {Emitter}
12142 * @api public
12143 */
12144
12145Emitter.prototype.off =
12146Emitter.prototype.removeListener =
12147Emitter.prototype.removeAllListeners =
12148Emitter.prototype.removeEventListener = function(event, fn){
12149 this._callbacks = this._callbacks || {};
12150
12151 // all
12152 if (0 == arguments.length) {
12153 this._callbacks = {};
12154 return this;
12155 }
12156
12157 // specific event
12158 var callbacks = this._callbacks['$' + event];
12159 if (!callbacks) return this;
12160
12161 // remove all handlers
12162 if (1 == arguments.length) {
12163 delete this._callbacks['$' + event];
12164 return this;
12165 }
12166
12167 // remove specific handler
12168 var cb;
12169 for (var i = 0; i < callbacks.length; i++) {
12170 cb = callbacks[i];
12171 if (cb === fn || cb.fn === fn) {
12172 callbacks.splice(i, 1);
12173 break;
12174 }
12175 }
12176 return this;
12177};
12178
12179/**
12180 * Emit `event` with the given args.
12181 *
12182 * @param {String} event
12183 * @param {Mixed} ...
12184 * @return {Emitter}
12185 */
12186
12187Emitter.prototype.emit = function(event){
12188 this._callbacks = this._callbacks || {};
12189 var args = [].slice.call(arguments, 1)
12190 , callbacks = this._callbacks['$' + event];
12191
12192 if (callbacks) {
12193 callbacks = callbacks.slice(0);
12194 for (var i = 0, len = callbacks.length; i < len; ++i) {
12195 callbacks[i].apply(this, args);
12196 }
12197 }
12198
12199 return this;
12200};
12201
12202/**
12203 * Return array of callbacks for `event`.
12204 *
12205 * @param {String} event
12206 * @return {Array}
12207 * @api public
12208 */
12209
12210Emitter.prototype.listeners = function(event){
12211 this._callbacks = this._callbacks || {};
12212 return this._callbacks['$' + event] || [];
12213};
12214
12215/**
12216 * Check if this emitter has `event` handlers.
12217 *
12218 * @param {String} event
12219 * @return {Boolean}
12220 * @api public
12221 */
12222
12223Emitter.prototype.hasListeners = function(event){
12224 return !! this.listeners(event).length;
12225};
12226
12227
12228/***/ }),
12229/* 49 */
12230/***/ (function(module, exports) {
12231
12232(function() {
12233 var base64map
12234 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
12235
12236 crypt = {
12237 // Bit-wise rotation left
12238 rotl: function(n, b) {
12239 return (n << b) | (n >>> (32 - b));
12240 },
12241
12242 // Bit-wise rotation right
12243 rotr: function(n, b) {
12244 return (n << (32 - b)) | (n >>> b);
12245 },
12246
12247 // Swap big-endian to little-endian and vice versa
12248 endian: function(n) {
12249 // If number given, swap endian
12250 if (n.constructor == Number) {
12251 return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00;
12252 }
12253
12254 // Else, assume array and swap all items
12255 for (var i = 0; i < n.length; i++)
12256 n[i] = crypt.endian(n[i]);
12257 return n;
12258 },
12259
12260 // Generate an array of any length of random bytes
12261 randomBytes: function(n) {
12262 for (var bytes = []; n > 0; n--)
12263 bytes.push(Math.floor(Math.random() * 256));
12264 return bytes;
12265 },
12266
12267 // Convert a byte array to big-endian 32-bit words
12268 bytesToWords: function(bytes) {
12269 for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
12270 words[b >>> 5] |= bytes[i] << (24 - b % 32);
12271 return words;
12272 },
12273
12274 // Convert big-endian 32-bit words to a byte array
12275 wordsToBytes: function(words) {
12276 for (var bytes = [], b = 0; b < words.length * 32; b += 8)
12277 bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
12278 return bytes;
12279 },
12280
12281 // Convert a byte array to a hex string
12282 bytesToHex: function(bytes) {
12283 for (var hex = [], i = 0; i < bytes.length; i++) {
12284 hex.push((bytes[i] >>> 4).toString(16));
12285 hex.push((bytes[i] & 0xF).toString(16));
12286 }
12287 return hex.join('');
12288 },
12289
12290 // Convert a hex string to a byte array
12291 hexToBytes: function(hex) {
12292 for (var bytes = [], c = 0; c < hex.length; c += 2)
12293 bytes.push(parseInt(hex.substr(c, 2), 16));
12294 return bytes;
12295 },
12296
12297 // Convert a byte array to a base-64 string
12298 bytesToBase64: function(bytes) {
12299 for (var base64 = [], i = 0; i < bytes.length; i += 3) {
12300 var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
12301 for (var j = 0; j < 4; j++)
12302 if (i * 8 + j * 6 <= bytes.length * 8)
12303 base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
12304 else
12305 base64.push('=');
12306 }
12307 return base64.join('');
12308 },
12309
12310 // Convert a base-64 string to a byte array
12311 base64ToBytes: function(base64) {
12312 // Remove non-base-64 characters
12313 base64 = base64.replace(/[^A-Z0-9+\/]/ig, '');
12314
12315 for (var bytes = [], i = 0, imod4 = 0; i < base64.length;
12316 imod4 = ++i % 4) {
12317 if (imod4 == 0) continue;
12318 bytes.push(((base64map.indexOf(base64.charAt(i - 1))
12319 & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2))
12320 | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
12321 }
12322 return bytes;
12323 }
12324 };
12325
12326 module.exports = crypt;
12327})();
12328
12329
12330/***/ }),
12331/* 50 */
12332/***/ (function(module, exports, __webpack_require__) {
12333
12334
12335/**
12336 * This is the common logic for both the Node.js and web browser
12337 * implementations of `debug()`.
12338 *
12339 * Expose `debug()` as the module.
12340 */
12341
12342exports = module.exports = createDebug.debug = createDebug.default = createDebug;
12343exports.coerce = coerce;
12344exports.disable = disable;
12345exports.enable = enable;
12346exports.enabled = enabled;
12347exports.humanize = __webpack_require__(57);
12348
12349/**
12350 * The currently active debug mode names, and names to skip.
12351 */
12352
12353exports.names = [];
12354exports.skips = [];
12355
12356/**
12357 * Map of special "%n" handling functions, for the debug "format" argument.
12358 *
12359 * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
12360 */
12361
12362exports.formatters = {};
12363
12364/**
12365 * Previous log timestamp.
12366 */
12367
12368var prevTime;
12369
12370/**
12371 * Select a color.
12372 * @param {String} namespace
12373 * @return {Number}
12374 * @api private
12375 */
12376
12377function selectColor(namespace) {
12378 var hash = 0, i;
12379
12380 for (i in namespace) {
12381 hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
12382 hash |= 0; // Convert to 32bit integer
12383 }
12384
12385 return exports.colors[Math.abs(hash) % exports.colors.length];
12386}
12387
12388/**
12389 * Create a debugger with the given `namespace`.
12390 *
12391 * @param {String} namespace
12392 * @return {Function}
12393 * @api public
12394 */
12395
12396function createDebug(namespace) {
12397
12398 function debug() {
12399 // disabled?
12400 if (!debug.enabled) return;
12401
12402 var self = debug;
12403
12404 // set `diff` timestamp
12405 var curr = +new Date();
12406 var ms = curr - (prevTime || curr);
12407 self.diff = ms;
12408 self.prev = prevTime;
12409 self.curr = curr;
12410 prevTime = curr;
12411
12412 // turn the `arguments` into a proper Array
12413 var args = new Array(arguments.length);
12414 for (var i = 0; i < args.length; i++) {
12415 args[i] = arguments[i];
12416 }
12417
12418 args[0] = exports.coerce(args[0]);
12419
12420 if ('string' !== typeof args[0]) {
12421 // anything else let's inspect with %O
12422 args.unshift('%O');
12423 }
12424
12425 // apply any `formatters` transformations
12426 var index = 0;
12427 args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
12428 // if we encounter an escaped % then don't increase the array index
12429 if (match === '%%') return match;
12430 index++;
12431 var formatter = exports.formatters[format];
12432 if ('function' === typeof formatter) {
12433 var val = args[index];
12434 match = formatter.call(self, val);
12435
12436 // now we need to remove `args[index]` since it's inlined in the `format`
12437 args.splice(index, 1);
12438 index--;
12439 }
12440 return match;
12441 });
12442
12443 // apply env-specific formatting (colors, etc.)
12444 exports.formatArgs.call(self, args);
12445
12446 var logFn = debug.log || exports.log || console.log.bind(console);
12447 logFn.apply(self, args);
12448 }
12449
12450 debug.namespace = namespace;
12451 debug.enabled = exports.enabled(namespace);
12452 debug.useColors = exports.useColors();
12453 debug.color = selectColor(namespace);
12454
12455 // env-specific initialization logic for debug instances
12456 if ('function' === typeof exports.init) {
12457 exports.init(debug);
12458 }
12459
12460 return debug;
12461}
12462
12463/**
12464 * Enables a debug mode by namespaces. This can include modes
12465 * separated by a colon and wildcards.
12466 *
12467 * @param {String} namespaces
12468 * @api public
12469 */
12470
12471function enable(namespaces) {
12472 exports.save(namespaces);
12473
12474 var split = (namespaces || '').split(/[\s,]+/);
12475 var len = split.length;
12476
12477 for (var i = 0; i < len; i++) {
12478 if (!split[i]) continue; // ignore empty strings
12479 namespaces = split[i].replace(/\*/g, '.*?');
12480 if (namespaces[0] === '-') {
12481 exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
12482 } else {
12483 exports.names.push(new RegExp('^' + namespaces + '$'));
12484 }
12485 }
12486}
12487
12488/**
12489 * Disable debug output.
12490 *
12491 * @api public
12492 */
12493
12494function disable() {
12495 exports.enable('');
12496}
12497
12498/**
12499 * Returns true if the given mode name is enabled, false otherwise.
12500 *
12501 * @param {String} name
12502 * @return {Boolean}
12503 * @api public
12504 */
12505
12506function enabled(name) {
12507 var i, len;
12508 for (i = 0, len = exports.skips.length; i < len; i++) {
12509 if (exports.skips[i].test(name)) {
12510 return false;
12511 }
12512 }
12513 for (i = 0, len = exports.names.length; i < len; i++) {
12514 if (exports.names[i].test(name)) {
12515 return true;
12516 }
12517 }
12518 return false;
12519}
12520
12521/**
12522 * Coerce `val`.
12523 *
12524 * @param {Mixed} val
12525 * @return {Mixed}
12526 * @api private
12527 */
12528
12529function coerce(val) {
12530 if (val instanceof Error) return val.stack || val.message;
12531 return val;
12532}
12533
12534
12535/***/ }),
12536/* 51 */
12537/***/ (function(module, exports, __webpack_require__) {
12538
12539/* WEBPACK VAR INJECTION */(function(global) {var require;/*!
12540 * @overview es6-promise - a tiny implementation of Promises/A+.
12541 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
12542 * @license Licensed under MIT license
12543 * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
12544 * @version 4.0.5
12545 */
12546
12547(function (global, factory) {
12548 true ? module.exports = factory() :
12549 typeof define === 'function' && define.amd ? define(factory) :
12550 (global.ES6Promise = factory());
12551}(this, (function () { 'use strict';
12552
12553function objectOrFunction(x) {
12554 return typeof x === 'function' || typeof x === 'object' && x !== null;
12555}
12556
12557function isFunction(x) {
12558 return typeof x === 'function';
12559}
12560
12561var _isArray = undefined;
12562if (!Array.isArray) {
12563 _isArray = function (x) {
12564 return Object.prototype.toString.call(x) === '[object Array]';
12565 };
12566} else {
12567 _isArray = Array.isArray;
12568}
12569
12570var isArray = _isArray;
12571
12572var len = 0;
12573var vertxNext = undefined;
12574var customSchedulerFn = undefined;
12575
12576var asap = function asap(callback, arg) {
12577 queue[len] = callback;
12578 queue[len + 1] = arg;
12579 len += 2;
12580 if (len === 2) {
12581 // If len is 2, that means that we need to schedule an async flush.
12582 // If additional callbacks are queued before the queue is flushed, they
12583 // will be processed by this flush that we are scheduling.
12584 if (customSchedulerFn) {
12585 customSchedulerFn(flush);
12586 } else {
12587 scheduleFlush();
12588 }
12589 }
12590};
12591
12592function setScheduler(scheduleFn) {
12593 customSchedulerFn = scheduleFn;
12594}
12595
12596function setAsap(asapFn) {
12597 asap = asapFn;
12598}
12599
12600var browserWindow = typeof window !== 'undefined' ? window : undefined;
12601var browserGlobal = browserWindow || {};
12602var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
12603var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]';
12604
12605// test for web worker but not in IE10
12606var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
12607
12608// node
12609function useNextTick() {
12610 // node version 0.10.x displays a deprecation warning when nextTick is used recursively
12611 // see https://github.com/cujojs/when/issues/410 for details
12612 return function () {
12613 return process.nextTick(flush);
12614 };
12615}
12616
12617// vertx
12618function useVertxTimer() {
12619 if (typeof vertxNext !== 'undefined') {
12620 return function () {
12621 vertxNext(flush);
12622 };
12623 }
12624
12625 return useSetTimeout();
12626}
12627
12628function useMutationObserver() {
12629 var iterations = 0;
12630 var observer = new BrowserMutationObserver(flush);
12631 var node = document.createTextNode('');
12632 observer.observe(node, { characterData: true });
12633
12634 return function () {
12635 node.data = iterations = ++iterations % 2;
12636 };
12637}
12638
12639// web worker
12640function useMessageChannel() {
12641 var channel = new MessageChannel();
12642 channel.port1.onmessage = flush;
12643 return function () {
12644 return channel.port2.postMessage(0);
12645 };
12646}
12647
12648function useSetTimeout() {
12649 // Store setTimeout reference so es6-promise will be unaffected by
12650 // other code modifying setTimeout (like sinon.useFakeTimers())
12651 var globalSetTimeout = setTimeout;
12652 return function () {
12653 return globalSetTimeout(flush, 1);
12654 };
12655}
12656
12657var queue = new Array(1000);
12658function flush() {
12659 for (var i = 0; i < len; i += 2) {
12660 var callback = queue[i];
12661 var arg = queue[i + 1];
12662
12663 callback(arg);
12664
12665 queue[i] = undefined;
12666 queue[i + 1] = undefined;
12667 }
12668
12669 len = 0;
12670}
12671
12672function attemptVertx() {
12673 try {
12674 var r = require;
12675 var vertx = __webpack_require__(63);
12676 vertxNext = vertx.runOnLoop || vertx.runOnContext;
12677 return useVertxTimer();
12678 } catch (e) {
12679 return useSetTimeout();
12680 }
12681}
12682
12683var scheduleFlush = undefined;
12684// Decide what async method to use to triggering processing of queued callbacks:
12685if (isNode) {
12686 scheduleFlush = useNextTick();
12687} else if (BrowserMutationObserver) {
12688 scheduleFlush = useMutationObserver();
12689} else if (isWorker) {
12690 scheduleFlush = useMessageChannel();
12691} else if (browserWindow === undefined && "function" === 'function') {
12692 scheduleFlush = attemptVertx();
12693} else {
12694 scheduleFlush = useSetTimeout();
12695}
12696
12697function then(onFulfillment, onRejection) {
12698 var _arguments = arguments;
12699
12700 var parent = this;
12701
12702 var child = new this.constructor(noop);
12703
12704 if (child[PROMISE_ID] === undefined) {
12705 makePromise(child);
12706 }
12707
12708 var _state = parent._state;
12709
12710 if (_state) {
12711 (function () {
12712 var callback = _arguments[_state - 1];
12713 asap(function () {
12714 return invokeCallback(_state, child, callback, parent._result);
12715 });
12716 })();
12717 } else {
12718 subscribe(parent, child, onFulfillment, onRejection);
12719 }
12720
12721 return child;
12722}
12723
12724/**
12725 `Promise.resolve` returns a promise that will become resolved with the
12726 passed `value`. It is shorthand for the following:
12727
12728 ```javascript
12729 let promise = new Promise(function(resolve, reject){
12730 resolve(1);
12731 });
12732
12733 promise.then(function(value){
12734 // value === 1
12735 });
12736 ```
12737
12738 Instead of writing the above, your code now simply becomes the following:
12739
12740 ```javascript
12741 let promise = Promise.resolve(1);
12742
12743 promise.then(function(value){
12744 // value === 1
12745 });
12746 ```
12747
12748 @method resolve
12749 @static
12750 @param {Any} value value that the returned promise will be resolved with
12751 Useful for tooling.
12752 @return {Promise} a promise that will become fulfilled with the given
12753 `value`
12754*/
12755function resolve(object) {
12756 /*jshint validthis:true */
12757 var Constructor = this;
12758
12759 if (object && typeof object === 'object' && object.constructor === Constructor) {
12760 return object;
12761 }
12762
12763 var promise = new Constructor(noop);
12764 _resolve(promise, object);
12765 return promise;
12766}
12767
12768var PROMISE_ID = Math.random().toString(36).substring(16);
12769
12770function noop() {}
12771
12772var PENDING = void 0;
12773var FULFILLED = 1;
12774var REJECTED = 2;
12775
12776var GET_THEN_ERROR = new ErrorObject();
12777
12778function selfFulfillment() {
12779 return new TypeError("You cannot resolve a promise with itself");
12780}
12781
12782function cannotReturnOwn() {
12783 return new TypeError('A promises callback cannot return that same promise.');
12784}
12785
12786function getThen(promise) {
12787 try {
12788 return promise.then;
12789 } catch (error) {
12790 GET_THEN_ERROR.error = error;
12791 return GET_THEN_ERROR;
12792 }
12793}
12794
12795function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
12796 try {
12797 then.call(value, fulfillmentHandler, rejectionHandler);
12798 } catch (e) {
12799 return e;
12800 }
12801}
12802
12803function handleForeignThenable(promise, thenable, then) {
12804 asap(function (promise) {
12805 var sealed = false;
12806 var error = tryThen(then, thenable, function (value) {
12807 if (sealed) {
12808 return;
12809 }
12810 sealed = true;
12811 if (thenable !== value) {
12812 _resolve(promise, value);
12813 } else {
12814 fulfill(promise, value);
12815 }
12816 }, function (reason) {
12817 if (sealed) {
12818 return;
12819 }
12820 sealed = true;
12821
12822 _reject(promise, reason);
12823 }, 'Settle: ' + (promise._label || ' unknown promise'));
12824
12825 if (!sealed && error) {
12826 sealed = true;
12827 _reject(promise, error);
12828 }
12829 }, promise);
12830}
12831
12832function handleOwnThenable(promise, thenable) {
12833 if (thenable._state === FULFILLED) {
12834 fulfill(promise, thenable._result);
12835 } else if (thenable._state === REJECTED) {
12836 _reject(promise, thenable._result);
12837 } else {
12838 subscribe(thenable, undefined, function (value) {
12839 return _resolve(promise, value);
12840 }, function (reason) {
12841 return _reject(promise, reason);
12842 });
12843 }
12844}
12845
12846function handleMaybeThenable(promise, maybeThenable, then$$) {
12847 if (maybeThenable.constructor === promise.constructor && then$$ === then && maybeThenable.constructor.resolve === resolve) {
12848 handleOwnThenable(promise, maybeThenable);
12849 } else {
12850 if (then$$ === GET_THEN_ERROR) {
12851 _reject(promise, GET_THEN_ERROR.error);
12852 } else if (then$$ === undefined) {
12853 fulfill(promise, maybeThenable);
12854 } else if (isFunction(then$$)) {
12855 handleForeignThenable(promise, maybeThenable, then$$);
12856 } else {
12857 fulfill(promise, maybeThenable);
12858 }
12859 }
12860}
12861
12862function _resolve(promise, value) {
12863 if (promise === value) {
12864 _reject(promise, selfFulfillment());
12865 } else if (objectOrFunction(value)) {
12866 handleMaybeThenable(promise, value, getThen(value));
12867 } else {
12868 fulfill(promise, value);
12869 }
12870}
12871
12872function publishRejection(promise) {
12873 if (promise._onerror) {
12874 promise._onerror(promise._result);
12875 }
12876
12877 publish(promise);
12878}
12879
12880function fulfill(promise, value) {
12881 if (promise._state !== PENDING) {
12882 return;
12883 }
12884
12885 promise._result = value;
12886 promise._state = FULFILLED;
12887
12888 if (promise._subscribers.length !== 0) {
12889 asap(publish, promise);
12890 }
12891}
12892
12893function _reject(promise, reason) {
12894 if (promise._state !== PENDING) {
12895 return;
12896 }
12897 promise._state = REJECTED;
12898 promise._result = reason;
12899
12900 asap(publishRejection, promise);
12901}
12902
12903function subscribe(parent, child, onFulfillment, onRejection) {
12904 var _subscribers = parent._subscribers;
12905 var length = _subscribers.length;
12906
12907 parent._onerror = null;
12908
12909 _subscribers[length] = child;
12910 _subscribers[length + FULFILLED] = onFulfillment;
12911 _subscribers[length + REJECTED] = onRejection;
12912
12913 if (length === 0 && parent._state) {
12914 asap(publish, parent);
12915 }
12916}
12917
12918function publish(promise) {
12919 var subscribers = promise._subscribers;
12920 var settled = promise._state;
12921
12922 if (subscribers.length === 0) {
12923 return;
12924 }
12925
12926 var child = undefined,
12927 callback = undefined,
12928 detail = promise._result;
12929
12930 for (var i = 0; i < subscribers.length; i += 3) {
12931 child = subscribers[i];
12932 callback = subscribers[i + settled];
12933
12934 if (child) {
12935 invokeCallback(settled, child, callback, detail);
12936 } else {
12937 callback(detail);
12938 }
12939 }
12940
12941 promise._subscribers.length = 0;
12942}
12943
12944function ErrorObject() {
12945 this.error = null;
12946}
12947
12948var TRY_CATCH_ERROR = new ErrorObject();
12949
12950function tryCatch(callback, detail) {
12951 try {
12952 return callback(detail);
12953 } catch (e) {
12954 TRY_CATCH_ERROR.error = e;
12955 return TRY_CATCH_ERROR;
12956 }
12957}
12958
12959function invokeCallback(settled, promise, callback, detail) {
12960 var hasCallback = isFunction(callback),
12961 value = undefined,
12962 error = undefined,
12963 succeeded = undefined,
12964 failed = undefined;
12965
12966 if (hasCallback) {
12967 value = tryCatch(callback, detail);
12968
12969 if (value === TRY_CATCH_ERROR) {
12970 failed = true;
12971 error = value.error;
12972 value = null;
12973 } else {
12974 succeeded = true;
12975 }
12976
12977 if (promise === value) {
12978 _reject(promise, cannotReturnOwn());
12979 return;
12980 }
12981 } else {
12982 value = detail;
12983 succeeded = true;
12984 }
12985
12986 if (promise._state !== PENDING) {
12987 // noop
12988 } else if (hasCallback && succeeded) {
12989 _resolve(promise, value);
12990 } else if (failed) {
12991 _reject(promise, error);
12992 } else if (settled === FULFILLED) {
12993 fulfill(promise, value);
12994 } else if (settled === REJECTED) {
12995 _reject(promise, value);
12996 }
12997}
12998
12999function initializePromise(promise, resolver) {
13000 try {
13001 resolver(function resolvePromise(value) {
13002 _resolve(promise, value);
13003 }, function rejectPromise(reason) {
13004 _reject(promise, reason);
13005 });
13006 } catch (e) {
13007 _reject(promise, e);
13008 }
13009}
13010
13011var id = 0;
13012function nextId() {
13013 return id++;
13014}
13015
13016function makePromise(promise) {
13017 promise[PROMISE_ID] = id++;
13018 promise._state = undefined;
13019 promise._result = undefined;
13020 promise._subscribers = [];
13021}
13022
13023function Enumerator(Constructor, input) {
13024 this._instanceConstructor = Constructor;
13025 this.promise = new Constructor(noop);
13026
13027 if (!this.promise[PROMISE_ID]) {
13028 makePromise(this.promise);
13029 }
13030
13031 if (isArray(input)) {
13032 this._input = input;
13033 this.length = input.length;
13034 this._remaining = input.length;
13035
13036 this._result = new Array(this.length);
13037
13038 if (this.length === 0) {
13039 fulfill(this.promise, this._result);
13040 } else {
13041 this.length = this.length || 0;
13042 this._enumerate();
13043 if (this._remaining === 0) {
13044 fulfill(this.promise, this._result);
13045 }
13046 }
13047 } else {
13048 _reject(this.promise, validationError());
13049 }
13050}
13051
13052function validationError() {
13053 return new Error('Array Methods must be provided an Array');
13054};
13055
13056Enumerator.prototype._enumerate = function () {
13057 var length = this.length;
13058 var _input = this._input;
13059
13060 for (var i = 0; this._state === PENDING && i < length; i++) {
13061 this._eachEntry(_input[i], i);
13062 }
13063};
13064
13065Enumerator.prototype._eachEntry = function (entry, i) {
13066 var c = this._instanceConstructor;
13067 var resolve$$ = c.resolve;
13068
13069 if (resolve$$ === resolve) {
13070 var _then = getThen(entry);
13071
13072 if (_then === then && entry._state !== PENDING) {
13073 this._settledAt(entry._state, i, entry._result);
13074 } else if (typeof _then !== 'function') {
13075 this._remaining--;
13076 this._result[i] = entry;
13077 } else if (c === Promise) {
13078 var promise = new c(noop);
13079 handleMaybeThenable(promise, entry, _then);
13080 this._willSettleAt(promise, i);
13081 } else {
13082 this._willSettleAt(new c(function (resolve$$) {
13083 return resolve$$(entry);
13084 }), i);
13085 }
13086 } else {
13087 this._willSettleAt(resolve$$(entry), i);
13088 }
13089};
13090
13091Enumerator.prototype._settledAt = function (state, i, value) {
13092 var promise = this.promise;
13093
13094 if (promise._state === PENDING) {
13095 this._remaining--;
13096
13097 if (state === REJECTED) {
13098 _reject(promise, value);
13099 } else {
13100 this._result[i] = value;
13101 }
13102 }
13103
13104 if (this._remaining === 0) {
13105 fulfill(promise, this._result);
13106 }
13107};
13108
13109Enumerator.prototype._willSettleAt = function (promise, i) {
13110 var enumerator = this;
13111
13112 subscribe(promise, undefined, function (value) {
13113 return enumerator._settledAt(FULFILLED, i, value);
13114 }, function (reason) {
13115 return enumerator._settledAt(REJECTED, i, reason);
13116 });
13117};
13118
13119/**
13120 `Promise.all` accepts an array of promises, and returns a new promise which
13121 is fulfilled with an array of fulfillment values for the passed promises, or
13122 rejected with the reason of the first passed promise to be rejected. It casts all
13123 elements of the passed iterable to promises as it runs this algorithm.
13124
13125 Example:
13126
13127 ```javascript
13128 let promise1 = resolve(1);
13129 let promise2 = resolve(2);
13130 let promise3 = resolve(3);
13131 let promises = [ promise1, promise2, promise3 ];
13132
13133 Promise.all(promises).then(function(array){
13134 // The array here would be [ 1, 2, 3 ];
13135 });
13136 ```
13137
13138 If any of the `promises` given to `all` are rejected, the first promise
13139 that is rejected will be given as an argument to the returned promises's
13140 rejection handler. For example:
13141
13142 Example:
13143
13144 ```javascript
13145 let promise1 = resolve(1);
13146 let promise2 = reject(new Error("2"));
13147 let promise3 = reject(new Error("3"));
13148 let promises = [ promise1, promise2, promise3 ];
13149
13150 Promise.all(promises).then(function(array){
13151 // Code here never runs because there are rejected promises!
13152 }, function(error) {
13153 // error.message === "2"
13154 });
13155 ```
13156
13157 @method all
13158 @static
13159 @param {Array} entries array of promises
13160 @param {String} label optional string for labeling the promise.
13161 Useful for tooling.
13162 @return {Promise} promise that is fulfilled when all `promises` have been
13163 fulfilled, or rejected if any of them become rejected.
13164 @static
13165*/
13166function all(entries) {
13167 return new Enumerator(this, entries).promise;
13168}
13169
13170/**
13171 `Promise.race` returns a new promise which is settled in the same way as the
13172 first passed promise to settle.
13173
13174 Example:
13175
13176 ```javascript
13177 let promise1 = new Promise(function(resolve, reject){
13178 setTimeout(function(){
13179 resolve('promise 1');
13180 }, 200);
13181 });
13182
13183 let promise2 = new Promise(function(resolve, reject){
13184 setTimeout(function(){
13185 resolve('promise 2');
13186 }, 100);
13187 });
13188
13189 Promise.race([promise1, promise2]).then(function(result){
13190 // result === 'promise 2' because it was resolved before promise1
13191 // was resolved.
13192 });
13193 ```
13194
13195 `Promise.race` is deterministic in that only the state of the first
13196 settled promise matters. For example, even if other promises given to the
13197 `promises` array argument are resolved, but the first settled promise has
13198 become rejected before the other promises became fulfilled, the returned
13199 promise will become rejected:
13200
13201 ```javascript
13202 let promise1 = new Promise(function(resolve, reject){
13203 setTimeout(function(){
13204 resolve('promise 1');
13205 }, 200);
13206 });
13207
13208 let promise2 = new Promise(function(resolve, reject){
13209 setTimeout(function(){
13210 reject(new Error('promise 2'));
13211 }, 100);
13212 });
13213
13214 Promise.race([promise1, promise2]).then(function(result){
13215 // Code here never runs
13216 }, function(reason){
13217 // reason.message === 'promise 2' because promise 2 became rejected before
13218 // promise 1 became fulfilled
13219 });
13220 ```
13221
13222 An example real-world use case is implementing timeouts:
13223
13224 ```javascript
13225 Promise.race([ajax('foo.json'), timeout(5000)])
13226 ```
13227
13228 @method race
13229 @static
13230 @param {Array} promises array of promises to observe
13231 Useful for tooling.
13232 @return {Promise} a promise which settles in the same way as the first passed
13233 promise to settle.
13234*/
13235function race(entries) {
13236 /*jshint validthis:true */
13237 var Constructor = this;
13238
13239 if (!isArray(entries)) {
13240 return new Constructor(function (_, reject) {
13241 return reject(new TypeError('You must pass an array to race.'));
13242 });
13243 } else {
13244 return new Constructor(function (resolve, reject) {
13245 var length = entries.length;
13246 for (var i = 0; i < length; i++) {
13247 Constructor.resolve(entries[i]).then(resolve, reject);
13248 }
13249 });
13250 }
13251}
13252
13253/**
13254 `Promise.reject` returns a promise rejected with the passed `reason`.
13255 It is shorthand for the following:
13256
13257 ```javascript
13258 let promise = new Promise(function(resolve, reject){
13259 reject(new Error('WHOOPS'));
13260 });
13261
13262 promise.then(function(value){
13263 // Code here doesn't run because the promise is rejected!
13264 }, function(reason){
13265 // reason.message === 'WHOOPS'
13266 });
13267 ```
13268
13269 Instead of writing the above, your code now simply becomes the following:
13270
13271 ```javascript
13272 let promise = Promise.reject(new Error('WHOOPS'));
13273
13274 promise.then(function(value){
13275 // Code here doesn't run because the promise is rejected!
13276 }, function(reason){
13277 // reason.message === 'WHOOPS'
13278 });
13279 ```
13280
13281 @method reject
13282 @static
13283 @param {Any} reason value that the returned promise will be rejected with.
13284 Useful for tooling.
13285 @return {Promise} a promise rejected with the given `reason`.
13286*/
13287function reject(reason) {
13288 /*jshint validthis:true */
13289 var Constructor = this;
13290 var promise = new Constructor(noop);
13291 _reject(promise, reason);
13292 return promise;
13293}
13294
13295function needsResolver() {
13296 throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
13297}
13298
13299function needsNew() {
13300 throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
13301}
13302
13303/**
13304 Promise objects represent the eventual result of an asynchronous operation. The
13305 primary way of interacting with a promise is through its `then` method, which
13306 registers callbacks to receive either a promise's eventual value or the reason
13307 why the promise cannot be fulfilled.
13308
13309 Terminology
13310 -----------
13311
13312 - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
13313 - `thenable` is an object or function that defines a `then` method.
13314 - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
13315 - `exception` is a value that is thrown using the throw statement.
13316 - `reason` is a value that indicates why a promise was rejected.
13317 - `settled` the final resting state of a promise, fulfilled or rejected.
13318
13319 A promise can be in one of three states: pending, fulfilled, or rejected.
13320
13321 Promises that are fulfilled have a fulfillment value and are in the fulfilled
13322 state. Promises that are rejected have a rejection reason and are in the
13323 rejected state. A fulfillment value is never a thenable.
13324
13325 Promises can also be said to *resolve* a value. If this value is also a
13326 promise, then the original promise's settled state will match the value's
13327 settled state. So a promise that *resolves* a promise that rejects will
13328 itself reject, and a promise that *resolves* a promise that fulfills will
13329 itself fulfill.
13330
13331
13332 Basic Usage:
13333 ------------
13334
13335 ```js
13336 let promise = new Promise(function(resolve, reject) {
13337 // on success
13338 resolve(value);
13339
13340 // on failure
13341 reject(reason);
13342 });
13343
13344 promise.then(function(value) {
13345 // on fulfillment
13346 }, function(reason) {
13347 // on rejection
13348 });
13349 ```
13350
13351 Advanced Usage:
13352 ---------------
13353
13354 Promises shine when abstracting away asynchronous interactions such as
13355 `XMLHttpRequest`s.
13356
13357 ```js
13358 function getJSON(url) {
13359 return new Promise(function(resolve, reject){
13360 let xhr = new XMLHttpRequest();
13361
13362 xhr.open('GET', url);
13363 xhr.onreadystatechange = handler;
13364 xhr.responseType = 'json';
13365 xhr.setRequestHeader('Accept', 'application/json');
13366 xhr.send();
13367
13368 function handler() {
13369 if (this.readyState === this.DONE) {
13370 if (this.status === 200) {
13371 resolve(this.response);
13372 } else {
13373 reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
13374 }
13375 }
13376 };
13377 });
13378 }
13379
13380 getJSON('/posts.json').then(function(json) {
13381 // on fulfillment
13382 }, function(reason) {
13383 // on rejection
13384 });
13385 ```
13386
13387 Unlike callbacks, promises are great composable primitives.
13388
13389 ```js
13390 Promise.all([
13391 getJSON('/posts'),
13392 getJSON('/comments')
13393 ]).then(function(values){
13394 values[0] // => postsJSON
13395 values[1] // => commentsJSON
13396
13397 return values;
13398 });
13399 ```
13400
13401 @class Promise
13402 @param {function} resolver
13403 Useful for tooling.
13404 @constructor
13405*/
13406function Promise(resolver) {
13407 this[PROMISE_ID] = nextId();
13408 this._result = this._state = undefined;
13409 this._subscribers = [];
13410
13411 if (noop !== resolver) {
13412 typeof resolver !== 'function' && needsResolver();
13413 this instanceof Promise ? initializePromise(this, resolver) : needsNew();
13414 }
13415}
13416
13417Promise.all = all;
13418Promise.race = race;
13419Promise.resolve = resolve;
13420Promise.reject = reject;
13421Promise._setScheduler = setScheduler;
13422Promise._setAsap = setAsap;
13423Promise._asap = asap;
13424
13425Promise.prototype = {
13426 constructor: Promise,
13427
13428 /**
13429 The primary way of interacting with a promise is through its `then` method,
13430 which registers callbacks to receive either a promise's eventual value or the
13431 reason why the promise cannot be fulfilled.
13432
13433 ```js
13434 findUser().then(function(user){
13435 // user is available
13436 }, function(reason){
13437 // user is unavailable, and you are given the reason why
13438 });
13439 ```
13440
13441 Chaining
13442 --------
13443
13444 The return value of `then` is itself a promise. This second, 'downstream'
13445 promise is resolved with the return value of the first promise's fulfillment
13446 or rejection handler, or rejected if the handler throws an exception.
13447
13448 ```js
13449 findUser().then(function (user) {
13450 return user.name;
13451 }, function (reason) {
13452 return 'default name';
13453 }).then(function (userName) {
13454 // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
13455 // will be `'default name'`
13456 });
13457
13458 findUser().then(function (user) {
13459 throw new Error('Found user, but still unhappy');
13460 }, function (reason) {
13461 throw new Error('`findUser` rejected and we're unhappy');
13462 }).then(function (value) {
13463 // never reached
13464 }, function (reason) {
13465 // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
13466 // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
13467 });
13468 ```
13469 If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
13470
13471 ```js
13472 findUser().then(function (user) {
13473 throw new PedagogicalException('Upstream error');
13474 }).then(function (value) {
13475 // never reached
13476 }).then(function (value) {
13477 // never reached
13478 }, function (reason) {
13479 // The `PedgagocialException` is propagated all the way down to here
13480 });
13481 ```
13482
13483 Assimilation
13484 ------------
13485
13486 Sometimes the value you want to propagate to a downstream promise can only be
13487 retrieved asynchronously. This can be achieved by returning a promise in the
13488 fulfillment or rejection handler. The downstream promise will then be pending
13489 until the returned promise is settled. This is called *assimilation*.
13490
13491 ```js
13492 findUser().then(function (user) {
13493 return findCommentsByAuthor(user);
13494 }).then(function (comments) {
13495 // The user's comments are now available
13496 });
13497 ```
13498
13499 If the assimliated promise rejects, then the downstream promise will also reject.
13500
13501 ```js
13502 findUser().then(function (user) {
13503 return findCommentsByAuthor(user);
13504 }).then(function (comments) {
13505 // If `findCommentsByAuthor` fulfills, we'll have the value here
13506 }, function (reason) {
13507 // If `findCommentsByAuthor` rejects, we'll have the reason here
13508 });
13509 ```
13510
13511 Simple Example
13512 --------------
13513
13514 Synchronous Example
13515
13516 ```javascript
13517 let result;
13518
13519 try {
13520 result = findResult();
13521 // success
13522 } catch(reason) {
13523 // failure
13524 }
13525 ```
13526
13527 Errback Example
13528
13529 ```js
13530 findResult(function(result, err){
13531 if (err) {
13532 // failure
13533 } else {
13534 // success
13535 }
13536 });
13537 ```
13538
13539 Promise Example;
13540
13541 ```javascript
13542 findResult().then(function(result){
13543 // success
13544 }, function(reason){
13545 // failure
13546 });
13547 ```
13548
13549 Advanced Example
13550 --------------
13551
13552 Synchronous Example
13553
13554 ```javascript
13555 let author, books;
13556
13557 try {
13558 author = findAuthor();
13559 books = findBooksByAuthor(author);
13560 // success
13561 } catch(reason) {
13562 // failure
13563 }
13564 ```
13565
13566 Errback Example
13567
13568 ```js
13569
13570 function foundBooks(books) {
13571
13572 }
13573
13574 function failure(reason) {
13575
13576 }
13577
13578 findAuthor(function(author, err){
13579 if (err) {
13580 failure(err);
13581 // failure
13582 } else {
13583 try {
13584 findBoooksByAuthor(author, function(books, err) {
13585 if (err) {
13586 failure(err);
13587 } else {
13588 try {
13589 foundBooks(books);
13590 } catch(reason) {
13591 failure(reason);
13592 }
13593 }
13594 });
13595 } catch(error) {
13596 failure(err);
13597 }
13598 // success
13599 }
13600 });
13601 ```
13602
13603 Promise Example;
13604
13605 ```javascript
13606 findAuthor().
13607 then(findBooksByAuthor).
13608 then(function(books){
13609 // found books
13610 }).catch(function(reason){
13611 // something went wrong
13612 });
13613 ```
13614
13615 @method then
13616 @param {Function} onFulfilled
13617 @param {Function} onRejected
13618 Useful for tooling.
13619 @return {Promise}
13620 */
13621 then: then,
13622
13623 /**
13624 `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
13625 as the catch block of a try/catch statement.
13626
13627 ```js
13628 function findAuthor(){
13629 throw new Error('couldn't find that author');
13630 }
13631
13632 // synchronous
13633 try {
13634 findAuthor();
13635 } catch(reason) {
13636 // something went wrong
13637 }
13638
13639 // async with promises
13640 findAuthor().catch(function(reason){
13641 // something went wrong
13642 });
13643 ```
13644
13645 @method catch
13646 @param {Function} onRejection
13647 Useful for tooling.
13648 @return {Promise}
13649 */
13650 'catch': function _catch(onRejection) {
13651 return this.then(null, onRejection);
13652 }
13653};
13654
13655function polyfill() {
13656 var local = undefined;
13657
13658 if (typeof global !== 'undefined') {
13659 local = global;
13660 } else if (typeof self !== 'undefined') {
13661 local = self;
13662 } else {
13663 try {
13664 local = Function('return this')();
13665 } catch (e) {
13666 throw new Error('polyfill failed because global object is unavailable in this environment');
13667 }
13668 }
13669
13670 var P = local.Promise;
13671
13672 if (P) {
13673 var promiseToString = null;
13674 try {
13675 promiseToString = Object.prototype.toString.call(P.resolve());
13676 } catch (e) {
13677 // silently ignored
13678 }
13679
13680 if (promiseToString === '[object Promise]' && !P.cast) {
13681 return;
13682 }
13683 }
13684
13685 local.Promise = Promise;
13686}
13687
13688// Strange compat..
13689Promise.polyfill = polyfill;
13690Promise.Promise = Promise;
13691
13692return Promise;
13693
13694})));
13695//# sourceMappingURL=es6-promise.map
13696/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8)))
13697
13698/***/ }),
13699/* 52 */
13700/***/ (function(module, exports, __webpack_require__) {
13701
13702"use strict";
13703/**
13704 * @author Toru Nagashima
13705 * @copyright 2015 Toru Nagashima. All rights reserved.
13706 * See LICENSE file in root directory for full license.
13707 */
13708
13709
13710
13711//-----------------------------------------------------------------------------
13712// Requirements
13713//-----------------------------------------------------------------------------
13714
13715var Commons = __webpack_require__(10);
13716var LISTENERS = Commons.LISTENERS;
13717var ATTRIBUTE = Commons.ATTRIBUTE;
13718var newNode = Commons.newNode;
13719
13720//-----------------------------------------------------------------------------
13721// Helpers
13722//-----------------------------------------------------------------------------
13723
13724/**
13725 * Gets a specified attribute listener from a given EventTarget object.
13726 *
13727 * @param {EventTarget} eventTarget - An EventTarget object to get.
13728 * @param {string} type - An event type to get.
13729 * @returns {function|null} The found attribute listener.
13730 */
13731function getAttributeListener(eventTarget, type) {
13732 var node = eventTarget[LISTENERS][type];
13733 while (node != null) {
13734 if (node.kind === ATTRIBUTE) {
13735 return node.listener;
13736 }
13737 node = node.next;
13738 }
13739 return null;
13740}
13741
13742/**
13743 * Sets a specified attribute listener to a given EventTarget object.
13744 *
13745 * @param {EventTarget} eventTarget - An EventTarget object to set.
13746 * @param {string} type - An event type to set.
13747 * @param {function|null} listener - A listener to be set.
13748 * @returns {void}
13749 */
13750function setAttributeListener(eventTarget, type, listener) {
13751 if (typeof listener !== "function" && typeof listener !== "object") {
13752 listener = null; // eslint-disable-line no-param-reassign
13753 }
13754
13755 var prev = null;
13756 var node = eventTarget[LISTENERS][type];
13757 while (node != null) {
13758 if (node.kind === ATTRIBUTE) {
13759 // Remove old value.
13760 if (prev == null) {
13761 eventTarget[LISTENERS][type] = node.next;
13762 }
13763 else {
13764 prev.next = node.next;
13765 }
13766 }
13767 else {
13768 prev = node;
13769 }
13770
13771 node = node.next;
13772 }
13773
13774 // Add new value.
13775 if (listener != null) {
13776 if (prev == null) {
13777 eventTarget[LISTENERS][type] = newNode(listener, ATTRIBUTE);
13778 }
13779 else {
13780 prev.next = newNode(listener, ATTRIBUTE);
13781 }
13782 }
13783}
13784
13785//-----------------------------------------------------------------------------
13786// Public Interface
13787//-----------------------------------------------------------------------------
13788
13789/**
13790 * Defines an `EventTarget` implementation which has `onfoobar` attributes.
13791 *
13792 * @param {EventTarget} EventTargetBase - A base implementation of EventTarget.
13793 * @param {string[]} types - A list of event types which are defined as attribute listeners.
13794 * @returns {EventTarget} The defined `EventTarget` implementation which has attribute listeners.
13795 */
13796exports.defineCustomEventTarget = function(EventTargetBase, types) {
13797 function EventTarget() {
13798 EventTargetBase.call(this);
13799 }
13800
13801 var descripter = {
13802 constructor: {
13803 value: EventTarget,
13804 configurable: true,
13805 writable: true
13806 }
13807 };
13808
13809 types.forEach(function(type) {
13810 descripter["on" + type] = {
13811 get: function() { return getAttributeListener(this, type); },
13812 set: function(listener) { setAttributeListener(this, type, listener); },
13813 configurable: true,
13814 enumerable: true
13815 };
13816 });
13817
13818 EventTarget.prototype = Object.create(EventTargetBase.prototype, descripter);
13819
13820 return EventTarget;
13821};
13822
13823
13824/***/ }),
13825/* 53 */
13826/***/ (function(module, exports, __webpack_require__) {
13827
13828"use strict";
13829/**
13830 * @author Toru Nagashima
13831 * @copyright 2015 Toru Nagashima. All rights reserved.
13832 * See LICENSE file in root directory for full license.
13833 */
13834
13835
13836
13837//-----------------------------------------------------------------------------
13838// Requirements
13839//-----------------------------------------------------------------------------
13840
13841var createUniqueKey = __webpack_require__(10).createUniqueKey;
13842
13843//-----------------------------------------------------------------------------
13844// Constsnts
13845//-----------------------------------------------------------------------------
13846
13847/**
13848 * The key of the flag which is turned on by `stopImmediatePropagation` method.
13849 *
13850 * @type {symbol|string}
13851 * @private
13852 */
13853var STOP_IMMEDIATE_PROPAGATION_FLAG =
13854 createUniqueKey("stop_immediate_propagation_flag");
13855
13856/**
13857 * The key of the flag which is turned on by `preventDefault` method.
13858 *
13859 * @type {symbol|string}
13860 * @private
13861 */
13862var CANCELED_FLAG = createUniqueKey("canceled_flag");
13863
13864/**
13865 * The key of the original event object.
13866 *
13867 * @type {symbol|string}
13868 * @private
13869 */
13870var ORIGINAL_EVENT = createUniqueKey("original_event");
13871
13872/**
13873 * Method definitions for the event wrapper.
13874 *
13875 * @type {object}
13876 * @private
13877 */
13878var wrapperPrototypeDefinition = Object.freeze({
13879 stopPropagation: Object.freeze({
13880 value: function stopPropagation() {
13881 var e = this[ORIGINAL_EVENT];
13882 if (typeof e.stopPropagation === "function") {
13883 e.stopPropagation();
13884 }
13885 },
13886 writable: true,
13887 configurable: true
13888 }),
13889
13890 stopImmediatePropagation: Object.freeze({
13891 value: function stopImmediatePropagation() {
13892 this[STOP_IMMEDIATE_PROPAGATION_FLAG] = true;
13893
13894 var e = this[ORIGINAL_EVENT];
13895 if (typeof e.stopImmediatePropagation === "function") {
13896 e.stopImmediatePropagation();
13897 }
13898 },
13899 writable: true,
13900 configurable: true
13901 }),
13902
13903 preventDefault: Object.freeze({
13904 value: function preventDefault() {
13905 if (this.cancelable === true) {
13906 this[CANCELED_FLAG] = true;
13907 }
13908
13909 var e = this[ORIGINAL_EVENT];
13910 if (typeof e.preventDefault === "function") {
13911 e.preventDefault();
13912 }
13913 },
13914 writable: true,
13915 configurable: true
13916 }),
13917
13918 defaultPrevented: Object.freeze({
13919 get: function defaultPrevented() { return this[CANCELED_FLAG]; },
13920 enumerable: true,
13921 configurable: true
13922 })
13923});
13924
13925//-----------------------------------------------------------------------------
13926// Public Interface
13927//-----------------------------------------------------------------------------
13928
13929exports.STOP_IMMEDIATE_PROPAGATION_FLAG = STOP_IMMEDIATE_PROPAGATION_FLAG;
13930
13931/**
13932 * Creates an event wrapper.
13933 *
13934 * We cannot modify several properties of `Event` object, so we need to create the wrapper.
13935 * Plus, this wrapper supports non `Event` objects.
13936 *
13937 * @param {Event|{type: string}} event - An original event to create the wrapper.
13938 * @param {EventTarget} eventTarget - The event target of the event.
13939 * @returns {Event} The created wrapper. This object is implemented `Event` interface.
13940 * @private
13941 */
13942exports.createEventWrapper = function createEventWrapper(event, eventTarget) {
13943 var timeStamp = (
13944 typeof event.timeStamp === "number" ? event.timeStamp : Date.now()
13945 );
13946 var propertyDefinition = {
13947 type: {value: event.type, enumerable: true},
13948 target: {value: eventTarget, enumerable: true},
13949 currentTarget: {value: eventTarget, enumerable: true},
13950 eventPhase: {value: 2, enumerable: true},
13951 bubbles: {value: Boolean(event.bubbles), enumerable: true},
13952 cancelable: {value: Boolean(event.cancelable), enumerable: true},
13953 timeStamp: {value: timeStamp, enumerable: true},
13954 isTrusted: {value: false, enumerable: true}
13955 };
13956 propertyDefinition[STOP_IMMEDIATE_PROPAGATION_FLAG] = {value: false, writable: true};
13957 propertyDefinition[CANCELED_FLAG] = {value: false, writable: true};
13958 propertyDefinition[ORIGINAL_EVENT] = {value: event};
13959
13960 // For CustomEvent.
13961 if (typeof event.detail !== "undefined") {
13962 propertyDefinition.detail = {value: event.detail, enumerable: true};
13963 }
13964
13965 return Object.create(
13966 Object.create(event, wrapperPrototypeDefinition),
13967 propertyDefinition
13968 );
13969};
13970
13971
13972/***/ }),
13973/* 54 */
13974/***/ (function(module, exports) {
13975
13976/*!
13977 * Determine if an object is a Buffer
13978 *
13979 * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
13980 * @license MIT
13981 */
13982
13983// The _isBuffer check is for Safari 5-7 support, because it's missing
13984// Object.prototype.constructor. Remove this eventually
13985module.exports = function (obj) {
13986 return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
13987}
13988
13989function isBuffer (obj) {
13990 return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
13991}
13992
13993// For Node v0.10 support. Remove this eventually.
13994function isSlowBuffer (obj) {
13995 return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
13996}
13997
13998
13999/***/ }),
14000/* 55 */
14001/***/ (function(module, exports, __webpack_require__) {
14002
14003(function(root) {
14004 var localStorageMemory = {};
14005 var cache = {};
14006
14007 /**
14008 * number of stored items.
14009 */
14010 localStorageMemory.length = 0;
14011
14012 /**
14013 * returns item for passed key, or null
14014 *
14015 * @para {String} key
14016 * name of item to be returned
14017 * @returns {String|null}
14018 */
14019 localStorageMemory.getItem = function(key) {
14020 return cache[key] || null;
14021 };
14022
14023 /**
14024 * sets item for key to passed value, as String
14025 *
14026 * @para {String} key
14027 * name of item to be set
14028 * @para {String} value
14029 * value, will always be turned into a String
14030 * @returns {undefined}
14031 */
14032 localStorageMemory.setItem = function(key, value) {
14033 if (typeof value === 'undefined') {
14034 localStorageMemory.removeItem(key);
14035 } else {
14036 if (!(cache.hasOwnProperty(key))) {
14037 localStorageMemory.length++;
14038 }
14039
14040 cache[key] = '' + value;
14041 }
14042 };
14043
14044 /**
14045 * removes item for passed key
14046 *
14047 * @para {String} key
14048 * name of item to be removed
14049 * @returns {undefined}
14050 */
14051 localStorageMemory.removeItem = function(key) {
14052 if (cache.hasOwnProperty(key)) {
14053 delete cache[key];
14054 localStorageMemory.length--;
14055 }
14056 };
14057
14058 /**
14059 * returns name of key at passed index
14060 *
14061 * @para {Number} index
14062 * Position for key to be returned (starts at 0)
14063 * @returns {String|null}
14064 */
14065 localStorageMemory.key = function(index) {
14066 return Object.keys(cache)[index] || null;
14067 };
14068
14069 /**
14070 * removes all stored items and sets length to 0
14071 *
14072 * @returns {undefined}
14073 */
14074 localStorageMemory.clear = function() {
14075 cache = {};
14076 localStorageMemory.length = 0;
14077 };
14078
14079 if (true) {
14080 module.exports = localStorageMemory;
14081 } else {
14082 root.localStorageMemory = localStorageMemory;
14083 }
14084})(this);
14085
14086
14087/***/ }),
14088/* 56 */
14089/***/ (function(module, exports, __webpack_require__) {
14090
14091(function(){
14092 var crypt = __webpack_require__(49),
14093 utf8 = __webpack_require__(19).utf8,
14094 isBuffer = __webpack_require__(54),
14095 bin = __webpack_require__(19).bin,
14096
14097 // The core
14098 md5 = function (message, options) {
14099 // Convert to byte array
14100 if (message.constructor == String)
14101 if (options && options.encoding === 'binary')
14102 message = bin.stringToBytes(message);
14103 else
14104 message = utf8.stringToBytes(message);
14105 else if (isBuffer(message))
14106 message = Array.prototype.slice.call(message, 0);
14107 else if (!Array.isArray(message))
14108 message = message.toString();
14109 // else, assume byte array already
14110
14111 var m = crypt.bytesToWords(message),
14112 l = message.length * 8,
14113 a = 1732584193,
14114 b = -271733879,
14115 c = -1732584194,
14116 d = 271733878;
14117
14118 // Swap endian
14119 for (var i = 0; i < m.length; i++) {
14120 m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF |
14121 ((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00;
14122 }
14123
14124 // Padding
14125 m[l >>> 5] |= 0x80 << (l % 32);
14126 m[(((l + 64) >>> 9) << 4) + 14] = l;
14127
14128 // Method shortcuts
14129 var FF = md5._ff,
14130 GG = md5._gg,
14131 HH = md5._hh,
14132 II = md5._ii;
14133
14134 for (var i = 0; i < m.length; i += 16) {
14135
14136 var aa = a,
14137 bb = b,
14138 cc = c,
14139 dd = d;
14140
14141 a = FF(a, b, c, d, m[i+ 0], 7, -680876936);
14142 d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
14143 c = FF(c, d, a, b, m[i+ 2], 17, 606105819);
14144 b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
14145 a = FF(a, b, c, d, m[i+ 4], 7, -176418897);
14146 d = FF(d, a, b, c, m[i+ 5], 12, 1200080426);
14147 c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
14148 b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
14149 a = FF(a, b, c, d, m[i+ 8], 7, 1770035416);
14150 d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
14151 c = FF(c, d, a, b, m[i+10], 17, -42063);
14152 b = FF(b, c, d, a, m[i+11], 22, -1990404162);
14153 a = FF(a, b, c, d, m[i+12], 7, 1804603682);
14154 d = FF(d, a, b, c, m[i+13], 12, -40341101);
14155 c = FF(c, d, a, b, m[i+14], 17, -1502002290);
14156 b = FF(b, c, d, a, m[i+15], 22, 1236535329);
14157
14158 a = GG(a, b, c, d, m[i+ 1], 5, -165796510);
14159 d = GG(d, a, b, c, m[i+ 6], 9, -1069501632);
14160 c = GG(c, d, a, b, m[i+11], 14, 643717713);
14161 b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
14162 a = GG(a, b, c, d, m[i+ 5], 5, -701558691);
14163 d = GG(d, a, b, c, m[i+10], 9, 38016083);
14164 c = GG(c, d, a, b, m[i+15], 14, -660478335);
14165 b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
14166 a = GG(a, b, c, d, m[i+ 9], 5, 568446438);
14167 d = GG(d, a, b, c, m[i+14], 9, -1019803690);
14168 c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
14169 b = GG(b, c, d, a, m[i+ 8], 20, 1163531501);
14170 a = GG(a, b, c, d, m[i+13], 5, -1444681467);
14171 d = GG(d, a, b, c, m[i+ 2], 9, -51403784);
14172 c = GG(c, d, a, b, m[i+ 7], 14, 1735328473);
14173 b = GG(b, c, d, a, m[i+12], 20, -1926607734);
14174
14175 a = HH(a, b, c, d, m[i+ 5], 4, -378558);
14176 d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
14177 c = HH(c, d, a, b, m[i+11], 16, 1839030562);
14178 b = HH(b, c, d, a, m[i+14], 23, -35309556);
14179 a = HH(a, b, c, d, m[i+ 1], 4, -1530992060);
14180 d = HH(d, a, b, c, m[i+ 4], 11, 1272893353);
14181 c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
14182 b = HH(b, c, d, a, m[i+10], 23, -1094730640);
14183 a = HH(a, b, c, d, m[i+13], 4, 681279174);
14184 d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
14185 c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
14186 b = HH(b, c, d, a, m[i+ 6], 23, 76029189);
14187 a = HH(a, b, c, d, m[i+ 9], 4, -640364487);
14188 d = HH(d, a, b, c, m[i+12], 11, -421815835);
14189 c = HH(c, d, a, b, m[i+15], 16, 530742520);
14190 b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
14191
14192 a = II(a, b, c, d, m[i+ 0], 6, -198630844);
14193 d = II(d, a, b, c, m[i+ 7], 10, 1126891415);
14194 c = II(c, d, a, b, m[i+14], 15, -1416354905);
14195 b = II(b, c, d, a, m[i+ 5], 21, -57434055);
14196 a = II(a, b, c, d, m[i+12], 6, 1700485571);
14197 d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
14198 c = II(c, d, a, b, m[i+10], 15, -1051523);
14199 b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
14200 a = II(a, b, c, d, m[i+ 8], 6, 1873313359);
14201 d = II(d, a, b, c, m[i+15], 10, -30611744);
14202 c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
14203 b = II(b, c, d, a, m[i+13], 21, 1309151649);
14204 a = II(a, b, c, d, m[i+ 4], 6, -145523070);
14205 d = II(d, a, b, c, m[i+11], 10, -1120210379);
14206 c = II(c, d, a, b, m[i+ 2], 15, 718787259);
14207 b = II(b, c, d, a, m[i+ 9], 21, -343485551);
14208
14209 a = (a + aa) >>> 0;
14210 b = (b + bb) >>> 0;
14211 c = (c + cc) >>> 0;
14212 d = (d + dd) >>> 0;
14213 }
14214
14215 return crypt.endian([a, b, c, d]);
14216 };
14217
14218 // Auxiliary functions
14219 md5._ff = function (a, b, c, d, x, s, t) {
14220 var n = a + (b & c | ~b & d) + (x >>> 0) + t;
14221 return ((n << s) | (n >>> (32 - s))) + b;
14222 };
14223 md5._gg = function (a, b, c, d, x, s, t) {
14224 var n = a + (b & d | c & ~d) + (x >>> 0) + t;
14225 return ((n << s) | (n >>> (32 - s))) + b;
14226 };
14227 md5._hh = function (a, b, c, d, x, s, t) {
14228 var n = a + (b ^ c ^ d) + (x >>> 0) + t;
14229 return ((n << s) | (n >>> (32 - s))) + b;
14230 };
14231 md5._ii = function (a, b, c, d, x, s, t) {
14232 var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
14233 return ((n << s) | (n >>> (32 - s))) + b;
14234 };
14235
14236 // Package private blocksize
14237 md5._blocksize = 16;
14238 md5._digestsize = 16;
14239
14240 module.exports = function (message, options) {
14241 if (message === undefined || message === null)
14242 throw new Error('Illegal argument ' + message);
14243
14244 var digestbytes = crypt.wordsToBytes(md5(message, options));
14245 return options && options.asBytes ? digestbytes :
14246 options && options.asString ? bin.bytesToString(digestbytes) :
14247 crypt.bytesToHex(digestbytes);
14248 };
14249
14250})();
14251
14252
14253/***/ }),
14254/* 57 */
14255/***/ (function(module, exports) {
14256
14257/**
14258 * Helpers.
14259 */
14260
14261var s = 1000
14262var m = s * 60
14263var h = m * 60
14264var d = h * 24
14265var y = d * 365.25
14266
14267/**
14268 * Parse or format the given `val`.
14269 *
14270 * Options:
14271 *
14272 * - `long` verbose formatting [false]
14273 *
14274 * @param {String|Number} val
14275 * @param {Object} options
14276 * @throws {Error} throw an error if val is not a non-empty string or a number
14277 * @return {String|Number}
14278 * @api public
14279 */
14280
14281module.exports = function (val, options) {
14282 options = options || {}
14283 var type = typeof val
14284 if (type === 'string' && val.length > 0) {
14285 return parse(val)
14286 } else if (type === 'number' && isNaN(val) === false) {
14287 return options.long ?
14288 fmtLong(val) :
14289 fmtShort(val)
14290 }
14291 throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))
14292}
14293
14294/**
14295 * Parse the given `str` and return milliseconds.
14296 *
14297 * @param {String} str
14298 * @return {Number}
14299 * @api private
14300 */
14301
14302function parse(str) {
14303 str = String(str)
14304 if (str.length > 10000) {
14305 return
14306 }
14307 var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)
14308 if (!match) {
14309 return
14310 }
14311 var n = parseFloat(match[1])
14312 var type = (match[2] || 'ms').toLowerCase()
14313 switch (type) {
14314 case 'years':
14315 case 'year':
14316 case 'yrs':
14317 case 'yr':
14318 case 'y':
14319 return n * y
14320 case 'days':
14321 case 'day':
14322 case 'd':
14323 return n * d
14324 case 'hours':
14325 case 'hour':
14326 case 'hrs':
14327 case 'hr':
14328 case 'h':
14329 return n * h
14330 case 'minutes':
14331 case 'minute':
14332 case 'mins':
14333 case 'min':
14334 case 'm':
14335 return n * m
14336 case 'seconds':
14337 case 'second':
14338 case 'secs':
14339 case 'sec':
14340 case 's':
14341 return n * s
14342 case 'milliseconds':
14343 case 'millisecond':
14344 case 'msecs':
14345 case 'msec':
14346 case 'ms':
14347 return n
14348 default:
14349 return undefined
14350 }
14351}
14352
14353/**
14354 * Short format for `ms`.
14355 *
14356 * @param {Number} ms
14357 * @return {String}
14358 * @api private
14359 */
14360
14361function fmtShort(ms) {
14362 if (ms >= d) {
14363 return Math.round(ms / d) + 'd'
14364 }
14365 if (ms >= h) {
14366 return Math.round(ms / h) + 'h'
14367 }
14368 if (ms >= m) {
14369 return Math.round(ms / m) + 'm'
14370 }
14371 if (ms >= s) {
14372 return Math.round(ms / s) + 's'
14373 }
14374 return ms + 'ms'
14375}
14376
14377/**
14378 * Long format for `ms`.
14379 *
14380 * @param {Number} ms
14381 * @return {String}
14382 * @api private
14383 */
14384
14385function fmtLong(ms) {
14386 return plural(ms, d, 'day') ||
14387 plural(ms, h, 'hour') ||
14388 plural(ms, m, 'minute') ||
14389 plural(ms, s, 'second') ||
14390 ms + ' ms'
14391}
14392
14393/**
14394 * Pluralization helper.
14395 */
14396
14397function plural(ms, n, name) {
14398 if (ms < n) {
14399 return
14400 }
14401 if (ms < n * 1.5) {
14402 return Math.floor(ms / n) + ' ' + name
14403 }
14404 return Math.ceil(ms / n) + ' ' + name + 's'
14405}
14406
14407
14408/***/ }),
14409/* 58 */
14410/***/ (function(module, exports, __webpack_require__) {
14411
14412/**
14413 * Check if `fn` is a function.
14414 *
14415 * @param {Function} fn
14416 * @return {Boolean}
14417 * @api private
14418 */
14419var isObject = __webpack_require__(11);
14420
14421function isFunction(fn) {
14422 var tag = isObject(fn) ? Object.prototype.toString.call(fn) : '';
14423 return tag === '[object Function]';
14424}
14425
14426module.exports = isFunction;
14427
14428
14429/***/ }),
14430/* 59 */
14431/***/ (function(module, exports, __webpack_require__) {
14432
14433/**
14434 * Module of mixed-in functions shared between node and client code
14435 */
14436var isObject = __webpack_require__(11);
14437
14438/**
14439 * Expose `RequestBase`.
14440 */
14441
14442module.exports = RequestBase;
14443
14444/**
14445 * Initialize a new `RequestBase`.
14446 *
14447 * @api public
14448 */
14449
14450function RequestBase(obj) {
14451 if (obj) return mixin(obj);
14452}
14453
14454/**
14455 * Mixin the prototype properties.
14456 *
14457 * @param {Object} obj
14458 * @return {Object}
14459 * @api private
14460 */
14461
14462function mixin(obj) {
14463 for (var key in RequestBase.prototype) {
14464 obj[key] = RequestBase.prototype[key];
14465 }
14466 return obj;
14467}
14468
14469/**
14470 * Clear previous timeout.
14471 *
14472 * @return {Request} for chaining
14473 * @api public
14474 */
14475
14476RequestBase.prototype.clearTimeout = function _clearTimeout(){
14477 clearTimeout(this._timer);
14478 clearTimeout(this._responseTimeoutTimer);
14479 delete this._timer;
14480 delete this._responseTimeoutTimer;
14481 return this;
14482};
14483
14484/**
14485 * Override default response body parser
14486 *
14487 * This function will be called to convert incoming data into request.body
14488 *
14489 * @param {Function}
14490 * @api public
14491 */
14492
14493RequestBase.prototype.parse = function parse(fn){
14494 this._parser = fn;
14495 return this;
14496};
14497
14498/**
14499 * Set format of binary response body.
14500 * In browser valid formats are 'blob' and 'arraybuffer',
14501 * which return Blob and ArrayBuffer, respectively.
14502 *
14503 * In Node all values result in Buffer.
14504 *
14505 * Examples:
14506 *
14507 * req.get('/')
14508 * .responseType('blob')
14509 * .end(callback);
14510 *
14511 * @param {String} val
14512 * @return {Request} for chaining
14513 * @api public
14514 */
14515
14516RequestBase.prototype.responseType = function(val){
14517 this._responseType = val;
14518 return this;
14519};
14520
14521/**
14522 * Override default request body serializer
14523 *
14524 * This function will be called to convert data set via .send or .attach into payload to send
14525 *
14526 * @param {Function}
14527 * @api public
14528 */
14529
14530RequestBase.prototype.serialize = function serialize(fn){
14531 this._serializer = fn;
14532 return this;
14533};
14534
14535/**
14536 * Set timeouts.
14537 *
14538 * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time.
14539 * - 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.
14540 *
14541 * Value of 0 or false means no timeout.
14542 *
14543 * @param {Number|Object} ms or {response, read, deadline}
14544 * @return {Request} for chaining
14545 * @api public
14546 */
14547
14548RequestBase.prototype.timeout = function timeout(options){
14549 if (!options || 'object' !== typeof options) {
14550 this._timeout = options;
14551 this._responseTimeout = 0;
14552 return this;
14553 }
14554
14555 if ('undefined' !== typeof options.deadline) {
14556 this._timeout = options.deadline;
14557 }
14558 if ('undefined' !== typeof options.response) {
14559 this._responseTimeout = options.response;
14560 }
14561 return this;
14562};
14563
14564/**
14565 * Set number of retry attempts on error.
14566 *
14567 * Failed requests will be retried 'count' times if timeout or err.code >= 500.
14568 *
14569 * @param {Number} count
14570 * @return {Request} for chaining
14571 * @api public
14572 */
14573
14574RequestBase.prototype.retry = function retry(count){
14575 // Default to 1 if no count passed or true
14576 if (arguments.length === 0 || count === true) count = 1;
14577 if (count <= 0) count = 0;
14578 this._maxRetries = count;
14579 this._retries = 0;
14580 return this;
14581};
14582
14583/**
14584 * Retry request
14585 *
14586 * @return {Request} for chaining
14587 * @api private
14588 */
14589
14590RequestBase.prototype._retry = function() {
14591 this.clearTimeout();
14592
14593 // node
14594 if (this.req) {
14595 this.req = null;
14596 this.req = this.request();
14597 }
14598
14599 this._aborted = false;
14600 this.timedout = false;
14601
14602 return this._end();
14603};
14604
14605/**
14606 * Promise support
14607 *
14608 * @param {Function} resolve
14609 * @param {Function} [reject]
14610 * @return {Request}
14611 */
14612
14613RequestBase.prototype.then = function then(resolve, reject) {
14614 if (!this._fullfilledPromise) {
14615 var self = this;
14616 if (this._endCalled) {
14617 console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises");
14618 }
14619 this._fullfilledPromise = new Promise(function(innerResolve, innerReject){
14620 self.end(function(err, res){
14621 if (err) innerReject(err); else innerResolve(res);
14622 });
14623 });
14624 }
14625 return this._fullfilledPromise.then(resolve, reject);
14626}
14627
14628RequestBase.prototype.catch = function(cb) {
14629 return this.then(undefined, cb);
14630};
14631
14632/**
14633 * Allow for extension
14634 */
14635
14636RequestBase.prototype.use = function use(fn) {
14637 fn(this);
14638 return this;
14639}
14640
14641RequestBase.prototype.ok = function(cb) {
14642 if ('function' !== typeof cb) throw Error("Callback required");
14643 this._okCallback = cb;
14644 return this;
14645};
14646
14647RequestBase.prototype._isResponseOK = function(res) {
14648 if (!res) {
14649 return false;
14650 }
14651
14652 if (this._okCallback) {
14653 return this._okCallback(res);
14654 }
14655
14656 return res.status >= 200 && res.status < 300;
14657};
14658
14659
14660/**
14661 * Get request header `field`.
14662 * Case-insensitive.
14663 *
14664 * @param {String} field
14665 * @return {String}
14666 * @api public
14667 */
14668
14669RequestBase.prototype.get = function(field){
14670 return this._header[field.toLowerCase()];
14671};
14672
14673/**
14674 * Get case-insensitive header `field` value.
14675 * This is a deprecated internal API. Use `.get(field)` instead.
14676 *
14677 * (getHeader is no longer used internally by the superagent code base)
14678 *
14679 * @param {String} field
14680 * @return {String}
14681 * @api private
14682 * @deprecated
14683 */
14684
14685RequestBase.prototype.getHeader = RequestBase.prototype.get;
14686
14687/**
14688 * Set header `field` to `val`, or multiple fields with one object.
14689 * Case-insensitive.
14690 *
14691 * Examples:
14692 *
14693 * req.get('/')
14694 * .set('Accept', 'application/json')
14695 * .set('X-API-Key', 'foobar')
14696 * .end(callback);
14697 *
14698 * req.get('/')
14699 * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
14700 * .end(callback);
14701 *
14702 * @param {String|Object} field
14703 * @param {String} val
14704 * @return {Request} for chaining
14705 * @api public
14706 */
14707
14708RequestBase.prototype.set = function(field, val){
14709 if (isObject(field)) {
14710 for (var key in field) {
14711 this.set(key, field[key]);
14712 }
14713 return this;
14714 }
14715 this._header[field.toLowerCase()] = val;
14716 this.header[field] = val;
14717 return this;
14718};
14719
14720/**
14721 * Remove header `field`.
14722 * Case-insensitive.
14723 *
14724 * Example:
14725 *
14726 * req.get('/')
14727 * .unset('User-Agent')
14728 * .end(callback);
14729 *
14730 * @param {String} field
14731 */
14732RequestBase.prototype.unset = function(field){
14733 delete this._header[field.toLowerCase()];
14734 delete this.header[field];
14735 return this;
14736};
14737
14738/**
14739 * Write the field `name` and `val`, or multiple fields with one object
14740 * for "multipart/form-data" request bodies.
14741 *
14742 * ``` js
14743 * request.post('/upload')
14744 * .field('foo', 'bar')
14745 * .end(callback);
14746 *
14747 * request.post('/upload')
14748 * .field({ foo: 'bar', baz: 'qux' })
14749 * .end(callback);
14750 * ```
14751 *
14752 * @param {String|Object} name
14753 * @param {String|Blob|File|Buffer|fs.ReadStream} val
14754 * @return {Request} for chaining
14755 * @api public
14756 */
14757RequestBase.prototype.field = function(name, val) {
14758
14759 // name should be either a string or an object.
14760 if (null === name || undefined === name) {
14761 throw new Error('.field(name, val) name can not be empty');
14762 }
14763
14764 if (this._data) {
14765 console.error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()");
14766 }
14767
14768 if (isObject(name)) {
14769 for (var key in name) {
14770 this.field(key, name[key]);
14771 }
14772 return this;
14773 }
14774
14775 if (Array.isArray(val)) {
14776 for (var i in val) {
14777 this.field(name, val[i]);
14778 }
14779 return this;
14780 }
14781
14782 // val should be defined now
14783 if (null === val || undefined === val) {
14784 throw new Error('.field(name, val) val can not be empty');
14785 }
14786 if ('boolean' === typeof val) {
14787 val = '' + val;
14788 }
14789 this._getFormData().append(name, val);
14790 return this;
14791};
14792
14793/**
14794 * Abort the request, and clear potential timeout.
14795 *
14796 * @return {Request}
14797 * @api public
14798 */
14799RequestBase.prototype.abort = function(){
14800 if (this._aborted) {
14801 return this;
14802 }
14803 this._aborted = true;
14804 this.xhr && this.xhr.abort(); // browser
14805 this.req && this.req.abort(); // node
14806 this.clearTimeout();
14807 this.emit('abort');
14808 return this;
14809};
14810
14811/**
14812 * Enable transmission of cookies with x-domain requests.
14813 *
14814 * Note that for this to work the origin must not be
14815 * using "Access-Control-Allow-Origin" with a wildcard,
14816 * and also must set "Access-Control-Allow-Credentials"
14817 * to "true".
14818 *
14819 * @api public
14820 */
14821
14822RequestBase.prototype.withCredentials = function(){
14823 // This is browser-only functionality. Node side is no-op.
14824 this._withCredentials = true;
14825 return this;
14826};
14827
14828/**
14829 * Set the max redirects to `n`. Does noting in browser XHR implementation.
14830 *
14831 * @param {Number} n
14832 * @return {Request} for chaining
14833 * @api public
14834 */
14835
14836RequestBase.prototype.redirects = function(n){
14837 this._maxRedirects = n;
14838 return this;
14839};
14840
14841/**
14842 * Convert to a plain javascript object (not JSON string) of scalar properties.
14843 * Note as this method is designed to return a useful non-this value,
14844 * it cannot be chained.
14845 *
14846 * @return {Object} describing method, url, and data of this request
14847 * @api public
14848 */
14849
14850RequestBase.prototype.toJSON = function(){
14851 return {
14852 method: this.method,
14853 url: this.url,
14854 data: this._data,
14855 headers: this._header
14856 };
14857};
14858
14859
14860/**
14861 * Send `data` as the request body, defaulting the `.type()` to "json" when
14862 * an object is given.
14863 *
14864 * Examples:
14865 *
14866 * // manual json
14867 * request.post('/user')
14868 * .type('json')
14869 * .send('{"name":"tj"}')
14870 * .end(callback)
14871 *
14872 * // auto json
14873 * request.post('/user')
14874 * .send({ name: 'tj' })
14875 * .end(callback)
14876 *
14877 * // manual x-www-form-urlencoded
14878 * request.post('/user')
14879 * .type('form')
14880 * .send('name=tj')
14881 * .end(callback)
14882 *
14883 * // auto x-www-form-urlencoded
14884 * request.post('/user')
14885 * .type('form')
14886 * .send({ name: 'tj' })
14887 * .end(callback)
14888 *
14889 * // defaults to x-www-form-urlencoded
14890 * request.post('/user')
14891 * .send('name=tobi')
14892 * .send('species=ferret')
14893 * .end(callback)
14894 *
14895 * @param {String|Object} data
14896 * @return {Request} for chaining
14897 * @api public
14898 */
14899
14900RequestBase.prototype.send = function(data){
14901 var isObj = isObject(data);
14902 var type = this._header['content-type'];
14903
14904 if (this._formData) {
14905 console.error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()");
14906 }
14907
14908 if (isObj && !this._data) {
14909 if (Array.isArray(data)) {
14910 this._data = [];
14911 } else if (!this._isHost(data)) {
14912 this._data = {};
14913 }
14914 } else if (data && this._data && this._isHost(this._data)) {
14915 throw Error("Can't merge these send calls");
14916 }
14917
14918 // merge
14919 if (isObj && isObject(this._data)) {
14920 for (var key in data) {
14921 this._data[key] = data[key];
14922 }
14923 } else if ('string' == typeof data) {
14924 // default to x-www-form-urlencoded
14925 if (!type) this.type('form');
14926 type = this._header['content-type'];
14927 if ('application/x-www-form-urlencoded' == type) {
14928 this._data = this._data
14929 ? this._data + '&' + data
14930 : data;
14931 } else {
14932 this._data = (this._data || '') + data;
14933 }
14934 } else {
14935 this._data = data;
14936 }
14937
14938 if (!isObj || this._isHost(data)) {
14939 return this;
14940 }
14941
14942 // default to json
14943 if (!type) this.type('json');
14944 return this;
14945};
14946
14947
14948/**
14949 * Sort `querystring` by the sort function
14950 *
14951 *
14952 * Examples:
14953 *
14954 * // default order
14955 * request.get('/user')
14956 * .query('name=Nick')
14957 * .query('search=Manny')
14958 * .sortQuery()
14959 * .end(callback)
14960 *
14961 * // customized sort function
14962 * request.get('/user')
14963 * .query('name=Nick')
14964 * .query('search=Manny')
14965 * .sortQuery(function(a, b){
14966 * return a.length - b.length;
14967 * })
14968 * .end(callback)
14969 *
14970 *
14971 * @param {Function} sort
14972 * @return {Request} for chaining
14973 * @api public
14974 */
14975
14976RequestBase.prototype.sortQuery = function(sort) {
14977 // _sort default to true but otherwise can be a function or boolean
14978 this._sort = typeof sort === 'undefined' ? true : sort;
14979 return this;
14980};
14981
14982/**
14983 * Invoke callback with timeout error.
14984 *
14985 * @api private
14986 */
14987
14988RequestBase.prototype._timeoutError = function(reason, timeout){
14989 if (this._aborted) {
14990 return;
14991 }
14992 var err = new Error(reason + timeout + 'ms exceeded');
14993 err.timeout = timeout;
14994 err.code = 'ECONNABORTED';
14995 this.timedout = true;
14996 this.abort();
14997 this.callback(err);
14998};
14999
15000RequestBase.prototype._setTimeouts = function() {
15001 var self = this;
15002
15003 // deadline
15004 if (this._timeout && !this._timer) {
15005 this._timer = setTimeout(function(){
15006 self._timeoutError('Timeout of ', self._timeout);
15007 }, this._timeout);
15008 }
15009 // response timeout
15010 if (this._responseTimeout && !this._responseTimeoutTimer) {
15011 this._responseTimeoutTimer = setTimeout(function(){
15012 self._timeoutError('Response timeout of ', self._responseTimeout);
15013 }, this._responseTimeout);
15014 }
15015}
15016
15017
15018/***/ }),
15019/* 60 */
15020/***/ (function(module, exports, __webpack_require__) {
15021
15022
15023/**
15024 * Module dependencies.
15025 */
15026
15027var utils = __webpack_require__(62);
15028
15029/**
15030 * Expose `ResponseBase`.
15031 */
15032
15033module.exports = ResponseBase;
15034
15035/**
15036 * Initialize a new `ResponseBase`.
15037 *
15038 * @api public
15039 */
15040
15041function ResponseBase(obj) {
15042 if (obj) return mixin(obj);
15043}
15044
15045/**
15046 * Mixin the prototype properties.
15047 *
15048 * @param {Object} obj
15049 * @return {Object}
15050 * @api private
15051 */
15052
15053function mixin(obj) {
15054 for (var key in ResponseBase.prototype) {
15055 obj[key] = ResponseBase.prototype[key];
15056 }
15057 return obj;
15058}
15059
15060/**
15061 * Get case-insensitive `field` value.
15062 *
15063 * @param {String} field
15064 * @return {String}
15065 * @api public
15066 */
15067
15068ResponseBase.prototype.get = function(field){
15069 return this.header[field.toLowerCase()];
15070};
15071
15072/**
15073 * Set header related properties:
15074 *
15075 * - `.type` the content type without params
15076 *
15077 * A response of "Content-Type: text/plain; charset=utf-8"
15078 * will provide you with a `.type` of "text/plain".
15079 *
15080 * @param {Object} header
15081 * @api private
15082 */
15083
15084ResponseBase.prototype._setHeaderProperties = function(header){
15085 // TODO: moar!
15086 // TODO: make this a util
15087
15088 // content-type
15089 var ct = header['content-type'] || '';
15090 this.type = utils.type(ct);
15091
15092 // params
15093 var params = utils.params(ct);
15094 for (var key in params) this[key] = params[key];
15095
15096 this.links = {};
15097
15098 // links
15099 try {
15100 if (header.link) {
15101 this.links = utils.parseLinks(header.link);
15102 }
15103 } catch (err) {
15104 // ignore
15105 }
15106};
15107
15108/**
15109 * Set flags such as `.ok` based on `status`.
15110 *
15111 * For example a 2xx response will give you a `.ok` of __true__
15112 * whereas 5xx will be __false__ and `.error` will be __true__. The
15113 * `.clientError` and `.serverError` are also available to be more
15114 * specific, and `.statusType` is the class of error ranging from 1..5
15115 * sometimes useful for mapping respond colors etc.
15116 *
15117 * "sugar" properties are also defined for common cases. Currently providing:
15118 *
15119 * - .noContent
15120 * - .badRequest
15121 * - .unauthorized
15122 * - .notAcceptable
15123 * - .notFound
15124 *
15125 * @param {Number} status
15126 * @api private
15127 */
15128
15129ResponseBase.prototype._setStatusProperties = function(status){
15130 var type = status / 100 | 0;
15131
15132 // status / class
15133 this.status = this.statusCode = status;
15134 this.statusType = type;
15135
15136 // basics
15137 this.info = 1 == type;
15138 this.ok = 2 == type;
15139 this.redirect = 3 == type;
15140 this.clientError = 4 == type;
15141 this.serverError = 5 == type;
15142 this.error = (4 == type || 5 == type)
15143 ? this.toError()
15144 : false;
15145
15146 // sugar
15147 this.accepted = 202 == status;
15148 this.noContent = 204 == status;
15149 this.badRequest = 400 == status;
15150 this.unauthorized = 401 == status;
15151 this.notAcceptable = 406 == status;
15152 this.forbidden = 403 == status;
15153 this.notFound = 404 == status;
15154};
15155
15156
15157/***/ }),
15158/* 61 */
15159/***/ (function(module, exports) {
15160
15161var ERROR_CODES = [
15162 'ECONNRESET',
15163 'ETIMEDOUT',
15164 'EADDRINFO',
15165 'ESOCKETTIMEDOUT'
15166];
15167
15168/**
15169 * Determine if a request should be retried.
15170 * (Borrowed from segmentio/superagent-retry)
15171 *
15172 * @param {Error} err
15173 * @param {Response} [res]
15174 * @returns {Boolean}
15175 */
15176module.exports = function shouldRetry(err, res) {
15177 if (err && err.code && ~ERROR_CODES.indexOf(err.code)) return true;
15178 if (res && res.status && res.status >= 500) return true;
15179 // Superagent timeout
15180 if (err && 'timeout' in err && err.code == 'ECONNABORTED') return true;
15181 return false;
15182};
15183
15184/***/ }),
15185/* 62 */
15186/***/ (function(module, exports) {
15187
15188
15189/**
15190 * Return the mime type for the given `str`.
15191 *
15192 * @param {String} str
15193 * @return {String}
15194 * @api private
15195 */
15196
15197exports.type = function(str){
15198 return str.split(/ *; */).shift();
15199};
15200
15201/**
15202 * Return header field parameters.
15203 *
15204 * @param {String} str
15205 * @return {Object}
15206 * @api private
15207 */
15208
15209exports.params = function(str){
15210 return str.split(/ *; */).reduce(function(obj, str){
15211 var parts = str.split(/ *= */);
15212 var key = parts.shift();
15213 var val = parts.shift();
15214
15215 if (key && val) obj[key] = val;
15216 return obj;
15217 }, {});
15218};
15219
15220/**
15221 * Parse Link header fields.
15222 *
15223 * @param {String} str
15224 * @return {Object}
15225 * @api private
15226 */
15227
15228exports.parseLinks = function(str){
15229 return str.split(/ *, */).reduce(function(obj, str){
15230 var parts = str.split(/ *; */);
15231 var url = parts[0].slice(1, -1);
15232 var rel = parts[1].split(/ *= */)[1].slice(1, -1);
15233 obj[rel] = url;
15234 return obj;
15235 }, {});
15236};
15237
15238/**
15239 * Strip content related fields from `header`.
15240 *
15241 * @param {Object} header
15242 * @return {Object} header
15243 * @api private
15244 */
15245
15246exports.cleanHeader = function(header, shouldStripCookie){
15247 delete header['content-type'];
15248 delete header['content-length'];
15249 delete header['transfer-encoding'];
15250 delete header['host'];
15251 if (shouldStripCookie) {
15252 delete header['cookie'];
15253 }
15254 return header;
15255};
15256
15257/***/ }),
15258/* 63 */
15259/***/ (function(module, exports) {
15260
15261/* (ignored) */
15262
15263/***/ }),
15264/* 64 */
15265/***/ (function(module, exports, __webpack_require__) {
15266
15267"use strict";
15268
15269
15270__webpack_require__(22);
15271
15272module.exports = __webpack_require__(23);
15273
15274/***/ })
15275/******/ ]);
15276});
15277//# sourceMappingURL=av-weapp.js.map