Speedometer: Update Angular 1 TodoMVC example to v1.6.5
[WebKit-https.git] / PerformanceTests / Speedometer / resources / todomvc / architecture-examples / angularjs / node_modules / angular / angular.js
1 /**
2  * @license AngularJS v1.6.5
3  * (c) 2010-2017 Google, Inc. http://angularjs.org
4  * License: MIT
5  */
6 (function(window) {'use strict';
7
8 /* exported
9   minErrConfig,
10   errorHandlingConfig,
11   isValidObjectMaxDepth
12 */
13
14 var minErrConfig = {
15   objectMaxDepth: 5
16 };
17
18 /**
19  * @ngdoc function
20  * @name angular.errorHandlingConfig
21  * @module ng
22  * @kind function
23  *
24  * @description
25  * Configure several aspects of error handling in AngularJS if used as a setter or return the
26  * current configuration if used as a getter. The following options are supported:
27  *
28  * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.
29  *
30  * Omitted or undefined options will leave the corresponding configuration values unchanged.
31  *
32  * @param {Object=} config - The configuration object. May only contain the options that need to be
33  *     updated. Supported keys:
34  *
35  * * `objectMaxDepth`  **{Number}** - The max depth for stringifying objects. Setting to a
36  *   non-positive or non-numeric value, removes the max depth limit.
37  *   Default: 5
38  */
39 function errorHandlingConfig(config) {
40   if (isObject(config)) {
41     if (isDefined(config.objectMaxDepth)) {
42       minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;
43     }
44   } else {
45     return minErrConfig;
46   }
47 }
48
49 /**
50  * @private
51  * @param {Number} maxDepth
52  * @return {boolean}
53  */
54 function isValidObjectMaxDepth(maxDepth) {
55   return isNumber(maxDepth) && maxDepth > 0;
56 }
57
58 /**
59  * @description
60  *
61  * This object provides a utility for producing rich Error messages within
62  * Angular. It can be called as follows:
63  *
64  * var exampleMinErr = minErr('example');
65  * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
66  *
67  * The above creates an instance of minErr in the example namespace. The
68  * resulting error will have a namespaced error code of example.one.  The
69  * resulting error will replace {0} with the value of foo, and {1} with the
70  * value of bar. The object is not restricted in the number of arguments it can
71  * take.
72  *
73  * If fewer arguments are specified than necessary for interpolation, the extra
74  * interpolation markers will be preserved in the final string.
75  *
76  * Since data will be parsed statically during a build step, some restrictions
77  * are applied with respect to how minErr instances are created and called.
78  * Instances should have names of the form namespaceMinErr for a minErr created
79  * using minErr('namespace') . Error codes, namespaces and template strings
80  * should all be static strings, not variables or general expressions.
81  *
82  * @param {string} module The namespace to use for the new minErr instance.
83  * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
84  *   error from returned function, for cases when a particular type of error is useful.
85  * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
86  */
87
88 function minErr(module, ErrorConstructor) {
89   ErrorConstructor = ErrorConstructor || Error;
90   return function() {
91     var code = arguments[0],
92       template = arguments[1],
93       message = '[' + (module ? module + ':' : '') + code + '] ',
94       templateArgs = sliceArgs(arguments, 2).map(function(arg) {
95         return toDebugString(arg, minErrConfig.objectMaxDepth);
96       }),
97       paramPrefix, i;
98
99     message += template.replace(/\{\d+\}/g, function(match) {
100       var index = +match.slice(1, -1);
101
102       if (index < templateArgs.length) {
103         return templateArgs[index];
104       }
105
106       return match;
107     });
108
109     message += '\nhttp://errors.angularjs.org/1.6.5/' +
110       (module ? module + '/' : '') + code;
111
112     for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
113       message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]);
114     }
115
116     return new ErrorConstructor(message);
117   };
118 }
119
120 /* We need to tell ESLint what variables are being exported */
121 /* exported
122   angular,
123   msie,
124   jqLite,
125   jQuery,
126   slice,
127   splice,
128   push,
129   toString,
130   minErrConfig,
131   errorHandlingConfig,
132   isValidObjectMaxDepth,
133   ngMinErr,
134   angularModule,
135   uid,
136   REGEX_STRING_REGEXP,
137   VALIDITY_STATE_PROPERTY,
138
139   lowercase,
140   uppercase,
141   manualLowercase,
142   manualUppercase,
143   nodeName_,
144   isArrayLike,
145   forEach,
146   forEachSorted,
147   reverseParams,
148   nextUid,
149   setHashKey,
150   extend,
151   toInt,
152   inherit,
153   merge,
154   noop,
155   identity,
156   valueFn,
157   isUndefined,
158   isDefined,
159   isObject,
160   isBlankObject,
161   isString,
162   isNumber,
163   isNumberNaN,
164   isDate,
165   isError,
166   isArray,
167   isFunction,
168   isRegExp,
169   isWindow,
170   isScope,
171   isFile,
172   isFormData,
173   isBlob,
174   isBoolean,
175   isPromiseLike,
176   trim,
177   escapeForRegexp,
178   isElement,
179   makeMap,
180   includes,
181   arrayRemove,
182   copy,
183   simpleCompare,
184   equals,
185   csp,
186   jq,
187   concat,
188   sliceArgs,
189   bind,
190   toJsonReplacer,
191   toJson,
192   fromJson,
193   convertTimezoneToLocal,
194   timezoneToOffset,
195   startingTag,
196   tryDecodeURIComponent,
197   parseKeyValue,
198   toKeyValue,
199   encodeUriSegment,
200   encodeUriQuery,
201   angularInit,
202   bootstrap,
203   getTestability,
204   snake_case,
205   bindJQuery,
206   assertArg,
207   assertArgFn,
208   assertNotHasOwnProperty,
209   getter,
210   getBlockNodes,
211   hasOwnProperty,
212   createMap,
213   stringify,
214
215   NODE_TYPE_ELEMENT,
216   NODE_TYPE_ATTRIBUTE,
217   NODE_TYPE_TEXT,
218   NODE_TYPE_COMMENT,
219   NODE_TYPE_DOCUMENT,
220   NODE_TYPE_DOCUMENT_FRAGMENT
221 */
222
223 ////////////////////////////////////
224
225 /**
226  * @ngdoc module
227  * @name ng
228  * @module ng
229  * @installation
230  * @description
231  *
232  * # ng (core module)
233  * The ng module is loaded by default when an AngularJS application is started. The module itself
234  * contains the essential components for an AngularJS application to function. The table below
235  * lists a high level breakdown of each of the services/factories, filters, directives and testing
236  * components available within this core module.
237  *
238  * <div doc-module-components="ng"></div>
239  */
240
241 var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
242
243 // The name of a form control's ValidityState property.
244 // This is used so that it's possible for internal tests to create mock ValidityStates.
245 var VALIDITY_STATE_PROPERTY = 'validity';
246
247
248 var hasOwnProperty = Object.prototype.hasOwnProperty;
249
250 /**
251  * @ngdoc function
252  * @name angular.lowercase
253  * @module ng
254  * @kind function
255  *
256  * @deprecated
257  * sinceVersion="1.5.0"
258  * removeVersion="1.7.0"
259  * Use [String.prototype.toLowerCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) instead.
260  *
261  * @description Converts the specified string to lowercase.
262  * @param {string} string String to be converted to lowercase.
263  * @returns {string} Lowercased string.
264  */
265 var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
266
267 /**
268  * @ngdoc function
269  * @name angular.uppercase
270  * @module ng
271  * @kind function
272  *
273  * @deprecated
274  * sinceVersion="1.5.0"
275  * removeVersion="1.7.0"
276  * Use [String.prototype.toUpperCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) instead.
277  *
278  * @description Converts the specified string to uppercase.
279  * @param {string} string String to be converted to uppercase.
280  * @returns {string} Uppercased string.
281  */
282 var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
283
284
285 var manualLowercase = function(s) {
286   /* eslint-disable no-bitwise */
287   return isString(s)
288       ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
289       : s;
290   /* eslint-enable */
291 };
292 var manualUppercase = function(s) {
293   /* eslint-disable no-bitwise */
294   return isString(s)
295       ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
296       : s;
297   /* eslint-enable */
298 };
299
300
301 // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
302 // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
303 // with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387
304 if ('i' !== 'I'.toLowerCase()) {
305   lowercase = manualLowercase;
306   uppercase = manualUppercase;
307 }
308
309
310 var
311     msie,             // holds major version number for IE, or NaN if UA is not IE.
312     jqLite,           // delay binding since jQuery could be loaded after us.
313     jQuery,           // delay binding
314     slice             = [].slice,
315     splice            = [].splice,
316     push              = [].push,
317     toString          = Object.prototype.toString,
318     getPrototypeOf    = Object.getPrototypeOf,
319     ngMinErr          = minErr('ng'),
320
321     /** @name angular */
322     angular           = window.angular || (window.angular = {}),
323     angularModule,
324     uid               = 0;
325
326 // Support: IE 9-11 only
327 /**
328  * documentMode is an IE-only property
329  * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
330  */
331 msie = window.document.documentMode;
332
333
334 /**
335  * @private
336  * @param {*} obj
337  * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
338  *                   String ...)
339  */
340 function isArrayLike(obj) {
341
342   // `null`, `undefined` and `window` are not array-like
343   if (obj == null || isWindow(obj)) return false;
344
345   // arrays, strings and jQuery/jqLite objects are array like
346   // * jqLite is either the jQuery or jqLite constructor function
347   // * we have to check the existence of jqLite first as this method is called
348   //   via the forEach method when constructing the jqLite object in the first place
349   if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;
350
351   // Support: iOS 8.2 (not reproducible in simulator)
352   // "length" in obj used to prevent JIT error (gh-11508)
353   var length = 'length' in Object(obj) && obj.length;
354
355   // NodeList objects (with `item` method) and
356   // other objects with suitable length characteristics are array-like
357   return isNumber(length) &&
358     (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item === 'function');
359
360 }
361
362 /**
363  * @ngdoc function
364  * @name angular.forEach
365  * @module ng
366  * @kind function
367  *
368  * @description
369  * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
370  * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
371  * is the value of an object property or an array element, `key` is the object property key or
372  * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
373  *
374  * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
375  * using the `hasOwnProperty` method.
376  *
377  * Unlike ES262's
378  * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
379  * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
380  * return the value provided.
381  *
382    ```js
383      var values = {name: 'misko', gender: 'male'};
384      var log = [];
385      angular.forEach(values, function(value, key) {
386        this.push(key + ': ' + value);
387      }, log);
388      expect(log).toEqual(['name: misko', 'gender: male']);
389    ```
390  *
391  * @param {Object|Array} obj Object to iterate over.
392  * @param {Function} iterator Iterator function.
393  * @param {Object=} context Object to become context (`this`) for the iterator function.
394  * @returns {Object|Array} Reference to `obj`.
395  */
396
397 function forEach(obj, iterator, context) {
398   var key, length;
399   if (obj) {
400     if (isFunction(obj)) {
401       for (key in obj) {
402         if (key !== 'prototype' && key !== 'length' && key !== 'name' && obj.hasOwnProperty(key)) {
403           iterator.call(context, obj[key], key, obj);
404         }
405       }
406     } else if (isArray(obj) || isArrayLike(obj)) {
407       var isPrimitive = typeof obj !== 'object';
408       for (key = 0, length = obj.length; key < length; key++) {
409         if (isPrimitive || key in obj) {
410           iterator.call(context, obj[key], key, obj);
411         }
412       }
413     } else if (obj.forEach && obj.forEach !== forEach) {
414         obj.forEach(iterator, context, obj);
415     } else if (isBlankObject(obj)) {
416       // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
417       for (key in obj) {
418         iterator.call(context, obj[key], key, obj);
419       }
420     } else if (typeof obj.hasOwnProperty === 'function') {
421       // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
422       for (key in obj) {
423         if (obj.hasOwnProperty(key)) {
424           iterator.call(context, obj[key], key, obj);
425         }
426       }
427     } else {
428       // Slow path for objects which do not have a method `hasOwnProperty`
429       for (key in obj) {
430         if (hasOwnProperty.call(obj, key)) {
431           iterator.call(context, obj[key], key, obj);
432         }
433       }
434     }
435   }
436   return obj;
437 }
438
439 function forEachSorted(obj, iterator, context) {
440   var keys = Object.keys(obj).sort();
441   for (var i = 0; i < keys.length; i++) {
442     iterator.call(context, obj[keys[i]], keys[i]);
443   }
444   return keys;
445 }
446
447
448 /**
449  * when using forEach the params are value, key, but it is often useful to have key, value.
450  * @param {function(string, *)} iteratorFn
451  * @returns {function(*, string)}
452  */
453 function reverseParams(iteratorFn) {
454   return function(value, key) {iteratorFn(key, value);};
455 }
456
457 /**
458  * A consistent way of creating unique IDs in angular.
459  *
460  * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
461  * we hit number precision issues in JavaScript.
462  *
463  * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
464  *
465  * @returns {number} an unique alpha-numeric string
466  */
467 function nextUid() {
468   return ++uid;
469 }
470
471
472 /**
473  * Set or clear the hashkey for an object.
474  * @param obj object
475  * @param h the hashkey (!truthy to delete the hashkey)
476  */
477 function setHashKey(obj, h) {
478   if (h) {
479     obj.$$hashKey = h;
480   } else {
481     delete obj.$$hashKey;
482   }
483 }
484
485
486 function baseExtend(dst, objs, deep) {
487   var h = dst.$$hashKey;
488
489   for (var i = 0, ii = objs.length; i < ii; ++i) {
490     var obj = objs[i];
491     if (!isObject(obj) && !isFunction(obj)) continue;
492     var keys = Object.keys(obj);
493     for (var j = 0, jj = keys.length; j < jj; j++) {
494       var key = keys[j];
495       var src = obj[key];
496
497       if (deep && isObject(src)) {
498         if (isDate(src)) {
499           dst[key] = new Date(src.valueOf());
500         } else if (isRegExp(src)) {
501           dst[key] = new RegExp(src);
502         } else if (src.nodeName) {
503           dst[key] = src.cloneNode(true);
504         } else if (isElement(src)) {
505           dst[key] = src.clone();
506         } else {
507           if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
508           baseExtend(dst[key], [src], true);
509         }
510       } else {
511         dst[key] = src;
512       }
513     }
514   }
515
516   setHashKey(dst, h);
517   return dst;
518 }
519
520 /**
521  * @ngdoc function
522  * @name angular.extend
523  * @module ng
524  * @kind function
525  *
526  * @description
527  * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
528  * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
529  * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
530  *
531  * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use
532  * {@link angular.merge} for this.
533  *
534  * @param {Object} dst Destination object.
535  * @param {...Object} src Source object(s).
536  * @returns {Object} Reference to `dst`.
537  */
538 function extend(dst) {
539   return baseExtend(dst, slice.call(arguments, 1), false);
540 }
541
542
543 /**
544 * @ngdoc function
545 * @name angular.merge
546 * @module ng
547 * @kind function
548 *
549 * @description
550 * Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
551 * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
552 * by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.
553 *
554 * Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source
555 * objects, performing a deep copy.
556 *
557 * @deprecated
558 * sinceVersion="1.6.5"
559 * This function is deprecated, but will not be removed in the 1.x lifecycle.
560 * There are edge cases (see {@link angular.merge#known-issues known issues}) that are not
561 * supported by this function. We suggest
562 * using [lodash's merge()](https://lodash.com/docs/4.17.4#merge) instead.
563 *
564 * @knownIssue
565 * This is a list of (known) object types that are not handled correctly by this function:
566 * - [`Blob`](https://developer.mozilla.org/docs/Web/API/Blob)
567 * - [`MediaStream`](https://developer.mozilla.org/docs/Web/API/MediaStream)
568 * - [`CanvasGradient`](https://developer.mozilla.org/docs/Web/API/CanvasGradient)
569 * - AngularJS {@link $rootScope.Scope scopes};
570 *
571 * @param {Object} dst Destination object.
572 * @param {...Object} src Source object(s).
573 * @returns {Object} Reference to `dst`.
574 */
575 function merge(dst) {
576   return baseExtend(dst, slice.call(arguments, 1), true);
577 }
578
579
580
581 function toInt(str) {
582   return parseInt(str, 10);
583 }
584
585 var isNumberNaN = Number.isNaN || function isNumberNaN(num) {
586   // eslint-disable-next-line no-self-compare
587   return num !== num;
588 };
589
590
591 function inherit(parent, extra) {
592   return extend(Object.create(parent), extra);
593 }
594
595 /**
596  * @ngdoc function
597  * @name angular.noop
598  * @module ng
599  * @kind function
600  *
601  * @description
602  * A function that performs no operations. This function can be useful when writing code in the
603  * functional style.
604    ```js
605      function foo(callback) {
606        var result = calculateResult();
607        (callback || angular.noop)(result);
608      }
609    ```
610  */
611 function noop() {}
612 noop.$inject = [];
613
614
615 /**
616  * @ngdoc function
617  * @name angular.identity
618  * @module ng
619  * @kind function
620  *
621  * @description
622  * A function that returns its first argument. This function is useful when writing code in the
623  * functional style.
624  *
625    ```js
626    function transformer(transformationFn, value) {
627      return (transformationFn || angular.identity)(value);
628    };
629
630    // E.g.
631    function getResult(fn, input) {
632      return (fn || angular.identity)(input);
633    };
634
635    getResult(function(n) { return n * 2; }, 21);   // returns 42
636    getResult(null, 21);                            // returns 21
637    getResult(undefined, 21);                       // returns 21
638    ```
639  *
640  * @param {*} value to be returned.
641  * @returns {*} the value passed in.
642  */
643 function identity($) {return $;}
644 identity.$inject = [];
645
646
647 function valueFn(value) {return function valueRef() {return value;};}
648
649 function hasCustomToString(obj) {
650   return isFunction(obj.toString) && obj.toString !== toString;
651 }
652
653
654 /**
655  * @ngdoc function
656  * @name angular.isUndefined
657  * @module ng
658  * @kind function
659  *
660  * @description
661  * Determines if a reference is undefined.
662  *
663  * @param {*} value Reference to check.
664  * @returns {boolean} True if `value` is undefined.
665  */
666 function isUndefined(value) {return typeof value === 'undefined';}
667
668
669 /**
670  * @ngdoc function
671  * @name angular.isDefined
672  * @module ng
673  * @kind function
674  *
675  * @description
676  * Determines if a reference is defined.
677  *
678  * @param {*} value Reference to check.
679  * @returns {boolean} True if `value` is defined.
680  */
681 function isDefined(value) {return typeof value !== 'undefined';}
682
683
684 /**
685  * @ngdoc function
686  * @name angular.isObject
687  * @module ng
688  * @kind function
689  *
690  * @description
691  * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
692  * considered to be objects. Note that JavaScript arrays are objects.
693  *
694  * @param {*} value Reference to check.
695  * @returns {boolean} True if `value` is an `Object` but not `null`.
696  */
697 function isObject(value) {
698   // http://jsperf.com/isobject4
699   return value !== null && typeof value === 'object';
700 }
701
702
703 /**
704  * Determine if a value is an object with a null prototype
705  *
706  * @returns {boolean} True if `value` is an `Object` with a null prototype
707  */
708 function isBlankObject(value) {
709   return value !== null && typeof value === 'object' && !getPrototypeOf(value);
710 }
711
712
713 /**
714  * @ngdoc function
715  * @name angular.isString
716  * @module ng
717  * @kind function
718  *
719  * @description
720  * Determines if a reference is a `String`.
721  *
722  * @param {*} value Reference to check.
723  * @returns {boolean} True if `value` is a `String`.
724  */
725 function isString(value) {return typeof value === 'string';}
726
727
728 /**
729  * @ngdoc function
730  * @name angular.isNumber
731  * @module ng
732  * @kind function
733  *
734  * @description
735  * Determines if a reference is a `Number`.
736  *
737  * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
738  *
739  * If you wish to exclude these then you can use the native
740  * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
741  * method.
742  *
743  * @param {*} value Reference to check.
744  * @returns {boolean} True if `value` is a `Number`.
745  */
746 function isNumber(value) {return typeof value === 'number';}
747
748
749 /**
750  * @ngdoc function
751  * @name angular.isDate
752  * @module ng
753  * @kind function
754  *
755  * @description
756  * Determines if a value is a date.
757  *
758  * @param {*} value Reference to check.
759  * @returns {boolean} True if `value` is a `Date`.
760  */
761 function isDate(value) {
762   return toString.call(value) === '[object Date]';
763 }
764
765
766 /**
767  * @ngdoc function
768  * @name angular.isArray
769  * @module ng
770  * @kind function
771  *
772  * @description
773  * Determines if a reference is an `Array`. Alias of Array.isArray.
774  *
775  * @param {*} value Reference to check.
776  * @returns {boolean} True if `value` is an `Array`.
777  */
778 var isArray = Array.isArray;
779
780 /**
781  * @description
782  * Determines if a reference is an `Error`.
783  * Loosely based on https://www.npmjs.com/package/iserror
784  *
785  * @param {*} value Reference to check.
786  * @returns {boolean} True if `value` is an `Error`.
787  */
788 function isError(value) {
789   var tag = toString.call(value);
790   switch (tag) {
791     case '[object Error]': return true;
792     case '[object Exception]': return true;
793     case '[object DOMException]': return true;
794     default: return value instanceof Error;
795   }
796 }
797
798 /**
799  * @ngdoc function
800  * @name angular.isFunction
801  * @module ng
802  * @kind function
803  *
804  * @description
805  * Determines if a reference is a `Function`.
806  *
807  * @param {*} value Reference to check.
808  * @returns {boolean} True if `value` is a `Function`.
809  */
810 function isFunction(value) {return typeof value === 'function';}
811
812
813 /**
814  * Determines if a value is a regular expression object.
815  *
816  * @private
817  * @param {*} value Reference to check.
818  * @returns {boolean} True if `value` is a `RegExp`.
819  */
820 function isRegExp(value) {
821   return toString.call(value) === '[object RegExp]';
822 }
823
824
825 /**
826  * Checks if `obj` is a window object.
827  *
828  * @private
829  * @param {*} obj Object to check
830  * @returns {boolean} True if `obj` is a window obj.
831  */
832 function isWindow(obj) {
833   return obj && obj.window === obj;
834 }
835
836
837 function isScope(obj) {
838   return obj && obj.$evalAsync && obj.$watch;
839 }
840
841
842 function isFile(obj) {
843   return toString.call(obj) === '[object File]';
844 }
845
846
847 function isFormData(obj) {
848   return toString.call(obj) === '[object FormData]';
849 }
850
851
852 function isBlob(obj) {
853   return toString.call(obj) === '[object Blob]';
854 }
855
856
857 function isBoolean(value) {
858   return typeof value === 'boolean';
859 }
860
861
862 function isPromiseLike(obj) {
863   return obj && isFunction(obj.then);
864 }
865
866
867 var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array]$/;
868 function isTypedArray(value) {
869   return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));
870 }
871
872 function isArrayBuffer(obj) {
873   return toString.call(obj) === '[object ArrayBuffer]';
874 }
875
876
877 var trim = function(value) {
878   return isString(value) ? value.trim() : value;
879 };
880
881 // Copied from:
882 // http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
883 // Prereq: s is a string.
884 var escapeForRegexp = function(s) {
885   return s
886     .replace(/([-()[\]{}+?*.$^|,:#<!\\])/g, '\\$1')
887     // eslint-disable-next-line no-control-regex
888     .replace(/\x08/g, '\\x08');
889 };
890
891
892 /**
893  * @ngdoc function
894  * @name angular.isElement
895  * @module ng
896  * @kind function
897  *
898  * @description
899  * Determines if a reference is a DOM element (or wrapped jQuery element).
900  *
901  * @param {*} value Reference to check.
902  * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
903  */
904 function isElement(node) {
905   return !!(node &&
906     (node.nodeName  // We are a direct element.
907     || (node.prop && node.attr && node.find)));  // We have an on and find method part of jQuery API.
908 }
909
910 /**
911  * @param str 'key1,key2,...'
912  * @returns {object} in the form of {key1:true, key2:true, ...}
913  */
914 function makeMap(str) {
915   var obj = {}, items = str.split(','), i;
916   for (i = 0; i < items.length; i++) {
917     obj[items[i]] = true;
918   }
919   return obj;
920 }
921
922
923 function nodeName_(element) {
924   return lowercase(element.nodeName || (element[0] && element[0].nodeName));
925 }
926
927 function includes(array, obj) {
928   return Array.prototype.indexOf.call(array, obj) !== -1;
929 }
930
931 function arrayRemove(array, value) {
932   var index = array.indexOf(value);
933   if (index >= 0) {
934     array.splice(index, 1);
935   }
936   return index;
937 }
938
939 /**
940  * @ngdoc function
941  * @name angular.copy
942  * @module ng
943  * @kind function
944  *
945  * @description
946  * Creates a deep copy of `source`, which should be an object or an array.
947  *
948  * * If no destination is supplied, a copy of the object or array is created.
949  * * If a destination is provided, all of its elements (for arrays) or properties (for objects)
950  *   are deleted and then all elements/properties from the source are copied to it.
951  * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
952  * * If `source` is identical to `destination` an exception will be thrown.
953  *
954  * <br />
955  * <div class="alert alert-warning">
956  *   Only enumerable properties are taken into account. Non-enumerable properties (both on `source`
957  *   and on `destination`) will be ignored.
958  * </div>
959  *
960  * @param {*} source The source that will be used to make a copy.
961  *                   Can be any type, including primitives, `null`, and `undefined`.
962  * @param {(Object|Array)=} destination Destination into which the source is copied. If
963  *     provided, must be of the same type as `source`.
964  * @returns {*} The copy or updated `destination`, if `destination` was specified.
965  *
966  * @example
967   <example module="copyExample" name="angular-copy">
968     <file name="index.html">
969       <div ng-controller="ExampleController">
970         <form novalidate class="simple-form">
971           <label>Name: <input type="text" ng-model="user.name" /></label><br />
972           <label>Age:  <input type="number" ng-model="user.age" /></label><br />
973           Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
974                   <label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
975           <button ng-click="reset()">RESET</button>
976           <button ng-click="update(user)">SAVE</button>
977         </form>
978         <pre>form = {{user | json}}</pre>
979         <pre>master = {{master | json}}</pre>
980       </div>
981     </file>
982     <file name="script.js">
983       // Module: copyExample
984       angular.
985         module('copyExample', []).
986         controller('ExampleController', ['$scope', function($scope) {
987           $scope.master = {};
988
989           $scope.reset = function() {
990             // Example with 1 argument
991             $scope.user = angular.copy($scope.master);
992           };
993
994           $scope.update = function(user) {
995             // Example with 2 arguments
996             angular.copy(user, $scope.master);
997           };
998
999           $scope.reset();
1000         }]);
1001     </file>
1002   </example>
1003  */
1004 function copy(source, destination, maxDepth) {
1005   var stackSource = [];
1006   var stackDest = [];
1007   maxDepth = isValidObjectMaxDepth(maxDepth) ? maxDepth : NaN;
1008
1009   if (destination) {
1010     if (isTypedArray(destination) || isArrayBuffer(destination)) {
1011       throw ngMinErr('cpta', 'Can\'t copy! TypedArray destination cannot be mutated.');
1012     }
1013     if (source === destination) {
1014       throw ngMinErr('cpi', 'Can\'t copy! Source and destination are identical.');
1015     }
1016
1017     // Empty the destination object
1018     if (isArray(destination)) {
1019       destination.length = 0;
1020     } else {
1021       forEach(destination, function(value, key) {
1022         if (key !== '$$hashKey') {
1023           delete destination[key];
1024         }
1025       });
1026     }
1027
1028     stackSource.push(source);
1029     stackDest.push(destination);
1030     return copyRecurse(source, destination, maxDepth);
1031   }
1032
1033   return copyElement(source, maxDepth);
1034
1035   function copyRecurse(source, destination, maxDepth) {
1036     maxDepth--;
1037     if (maxDepth < 0) {
1038       return '...';
1039     }
1040     var h = destination.$$hashKey;
1041     var key;
1042     if (isArray(source)) {
1043       for (var i = 0, ii = source.length; i < ii; i++) {
1044         destination.push(copyElement(source[i], maxDepth));
1045       }
1046     } else if (isBlankObject(source)) {
1047       // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
1048       for (key in source) {
1049         destination[key] = copyElement(source[key], maxDepth);
1050       }
1051     } else if (source && typeof source.hasOwnProperty === 'function') {
1052       // Slow path, which must rely on hasOwnProperty
1053       for (key in source) {
1054         if (source.hasOwnProperty(key)) {
1055           destination[key] = copyElement(source[key], maxDepth);
1056         }
1057       }
1058     } else {
1059       // Slowest path --- hasOwnProperty can't be called as a method
1060       for (key in source) {
1061         if (hasOwnProperty.call(source, key)) {
1062           destination[key] = copyElement(source[key], maxDepth);
1063         }
1064       }
1065     }
1066     setHashKey(destination, h);
1067     return destination;
1068   }
1069
1070   function copyElement(source, maxDepth) {
1071     // Simple values
1072     if (!isObject(source)) {
1073       return source;
1074     }
1075
1076     // Already copied values
1077     var index = stackSource.indexOf(source);
1078     if (index !== -1) {
1079       return stackDest[index];
1080     }
1081
1082     if (isWindow(source) || isScope(source)) {
1083       throw ngMinErr('cpws',
1084         'Can\'t copy! Making copies of Window or Scope instances is not supported.');
1085     }
1086
1087     var needsRecurse = false;
1088     var destination = copyType(source);
1089
1090     if (destination === undefined) {
1091       destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
1092       needsRecurse = true;
1093     }
1094
1095     stackSource.push(source);
1096     stackDest.push(destination);
1097
1098     return needsRecurse
1099       ? copyRecurse(source, destination, maxDepth)
1100       : destination;
1101   }
1102
1103   function copyType(source) {
1104     switch (toString.call(source)) {
1105       case '[object Int8Array]':
1106       case '[object Int16Array]':
1107       case '[object Int32Array]':
1108       case '[object Float32Array]':
1109       case '[object Float64Array]':
1110       case '[object Uint8Array]':
1111       case '[object Uint8ClampedArray]':
1112       case '[object Uint16Array]':
1113       case '[object Uint32Array]':
1114         return new source.constructor(copyElement(source.buffer), source.byteOffset, source.length);
1115
1116       case '[object ArrayBuffer]':
1117         // Support: IE10
1118         if (!source.slice) {
1119           // If we're in this case we know the environment supports ArrayBuffer
1120           /* eslint-disable no-undef */
1121           var copied = new ArrayBuffer(source.byteLength);
1122           new Uint8Array(copied).set(new Uint8Array(source));
1123           /* eslint-enable */
1124           return copied;
1125         }
1126         return source.slice(0);
1127
1128       case '[object Boolean]':
1129       case '[object Number]':
1130       case '[object String]':
1131       case '[object Date]':
1132         return new source.constructor(source.valueOf());
1133
1134       case '[object RegExp]':
1135         var re = new RegExp(source.source, source.toString().match(/[^/]*$/)[0]);
1136         re.lastIndex = source.lastIndex;
1137         return re;
1138
1139       case '[object Blob]':
1140         return new source.constructor([source], {type: source.type});
1141     }
1142
1143     if (isFunction(source.cloneNode)) {
1144       return source.cloneNode(true);
1145     }
1146   }
1147 }
1148
1149
1150 // eslint-disable-next-line no-self-compare
1151 function simpleCompare(a, b) { return a === b || (a !== a && b !== b); }
1152
1153
1154 /**
1155  * @ngdoc function
1156  * @name angular.equals
1157  * @module ng
1158  * @kind function
1159  *
1160  * @description
1161  * Determines if two objects or two values are equivalent. Supports value types, regular
1162  * expressions, arrays and objects.
1163  *
1164  * Two objects or values are considered equivalent if at least one of the following is true:
1165  *
1166  * * Both objects or values pass `===` comparison.
1167  * * Both objects or values are of the same type and all of their properties are equal by
1168  *   comparing them with `angular.equals`.
1169  * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
1170  * * Both values represent the same regular expression (In JavaScript,
1171  *   /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
1172  *   representation matches).
1173  *
1174  * During a property comparison, properties of `function` type and properties with names
1175  * that begin with `$` are ignored.
1176  *
1177  * Scope and DOMWindow objects are being compared only by identify (`===`).
1178  *
1179  * @param {*} o1 Object or value to compare.
1180  * @param {*} o2 Object or value to compare.
1181  * @returns {boolean} True if arguments are equal.
1182  *
1183  * @example
1184    <example module="equalsExample" name="equalsExample">
1185      <file name="index.html">
1186       <div ng-controller="ExampleController">
1187         <form novalidate>
1188           <h3>User 1</h3>
1189           Name: <input type="text" ng-model="user1.name">
1190           Age: <input type="number" ng-model="user1.age">
1191
1192           <h3>User 2</h3>
1193           Name: <input type="text" ng-model="user2.name">
1194           Age: <input type="number" ng-model="user2.age">
1195
1196           <div>
1197             <br/>
1198             <input type="button" value="Compare" ng-click="compare()">
1199           </div>
1200           User 1: <pre>{{user1 | json}}</pre>
1201           User 2: <pre>{{user2 | json}}</pre>
1202           Equal: <pre>{{result}}</pre>
1203         </form>
1204       </div>
1205     </file>
1206     <file name="script.js">
1207         angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) {
1208           $scope.user1 = {};
1209           $scope.user2 = {};
1210           $scope.compare = function() {
1211             $scope.result = angular.equals($scope.user1, $scope.user2);
1212           };
1213         }]);
1214     </file>
1215   </example>
1216  */
1217 function equals(o1, o2) {
1218   if (o1 === o2) return true;
1219   if (o1 === null || o2 === null) return false;
1220   // eslint-disable-next-line no-self-compare
1221   if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
1222   var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
1223   if (t1 === t2 && t1 === 'object') {
1224     if (isArray(o1)) {
1225       if (!isArray(o2)) return false;
1226       if ((length = o1.length) === o2.length) {
1227         for (key = 0; key < length; key++) {
1228           if (!equals(o1[key], o2[key])) return false;
1229         }
1230         return true;
1231       }
1232     } else if (isDate(o1)) {
1233       if (!isDate(o2)) return false;
1234       return simpleCompare(o1.getTime(), o2.getTime());
1235     } else if (isRegExp(o1)) {
1236       if (!isRegExp(o2)) return false;
1237       return o1.toString() === o2.toString();
1238     } else {
1239       if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
1240         isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
1241       keySet = createMap();
1242       for (key in o1) {
1243         if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
1244         if (!equals(o1[key], o2[key])) return false;
1245         keySet[key] = true;
1246       }
1247       for (key in o2) {
1248         if (!(key in keySet) &&
1249             key.charAt(0) !== '$' &&
1250             isDefined(o2[key]) &&
1251             !isFunction(o2[key])) return false;
1252       }
1253       return true;
1254     }
1255   }
1256   return false;
1257 }
1258
1259 var csp = function() {
1260   if (!isDefined(csp.rules)) {
1261
1262
1263     var ngCspElement = (window.document.querySelector('[ng-csp]') ||
1264                     window.document.querySelector('[data-ng-csp]'));
1265
1266     if (ngCspElement) {
1267       var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
1268                     ngCspElement.getAttribute('data-ng-csp');
1269       csp.rules = {
1270         noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),
1271         noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)
1272       };
1273     } else {
1274       csp.rules = {
1275         noUnsafeEval: noUnsafeEval(),
1276         noInlineStyle: false
1277       };
1278     }
1279   }
1280
1281   return csp.rules;
1282
1283   function noUnsafeEval() {
1284     try {
1285       // eslint-disable-next-line no-new, no-new-func
1286       new Function('');
1287       return false;
1288     } catch (e) {
1289       return true;
1290     }
1291   }
1292 };
1293
1294 /**
1295  * @ngdoc directive
1296  * @module ng
1297  * @name ngJq
1298  *
1299  * @element ANY
1300  * @param {string=} ngJq the name of the library available under `window`
1301  * to be used for angular.element
1302  * @description
1303  * Use this directive to force the angular.element library.  This should be
1304  * used to force either jqLite by leaving ng-jq blank or setting the name of
1305  * the jquery variable under window (eg. jQuery).
1306  *
1307  * Since angular looks for this directive when it is loaded (doesn't wait for the
1308  * DOMContentLoaded event), it must be placed on an element that comes before the script
1309  * which loads angular. Also, only the first instance of `ng-jq` will be used and all
1310  * others ignored.
1311  *
1312  * @example
1313  * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
1314  ```html
1315  <!doctype html>
1316  <html ng-app ng-jq>
1317  ...
1318  ...
1319  </html>
1320  ```
1321  * @example
1322  * This example shows how to use a jQuery based library of a different name.
1323  * The library name must be available at the top most 'window'.
1324  ```html
1325  <!doctype html>
1326  <html ng-app ng-jq="jQueryLib">
1327  ...
1328  ...
1329  </html>
1330  ```
1331  */
1332 var jq = function() {
1333   if (isDefined(jq.name_)) return jq.name_;
1334   var el;
1335   var i, ii = ngAttrPrefixes.length, prefix, name;
1336   for (i = 0; i < ii; ++i) {
1337     prefix = ngAttrPrefixes[i];
1338     el = window.document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]');
1339     if (el) {
1340       name = el.getAttribute(prefix + 'jq');
1341       break;
1342     }
1343   }
1344
1345   return (jq.name_ = name);
1346 };
1347
1348 function concat(array1, array2, index) {
1349   return array1.concat(slice.call(array2, index));
1350 }
1351
1352 function sliceArgs(args, startIndex) {
1353   return slice.call(args, startIndex || 0);
1354 }
1355
1356
1357 /**
1358  * @ngdoc function
1359  * @name angular.bind
1360  * @module ng
1361  * @kind function
1362  *
1363  * @description
1364  * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
1365  * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
1366  * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
1367  * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
1368  *
1369  * @param {Object} self Context which `fn` should be evaluated in.
1370  * @param {function()} fn Function to be bound.
1371  * @param {...*} args Optional arguments to be prebound to the `fn` function call.
1372  * @returns {function()} Function that wraps the `fn` with all the specified bindings.
1373  */
1374 function bind(self, fn) {
1375   var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
1376   if (isFunction(fn) && !(fn instanceof RegExp)) {
1377     return curryArgs.length
1378       ? function() {
1379           return arguments.length
1380             ? fn.apply(self, concat(curryArgs, arguments, 0))
1381             : fn.apply(self, curryArgs);
1382         }
1383       : function() {
1384           return arguments.length
1385             ? fn.apply(self, arguments)
1386             : fn.call(self);
1387         };
1388   } else {
1389     // In IE, native methods are not functions so they cannot be bound (note: they don't need to be).
1390     return fn;
1391   }
1392 }
1393
1394
1395 function toJsonReplacer(key, value) {
1396   var val = value;
1397
1398   if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
1399     val = undefined;
1400   } else if (isWindow(value)) {
1401     val = '$WINDOW';
1402   } else if (value &&  window.document === value) {
1403     val = '$DOCUMENT';
1404   } else if (isScope(value)) {
1405     val = '$SCOPE';
1406   }
1407
1408   return val;
1409 }
1410
1411
1412 /**
1413  * @ngdoc function
1414  * @name angular.toJson
1415  * @module ng
1416  * @kind function
1417  *
1418  * @description
1419  * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
1420  * stripped since angular uses this notation internally.
1421  *
1422  * @param {Object|Array|Date|string|number|boolean} obj Input to be serialized into JSON.
1423  * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
1424  *    If set to an integer, the JSON output will contain that many spaces per indentation.
1425  * @returns {string|undefined} JSON-ified string representing `obj`.
1426  * @knownIssue
1427  *
1428  * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date`
1429  * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the
1430  * `Date.prototype.toJSON` method as follows:
1431  *
1432  * ```
1433  * var _DatetoJSON = Date.prototype.toJSON;
1434  * Date.prototype.toJSON = function() {
1435  *   try {
1436  *     return _DatetoJSON.call(this);
1437  *   } catch(e) {
1438  *     if (e instanceof RangeError) {
1439  *       return null;
1440  *     }
1441  *     throw e;
1442  *   }
1443  * };
1444  * ```
1445  *
1446  * See https://github.com/angular/angular.js/pull/14221 for more information.
1447  */
1448 function toJson(obj, pretty) {
1449   if (isUndefined(obj)) return undefined;
1450   if (!isNumber(pretty)) {
1451     pretty = pretty ? 2 : null;
1452   }
1453   return JSON.stringify(obj, toJsonReplacer, pretty);
1454 }
1455
1456
1457 /**
1458  * @ngdoc function
1459  * @name angular.fromJson
1460  * @module ng
1461  * @kind function
1462  *
1463  * @description
1464  * Deserializes a JSON string.
1465  *
1466  * @param {string} json JSON string to deserialize.
1467  * @returns {Object|Array|string|number} Deserialized JSON string.
1468  */
1469 function fromJson(json) {
1470   return isString(json)
1471       ? JSON.parse(json)
1472       : json;
1473 }
1474
1475
1476 var ALL_COLONS = /:/g;
1477 function timezoneToOffset(timezone, fallback) {
1478   // Support: IE 9-11 only, Edge 13-15+
1479   // IE/Edge do not "understand" colon (`:`) in timezone
1480   timezone = timezone.replace(ALL_COLONS, '');
1481   var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
1482   return isNumberNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
1483 }
1484
1485
1486 function addDateMinutes(date, minutes) {
1487   date = new Date(date.getTime());
1488   date.setMinutes(date.getMinutes() + minutes);
1489   return date;
1490 }
1491
1492
1493 function convertTimezoneToLocal(date, timezone, reverse) {
1494   reverse = reverse ? -1 : 1;
1495   var dateTimezoneOffset = date.getTimezoneOffset();
1496   var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
1497   return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));
1498 }
1499
1500
1501 /**
1502  * @returns {string} Returns the string representation of the element.
1503  */
1504 function startingTag(element) {
1505   element = jqLite(element).clone().empty();
1506   var elemHtml = jqLite('<div>').append(element).html();
1507   try {
1508     return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
1509         elemHtml.
1510           match(/^(<[^>]+>)/)[1].
1511           replace(/^<([\w-]+)/, function(match, nodeName) {return '<' + lowercase(nodeName);});
1512   } catch (e) {
1513     return lowercase(elemHtml);
1514   }
1515
1516 }
1517
1518
1519 /////////////////////////////////////////////////
1520
1521 /**
1522  * Tries to decode the URI component without throwing an exception.
1523  *
1524  * @private
1525  * @param str value potential URI component to check.
1526  * @returns {boolean} True if `value` can be decoded
1527  * with the decodeURIComponent function.
1528  */
1529 function tryDecodeURIComponent(value) {
1530   try {
1531     return decodeURIComponent(value);
1532   } catch (e) {
1533     // Ignore any invalid uri component.
1534   }
1535 }
1536
1537
1538 /**
1539  * Parses an escaped url query string into key-value pairs.
1540  * @returns {Object.<string,boolean|Array>}
1541  */
1542 function parseKeyValue(/**string*/keyValue) {
1543   var obj = {};
1544   forEach((keyValue || '').split('&'), function(keyValue) {
1545     var splitPoint, key, val;
1546     if (keyValue) {
1547       key = keyValue = keyValue.replace(/\+/g,'%20');
1548       splitPoint = keyValue.indexOf('=');
1549       if (splitPoint !== -1) {
1550         key = keyValue.substring(0, splitPoint);
1551         val = keyValue.substring(splitPoint + 1);
1552       }
1553       key = tryDecodeURIComponent(key);
1554       if (isDefined(key)) {
1555         val = isDefined(val) ? tryDecodeURIComponent(val) : true;
1556         if (!hasOwnProperty.call(obj, key)) {
1557           obj[key] = val;
1558         } else if (isArray(obj[key])) {
1559           obj[key].push(val);
1560         } else {
1561           obj[key] = [obj[key],val];
1562         }
1563       }
1564     }
1565   });
1566   return obj;
1567 }
1568
1569 function toKeyValue(obj) {
1570   var parts = [];
1571   forEach(obj, function(value, key) {
1572     if (isArray(value)) {
1573       forEach(value, function(arrayValue) {
1574         parts.push(encodeUriQuery(key, true) +
1575                    (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
1576       });
1577     } else {
1578     parts.push(encodeUriQuery(key, true) +
1579                (value === true ? '' : '=' + encodeUriQuery(value, true)));
1580     }
1581   });
1582   return parts.length ? parts.join('&') : '';
1583 }
1584
1585
1586 /**
1587  * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
1588  * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
1589  * segments:
1590  *    segment       = *pchar
1591  *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
1592  *    pct-encoded   = "%" HEXDIG HEXDIG
1593  *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
1594  *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
1595  *                     / "*" / "+" / "," / ";" / "="
1596  */
1597 function encodeUriSegment(val) {
1598   return encodeUriQuery(val, true).
1599              replace(/%26/gi, '&').
1600              replace(/%3D/gi, '=').
1601              replace(/%2B/gi, '+');
1602 }
1603
1604
1605 /**
1606  * This method is intended for encoding *key* or *value* parts of query component. We need a custom
1607  * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
1608  * encoded per http://tools.ietf.org/html/rfc3986:
1609  *    query         = *( pchar / "/" / "?" )
1610  *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
1611  *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
1612  *    pct-encoded   = "%" HEXDIG HEXDIG
1613  *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
1614  *                     / "*" / "+" / "," / ";" / "="
1615  */
1616 function encodeUriQuery(val, pctEncodeSpaces) {
1617   return encodeURIComponent(val).
1618              replace(/%40/gi, '@').
1619              replace(/%3A/gi, ':').
1620              replace(/%24/g, '$').
1621              replace(/%2C/gi, ',').
1622              replace(/%3B/gi, ';').
1623              replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
1624 }
1625
1626 var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
1627
1628 function getNgAttribute(element, ngAttr) {
1629   var attr, i, ii = ngAttrPrefixes.length;
1630   for (i = 0; i < ii; ++i) {
1631     attr = ngAttrPrefixes[i] + ngAttr;
1632     if (isString(attr = element.getAttribute(attr))) {
1633       return attr;
1634     }
1635   }
1636   return null;
1637 }
1638
1639 function allowAutoBootstrap(document) {
1640   var script = document.currentScript;
1641
1642   if (!script) {
1643     // Support: IE 9-11 only
1644     // IE does not have `document.currentScript`
1645     return true;
1646   }
1647
1648   // If the `currentScript` property has been clobbered just return false, since this indicates a probable attack
1649   if (!(script instanceof window.HTMLScriptElement || script instanceof window.SVGScriptElement)) {
1650     return false;
1651   }
1652
1653   var attributes = script.attributes;
1654   var srcs = [attributes.getNamedItem('src'), attributes.getNamedItem('href'), attributes.getNamedItem('xlink:href')];
1655
1656   return srcs.every(function(src) {
1657     if (!src) {
1658       return true;
1659     }
1660     if (!src.value) {
1661       return false;
1662     }
1663
1664     var link = document.createElement('a');
1665     link.href = src.value;
1666
1667     if (document.location.origin === link.origin) {
1668       // Same-origin resources are always allowed, even for non-whitelisted schemes.
1669       return true;
1670     }
1671     // Disabled bootstrapping unless angular.js was loaded from a known scheme used on the web.
1672     // This is to prevent angular.js bundled with browser extensions from being used to bypass the
1673     // content security policy in web pages and other browser extensions.
1674     switch (link.protocol) {
1675       case 'http:':
1676       case 'https:':
1677       case 'ftp:':
1678       case 'blob:':
1679       case 'file:':
1680       case 'data:':
1681         return true;
1682       default:
1683         return false;
1684     }
1685   });
1686 }
1687
1688 // Cached as it has to run during loading so that document.currentScript is available.
1689 var isAutoBootstrapAllowed = allowAutoBootstrap(window.document);
1690
1691 /**
1692  * @ngdoc directive
1693  * @name ngApp
1694  * @module ng
1695  *
1696  * @element ANY
1697  * @param {angular.Module} ngApp an optional application
1698  *   {@link angular.module module} name to load.
1699  * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be
1700  *   created in "strict-di" mode. This means that the application will fail to invoke functions which
1701  *   do not use explicit function annotation (and are thus unsuitable for minification), as described
1702  *   in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in
1703  *   tracking down the root of these bugs.
1704  *
1705  * @description
1706  *
1707  * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
1708  * designates the **root element** of the application and is typically placed near the root element
1709  * of the page - e.g. on the `<body>` or `<html>` tags.
1710  *
1711  * There are a few things to keep in mind when using `ngApp`:
1712  * - only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
1713  *   found in the document will be used to define the root element to auto-bootstrap as an
1714  *   application. To run multiple applications in an HTML document you must manually bootstrap them using
1715  *   {@link angular.bootstrap} instead.
1716  * - AngularJS applications cannot be nested within each other.
1717  * - Do not use a directive that uses {@link ng.$compile#transclusion transclusion} on the same element as `ngApp`.
1718  *   This includes directives such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and
1719  *   {@link ngRoute.ngView `ngView`}.
1720  *   Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
1721  *   causing animations to stop working and making the injector inaccessible from outside the app.
1722  *
1723  * You can specify an **AngularJS module** to be used as the root module for the application.  This
1724  * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
1725  * should contain the application code needed or have dependencies on other modules that will
1726  * contain the code. See {@link angular.module} for more information.
1727  *
1728  * In the example below if the `ngApp` directive were not placed on the `html` element then the
1729  * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
1730  * would not be resolved to `3`.
1731  *
1732  * `ngApp` is the easiest, and most common way to bootstrap an application.
1733  *
1734  <example module="ngAppDemo" name="ng-app">
1735    <file name="index.html">
1736    <div ng-controller="ngAppDemoController">
1737      I can add: {{a}} + {{b}} =  {{ a+b }}
1738    </div>
1739    </file>
1740    <file name="script.js">
1741    angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
1742      $scope.a = 1;
1743      $scope.b = 2;
1744    });
1745    </file>
1746  </example>
1747  *
1748  * Using `ngStrictDi`, you would see something like this:
1749  *
1750  <example ng-app-included="true" name="strict-di">
1751    <file name="index.html">
1752    <div ng-app="ngAppStrictDemo" ng-strict-di>
1753        <div ng-controller="GoodController1">
1754            I can add: {{a}} + {{b}} =  {{ a+b }}
1755
1756            <p>This renders because the controller does not fail to
1757               instantiate, by using explicit annotation style (see
1758               script.js for details)
1759            </p>
1760        </div>
1761
1762        <div ng-controller="GoodController2">
1763            Name: <input ng-model="name"><br />
1764            Hello, {{name}}!
1765
1766            <p>This renders because the controller does not fail to
1767               instantiate, by using explicit annotation style
1768               (see script.js for details)
1769            </p>
1770        </div>
1771
1772        <div ng-controller="BadController">
1773            I can add: {{a}} + {{b}} =  {{ a+b }}
1774
1775            <p>The controller could not be instantiated, due to relying
1776               on automatic function annotations (which are disabled in
1777               strict mode). As such, the content of this section is not
1778               interpolated, and there should be an error in your web console.
1779            </p>
1780        </div>
1781    </div>
1782    </file>
1783    <file name="script.js">
1784    angular.module('ngAppStrictDemo', [])
1785      // BadController will fail to instantiate, due to relying on automatic function annotation,
1786      // rather than an explicit annotation
1787      .controller('BadController', function($scope) {
1788        $scope.a = 1;
1789        $scope.b = 2;
1790      })
1791      // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
1792      // due to using explicit annotations using the array style and $inject property, respectively.
1793      .controller('GoodController1', ['$scope', function($scope) {
1794        $scope.a = 1;
1795        $scope.b = 2;
1796      }])
1797      .controller('GoodController2', GoodController2);
1798      function GoodController2($scope) {
1799        $scope.name = 'World';
1800      }
1801      GoodController2.$inject = ['$scope'];
1802    </file>
1803    <file name="style.css">
1804    div[ng-controller] {
1805        margin-bottom: 1em;
1806        -webkit-border-radius: 4px;
1807        border-radius: 4px;
1808        border: 1px solid;
1809        padding: .5em;
1810    }
1811    div[ng-controller^=Good] {
1812        border-color: #d6e9c6;
1813        background-color: #dff0d8;
1814        color: #3c763d;
1815    }
1816    div[ng-controller^=Bad] {
1817        border-color: #ebccd1;
1818        background-color: #f2dede;
1819        color: #a94442;
1820        margin-bottom: 0;
1821    }
1822    </file>
1823  </example>
1824  */
1825 function angularInit(element, bootstrap) {
1826   var appElement,
1827       module,
1828       config = {};
1829
1830   // The element `element` has priority over any other element.
1831   forEach(ngAttrPrefixes, function(prefix) {
1832     var name = prefix + 'app';
1833
1834     if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
1835       appElement = element;
1836       module = element.getAttribute(name);
1837     }
1838   });
1839   forEach(ngAttrPrefixes, function(prefix) {
1840     var name = prefix + 'app';
1841     var candidate;
1842
1843     if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
1844       appElement = candidate;
1845       module = candidate.getAttribute(name);
1846     }
1847   });
1848   if (appElement) {
1849     if (!isAutoBootstrapAllowed) {
1850       window.console.error('Angular: disabling automatic bootstrap. <script> protocol indicates ' +
1851           'an extension, document.location.href does not match.');
1852       return;
1853     }
1854     config.strictDi = getNgAttribute(appElement, 'strict-di') !== null;
1855     bootstrap(appElement, module ? [module] : [], config);
1856   }
1857 }
1858
1859 /**
1860  * @ngdoc function
1861  * @name angular.bootstrap
1862  * @module ng
1863  * @description
1864  * Use this function to manually start up angular application.
1865  *
1866  * For more information, see the {@link guide/bootstrap Bootstrap guide}.
1867  *
1868  * Angular will detect if it has been loaded into the browser more than once and only allow the
1869  * first loaded script to be bootstrapped and will report a warning to the browser console for
1870  * each of the subsequent scripts. This prevents strange results in applications, where otherwise
1871  * multiple instances of Angular try to work on the DOM.
1872  *
1873  * <div class="alert alert-warning">
1874  * **Note:** Protractor based end-to-end tests cannot use this function to bootstrap manually.
1875  * They must use {@link ng.directive:ngApp ngApp}.
1876  * </div>
1877  *
1878  * <div class="alert alert-warning">
1879  * **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},
1880  * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.
1881  * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
1882  * causing animations to stop working and making the injector inaccessible from outside the app.
1883  * </div>
1884  *
1885  * ```html
1886  * <!doctype html>
1887  * <html>
1888  * <body>
1889  * <div ng-controller="WelcomeController">
1890  *   {{greeting}}
1891  * </div>
1892  *
1893  * <script src="angular.js"></script>
1894  * <script>
1895  *   var app = angular.module('demo', [])
1896  *   .controller('WelcomeController', function($scope) {
1897  *       $scope.greeting = 'Welcome!';
1898  *   });
1899  *   angular.bootstrap(document, ['demo']);
1900  * </script>
1901  * </body>
1902  * </html>
1903  * ```
1904  *
1905  * @param {DOMElement} element DOM element which is the root of angular application.
1906  * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.
1907  *     Each item in the array should be the name of a predefined module or a (DI annotated)
1908  *     function that will be invoked by the injector as a `config` block.
1909  *     See: {@link angular.module modules}
1910  * @param {Object=} config an object for defining configuration options for the application. The
1911  *     following keys are supported:
1912  *
1913  * * `strictDi` - disable automatic function annotation for the application. This is meant to
1914  *   assist in finding bugs which break minified code. Defaults to `false`.
1915  *
1916  * @returns {auto.$injector} Returns the newly created injector for this app.
1917  */
1918 function bootstrap(element, modules, config) {
1919   if (!isObject(config)) config = {};
1920   var defaultConfig = {
1921     strictDi: false
1922   };
1923   config = extend(defaultConfig, config);
1924   var doBootstrap = function() {
1925     element = jqLite(element);
1926
1927     if (element.injector()) {
1928       var tag = (element[0] === window.document) ? 'document' : startingTag(element);
1929       // Encode angle brackets to prevent input from being sanitized to empty string #8683.
1930       throw ngMinErr(
1931           'btstrpd',
1932           'App already bootstrapped with this element \'{0}\'',
1933           tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
1934     }
1935
1936     modules = modules || [];
1937     modules.unshift(['$provide', function($provide) {
1938       $provide.value('$rootElement', element);
1939     }]);
1940
1941     if (config.debugInfoEnabled) {
1942       // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
1943       modules.push(['$compileProvider', function($compileProvider) {
1944         $compileProvider.debugInfoEnabled(true);
1945       }]);
1946     }
1947
1948     modules.unshift('ng');
1949     var injector = createInjector(modules, config.strictDi);
1950     injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
1951        function bootstrapApply(scope, element, compile, injector) {
1952         scope.$apply(function() {
1953           element.data('$injector', injector);
1954           compile(element)(scope);
1955         });
1956       }]
1957     );
1958     return injector;
1959   };
1960
1961   var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
1962   var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
1963
1964   if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
1965     config.debugInfoEnabled = true;
1966     window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
1967   }
1968
1969   if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
1970     return doBootstrap();
1971   }
1972
1973   window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
1974   angular.resumeBootstrap = function(extraModules) {
1975     forEach(extraModules, function(module) {
1976       modules.push(module);
1977     });
1978     return doBootstrap();
1979   };
1980
1981   if (isFunction(angular.resumeDeferredBootstrap)) {
1982     angular.resumeDeferredBootstrap();
1983   }
1984 }
1985
1986 /**
1987  * @ngdoc function
1988  * @name angular.reloadWithDebugInfo
1989  * @module ng
1990  * @description
1991  * Use this function to reload the current application with debug information turned on.
1992  * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.
1993  *
1994  * See {@link ng.$compileProvider#debugInfoEnabled} for more.
1995  */
1996 function reloadWithDebugInfo() {
1997   window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;
1998   window.location.reload();
1999 }
2000
2001 /**
2002  * @name angular.getTestability
2003  * @module ng
2004  * @description
2005  * Get the testability service for the instance of Angular on the given
2006  * element.
2007  * @param {DOMElement} element DOM element which is the root of angular application.
2008  */
2009 function getTestability(rootElement) {
2010   var injector = angular.element(rootElement).injector();
2011   if (!injector) {
2012     throw ngMinErr('test',
2013       'no injector found for element argument to getTestability');
2014   }
2015   return injector.get('$$testability');
2016 }
2017
2018 var SNAKE_CASE_REGEXP = /[A-Z]/g;
2019 function snake_case(name, separator) {
2020   separator = separator || '_';
2021   return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
2022     return (pos ? separator : '') + letter.toLowerCase();
2023   });
2024 }
2025
2026 var bindJQueryFired = false;
2027 function bindJQuery() {
2028   var originalCleanData;
2029
2030   if (bindJQueryFired) {
2031     return;
2032   }
2033
2034   // bind to jQuery if present;
2035   var jqName = jq();
2036   jQuery = isUndefined(jqName) ? window.jQuery :   // use jQuery (if present)
2037            !jqName             ? undefined     :   // use jqLite
2038                                  window[jqName];   // use jQuery specified by `ngJq`
2039
2040   // Use jQuery if it exists with proper functionality, otherwise default to us.
2041   // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
2042   // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
2043   // versions. It will not work for sure with jQuery <1.7, though.
2044   if (jQuery && jQuery.fn.on) {
2045     jqLite = jQuery;
2046     extend(jQuery.fn, {
2047       scope: JQLitePrototype.scope,
2048       isolateScope: JQLitePrototype.isolateScope,
2049       controller: /** @type {?} */ (JQLitePrototype).controller,
2050       injector: JQLitePrototype.injector,
2051       inheritedData: JQLitePrototype.inheritedData
2052     });
2053
2054     // All nodes removed from the DOM via various jQuery APIs like .remove()
2055     // are passed through jQuery.cleanData. Monkey-patch this method to fire
2056     // the $destroy event on all removed nodes.
2057     originalCleanData = jQuery.cleanData;
2058     jQuery.cleanData = function(elems) {
2059       var events;
2060       for (var i = 0, elem; (elem = elems[i]) != null; i++) {
2061         events = jQuery._data(elem, 'events');
2062         if (events && events.$destroy) {
2063           jQuery(elem).triggerHandler('$destroy');
2064         }
2065       }
2066       originalCleanData(elems);
2067     };
2068   } else {
2069     jqLite = JQLite;
2070   }
2071
2072   angular.element = jqLite;
2073
2074   // Prevent double-proxying.
2075   bindJQueryFired = true;
2076 }
2077
2078 /**
2079  * throw error if the argument is falsy.
2080  */
2081 function assertArg(arg, name, reason) {
2082   if (!arg) {
2083     throw ngMinErr('areq', 'Argument \'{0}\' is {1}', (name || '?'), (reason || 'required'));
2084   }
2085   return arg;
2086 }
2087
2088 function assertArgFn(arg, name, acceptArrayAnnotation) {
2089   if (acceptArrayAnnotation && isArray(arg)) {
2090       arg = arg[arg.length - 1];
2091   }
2092
2093   assertArg(isFunction(arg), name, 'not a function, got ' +
2094       (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
2095   return arg;
2096 }
2097
2098 /**
2099  * throw error if the name given is hasOwnProperty
2100  * @param  {String} name    the name to test
2101  * @param  {String} context the context in which the name is used, such as module or directive
2102  */
2103 function assertNotHasOwnProperty(name, context) {
2104   if (name === 'hasOwnProperty') {
2105     throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
2106   }
2107 }
2108
2109 /**
2110  * Return the value accessible from the object by path. Any undefined traversals are ignored
2111  * @param {Object} obj starting object
2112  * @param {String} path path to traverse
2113  * @param {boolean} [bindFnToScope=true]
2114  * @returns {Object} value as accessible by path
2115  */
2116 //TODO(misko): this function needs to be removed
2117 function getter(obj, path, bindFnToScope) {
2118   if (!path) return obj;
2119   var keys = path.split('.');
2120   var key;
2121   var lastInstance = obj;
2122   var len = keys.length;
2123
2124   for (var i = 0; i < len; i++) {
2125     key = keys[i];
2126     if (obj) {
2127       obj = (lastInstance = obj)[key];
2128     }
2129   }
2130   if (!bindFnToScope && isFunction(obj)) {
2131     return bind(lastInstance, obj);
2132   }
2133   return obj;
2134 }
2135
2136 /**
2137  * Return the DOM siblings between the first and last node in the given array.
2138  * @param {Array} array like object
2139  * @returns {Array} the inputted object or a jqLite collection containing the nodes
2140  */
2141 function getBlockNodes(nodes) {
2142   // TODO(perf): update `nodes` instead of creating a new object?
2143   var node = nodes[0];
2144   var endNode = nodes[nodes.length - 1];
2145   var blockNodes;
2146
2147   for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {
2148     if (blockNodes || nodes[i] !== node) {
2149       if (!blockNodes) {
2150         blockNodes = jqLite(slice.call(nodes, 0, i));
2151       }
2152       blockNodes.push(node);
2153     }
2154   }
2155
2156   return blockNodes || nodes;
2157 }
2158
2159
2160 /**
2161  * Creates a new object without a prototype. This object is useful for lookup without having to
2162  * guard against prototypically inherited properties via hasOwnProperty.
2163  *
2164  * Related micro-benchmarks:
2165  * - http://jsperf.com/object-create2
2166  * - http://jsperf.com/proto-map-lookup/2
2167  * - http://jsperf.com/for-in-vs-object-keys2
2168  *
2169  * @returns {Object}
2170  */
2171 function createMap() {
2172   return Object.create(null);
2173 }
2174
2175 function stringify(value) {
2176   if (value == null) { // null || undefined
2177     return '';
2178   }
2179   switch (typeof value) {
2180     case 'string':
2181       break;
2182     case 'number':
2183       value = '' + value;
2184       break;
2185     default:
2186       if (hasCustomToString(value) && !isArray(value) && !isDate(value)) {
2187         value = value.toString();
2188       } else {
2189         value = toJson(value);
2190       }
2191   }
2192
2193   return value;
2194 }
2195
2196 var NODE_TYPE_ELEMENT = 1;
2197 var NODE_TYPE_ATTRIBUTE = 2;
2198 var NODE_TYPE_TEXT = 3;
2199 var NODE_TYPE_COMMENT = 8;
2200 var NODE_TYPE_DOCUMENT = 9;
2201 var NODE_TYPE_DOCUMENT_FRAGMENT = 11;
2202
2203 /**
2204  * @ngdoc type
2205  * @name angular.Module
2206  * @module ng
2207  * @description
2208  *
2209  * Interface for configuring angular {@link angular.module modules}.
2210  */
2211
2212 function setupModuleLoader(window) {
2213
2214   var $injectorMinErr = minErr('$injector');
2215   var ngMinErr = minErr('ng');
2216
2217   function ensure(obj, name, factory) {
2218     return obj[name] || (obj[name] = factory());
2219   }
2220
2221   var angular = ensure(window, 'angular', Object);
2222
2223   // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
2224   angular.$$minErr = angular.$$minErr || minErr;
2225
2226   return ensure(angular, 'module', function() {
2227     /** @type {Object.<string, angular.Module>} */
2228     var modules = {};
2229
2230     /**
2231      * @ngdoc function
2232      * @name angular.module
2233      * @module ng
2234      * @description
2235      *
2236      * The `angular.module` is a global place for creating, registering and retrieving Angular
2237      * modules.
2238      * All modules (angular core or 3rd party) that should be available to an application must be
2239      * registered using this mechanism.
2240      *
2241      * Passing one argument retrieves an existing {@link angular.Module},
2242      * whereas passing more than one argument creates a new {@link angular.Module}
2243      *
2244      *
2245      * # Module
2246      *
2247      * A module is a collection of services, directives, controllers, filters, and configuration information.
2248      * `angular.module` is used to configure the {@link auto.$injector $injector}.
2249      *
2250      * ```js
2251      * // Create a new module
2252      * var myModule = angular.module('myModule', []);
2253      *
2254      * // register a new service
2255      * myModule.value('appName', 'MyCoolApp');
2256      *
2257      * // configure existing services inside initialization blocks.
2258      * myModule.config(['$locationProvider', function($locationProvider) {
2259      *   // Configure existing providers
2260      *   $locationProvider.hashPrefix('!');
2261      * }]);
2262      * ```
2263      *
2264      * Then you can create an injector and load your modules like this:
2265      *
2266      * ```js
2267      * var injector = angular.injector(['ng', 'myModule'])
2268      * ```
2269      *
2270      * However it's more likely that you'll just use
2271      * {@link ng.directive:ngApp ngApp} or
2272      * {@link angular.bootstrap} to simplify this process for you.
2273      *
2274      * @param {!string} name The name of the module to create or retrieve.
2275      * @param {!Array.<string>=} requires If specified then new module is being created. If
2276      *        unspecified then the module is being retrieved for further configuration.
2277      * @param {Function=} configFn Optional configuration function for the module. Same as
2278      *        {@link angular.Module#config Module#config()}.
2279      * @returns {angular.Module} new module with the {@link angular.Module} api.
2280      */
2281     return function module(name, requires, configFn) {
2282
2283       var info = {};
2284
2285       var assertNotHasOwnProperty = function(name, context) {
2286         if (name === 'hasOwnProperty') {
2287           throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
2288         }
2289       };
2290
2291       assertNotHasOwnProperty(name, 'module');
2292       if (requires && modules.hasOwnProperty(name)) {
2293         modules[name] = null;
2294       }
2295       return ensure(modules, name, function() {
2296         if (!requires) {
2297           throw $injectorMinErr('nomod', 'Module \'{0}\' is not available! You either misspelled ' +
2298              'the module name or forgot to load it. If registering a module ensure that you ' +
2299              'specify the dependencies as the second argument.', name);
2300         }
2301
2302         /** @type {!Array.<Array.<*>>} */
2303         var invokeQueue = [];
2304
2305         /** @type {!Array.<Function>} */
2306         var configBlocks = [];
2307
2308         /** @type {!Array.<Function>} */
2309         var runBlocks = [];
2310
2311         var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
2312
2313         /** @type {angular.Module} */
2314         var moduleInstance = {
2315           // Private state
2316           _invokeQueue: invokeQueue,
2317           _configBlocks: configBlocks,
2318           _runBlocks: runBlocks,
2319
2320           /**
2321            * @ngdoc method
2322            * @name angular.Module#info
2323            * @module ng
2324            *
2325            * @param {Object=} info Information about the module
2326            * @returns {Object|Module} The current info object for this module if called as a getter,
2327            *                          or `this` if called as a setter.
2328            *
2329            * @description
2330            * Read and write custom information about this module.
2331            * For example you could put the version of the module in here.
2332            *
2333            * ```js
2334            * angular.module('myModule', []).info({ version: '1.0.0' });
2335            * ```
2336            *
2337            * The version could then be read back out by accessing the module elsewhere:
2338            *
2339            * ```
2340            * var version = angular.module('myModule').info().version;
2341            * ```
2342            *
2343            * You can also retrieve this information during runtime via the
2344            * {@link $injector#modules `$injector.modules`} property:
2345            *
2346            * ```js
2347            * var version = $injector.modules['myModule'].info().version;
2348            * ```
2349            */
2350           info: function(value) {
2351             if (isDefined(value)) {
2352               if (!isObject(value)) throw ngMinErr('aobj', 'Argument \'{0}\' must be an object', 'value');
2353               info = value;
2354               return this;
2355             }
2356             return info;
2357           },
2358
2359           /**
2360            * @ngdoc property
2361            * @name angular.Module#requires
2362            * @module ng
2363            *
2364            * @description
2365            * Holds the list of modules which the injector will load before the current module is
2366            * loaded.
2367            */
2368           requires: requires,
2369
2370           /**
2371            * @ngdoc property
2372            * @name angular.Module#name
2373            * @module ng
2374            *
2375            * @description
2376            * Name of the module.
2377            */
2378           name: name,
2379
2380
2381           /**
2382            * @ngdoc method
2383            * @name angular.Module#provider
2384            * @module ng
2385            * @param {string} name service name
2386            * @param {Function} providerType Construction function for creating new instance of the
2387            *                                service.
2388            * @description
2389            * See {@link auto.$provide#provider $provide.provider()}.
2390            */
2391           provider: invokeLaterAndSetModuleName('$provide', 'provider'),
2392
2393           /**
2394            * @ngdoc method
2395            * @name angular.Module#factory
2396            * @module ng
2397            * @param {string} name service name
2398            * @param {Function} providerFunction Function for creating new instance of the service.
2399            * @description
2400            * See {@link auto.$provide#factory $provide.factory()}.
2401            */
2402           factory: invokeLaterAndSetModuleName('$provide', 'factory'),
2403
2404           /**
2405            * @ngdoc method
2406            * @name angular.Module#service
2407            * @module ng
2408            * @param {string} name service name
2409            * @param {Function} constructor A constructor function that will be instantiated.
2410            * @description
2411            * See {@link auto.$provide#service $provide.service()}.
2412            */
2413           service: invokeLaterAndSetModuleName('$provide', 'service'),
2414
2415           /**
2416            * @ngdoc method
2417            * @name angular.Module#value
2418            * @module ng
2419            * @param {string} name service name
2420            * @param {*} object Service instance object.
2421            * @description
2422            * See {@link auto.$provide#value $provide.value()}.
2423            */
2424           value: invokeLater('$provide', 'value'),
2425
2426           /**
2427            * @ngdoc method
2428            * @name angular.Module#constant
2429            * @module ng
2430            * @param {string} name constant name
2431            * @param {*} object Constant value.
2432            * @description
2433            * Because the constants are fixed, they get applied before other provide methods.
2434            * See {@link auto.$provide#constant $provide.constant()}.
2435            */
2436           constant: invokeLater('$provide', 'constant', 'unshift'),
2437
2438            /**
2439            * @ngdoc method
2440            * @name angular.Module#decorator
2441            * @module ng
2442            * @param {string} name The name of the service to decorate.
2443            * @param {Function} decorFn This function will be invoked when the service needs to be
2444            *                           instantiated and should return the decorated service instance.
2445            * @description
2446            * See {@link auto.$provide#decorator $provide.decorator()}.
2447            */
2448           decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks),
2449
2450           /**
2451            * @ngdoc method
2452            * @name angular.Module#animation
2453            * @module ng
2454            * @param {string} name animation name
2455            * @param {Function} animationFactory Factory function for creating new instance of an
2456            *                                    animation.
2457            * @description
2458            *
2459            * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
2460            *
2461            *
2462            * Defines an animation hook that can be later used with
2463            * {@link $animate $animate} service and directives that use this service.
2464            *
2465            * ```js
2466            * module.animation('.animation-name', function($inject1, $inject2) {
2467            *   return {
2468            *     eventName : function(element, done) {
2469            *       //code to run the animation
2470            *       //once complete, then run done()
2471            *       return function cancellationFunction(element) {
2472            *         //code to cancel the animation
2473            *       }
2474            *     }
2475            *   }
2476            * })
2477            * ```
2478            *
2479            * See {@link ng.$animateProvider#register $animateProvider.register()} and
2480            * {@link ngAnimate ngAnimate module} for more information.
2481            */
2482           animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
2483
2484           /**
2485            * @ngdoc method
2486            * @name angular.Module#filter
2487            * @module ng
2488            * @param {string} name Filter name - this must be a valid angular expression identifier
2489            * @param {Function} filterFactory Factory function for creating new instance of filter.
2490            * @description
2491            * See {@link ng.$filterProvider#register $filterProvider.register()}.
2492            *
2493            * <div class="alert alert-warning">
2494            * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
2495            * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
2496            * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
2497            * (`myapp_subsection_filterx`).
2498            * </div>
2499            */
2500           filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
2501
2502           /**
2503            * @ngdoc method
2504            * @name angular.Module#controller
2505            * @module ng
2506            * @param {string|Object} name Controller name, or an object map of controllers where the
2507            *    keys are the names and the values are the constructors.
2508            * @param {Function} constructor Controller constructor function.
2509            * @description
2510            * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
2511            */
2512           controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
2513
2514           /**
2515            * @ngdoc method
2516            * @name angular.Module#directive
2517            * @module ng
2518            * @param {string|Object} name Directive name, or an object map of directives where the
2519            *    keys are the names and the values are the factories.
2520            * @param {Function} directiveFactory Factory function for creating new instance of
2521            * directives.
2522            * @description
2523            * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
2524            */
2525           directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
2526
2527           /**
2528            * @ngdoc method
2529            * @name angular.Module#component
2530            * @module ng
2531            * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp)
2532            * @param {Object} options Component definition object (a simplified
2533            *    {@link ng.$compile#directive-definition-object directive definition object})
2534            *
2535            * @description
2536            * See {@link ng.$compileProvider#component $compileProvider.component()}.
2537            */
2538           component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
2539
2540           /**
2541            * @ngdoc method
2542            * @name angular.Module#config
2543            * @module ng
2544            * @param {Function} configFn Execute this function on module load. Useful for service
2545            *    configuration.
2546            * @description
2547            * Use this method to register work which needs to be performed on module loading.
2548            * For more about how to configure services, see
2549            * {@link providers#provider-recipe Provider Recipe}.
2550            */
2551           config: config,
2552
2553           /**
2554            * @ngdoc method
2555            * @name angular.Module#run
2556            * @module ng
2557            * @param {Function} initializationFn Execute this function after injector creation.
2558            *    Useful for application initialization.
2559            * @description
2560            * Use this method to register work which should be performed when the injector is done
2561            * loading all modules.
2562            */
2563           run: function(block) {
2564             runBlocks.push(block);
2565             return this;
2566           }
2567         };
2568
2569         if (configFn) {
2570           config(configFn);
2571         }
2572
2573         return moduleInstance;
2574
2575         /**
2576          * @param {string} provider
2577          * @param {string} method
2578          * @param {String=} insertMethod
2579          * @returns {angular.Module}
2580          */
2581         function invokeLater(provider, method, insertMethod, queue) {
2582           if (!queue) queue = invokeQueue;
2583           return function() {
2584             queue[insertMethod || 'push']([provider, method, arguments]);
2585             return moduleInstance;
2586           };
2587         }
2588
2589         /**
2590          * @param {string} provider
2591          * @param {string} method
2592          * @returns {angular.Module}
2593          */
2594         function invokeLaterAndSetModuleName(provider, method, queue) {
2595           if (!queue) queue = invokeQueue;
2596           return function(recipeName, factoryFunction) {
2597             if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
2598             queue.push([provider, method, arguments]);
2599             return moduleInstance;
2600           };
2601         }
2602       });
2603     };
2604   });
2605
2606 }
2607
2608 /* global shallowCopy: true */
2609
2610 /**
2611  * Creates a shallow copy of an object, an array or a primitive.
2612  *
2613  * Assumes that there are no proto properties for objects.
2614  */
2615 function shallowCopy(src, dst) {
2616   if (isArray(src)) {
2617     dst = dst || [];
2618
2619     for (var i = 0, ii = src.length; i < ii; i++) {
2620       dst[i] = src[i];
2621     }
2622   } else if (isObject(src)) {
2623     dst = dst || {};
2624
2625     for (var key in src) {
2626       if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
2627         dst[key] = src[key];
2628       }
2629     }
2630   }
2631
2632   return dst || src;
2633 }
2634
2635 /* exported toDebugString */
2636
2637 function serializeObject(obj, maxDepth) {
2638   var seen = [];
2639
2640   // There is no direct way to stringify object until reaching a specific depth
2641   // and a very deep object can cause a performance issue, so we copy the object
2642   // based on this specific depth and then stringify it.
2643   if (isValidObjectMaxDepth(maxDepth)) {
2644     // This file is also included in `angular-loader`, so `copy()` might not always be available in
2645     // the closure. Therefore, it is lazily retrieved as `angular.copy()` when needed.
2646     obj = angular.copy(obj, null, maxDepth);
2647   }
2648   return JSON.stringify(obj, function(key, val) {
2649     val = toJsonReplacer(key, val);
2650     if (isObject(val)) {
2651
2652       if (seen.indexOf(val) >= 0) return '...';
2653
2654       seen.push(val);
2655     }
2656     return val;
2657   });
2658 }
2659
2660 function toDebugString(obj, maxDepth) {
2661   if (typeof obj === 'function') {
2662     return obj.toString().replace(/ \{[\s\S]*$/, '');
2663   } else if (isUndefined(obj)) {
2664     return 'undefined';
2665   } else if (typeof obj !== 'string') {
2666     return serializeObject(obj, maxDepth);
2667   }
2668   return obj;
2669 }
2670
2671 /* global angularModule: true,
2672   version: true,
2673
2674   $CompileProvider,
2675
2676   htmlAnchorDirective,
2677   inputDirective,
2678   inputDirective,
2679   formDirective,
2680   scriptDirective,
2681   selectDirective,
2682   optionDirective,
2683   ngBindDirective,
2684   ngBindHtmlDirective,
2685   ngBindTemplateDirective,
2686   ngClassDirective,
2687   ngClassEvenDirective,
2688   ngClassOddDirective,
2689   ngCloakDirective,
2690   ngControllerDirective,
2691   ngFormDirective,
2692   ngHideDirective,
2693   ngIfDirective,
2694   ngIncludeDirective,
2695   ngIncludeFillContentDirective,
2696   ngInitDirective,
2697   ngNonBindableDirective,
2698   ngPluralizeDirective,
2699   ngRepeatDirective,
2700   ngShowDirective,
2701   ngStyleDirective,
2702   ngSwitchDirective,
2703   ngSwitchWhenDirective,
2704   ngSwitchDefaultDirective,
2705   ngOptionsDirective,
2706   ngTranscludeDirective,
2707   ngModelDirective,
2708   ngListDirective,
2709   ngChangeDirective,
2710   patternDirective,
2711   patternDirective,
2712   requiredDirective,
2713   requiredDirective,
2714   minlengthDirective,
2715   minlengthDirective,
2716   maxlengthDirective,
2717   maxlengthDirective,
2718   ngValueDirective,
2719   ngModelOptionsDirective,
2720   ngAttributeAliasDirectives,
2721   ngEventDirectives,
2722
2723   $AnchorScrollProvider,
2724   $AnimateProvider,
2725   $CoreAnimateCssProvider,
2726   $$CoreAnimateJsProvider,
2727   $$CoreAnimateQueueProvider,
2728   $$AnimateRunnerFactoryProvider,
2729   $$AnimateAsyncRunFactoryProvider,
2730   $BrowserProvider,
2731   $CacheFactoryProvider,
2732   $ControllerProvider,
2733   $DateProvider,
2734   $DocumentProvider,
2735   $$IsDocumentHiddenProvider,
2736   $ExceptionHandlerProvider,
2737   $FilterProvider,
2738   $$ForceReflowProvider,
2739   $InterpolateProvider,
2740   $IntervalProvider,
2741   $HttpProvider,
2742   $HttpParamSerializerProvider,
2743   $HttpParamSerializerJQLikeProvider,
2744   $HttpBackendProvider,
2745   $xhrFactoryProvider,
2746   $jsonpCallbacksProvider,
2747   $LocationProvider,
2748   $LogProvider,
2749   $$MapProvider,
2750   $ParseProvider,
2751   $RootScopeProvider,
2752   $QProvider,
2753   $$QProvider,
2754   $$SanitizeUriProvider,
2755   $SceProvider,
2756   $SceDelegateProvider,
2757   $SnifferProvider,
2758   $TemplateCacheProvider,
2759   $TemplateRequestProvider,
2760   $$TestabilityProvider,
2761   $TimeoutProvider,
2762   $$RAFProvider,
2763   $WindowProvider,
2764   $$jqLiteProvider,
2765   $$CookieReaderProvider
2766 */
2767
2768
2769 /**
2770  * @ngdoc object
2771  * @name angular.version
2772  * @module ng
2773  * @description
2774  * An object that contains information about the current AngularJS version.
2775  *
2776  * This object has the following properties:
2777  *
2778  * - `full` – `{string}` – Full version string, such as "0.9.18".
2779  * - `major` – `{number}` – Major version number, such as "0".
2780  * - `minor` – `{number}` – Minor version number, such as "9".
2781  * - `dot` – `{number}` – Dot version number, such as "18".
2782  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
2783  */
2784 var version = {
2785   // These placeholder strings will be replaced by grunt's `build` task.
2786   // They need to be double- or single-quoted.
2787   full: '1.6.5',
2788   major: 1,
2789   minor: 6,
2790   dot: 5,
2791   codeName: 'toffee-salinization'
2792 };
2793
2794
2795 function publishExternalAPI(angular) {
2796   extend(angular, {
2797     'errorHandlingConfig': errorHandlingConfig,
2798     'bootstrap': bootstrap,
2799     'copy': copy,
2800     'extend': extend,
2801     'merge': merge,
2802     'equals': equals,
2803     'element': jqLite,
2804     'forEach': forEach,
2805     'injector': createInjector,
2806     'noop': noop,
2807     'bind': bind,
2808     'toJson': toJson,
2809     'fromJson': fromJson,
2810     'identity': identity,
2811     'isUndefined': isUndefined,
2812     'isDefined': isDefined,
2813     'isString': isString,
2814     'isFunction': isFunction,
2815     'isObject': isObject,
2816     'isNumber': isNumber,
2817     'isElement': isElement,
2818     'isArray': isArray,
2819     'version': version,
2820     'isDate': isDate,
2821     'lowercase': lowercase,
2822     'uppercase': uppercase,
2823     'callbacks': {$$counter: 0},
2824     'getTestability': getTestability,
2825     'reloadWithDebugInfo': reloadWithDebugInfo,
2826     '$$minErr': minErr,
2827     '$$csp': csp,
2828     '$$encodeUriSegment': encodeUriSegment,
2829     '$$encodeUriQuery': encodeUriQuery,
2830     '$$stringify': stringify
2831   });
2832
2833   angularModule = setupModuleLoader(window);
2834
2835   angularModule('ng', ['ngLocale'], ['$provide',
2836     function ngModule($provide) {
2837       // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
2838       $provide.provider({
2839         $$sanitizeUri: $$SanitizeUriProvider
2840       });
2841       $provide.provider('$compile', $CompileProvider).
2842         directive({
2843             a: htmlAnchorDirective,
2844             input: inputDirective,
2845             textarea: inputDirective,
2846             form: formDirective,
2847             script: scriptDirective,
2848             select: selectDirective,
2849             option: optionDirective,
2850             ngBind: ngBindDirective,
2851             ngBindHtml: ngBindHtmlDirective,
2852             ngBindTemplate: ngBindTemplateDirective,
2853             ngClass: ngClassDirective,
2854             ngClassEven: ngClassEvenDirective,
2855             ngClassOdd: ngClassOddDirective,
2856             ngCloak: ngCloakDirective