首页 > 代码库 > Angularjs 源码

Angularjs 源码

‘use strict‘;/* We need to tell jshint what variables are being exported *//* global    -angular,    -msie,    -jqLite,    -jQuery,    -slice,    -push,    -toString,    -ngMinErr,    -_angular,    -angularModule,    -nodeName_,    -uid,    -lowercase,    -uppercase,    -manualLowercase,    -manualUppercase,    -nodeName_,    -isArrayLike,    -forEach,    -sortedKeys,    -forEachSorted,    -reverseParams,    -nextUid,    -setHashKey,    -extend,    -int,    -inherit,    -noop,    -identity,    -valueFn,    -isUndefined,    -isDefined,    -isObject,    -isString,    -isNumber,    -isDate,    -isArray,    -isFunction,    -isRegExp,    -isWindow,    -isScope,    -isFile,    -isBoolean,    -trim,    -isElement,    -makeMap,    -map,    -size,    -includes,    -indexOf,    -arrayRemove,    -isLeafNode,    -copy,    -shallowCopy,    -equals,    -csp,    -concat,    -sliceArgs,    -bind,    -toJsonReplacer,    -toJson,    -fromJson,    -toBoolean,    -startingTag,    -tryDecodeURIComponent,    -parseKeyValue,    -toKeyValue,    -encodeUriSegment,    -encodeUriQuery,    -angularInit,    -bootstrap,    -snake_case,    -bindJQuery,    -assertArg,    -assertArgFn,    -assertNotHasOwnProperty,    -getter,    -getBlockElements,*//////////////////////////////////////** * @ngdoc function * @name angular.lowercase * @function * * @description Converts the specified string to lowercase. * @param {string} string String to be converted to lowercase. * @returns {string} Lowercased string. */var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};/** * @ngdoc function * @name angular.uppercase * @function * * @description Converts the specified string to uppercase. * @param {string} string String to be converted to uppercase. * @returns {string} Uppercased string. */var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;};var manualLowercase = function(s) {  /* jshint bitwise: false */  return isString(s)      ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})      : s;};var manualUppercase = function(s) {  /* jshint bitwise: false */  return isString(s)      ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})      : s;};// String#toLowerCase and String#toUpperCase don‘t produce correct results in browsers with Turkish// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods// with correct but slower alternatives.if (‘i‘ !== ‘I‘.toLowerCase()) {  lowercase = manualLowercase;  uppercase = manualUppercase;}var /** holds major version number for IE or NaN for real browsers */    msie,    jqLite,           // delay binding since jQuery could be loaded after us.    jQuery,           // delay binding    slice             = [].slice,    push              = [].push,    toString          = Object.prototype.toString,    ngMinErr          = minErr(‘ng‘),    _angular          = window.angular,    /** @name angular */    angular           = window.angular || (window.angular = {}),    angularModule,    nodeName_,    uid               = [‘0‘, ‘0‘, ‘0‘];/** * IE 11 changed the format of the UserAgent string. * See http://msdn.microsoft.com/en-us/library/ms537503.aspx */msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);if (isNaN(msie)) {  msie = int((/trident\/.*; rv:(\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);}/** * @private * @param {*} obj * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, *                   String ...) */function isArrayLike(obj) {  if (obj == null || isWindow(obj)) {    return false;  }  var length = obj.length;  if (obj.nodeType === 1 && length) {    return true;  }  return isString(obj) || isArray(obj) || length === 0 ||         typeof length === ‘number‘ && length > 0 && (length - 1) in obj;}/** * @ngdoc function * @name angular.forEach * @function * * @description * Invokes the `iterator` function once for each item in `obj` collection, which can be either an * object or an array. The `iterator` function is invoked with `iterator(value, key)`, where `value` * is the value of an object property or an array element and `key` is the object property key or * array element index. Specifying a `context` for the function is optional. * * Note: this function was previously known as `angular.foreach`. *   <pre>     var values = {name: ‘misko‘, gender: ‘male‘};     var log = [];     angular.forEach(values, function(value, key){       this.push(key + ‘: ‘ + value);     }, log);     expect(log).toEqual([‘name: misko‘, ‘gender:male‘]);   </pre> * * @param {Object|Array} obj Object to iterate over. * @param {Function} iterator Iterator function. * @param {Object=} context Object to become context (`this`) for the iterator function. * @returns {Object|Array} Reference to `obj`. */function forEach(obj, iterator, context) {  var key;  if (obj) {    if (isFunction(obj)){      for (key in obj) {        if (key != ‘prototype‘ && key != ‘length‘ && key != ‘name‘ && obj.hasOwnProperty(key)) {          iterator.call(context, obj[key], key);        }      }    } else if (obj.forEach && obj.forEach !== forEach) {      obj.forEach(iterator, context);    } else if (isArrayLike(obj)) {      for (key = 0; key < obj.length; key++)        iterator.call(context, obj[key], key);    } else {      for (key in obj) {        if (obj.hasOwnProperty(key)) {          iterator.call(context, obj[key], key);        }      }    }  }  return obj;}function sortedKeys(obj) {  var keys = [];  for (var key in obj) {    if (obj.hasOwnProperty(key)) {      keys.push(key);    }  }  return keys.sort();}function forEachSorted(obj, iterator, context) {  var keys = sortedKeys(obj);  for ( var i = 0; i < keys.length; i++) {    iterator.call(context, obj[keys[i]], keys[i]);  }  return keys;}/** * when using forEach the params are value, key, but it is often useful to have key, value. * @param {function(string, *)} iteratorFn * @returns {function(*, string)} */function reverseParams(iteratorFn) {  return function(value, key) { iteratorFn(key, value); };}/** * A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric * characters such as ‘012ABC‘. The reason why we are not using simply a number counter is that * the number string gets longer over time, and it can also overflow, where as the nextId * will grow much slower, it is a string, and it will never overflow. * * @returns an unique alpha-numeric string */function nextUid() {  var index = uid.length;  var digit;  while(index) {    index--;    digit = uid[index].charCodeAt(0);    if (digit == 57 /*‘9‘*/) {      uid[index] = ‘A‘;      return uid.join(‘‘);    }    if (digit == 90  /*‘Z‘*/) {      uid[index] = ‘0‘;    } else {      uid[index] = String.fromCharCode(digit + 1);      return uid.join(‘‘);    }  }  uid.unshift(‘0‘);  return uid.join(‘‘);}/** * Set or clear the hashkey for an object. * @param obj object * @param h the hashkey (!truthy to delete the hashkey) */function setHashKey(obj, h) {  if (h) {    obj.$$hashKey = h;  }  else {    delete obj.$$hashKey;  }}/** * @ngdoc function * @name angular.extend * @function * * @description * Extends the destination object `dst` by copying all of the properties from the `src` object(s) * to `dst`. You can specify multiple `src` objects. * * @param {Object} dst Destination object. * @param {...Object} src Source object(s). * @returns {Object} Reference to `dst`. */function extend(dst) {  var h = dst.$$hashKey;  forEach(arguments, function(obj){    if (obj !== dst) {      forEach(obj, function(value, key){        dst[key] = value;      });    }  });  setHashKey(dst,h);  return dst;}function int(str) {  return parseInt(str, 10);}function inherit(parent, extra) {  return extend(new (extend(function() {}, {prototype:parent}))(), extra);}/** * @ngdoc function * @name angular.noop * @function * * @description * A function that performs no operations. This function can be useful when writing code in the * functional style.   <pre>     function foo(callback) {       var result = calculateResult();       (callback || angular.noop)(result);     }   </pre> */function noop() {}noop.$inject = [];/** * @ngdoc function * @name angular.identity * @function * * @description * A function that returns its first argument. This function is useful when writing code in the * functional style. *   <pre>     function transformer(transformationFn, value) {       return (transformationFn || angular.identity)(value);     };   </pre> */function identity($) {return $;}identity.$inject = [];function valueFn(value) {return function() {return value;};}/** * @ngdoc function * @name angular.isUndefined * @function * * @description * Determines if a reference is undefined. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is undefined. */function isUndefined(value){return typeof value =http://www.mamicode.com/= ‘undefined‘;}/** * @ngdoc function * @name angular.isDefined * @function * * @description * Determines if a reference is defined. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is defined. */function isDefined(value){return typeof value != ‘undefined‘;}/** * @ngdoc function * @name angular.isObject * @function * * @description * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not * considered to be objects. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is an `Object` but not `null`. */function isObject(value){return value != null && typeof value =http://www.mamicode.com/= ‘object‘;}/** * @ngdoc function * @name angular.isString * @function * * @description * Determines if a reference is a `String`. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `String`. */function isString(value){return typeof value =http://www.mamicode.com/= ‘string‘;}/** * @ngdoc function * @name angular.isNumber * @function * * @description * Determines if a reference is a `Number`. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Number`. */function isNumber(value){return typeof value =http://www.mamicode.com/= ‘number‘;}/** * @ngdoc function * @name angular.isDate * @function * * @description * Determines if a value is a date. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Date`. */function isDate(value){  return toString.apply(value) == ‘[object Date]‘;}/** * @ngdoc function * @name angular.isArray * @function * * @description * Determines if a reference is an `Array`. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is an `Array`. */function isArray(value) {  return toString.apply(value) == ‘[object Array]‘;}/** * @ngdoc function * @name angular.isFunction * @function * * @description * Determines if a reference is a `Function`. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Function`. */function isFunction(value){return typeof value =http://www.mamicode.com/= ‘function‘;}/** * Determines if a value is a regular expression object. * * @private * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `RegExp`. */function isRegExp(value) {  return toString.apply(value) == ‘[object RegExp]‘;}/** * Checks if `obj` is a window object. * * @private * @param {*} obj Object to check * @returns {boolean} True if `obj` is a window obj. */function isWindow(obj) {  return obj && obj.document && obj.location && obj.alert && obj.setInterval;}function isScope(obj) {  return obj && obj.$evalAsync && obj.$watch;}function isFile(obj) {  return toString.apply(obj) === ‘[object File]‘;}function isBoolean(value) {  return typeof value =http://www.mamicode.com/= ‘boolean‘;}var trim = (function() {  // native trim is way faster: http://jsperf.com/angular-trim-test  // but IE doesn‘t have it... :-(  // TODO: we should move this into IE/ES5 polyfill  if (!String.prototype.trim) {    return function(value) {      return isString(value) ? value.replace(/^\s\s*/, ‘‘).replace(/\s\s*$/, ‘‘) : value;    };  }  return function(value) {    return isString(value) ? value.trim() : value;  };})();/** * @ngdoc function * @name angular.isElement * @function * * @description * Determines if a reference is a DOM element (or wrapped jQuery element). * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element). */function isElement(node) {  return node &&    (node.nodeName  // we are a direct element    || (node.on && node.find));  // we have an on and find method part of jQuery API}/** * @param str ‘key1,key2,...‘ * @returns {object} in the form of {key1:true, key2:true, ...} */function makeMap(str){  var obj = {}, items = str.split(","), i;  for ( i = 0; i < items.length; i++ )    obj[ items[i] ] = true;  return obj;}if (msie < 9) {  nodeName_ = function(element) {    element = element.nodeName ? element : element[0];    return (element.scopeName && element.scopeName != ‘HTML‘)      ? uppercase(element.scopeName + ‘:‘ + element.nodeName) : element.nodeName;  };} else {  nodeName_ = function(element) {    return element.nodeName ? element.nodeName : element[0].nodeName;  };}function map(obj, iterator, context) {  var results = [];  forEach(obj, function(value, index, list) {    results.push(iterator.call(context, value, index, list));  });  return results;}/** * @description * Determines the number of elements in an array, the number of properties an object has, or * the length of a string. * * Note: This function is used to augment the Object type in Angular expressions. See * {@link angular.Object} for more information about Angular arrays. * * @param {Object|Array|string} obj Object, array, or string to inspect. * @param {boolean} [ownPropsOnly=false] Count only "own" properties in an object * @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array. */function size(obj, ownPropsOnly) {  var count = 0, key;  if (isArray(obj) || isString(obj)) {    return obj.length;  } else if (isObject(obj)){    for (key in obj)      if (!ownPropsOnly || obj.hasOwnProperty(key))        count++;  }  return count;}function includes(array, obj) {  return indexOf(array, obj) != -1;}function indexOf(array, obj) {  if (array.indexOf) return array.indexOf(obj);  for ( var i = 0; i < array.length; i++) {    if (obj === array[i]) return i;  }  return -1;}function arrayRemove(array, value) {  var index = indexOf(array, value);  if (index >=0)    array.splice(index, 1);  return value;}function isLeafNode (node) {  if (node) {    switch (node.nodeName) {    case "OPTION":    case "PRE":    case "TITLE":      return true;    }  }  return false;}/** * @ngdoc function * @name angular.copy * @function * * @description * Creates a deep copy of `source`, which should be an object or an array. * * * If no destination is supplied, a copy of the object or array is created. * * If a destination is provided, all of its elements (for array) or properties (for objects) *   are deleted and then all elements/properties from the source are copied to it. * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned. * * If `source` is identical to ‘destination‘ an exception will be thrown. * * @param {*} source The source that will be used to make a copy. *                   Can be any type, including primitives, `null`, and `undefined`. * @param {(Object|Array)=} destination Destination into which the source is copied. If *     provided, must be of the same type as `source`. * @returns {*} The copy or updated `destination`, if `destination` was specified. * * @example <doc:example> <doc:source> <div ng-controller="Controller"> <form novalidate class="simple-form"> Name: <input type="text" ng-model="user.name" /><br /> E-mail: <input type="email" ng-model="user.email" /><br /> Gender: <input type="radio" ng-model="user.gender" value="http://www.mamicode.com/male" />male <input type="radio" ng-model="user.gender" value="http://www.mamicode.com/female" />female<br /> <button ng-click="reset()">RESET</button> <button ng-click="update(user)">SAVE</button> </form> <pre>form = {{user | json}}</pre> <pre>master = {{master | json}}</pre> </div> <script> function Controller($scope) {    $scope.master= {};    $scope.update = function(user) {      // Example with 1 argument      $scope.master= angular.copy(user);    };    $scope.reset = function() {      // Example with 2 arguments      angular.copy($scope.master, $scope.user);    };    $scope.reset();  } </script> </doc:source> </doc:example> */function copy(source, destination){  if (isWindow(source) || isScope(source)) {    throw ngMinErr(‘cpws‘,      "Can‘t copy! Making copies of Window or Scope instances is not supported.");  }  if (!destination) {    destination = source;    if (source) {      if (isArray(source)) {        destination = copy(source, []);      } else if (isDate(source)) {        destination = new Date(source.getTime());      } else if (isRegExp(source)) {        destination = new RegExp(source.source);      } else if (isObject(source)) {        destination = copy(source, {});      }    }  } else {    if (source === destination) throw ngMinErr(‘cpi‘,      "Can‘t copy! Source and destination are identical.");    if (isArray(source)) {      destination.length = 0;      for ( var i = 0; i < source.length; i++) {        destination.push(copy(source[i]));      }    } else {      var h = destination.$$hashKey;      forEach(destination, function(value, key){        delete destination[key];      });      for ( var key in source) {        destination[key] = copy(source[key]);      }      setHashKey(destination,h);    }  }  return destination;}/** * Create a shallow copy of an object */function shallowCopy(src, dst) {  dst = dst || {};  for(var key in src) {    // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src    // so we don‘t need to worry hasOwnProperty here    if (src.hasOwnProperty(key) && key.substr(0, 2) !== ‘$$‘) {      dst[key] = src[key];    }  }  return dst;}/** * @ngdoc function * @name angular.equals * @function * * @description * Determines if two objects or two values are equivalent. Supports value types, regular * expressions, arrays and objects. * * Two objects or values are considered equivalent if at least one of the following is true: * * * Both objects or values pass `===` comparison. * * Both objects or values are of the same type and all of their properties are equal by *   comparing them with `angular.equals`. * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal) * * Both values represent the same regular expression (In JavasScript, *   /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual *   representation matches). * * During a property comparison, properties of `function` type and properties with names * that begin with `$` are ignored. * * Scope and DOMWindow objects are being compared only by identify (`===`). * * @param {*} o1 Object or value to compare. * @param {*} o2 Object or value to compare. * @returns {boolean} True if arguments are equal. */function equals(o1, o2) {  if (o1 === o2) return true;  if (o1 === null || o2 === null) return false;  if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN  var t1 = typeof o1, t2 = typeof o2, length, key, keySet;  if (t1 == t2) {    if (t1 == ‘object‘) {      if (isArray(o1)) {        if (!isArray(o2)) return false;        if ((length = o1.length) == o2.length) {          for(key=0; key<length; key++) {            if (!equals(o1[key], o2[key])) return false;          }          return true;        }      } else if (isDate(o1)) {        return isDate(o2) && o1.getTime() == o2.getTime();      } else if (isRegExp(o1) && isRegExp(o2)) {        return o1.toString() == o2.toString();      } else {        if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;        keySet = {};        for(key in o1) {          if (key.charAt(0) === ‘$‘ || isFunction(o1[key])) continue;          if (!equals(o1[key], o2[key])) return false;          keySet[key] = true;        }        for(key in o2) {          if (!keySet.hasOwnProperty(key) &&              key.charAt(0) !== ‘$‘ &&              o2[key] !== undefined &&              !isFunction(o2[key])) return false;        }        return true;      }    }  }  return false;}function csp() {  return (document.securityPolicy && document.securityPolicy.isActive) ||      (document.querySelector &&      !!(document.querySelector(‘[ng-csp]‘) || document.querySelector(‘[data-ng-csp]‘)));}function concat(array1, array2, index) {  return array1.concat(slice.call(array2, index));}function sliceArgs(args, startIndex) {  return slice.call(args, startIndex || 0);}/* jshint -W101 *//** * @ngdoc function * @name angular.bind * @function * * @description * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for * `fn`). You can supply optional `args` that are prebound to the function. This feature is also * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application). * * @param {Object} self Context which `fn` should be evaluated in. * @param {function()} fn Function to be bound. * @param {...*} args Optional arguments to be prebound to the `fn` function call. * @returns {function()} Function that wraps the `fn` with all the specified bindings. *//* jshint +W101 */function bind(self, fn) {  var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];  if (isFunction(fn) && !(fn instanceof RegExp)) {    return curryArgs.length      ? function() {          return arguments.length            ? fn.apply(self, curryArgs.concat(slice.call(arguments, 0)))            : fn.apply(self, curryArgs);        }      : function() {          return arguments.length            ? fn.apply(self, arguments)            : fn.call(self);        };  } else {    // in IE, native methods are not functions so they cannot be bound (note: they don‘t need to be)    return fn;  }}function toJsonReplacer(key, value) {  var val = value;  if (typeof key === ‘string‘ && key.charAt(0) === ‘$‘) {    val = undefined;  } else if (isWindow(value)) {    val = ‘$WINDOW‘;  } else if (value &&  document === value) {    val = ‘$DOCUMENT‘;  } else if (isScope(value)) {    val = ‘$SCOPE‘;  }  return val;}/** * @ngdoc function * @name angular.toJson * @function * * @description * Serializes input into a JSON-formatted string. Properties with leading $ characters will be * stripped since angular uses this notation internally. * * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON. * @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace. * @returns {string|undefined} JSON-ified string representing `obj`. */function toJson(obj, pretty) {  if (typeof obj === ‘undefined‘) return undefined;  return JSON.stringify(obj, toJsonReplacer, pretty ? ‘  ‘ : null);}/** * @ngdoc function * @name angular.fromJson * @function * * @description * Deserializes a JSON string. * * @param {string} json JSON string to deserialize. * @returns {Object|Array|Date|string|number} Deserialized thingy. */function fromJson(json) {  return isString(json)      ? JSON.parse(json)      : json;}function toBoolean(value) {  if (value && value.length !== 0) {    var v = lowercase("" + value);    value = !(v == ‘f‘ || v == ‘0‘ || v == ‘false‘ || v == ‘no‘ || v == ‘n‘ || v == ‘[]‘);  } else {    value = false;  }  return value;}/** * @returns {string} Returns the string representation of the element. */function startingTag(element) {  element = jqLite(element).clone();  try {    // turns out IE does not let you set .html() on elements which    // are not allowed to have children. So we just ignore it.    element.html(‘‘);  } catch(e) {}  // As Per DOM Standards  var TEXT_NODE = 3;  var elemHtml = jqLite(‘<div>‘).append(element).html();  try {    return element[0].nodeType === TEXT_NODE ? lowercase(elemHtml) :        elemHtml.          match(/^(<[^>]+>)/)[1].          replace(/^<([\w\-]+)/, function(match, nodeName) { return ‘<‘ + lowercase(nodeName); });  } catch(e) {    return lowercase(elemHtml);  }}//////////////////////////////////////////////////** * Tries to decode the URI component without throwing an exception. * * @private * @param str value potential URI component to check. * @returns {boolean} True if `value` can be decoded * with the decodeURIComponent function. */function tryDecodeURIComponent(value) {  try {    return decodeURIComponent(value);  } catch(e) {    // Ignore any invalid uri component  }}/** * Parses an escaped url query string into key-value pairs. * @returns Object.<(string|boolean)> */function parseKeyValue(/**string*/keyValue) {  var obj = {}, key_value, key;  forEach((keyValue || "").split(‘&‘), function(keyValue){    if ( keyValue ) {      key_value = keyValue.split(‘=‘);      key = tryDecodeURIComponent(key_value[0]);      if ( isDefined(key) ) {        var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;        if (!obj[key]) {          obj[key] = val;        } else if(isArray(obj[key])) {          obj[key].push(val);        } else {          obj[key] = [obj[key],val];        }      }    }  });  return obj;}function toKeyValue(obj) {  var parts = [];  forEach(obj, function(value, key) {    if (isArray(value)) {      forEach(value, function(arrayValue) {        parts.push(encodeUriQuery(key, true) +                   (arrayValue === true ? ‘‘ : ‘=‘ + encodeUriQuery(arrayValue, true)));      });    } else {    parts.push(encodeUriQuery(key, true) +               (value === true ? ‘‘ : ‘=‘ + encodeUriQuery(value, true)));    }  });  return parts.length ? parts.join(‘&‘) : ‘‘;}/** * We need our custom method because encodeURIComponent is too aggressive and doesn‘t follow * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path * segments: *    segment       = *pchar *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@" *    pct-encoded   = "%" HEXDIG HEXDIG *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~" *    sub-delims    = "!" / "$" / "&" / "‘" / "(" / ")" *                     / "*" / "+" / "," / ";" / "=" */function encodeUriSegment(val) {  return encodeUriQuery(val, true).             replace(/%26/gi, ‘&‘).             replace(/%3D/gi, ‘=‘).             replace(/%2B/gi, ‘+‘);}/** * This method is intended for encoding *key* or *value* parts of query component. We need a custom * method because encodeURIComponent is too aggressive and encodes stuff that doesn‘t have to be * encoded per http://tools.ietf.org/html/rfc3986: *    query       = *( pchar / "/" / "?" ) *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@" *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~" *    pct-encoded   = "%" HEXDIG HEXDIG *    sub-delims    = "!" / "$" / "&" / "‘" / "(" / ")" *                     / "*" / "+" / "," / ";" / "=" */function encodeUriQuery(val, pctEncodeSpaces) {  return encodeURIComponent(val).             replace(/%40/gi, ‘@‘).             replace(/%3A/gi, ‘:‘).             replace(/%24/g, ‘$‘).             replace(/%2C/gi, ‘,‘).             replace(/%20/g, (pctEncodeSpaces ? ‘%20‘ : ‘+‘));}/** * @ngdoc directive * @name ng.directive:ngApp * * @element ANY * @param {angular.Module} ngApp an optional application *   {@link angular.module module} name to load. * * @description * * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive * designates the **root element** of the application and is typically placed near the root element * of the page - e.g. on the `<body>` or `<html>` tags. * * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp` * found in the document will be used to define the root element to auto-bootstrap as an * application. To run multiple applications in an HTML document you must manually bootstrap them using * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other. * * You can specify an **AngularJS module** to be used as the root module for the application.  This * module will be loaded into the {@link AUTO.$injector} when the application is bootstrapped and * should contain the application code needed or have dependencies on other modules that will * contain the code. See {@link angular.module} for more information. * * In the example below if the `ngApp` directive were not placed on the `html` element then the * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}` * would not be resolved to `3`. * * `ngApp` is the easiest, and most common, way to bootstrap an application. * <example module="ngAppDemo">   <file name="index.html">   <div ng-controller="ngAppDemoController">     I can add: {{a}} + {{b}} =  {{ a+b }}   </file>   <file name="script.js">   angular.module(‘ngAppDemo‘, []).controller(‘ngAppDemoController‘, function($scope) {     $scope.a = 1;     $scope.b = 2;   });   </file> </example> * */function angularInit(element, bootstrap) {  var elements = [element],      appElement,      module,      names = [‘ng:app‘, ‘ng-app‘, ‘x-ng-app‘, ‘data-ng-app‘],      NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;  function append(element) {    element && elements.push(element);  }  forEach(names, function(name) {    names[name] = true;    append(document.getElementById(name));    name = name.replace(‘:‘, ‘\\:‘);    if (element.querySelectorAll) {      forEach(element.querySelectorAll(‘.‘ + name), append);      forEach(element.querySelectorAll(‘.‘ + name + ‘\\:‘), append);      forEach(element.querySelectorAll(‘[‘ + name + ‘]‘), append);    }  });  forEach(elements, function(element) {    if (!appElement) {      var className = ‘ ‘ + element.className + ‘ ‘;      var match = NG_APP_CLASS_REGEXP.exec(className);      if (match) {        appElement = element;        module = (match[2] || ‘‘).replace(/\s+/g, ‘,‘);      } else {        forEach(element.attributes, function(attr) {          if (!appElement && names[attr.name]) {            appElement = element;            module = attr.value;          }        });      }    }  });  if (appElement) {    bootstrap(appElement, module ? [module] : []);  }}/** * @ngdoc function * @name angular.bootstrap * @description * Use this function to manually start up angular application. * * See: {@link guide/bootstrap Bootstrap} * * Note that ngScenario-based end-to-end tests cannot use this function to bootstrap manually. * They must use {@link api/ng.directive:ngApp ngApp}. * * @param {Element} element DOM element which is the root of angular application. * @param {Array<String|Function|Array>=} modules an array of modules to load into the application. *     Each item in the array should be the name of a predefined module or a (DI annotated) *     function that will be invoked by the injector as a run block. *     See: {@link angular.module modules} * @returns {AUTO.$injector} Returns the newly created injector for this app. */function bootstrap(element, modules) {  var doBootstrap = function() {    element = jqLite(element);    if (element.injector()) {      var tag = (element[0] === document) ? ‘document‘ : startingTag(element);      throw ngMinErr(‘btstrpd‘, "App Already Bootstrapped with this Element ‘{0}‘", tag);    }    modules = modules || [];    modules.unshift([‘$provide‘, function($provide) {      $provide.value(‘$rootElement‘, element);    }]);    modules.unshift(‘ng‘);    var injector = createInjector(modules);    injector.invoke([‘$rootScope‘, ‘$rootElement‘, ‘$compile‘, ‘$injector‘, ‘$animate‘,       function(scope, element, compile, injector, animate) {        scope.$apply(function() {          element.data(‘$injector‘, injector);          compile(element)(scope);        });      }]    );    return injector;  };  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {    return doBootstrap();  }  window.name = window.name.replace(NG_DEFER_BOOTSTRAP, ‘‘);  angular.resumeBootstrap = function(extraModules) {    forEach(extraModules, function(module) {      modules.push(module);    });    doBootstrap();  };}var SNAKE_CASE_REGEXP = /[A-Z]/g;function snake_case(name, separator){  separator = separator || ‘_‘;  return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {    return (pos ? separator : ‘‘) + letter.toLowerCase();  });}function bindJQuery() {  // bind to jQuery if present;  jQuery = window.jQuery;  // reset to jQuery or default to us.  if (jQuery) {    jqLite = jQuery;    extend(jQuery.fn, {      scope: JQLitePrototype.scope,      isolateScope: JQLitePrototype.isolateScope,      controller: JQLitePrototype.controller,      injector: JQLitePrototype.injector,      inheritedData: JQLitePrototype.inheritedData    });    // Method signature:    //     jqLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments)    jqLitePatchJQueryRemove(‘remove‘, true, true, false);    jqLitePatchJQueryRemove(‘empty‘, false, false, false);    jqLitePatchJQueryRemove(‘html‘, false, false, true);  } else {    jqLite = JQLite;  }  angular.element = jqLite;}/** * throw error if the argument is falsy. */function assertArg(arg, name, reason) {  if (!arg) {    throw ngMinErr(‘areq‘, "Argument ‘{0}‘ is {1}", (name || ‘?‘), (reason || "required"));  }  return arg;}function assertArgFn(arg, name, acceptArrayAnnotation) {  if (acceptArrayAnnotation && isArray(arg)) {      arg = arg[arg.length - 1];  }  assertArg(isFunction(arg), name, ‘not a function, got ‘ +      (arg && typeof arg == ‘object‘ ? arg.constructor.name || ‘Object‘ : typeof arg));  return arg;}/** * throw error if the name given is hasOwnProperty * @param  {String} name    the name to test * @param  {String} context the context in which the name is used, such as module or directive */function assertNotHasOwnProperty(name, context) {  if (name === ‘hasOwnProperty‘) {    throw ngMinErr(‘badname‘, "hasOwnProperty is not a valid {0} name", context);  }}/** * Return the value accessible from the object by path. Any undefined traversals are ignored * @param {Object} obj starting object * @param {string} path path to traverse * @param {boolean=true} bindFnToScope * @returns value as accessible by path *///TODO(misko): this function needs to be removedfunction getter(obj, path, bindFnToScope) {  if (!path) return obj;  var keys = path.split(‘.‘);  var key;  var lastInstance = obj;  var len = keys.length;  for (var i = 0; i < len; i++) {    key = keys[i];    if (obj) {      obj = (lastInstance = obj)[key];    }  }  if (!bindFnToScope && isFunction(obj)) {    return bind(lastInstance, obj);  }  return obj;}/** * Return the siblings between `startNode` and `endNode`, inclusive * @param {Object} object with `startNode` and `endNode` properties * @returns jQlite object containing the elements */function getBlockElements(block) {  if (block.startNode === block.endNode) {    return jqLite(block.startNode);  }  var element = block.startNode;  var elements = [element];  do {    element = element.nextSibling;    if (!element) break;    elements.push(element);  } while (element !== block.endNode);  return jqLite(elements);}