diff --git a/xos/gui/_dockerignore b/xos/gui/.dockerignore
similarity index 100%
rename from xos/gui/_dockerignore
rename to xos/gui/.dockerignore
diff --git a/xos/gui/_gitignore b/xos/gui/.gitignore
similarity index 100%
rename from xos/gui/_gitignore
rename to xos/gui/.gitignore
diff --git a/xos/gui/.tmp/app.config.js b/xos/gui/.tmp/app.config.js
deleted file mode 100755
index 64a2ea1..0000000
--- a/xos/gui/.tmp/app.config.js
+++ /dev/null
@@ -1,23 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-angular.module('vnaasgui')
-  .constant('AppConfig', {
-    apiEndpoint: '/xos/api',
-    websocketClient: '/',
-  });
diff --git a/xos/gui/.tmp/index.html b/xos/gui/.tmp/index.html
deleted file mode 100755
index 10ec110..0000000
--- a/xos/gui/.tmp/index.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-<!--
-Copyright 2017-present Open Networking Foundation
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-
-<!DOCTYPE html>
-<html lang="en" ng-app="vnaasgui">
-<head>
-  <meta charset="UTF-8">
-  <title>vNaaS GUI</title>
-  <link href="/xos/loader.css" rel="stylesheet">
-  <link href="/xos/app.css" rel="stylesheet">
-  <link href="./app/style/style.css" rel="stylesheet">
-</head>
-<body>
-  <div ui-view></div>
-  <script src="/xos/vendor.js"></script>
-  <script src="/xos/app.js"></script>
-  <script src="/xos/loader.js"></script>
-  <script src="/xos/app.config.js"></script>
-  <script src="/xos/style.config.js"></script>
-  <script src="/mapconstants.js"></script>
-<script type="text/javascript" src="index.js"></script></body>
-</html>
\ No newline at end of file
diff --git a/xos/gui/.tmp/index.js b/xos/gui/.tmp/index.js
deleted file mode 100755
index 667fbd8..0000000
--- a/xos/gui/.tmp/index.js
+++ /dev/null
@@ -1,63551 +0,0 @@
-/******/ (function(modules) { // webpackBootstrap
-/******/ 	// The module cache
-/******/ 	var installedModules = {};
-/******/
-/******/ 	// The require function
-/******/ 	function __webpack_require__(moduleId) {
-/******/
-/******/ 		// Check if module is in cache
-/******/ 		if(installedModules[moduleId])
-/******/ 			return installedModules[moduleId].exports;
-/******/
-/******/ 		// Create a new module (and put it into the cache)
-/******/ 		var module = installedModules[moduleId] = {
-/******/ 			i: moduleId,
-/******/ 			l: false,
-/******/ 			exports: {}
-/******/ 		};
-/******/
-/******/ 		// Execute the module function
-/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/ 		// Flag the module as loaded
-/******/ 		module.l = true;
-/******/
-/******/ 		// Return the exports of the module
-/******/ 		return module.exports;
-/******/ 	}
-/******/
-/******/
-/******/ 	// expose the modules object (__webpack_modules__)
-/******/ 	__webpack_require__.m = modules;
-/******/
-/******/ 	// expose the module cache
-/******/ 	__webpack_require__.c = installedModules;
-/******/
-/******/ 	// identity function for calling harmory imports with the correct context
-/******/ 	__webpack_require__.i = function(value) { return value; };
-/******/
-/******/ 	// define getter function for harmory exports
-/******/ 	__webpack_require__.d = function(exports, name, getter) {
-/******/ 		Object.defineProperty(exports, name, {
-/******/ 			configurable: false,
-/******/ 			enumerable: true,
-/******/ 			get: getter
-/******/ 		});
-/******/ 	};
-/******/
-/******/ 	// getDefaultExport function for compatibility with non-harmony modules
-/******/ 	__webpack_require__.n = function(module) {
-/******/ 		var getter = module && module.__esModule ?
-/******/ 			function getDefault() { return module['default']; } :
-/******/ 			function getModuleExports() { return module; };
-/******/ 		__webpack_require__.d(getter, 'a', getter);
-/******/ 		return getter;
-/******/ 	};
-/******/
-/******/ 	// Object.prototype.hasOwnProperty.call
-/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
-/******/
-/******/ 	// __webpack_public_path__
-/******/ 	__webpack_require__.p = "";
-/******/
-/******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 16);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
-__webpack_require__(10);
-module.exports = angular;
-
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
-__webpack_require__(8);
-module.exports = 'ngCookies';
-
-
-/***/ },
-/* 2 */
-/***/ function(module, exports, __webpack_require__) {
-
-__webpack_require__(9);
-module.exports = 'ngResource';
-
-
-/***/ },
-/* 3 */
-/***/ function(module, exports, __webpack_require__) {
-
-/*!
- * State-based routing for AngularJS
- * @version v1.0.0-beta.1
- * @link https://ui-router.github.io
- * @license MIT License, http://www.opensource.org/licenses/MIT
- */
-(function webpackUniversalModuleDefinition(root, factory) {
-	if(true)
-		module.exports = factory();
-	else if(typeof define === 'function' && define.amd)
-		define("angular-ui-router", [], factory);
-	else if(typeof exports === 'object')
-		exports["angular-ui-router"] = factory();
-	else
-		root["angular-ui-router"] = factory();
-})(this, function() {
-return /******/ (function(modules) { // webpackBootstrap
-/******/ 	// The module cache
-/******/ 	var installedModules = {};
-/******/
-/******/ 	// The require function
-/******/ 	function __webpack_require__(moduleId) {
-/******/
-/******/ 		// Check if module is in cache
-/******/ 		if(installedModules[moduleId])
-/******/ 			return installedModules[moduleId].exports;
-/******/
-/******/ 		// Create a new module (and put it into the cache)
-/******/ 		var module = installedModules[moduleId] = {
-/******/ 			exports: {},
-/******/ 			id: moduleId,
-/******/ 			loaded: false
-/******/ 		};
-/******/
-/******/ 		// Execute the module function
-/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/ 		// Flag the module as loaded
-/******/ 		module.loaded = true;
-/******/
-/******/ 		// Return the exports of the module
-/******/ 		return module.exports;
-/******/ 	}
-/******/
-/******/
-/******/ 	// expose the modules object (__webpack_modules__)
-/******/ 	__webpack_require__.m = modules;
-/******/
-/******/ 	// expose the module cache
-/******/ 	__webpack_require__.c = installedModules;
-/******/
-/******/ 	// __webpack_public_path__
-/******/ 	__webpack_require__.p = "";
-/******/
-/******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/**
-	 * Main entry point for angular 1.x build
-	 * @module ng1
-	 */
-	/** for typedoc */
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	__export(__webpack_require__(1));
-	__export(__webpack_require__(53));
-	__export(__webpack_require__(55));
-	__webpack_require__(58);
-	__webpack_require__(59);
-	__webpack_require__(60);
-	__webpack_require__(61);
-	Object.defineProperty(exports, "__esModule", { value: true });
-	exports.default = "ui.router";
-
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/** @module common */ /** */
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	__export(__webpack_require__(2));
-	__export(__webpack_require__(46));
-	__export(__webpack_require__(47));
-	__export(__webpack_require__(48));
-	__export(__webpack_require__(49));
-	__export(__webpack_require__(50));
-	__export(__webpack_require__(51));
-	__export(__webpack_require__(52));
-	__export(__webpack_require__(44));
-	var router_1 = __webpack_require__(26);
-	exports.UIRouter = router_1.UIRouter;
-
-
-/***/ },
-/* 2 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	/** @module common */ /** for typedoc */
-	__export(__webpack_require__(3));
-	__export(__webpack_require__(6));
-	__export(__webpack_require__(7));
-	__export(__webpack_require__(5));
-	__export(__webpack_require__(4));
-	__export(__webpack_require__(8));
-	__export(__webpack_require__(9));
-	__export(__webpack_require__(12));
-
-
-/***/ },
-/* 3 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/**
-	 * Random utility functions used in the UI-Router code
-	 *
-	 * @preferred @module common
-	 */ /** for typedoc */
-	"use strict";
-	var predicates_1 = __webpack_require__(4);
-	var hof_1 = __webpack_require__(5);
-	var coreservices_1 = __webpack_require__(6);
-	var w = typeof window === 'undefined' ? {} : window;
-	var angular = w.angular || {};
-	exports.fromJson = angular.fromJson || JSON.parse.bind(JSON);
-	exports.toJson = angular.toJson || JSON.stringify.bind(JSON);
-	exports.copy = angular.copy || _copy;
-	exports.forEach = angular.forEach || _forEach;
-	exports.extend = angular.extend || _extend;
-	exports.equals = angular.equals || _equals;
-	exports.identity = function (x) { return x; };
-	exports.noop = function () { return undefined; };
-	exports.abstractKey = 'abstract';
-	/**
-	 * Binds and copies functions onto an object
-	 *
-	 * Takes functions from the 'from' object, binds those functions to the _this object, and puts the bound functions
-	 * on the 'to' object.
-	 *
-	 * This example creates an new class instance whose functions are prebound to the new'd object.
-	 * @example
-	 * ```
-	 *
-	 * class Foo {
-	 *   constructor(data) {
-	 *     // Binds all functions from Foo.prototype to 'this',
-	 *     // then copies them to 'this'
-	 *     bindFunctions(Foo.prototype, this, this);
-	 *     this.data = data;
-	 *   }
-	 *
-	 *   log() {
-	 *     console.log(this.data);
-	 *   }
-	 * }
-	 *
-	 * let myFoo = new Foo([1,2,3]);
-	 * var logit = myFoo.log;
-	 * logit(); // logs [1, 2, 3] from the myFoo 'this' instance
-	 * ```
-	 *
-	 * This example creates a bound version of a service function, and copies it to another object
-	 * @example
-	 * ```
-	 *
-	 * var SomeService = {
-	 *   this.data = [3, 4, 5];
-	 *   this.log = function() {
-	 *     console.log(this.data);
-	 *   }
-	 * }
-	 *
-	 * // Constructor fn
-	 * function OtherThing() {
-	 *   // Binds all functions from SomeService to SomeService,
-	 *   // then copies them to 'this'
-	 *   bindFunctions(SomeService, this, SomeService);
-	 * }
-	 *
-	 * let myOtherThing = new OtherThing();
-	 * myOtherThing.log(); // logs [3, 4, 5] from SomeService's 'this'
-	 * ```
-	 *
-	 * @param from The object which contains the functions to be bound
-	 * @param to The object which will receive the bound functions
-	 * @param bindTo The object which the functions will be bound to
-	 * @param fnNames The function names which will be bound (Defaults to all the functions found on the 'from' object)
-	 */
-	function bindFunctions(from, to, bindTo, fnNames) {
-	    if (fnNames === void 0) { fnNames = Object.keys(from); }
-	    return fnNames.filter(function (name) { return typeof from[name] === 'function'; })
-	        .forEach(function (name) { return to[name] = from[name].bind(bindTo); });
-	}
-	exports.bindFunctions = bindFunctions;
-	/**
-	 * prototypal inheritance helper.
-	 * Creates a new object which has `parent` object as its prototype, and then copies the properties from `extra` onto it
-	 */
-	exports.inherit = function (parent, extra) {
-	    return exports.extend(new (exports.extend(function () { }, { prototype: parent }))(), extra);
-	};
-	/**
-	 * Given an arguments object, converts the arguments at index idx and above to an array.
-	 * This is similar to es6 rest parameters.
-	 *
-	 * Optionally, the argument at index idx may itself already be an array.
-	 *
-	 * For example,
-	 * given either:
-	 *        arguments = [ obj, "foo", "bar" ]
-	 * or:
-	 *        arguments = [ obj, ["foo", "bar"] ]
-	 * then:
-	 *        restArgs(arguments, 1) == ["foo", "bar"]
-	 *
-	 * This allows functions like pick() to be implemented such that it allows either a bunch
-	 * of string arguments (like es6 rest parameters), or a single array of strings:
-	 *
-	 * given:
-	 *        var obj = { foo: 1, bar: 2, baz: 3 };
-	 * then:
-	 *        pick(obj, "foo", "bar");   // returns { foo: 1, bar: 2 }
-	 *        pick(obj, ["foo", "bar"]); // returns { foo: 1, bar: 2 }
-	 */
-	var restArgs = function (args, idx) {
-	    if (idx === void 0) { idx = 0; }
-	    return Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(args, idx));
-	};
-	/** Given an array, returns true if the object is found in the array, (using indexOf) */
-	exports.inArray = function (array, obj) { return array.indexOf(obj) !== -1; };
-	/** Given an array, and an item, if the item is found in the array, it removes it (in-place).  The same array is returned */
-	exports.removeFrom = hof_1.curry(function (array, obj) {
-	    var idx = array.indexOf(obj);
-	    if (idx >= 0)
-	        array.splice(idx, 1);
-	    return array;
-	});
-	/**
-	 * Applies a set of defaults to an options object.  The options object is filtered
-	 * to only those properties of the objects in the defaultsList.
-	 * Earlier objects in the defaultsList take precedence when applying defaults.
-	 */
-	function defaults(opts) {
-	    if (opts === void 0) { opts = {}; }
-	    var defaultsList = [];
-	    for (var _i = 1; _i < arguments.length; _i++) {
-	        defaultsList[_i - 1] = arguments[_i];
-	    }
-	    var defaults = merge.apply(null, [{}].concat(defaultsList));
-	    return exports.extend({}, defaults, pick(opts || {}, Object.keys(defaults)));
-	}
-	exports.defaults = defaults;
-	/**
-	 * Merges properties from the list of objects to the destination object.
-	 * If a property already exists in the destination object, then it is not overwritten.
-	 */
-	function merge(dst) {
-	    var objs = [];
-	    for (var _i = 1; _i < arguments.length; _i++) {
-	        objs[_i - 1] = arguments[_i];
-	    }
-	    exports.forEach(objs, function (obj) {
-	        exports.forEach(obj, function (value, key) {
-	            if (!dst.hasOwnProperty(key))
-	                dst[key] = value;
-	        });
-	    });
-	    return dst;
-	}
-	exports.merge = merge;
-	/** Reduce function that merges each element of the list into a single object, using extend */
-	exports.mergeR = function (memo, item) { return exports.extend(memo, item); };
-	/**
-	 * Finds the common ancestor path between two states.
-	 *
-	 * @param {Object} first The first state.
-	 * @param {Object} second The second state.
-	 * @return {Array} Returns an array of state names in descending order, not including the root.
-	 */
-	function ancestors(first, second) {
-	    var path = [];
-	    for (var n in first.path) {
-	        if (first.path[n] !== second.path[n])
-	            break;
-	        path.push(first.path[n]);
-	    }
-	    return path;
-	}
-	exports.ancestors = ancestors;
-	/**
-	 * Performs a non-strict comparison of the subset of two objects, defined by a list of keys.
-	 *
-	 * @param {Object} a The first object.
-	 * @param {Object} b The second object.
-	 * @param {Array} keys The list of keys within each object to compare. If the list is empty or not specified,
-	 *                     it defaults to the list of keys in `a`.
-	 * @return {Boolean} Returns `true` if the keys match, otherwise `false`.
-	 */
-	function equalForKeys(a, b, keys) {
-	    if (keys === void 0) { keys = Object.keys(a); }
-	    for (var i = 0; i < keys.length; i++) {
-	        var k = keys[i];
-	        if (a[k] != b[k])
-	            return false; // Not '===', values aren't necessarily normalized
-	    }
-	    return true;
-	}
-	exports.equalForKeys = equalForKeys;
-	function pickOmitImpl(predicate, obj) {
-	    var objCopy = {}, keys = restArgs(arguments, 2);
-	    for (var key in obj) {
-	        if (predicate(keys, key))
-	            objCopy[key] = obj[key];
-	    }
-	    return objCopy;
-	}
-	/** Return a copy of the object only containing the whitelisted properties. */
-	function pick(obj) { return pickOmitImpl.apply(null, [exports.inArray].concat(restArgs(arguments))); }
-	exports.pick = pick;
-	/** Return a copy of the object omitting the blacklisted properties. */
-	function omit(obj) { return pickOmitImpl.apply(null, [hof_1.not(exports.inArray)].concat(restArgs(arguments))); }
-	exports.omit = omit;
-	/**
-	 * Maps an array, or object to a property (by name)
-	 */
-	function pluck(collection, propName) {
-	    return map(collection, hof_1.prop(propName));
-	}
-	exports.pluck = pluck;
-	/** Filters an Array or an Object's properties based on a predicate */
-	function filter(collection, callback) {
-	    var arr = predicates_1.isArray(collection), result = arr ? [] : {};
-	    var accept = arr ? function (x) { return result.push(x); } : function (x, key) { return result[key] = x; };
-	    exports.forEach(collection, function (item, i) {
-	        if (callback(item, i))
-	            accept(item, i);
-	    });
-	    return result;
-	}
-	exports.filter = filter;
-	/** Finds an object from an array, or a property of an object, that matches a predicate */
-	function find(collection, callback) {
-	    var result;
-	    exports.forEach(collection, function (item, i) {
-	        if (result)
-	            return;
-	        if (callback(item, i))
-	            result = item;
-	    });
-	    return result;
-	}
-	exports.find = find;
-	/** Given an object, returns a new object, where each property is transformed by the callback function */
-	exports.mapObj = map;
-	/** Maps an array or object properties using a callback function */
-	function map(collection, callback) {
-	    var result = predicates_1.isArray(collection) ? [] : {};
-	    exports.forEach(collection, function (item, i) { return result[i] = callback(item, i); });
-	    return result;
-	}
-	exports.map = map;
-	/**
-	 * Given an object, return its enumerable property values
-	 *
-	 * @example
-	 * ```
-	 *
-	 * let foo = { a: 1, b: 2, c: 3 }
-	 * let vals = values(foo); // [ 1, 2, 3 ]
-	 * ```
-	 */
-	exports.values = function (obj) { return Object.keys(obj).map(function (key) { return obj[key]; }); };
-	/**
-	 * Reduce function that returns true if all of the values are truthy.
-	 *
-	 * @example
-	 * ```
-	 *
-	 * let vals = [ 1, true, {}, "hello world"];
-	 * vals.reduce(allTrueR, true); // true
-	 *
-	 * vals.push(0);
-	 * vals.reduce(allTrueR, true); // false
-	 * ```
-	 */
-	exports.allTrueR = function (memo, elem) { return memo && elem; };
-	/**
-	 * Reduce function that returns true if any of the values are truthy.
-	 *
-	 *  * @example
-	 * ```
-	 *
-	 * let vals = [ 0, null, undefined ];
-	 * vals.reduce(anyTrueR, true); // false
-	 *
-	 * vals.push("hello world");
-	 * vals.reduce(anyTrueR, true); // true
-	 * ```
-	 */
-	exports.anyTrueR = function (memo, elem) { return memo || elem; };
-	/**
-	 * Reduce function which un-nests a single level of arrays
-	 * @example
-	 * ```
-	 *
-	 * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
-	 * input.reduce(unnestR, []) // [ "a", "b", "c", "d", [ "double, "nested" ] ]
-	 * ```
-	 */
-	exports.unnestR = function (memo, elem) { return memo.concat(elem); };
-	/**
-	 * Reduce function which recursively un-nests all arrays
-	 *
-	 * @example
-	 * ```
-	 *
-	 * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
-	 * input.reduce(unnestR, []) // [ "a", "b", "c", "d", "double, "nested" ]
-	 * ```
-	 */
-	exports.flattenR = function (memo, elem) { return predicates_1.isArray(elem) ? memo.concat(elem.reduce(exports.flattenR, [])) : pushR(memo, elem); };
-	/** Reduce function that pushes an object to an array, then returns the array.  Mostly just for [[flattenR]] */
-	function pushR(arr, obj) { arr.push(obj); return arr; }
-	exports.pushR = pushR;
-	/** Reduce function that filters out duplicates */
-	exports.uniqR = function (acc, token) { return exports.inArray(acc, token) ? acc : pushR(acc, token); };
-	/**
-	 * Return a new array with a single level of arrays unnested.
-	 *
-	 * @example
-	 * ```
-	 *
-	 * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
-	 * unnest(input) // [ "a", "b", "c", "d", [ "double, "nested" ] ]
-	 * ```
-	 */
-	exports.unnest = function (arr) { return arr.reduce(exports.unnestR, []); };
-	/**
-	 * Return a completely flattened version of an array.
-	 *
-	 * @example
-	 * ```
-	 *
-	 * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
-	 * flatten(input) // [ "a", "b", "c", "d", "double, "nested" ]
-	 * ```
-	 */
-	exports.flatten = function (arr) { return arr.reduce(exports.flattenR, []); };
-	/**
-	 * Given a .filter Predicate, builds a .filter Predicate which throws an error if any elements do not pass.
-	 * @example
-	 * ```
-	 *
-	 * let isNumber = (obj) => typeof(obj) === 'number';
-	 * let allNumbers = [ 1, 2, 3, 4, 5 ];
-	 * allNumbers.filter(assertPredicate(isNumber)); //OK
-	 *
-	 * let oneString = [ 1, 2, 3, 4, "5" ];
-	 * oneString.filter(assertPredicate(isNumber, "Not all numbers")); // throws Error(""Not all numbers"");
-	 * ```
-	 */
-	function assertPredicate(predicate, errMsg) {
-	    if (errMsg === void 0) { errMsg = "assert failure"; }
-	    return function (obj) {
-	        if (!predicate(obj)) {
-	            throw new Error(predicates_1.isFunction(errMsg) ? errMsg(obj) : errMsg);
-	        }
-	        return true;
-	    };
-	}
-	exports.assertPredicate = assertPredicate;
-	/**
-	 * Like _.pairs: Given an object, returns an array of key/value pairs
-	 *
-	 * @example
-	 * ```
-	 *
-	 * pairs({ foo: "FOO", bar: "BAR }) // [ [ "foo", "FOO" ], [ "bar": "BAR" ] ]
-	 * ```
-	 */
-	exports.pairs = function (object) { return Object.keys(object).map(function (key) { return [key, object[key]]; }); };
-	/**
-	 * Given two or more parallel arrays, returns an array of tuples where
-	 * each tuple is composed of [ a[i], b[i], ... z[i] ]
-	 *
-	 * @example
-	 * ```
-	 *
-	 * let foo = [ 0, 2, 4, 6 ];
-	 * let bar = [ 1, 3, 5, 7 ];
-	 * let baz = [ 10, 30, 50, 70 ];
-	 * arrayTuples(foo, bar);       // [ [0, 1], [2, 3], [4, 5], [6, 7] ]
-	 * arrayTuples(foo, bar, baz);  // [ [0, 1, 10], [2, 3, 30], [4, 5, 50], [6, 7, 70] ]
-	 * ```
-	 */
-	function arrayTuples() {
-	    var arrayArgs = [];
-	    for (var _i = 0; _i < arguments.length; _i++) {
-	        arrayArgs[_i - 0] = arguments[_i];
-	    }
-	    if (arrayArgs.length === 0)
-	        return [];
-	    var length = arrayArgs.reduce(function (min, arr) { return Math.min(arr.length, min); }, 9007199254740991); // aka 2^53 − 1 aka Number.MAX_SAFE_INTEGER
-	    return Array.apply(null, Array(length)).map(function (ignored, idx) { return arrayArgs.map(function (arr) { return arr[idx]; }); });
-	}
-	exports.arrayTuples = arrayTuples;
-	/**
-	 * Reduce function which builds an object from an array of [key, value] pairs.
-	 *
-	 * Each iteration sets the key/val pair on the memo object, then returns the memo for the next iteration.
-	 *
-	 * Each keyValueTuple should be an array with values [ key: string, value: any ]
-	 *
-	 * @example
-	 * ```
-	 *
-	 * var pairs = [ ["fookey", "fooval"], ["barkey", "barval"] ]
-	 *
-	 * var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {})
-	 * // pairsToObj == { fookey: "fooval", barkey: "barval" }
-	 *
-	 * // Or, more simply:
-	 * var pairsToObj = pairs.reduce(applyPairs, {})
-	 * // pairsToObj == { fookey: "fooval", barkey: "barval" }
-	 * ```
-	 */
-	function applyPairs(memo, keyValTuple) {
-	    var key, value;
-	    if (predicates_1.isArray(keyValTuple))
-	        key = keyValTuple[0], value = keyValTuple[1];
-	    if (!predicates_1.isString(key))
-	        throw new Error("invalid parameters to applyPairs");
-	    memo[key] = value;
-	    return memo;
-	}
-	exports.applyPairs = applyPairs;
-	/** Get the last element of an array */
-	function tail(arr) {
-	    return arr.length && arr[arr.length - 1] || undefined;
-	}
-	exports.tail = tail;
-	/**
-	 * shallow copy from src to dest
-	 *
-	 * note: This is a shallow copy, while angular.copy is a deep copy.
-	 * ui-router uses `copy` only to make copies of state parameters.
-	 */
-	function _copy(src, dest) {
-	    if (dest)
-	        Object.keys(dest).forEach(function (key) { return delete dest[key]; });
-	    if (!dest)
-	        dest = {};
-	    return exports.extend(dest, src);
-	}
-	function _forEach(obj, cb, _this) {
-	    if (predicates_1.isArray(obj))
-	        return obj.forEach(cb, _this);
-	    Object.keys(obj).forEach(function (key) { return cb(obj[key], key); });
-	}
-	function _copyProps(to, from) { Object.keys(from).forEach(function (key) { return to[key] = from[key]; }); return to; }
-	function _extend(toObj, rest) {
-	    return restArgs(arguments, 1).filter(exports.identity).reduce(_copyProps, toObj);
-	}
-	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;
-	    if (t1 !== t2 || t1 !== 'object')
-	        return false;
-	    var tup = [o1, o2];
-	    if (hof_1.all(predicates_1.isArray)(tup))
-	        return _arraysEq(o1, o2);
-	    if (hof_1.all(predicates_1.isDate)(tup))
-	        return o1.getTime() === o2.getTime();
-	    if (hof_1.all(predicates_1.isRegExp)(tup))
-	        return o1.toString() === o2.toString();
-	    if (hof_1.all(predicates_1.isFunction)(tup))
-	        return true; // meh
-	    var predicates = [predicates_1.isFunction, predicates_1.isArray, predicates_1.isDate, predicates_1.isRegExp];
-	    if (predicates.map(hof_1.any).reduce(function (b, fn) { return b || !!fn(tup); }, false))
-	        return false;
-	    var key, keys = {};
-	    for (key in o1) {
-	        if (!_equals(o1[key], o2[key]))
-	            return false;
-	        keys[key] = true;
-	    }
-	    for (key in o2) {
-	        if (!keys[key])
-	            return false;
-	    }
-	    return true;
-	}
-	function _arraysEq(a1, a2) {
-	    if (a1.length !== a2.length)
-	        return false;
-	    return arrayTuples(a1, a2).reduce(function (b, t) { return b && _equals(t[0], t[1]); }, true);
-	}
-	// issue #2676
-	exports.silenceUncaughtInPromise = function (promise) {
-	    return promise.catch(function (e) { return 0; }) && promise;
-	};
-	exports.silentRejection = function (error) {
-	    return exports.silenceUncaughtInPromise(coreservices_1.services.$q.reject(error));
-	};
-
-
-/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** Predicates @module common_predicates */ /** */
-	var hof_1 = __webpack_require__(5);
-	var toStr = Object.prototype.toString;
-	var tis = function (t) { return function (x) { return typeof (x) === t; }; };
-	exports.isUndefined = tis('undefined');
-	exports.isDefined = hof_1.not(exports.isUndefined);
-	exports.isNull = function (o) { return o === null; };
-	exports.isFunction = tis('function');
-	exports.isNumber = tis('number');
-	exports.isString = tis('string');
-	exports.isObject = function (x) { return x !== null && typeof x === 'object'; };
-	exports.isArray = Array.isArray;
-	exports.isDate = (function (x) { return toStr.call(x) === '[object Date]'; });
-	exports.isRegExp = (function (x) { return toStr.call(x) === '[object RegExp]'; });
-	/**
-	 * Predicate which checks if a value is injectable
-	 *
-	 * A value is "injectable" if it is a function, or if it is an ng1 array-notation-style array
-	 * where all the elements in the array are Strings, except the last one, which is a Function
-	 */
-	function isInjectable(val) {
-	    if (exports.isArray(val) && val.length) {
-	        var head = val.slice(0, -1), tail = val.slice(-1);
-	        return !(head.filter(hof_1.not(exports.isString)).length || tail.filter(hof_1.not(exports.isFunction)).length);
-	    }
-	    return exports.isFunction(val);
-	}
-	exports.isInjectable = isInjectable;
-	/**
-	 * Predicate which checks if a value looks like a Promise
-	 *
-	 * It is probably a Promise if it's an object, and it has a `then` property which is a Function
-	 */
-	exports.isPromise = hof_1.and(exports.isObject, hof_1.pipe(hof_1.prop('then'), exports.isFunction));
-
-
-/***/ },
-/* 5 */
-/***/ function(module, exports) {
-
-	/**
-	 * Higher order functions
-	 *
-	 * @module common_hof
-	 */ /** */
-	"use strict";
-	/**
-	 * Returns a new function for [Partial Application](https://en.wikipedia.org/wiki/Partial_application) of the original function.
-	 *
-	 * Given a function with N parameters, returns a new function that supports partial application.
-	 * The new function accepts anywhere from 1 to N parameters.  When that function is called with M parameters,
-	 * where M is less than N, it returns a new function that accepts the remaining parameters.  It continues to
-	 * accept more parameters until all N parameters have been supplied.
-	 *
-	 *
-	 * This contrived example uses a partially applied function as an predicate, which returns true
-	 * if an object is found in both arrays.
-	 * @example
-	 * ```
-	 * // returns true if an object is in both of the two arrays
-	 * function inBoth(array1, array2, object) {
-	 *   return array1.indexOf(object) !== -1 &&
-	 *          array2.indexOf(object) !== 1;
-	 * }
-	 * let obj1, obj2, obj3, obj4, obj5, obj6, obj7
-	 * let foos = [obj1, obj3]
-	 * let bars = [obj3, obj4, obj5]
-	 *
-	 * // A curried "copy" of inBoth
-	 * let curriedInBoth = curry(inBoth);
-	 * // Partially apply both the array1 and array2
-	 * let inFoosAndBars = curriedInBoth(foos, bars);
-	 *
-	 * // Supply the final argument; since all arguments are
-	 * // supplied, the original inBoth function is then called.
-	 * let obj1InBoth = inFoosAndBars(obj1); // false
-	 *
-	 * // Use the inFoosAndBars as a predicate.
-	 * // Filter, on each iteration, supplies the final argument
-	 * let allObjs = [ obj1, obj2, obj3, obj4, obj5, obj6, obj7 ];
-	 * let foundInBoth = allObjs.filter(inFoosAndBars); // [ obj3 ]
-	 *
-	 * ```
-	 *
-	 * Stolen from: http://stackoverflow.com/questions/4394747/javascript-curry-function
-	 *
-	 * @param fn
-	 * @returns {*|function(): (*|any)}
-	 */
-	function curry(fn) {
-	    var initial_args = [].slice.apply(arguments, [1]);
-	    var func_args_length = fn.length;
-	    function curried(args) {
-	        if (args.length >= func_args_length)
-	            return fn.apply(null, args);
-	        return function () {
-	            return curried(args.concat([].slice.apply(arguments)));
-	        };
-	    }
-	    return curried(initial_args);
-	}
-	exports.curry = curry;
-	/**
-	 * Given a varargs list of functions, returns a function that composes the argument functions, right-to-left
-	 * given: f(x), g(x), h(x)
-	 * let composed = compose(f,g,h)
-	 * then, composed is: f(g(h(x)))
-	 */
-	function compose() {
-	    var args = arguments;
-	    var start = args.length - 1;
-	    return function () {
-	        var i = start, result = args[start].apply(this, arguments);
-	        while (i--)
-	            result = args[i].call(this, result);
-	        return result;
-	    };
-	}
-	exports.compose = compose;
-	/**
-	 * Given a varargs list of functions, returns a function that is composes the argument functions, left-to-right
-	 * given: f(x), g(x), h(x)
-	 * let piped = pipe(f,g,h);
-	 * then, piped is: h(g(f(x)))
-	 */
-	function pipe() {
-	    var funcs = [];
-	    for (var _i = 0; _i < arguments.length; _i++) {
-	        funcs[_i - 0] = arguments[_i];
-	    }
-	    return compose.apply(null, [].slice.call(arguments).reverse());
-	}
-	exports.pipe = pipe;
-	/**
-	 * Given a property name, returns a function that returns that property from an object
-	 * let obj = { foo: 1, name: "blarg" };
-	 * let getName = prop("name");
-	 * getName(obj) === "blarg"
-	 */
-	exports.prop = function (name) { return function (obj) { return obj && obj[name]; }; };
-	/**
-	 * Given a property name and a value, returns a function that returns a boolean based on whether
-	 * the passed object has a property that matches the value
-	 * let obj = { foo: 1, name: "blarg" };
-	 * let getName = propEq("name", "blarg");
-	 * getName(obj) === true
-	 */
-	exports.propEq = curry(function (name, val, obj) { return obj && obj[name] === val; });
-	/**
-	 * Given a dotted property name, returns a function that returns a nested property from an object, or undefined
-	 * let obj = { id: 1, nestedObj: { foo: 1, name: "blarg" }, };
-	 * let getName = prop("nestedObj.name");
-	 * getName(obj) === "blarg"
-	 * let propNotFound = prop("this.property.doesnt.exist");
-	 * propNotFound(obj) === undefined
-	 */
-	exports.parse = function (name) { return pipe.apply(null, name.split(".").map(exports.prop)); };
-	/**
-	 * Given a function that returns a truthy or falsey value, returns a
-	 * function that returns the opposite (falsey or truthy) value given the same inputs
-	 */
-	exports.not = function (fn) { return function () {
-	    var args = [];
-	    for (var _i = 0; _i < arguments.length; _i++) {
-	        args[_i - 0] = arguments[_i];
-	    }
-	    return !fn.apply(null, args);
-	}; };
-	/**
-	 * Given two functions that return truthy or falsey values, returns a function that returns truthy
-	 * if both functions return truthy for the given arguments
-	 */
-	function and(fn1, fn2) {
-	    return function () {
-	        var args = [];
-	        for (var _i = 0; _i < arguments.length; _i++) {
-	            args[_i - 0] = arguments[_i];
-	        }
-	        return fn1.apply(null, args) && fn2.apply(null, args);
-	    };
-	}
-	exports.and = and;
-	/**
-	 * Given two functions that return truthy or falsey values, returns a function that returns truthy
-	 * if at least one of the functions returns truthy for the given arguments
-	 */
-	function or(fn1, fn2) {
-	    return function () {
-	        var args = [];
-	        for (var _i = 0; _i < arguments.length; _i++) {
-	            args[_i - 0] = arguments[_i];
-	        }
-	        return fn1.apply(null, args) || fn2.apply(null, args);
-	    };
-	}
-	exports.or = or;
-	/**
-	 * Check if all the elements of an array match a predicate function
-	 *
-	 * @param fn1 a predicate function `fn1`
-	 * @returns a function which takes an array and returns true if `fn1` is true for all elements of the array
-	 */
-	exports.all = function (fn1) { return function (arr) { return arr.reduce(function (b, x) { return b && !!fn1(x); }, true); }; };
-	exports.any = function (fn1) { return function (arr) { return arr.reduce(function (b, x) { return b || !!fn1(x); }, false); }; };
-	exports.none = exports.not(exports.any);
-	/** Given a class, returns a Predicate function that returns true if the object is of that class */
-	exports.is = function (ctor) { return function (obj) { return (obj != null && obj.constructor === ctor || obj instanceof ctor); }; };
-	/** Given a value, returns a Predicate function that returns true if another value is === equal to the original value */
-	exports.eq = function (val) { return function (other) { return val === other; }; };
-	/** Given a value, returns a function which returns the value */
-	exports.val = function (v) { return function () { return v; }; };
-	function invoke(fnName, args) {
-	    return function (obj) { return obj[fnName].apply(obj, args); };
-	}
-	exports.invoke = invoke;
-	/**
-	 * Sorta like Pattern Matching (a functional programming conditional construct)
-	 *
-	 * See http://c2.com/cgi/wiki?PatternMatching
-	 *
-	 * This is a conditional construct which allows a series of predicates and output functions
-	 * to be checked and then applied.  Each predicate receives the input.  If the predicate
-	 * returns truthy, then its matching output function (mapping function) is provided with
-	 * the input and, then the result is returned.
-	 *
-	 * Each combination (2-tuple) of predicate + output function should be placed in an array
-	 * of size 2: [ predicate, mapFn ]
-	 *
-	 * These 2-tuples should be put in an outer array.
-	 *
-	 * @example
-	 * ```
-	 *
-	 * // Here's a 2-tuple where the first element is the isString predicate
-	 * // and the second element is a function that returns a description of the input
-	 * let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];
-	 *
-	 * // Second tuple: predicate "isNumber", mapfn returns a description
-	 * let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];
-	 *
-	 * let third = [ (input) => input === null,  (input) => `Oh, null...` ];
-	 *
-	 * let fourth = [ (input) => input === undefined,  (input) => `notdefined` ];
-	 *
-	 * let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);
-	 *
-	 * console.log(descriptionOf(undefined)); // 'notdefined'
-	 * console.log(descriptionOf(55)); // '(55) That's a number!'
-	 * console.log(descriptionOf("foo")); // 'Here's your string foo'
-	 * ```
-	 *
-	 * @param struct A 2D array.  Each element of the array should be an array, a 2-tuple,
-	 * with a Predicate and a mapping/output function
-	 * @returns {function(any): *}
-	 */
-	function pattern(struct) {
-	    return function (x) {
-	        for (var i = 0; i < struct.length; i++) {
-	            if (struct[i][0](x))
-	                return struct[i][1](x);
-	        }
-	    };
-	}
-	exports.pattern = pattern;
-
-
-/***/ },
-/* 6 */
-/***/ function(module, exports) {
-
-	/**
-	 * This module is a stub for core services such as Dependency Injection or Browser Location.
-	 * Core services may be implemented by a specific framework, such as ng1 or ng2, or be pure javascript.
-	 *
-	 * @module common
-	 */
-	"use strict";
-	/** for typedoc */
-	//import {IQService} from "angular";
-	//import {IInjectorService} from "angular";
-	var notImplemented = function (fnname) { return function () {
-	    throw new Error(fnname + "(): No coreservices implementation for UI-Router is loaded. You should include one of: ['angular1.js']");
-	}; };
-	var services = {
-	    $q: undefined,
-	    $injector: undefined,
-	    location: {},
-	    locationConfig: {},
-	    template: {}
-	};
-	exports.services = services;
-	["replace", "url", "path", "search", "hash", "onChange"]
-	    .forEach(function (key) { return services.location[key] = notImplemented(key); });
-	["port", "protocol", "host", "baseHref", "html5Mode", "hashPrefix"]
-	    .forEach(function (key) { return services.locationConfig[key] = notImplemented(key); });
-
-
-/***/ },
-/* 7 */
-/***/ function(module, exports) {
-
-	"use strict";
-	/** @module common */
-	/**
-	 * Matches state names using glob-like patterns.
-	 *
-	 * See: [[StateService.includes]]
-	 */
-	var Glob = (function () {
-	    function Glob(text) {
-	        this.text = text;
-	        this.glob = text.split('.');
-	    }
-	    Glob.prototype.matches = function (name) {
-	        var segments = name.split('.');
-	        // match single stars
-	        for (var i = 0, l = this.glob.length; i < l; i++) {
-	            if (this.glob[i] === '*')
-	                segments[i] = '*';
-	        }
-	        // match greedy starts
-	        if (this.glob[0] === '**') {
-	            segments = segments.slice(segments.indexOf(this.glob[1]));
-	            segments.unshift('**');
-	        }
-	        // match greedy ends
-	        if (this.glob[this.glob.length - 1] === '**') {
-	            segments.splice(segments.indexOf(this.glob[this.glob.length - 2]) + 1, Number.MAX_VALUE);
-	            segments.push('**');
-	        }
-	        if (this.glob.length != segments.length)
-	            return false;
-	        return segments.join('') === this.glob.join('');
-	    };
-	    Glob.is = function (text) {
-	        return text.indexOf('*') > -1;
-	    };
-	    Glob.fromString = function (text) {
-	        if (!this.is(text))
-	            return null;
-	        return new Glob(text);
-	    };
-	    return Glob;
-	}());
-	exports.Glob = Glob;
-
-
-/***/ },
-/* 8 */
-/***/ function(module, exports) {
-
-	/** @module common */ /** for typedoc */
-	"use strict";
-	var Queue = (function () {
-	    function Queue(_items, _limit) {
-	        if (_items === void 0) { _items = []; }
-	        if (_limit === void 0) { _limit = null; }
-	        this._items = _items;
-	        this._limit = _limit;
-	    }
-	    Queue.prototype.enqueue = function (item) {
-	        var items = this._items;
-	        items.push(item);
-	        if (this._limit && items.length > this._limit)
-	            items.shift();
-	        return item;
-	    };
-	    Queue.prototype.dequeue = function () {
-	        if (this.size())
-	            return this._items.splice(0, 1)[0];
-	    };
-	    Queue.prototype.clear = function () {
-	        var current = this._items;
-	        this._items = [];
-	        return current;
-	    };
-	    Queue.prototype.size = function () {
-	        return this._items.length;
-	    };
-	    Queue.prototype.remove = function (item) {
-	        var idx = this._items.indexOf(item);
-	        return idx > -1 && this._items.splice(idx, 1)[0];
-	    };
-	    Queue.prototype.peekTail = function () {
-	        return this._items[this._items.length - 1];
-	    };
-	    Queue.prototype.peekHead = function () {
-	        if (this.size())
-	            return this._items[0];
-	    };
-	    return Queue;
-	}());
-	exports.Queue = Queue;
-
-
-/***/ },
-/* 9 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/** @module common_strings */ /** */
-	"use strict";
-	var predicates_1 = __webpack_require__(4);
-	var rejectFactory_1 = __webpack_require__(10);
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	var transition_1 = __webpack_require__(11);
-	var resolvable_1 = __webpack_require__(19);
-	/**
-	 * Returns a string shortened to a maximum length
-	 *
-	 * If the string is already less than the `max` length, return the string.
-	 * Else return the string, shortened to `max - 3` and append three dots ("...").
-	 *
-	 * @param max the maximum length of the string to return
-	 * @param str the input string
-	 */
-	function maxLength(max, str) {
-	    if (str.length <= max)
-	        return str;
-	    return str.substr(0, max - 3) + "...";
-	}
-	exports.maxLength = maxLength;
-	/**
-	 * Returns a string, with spaces added to the end, up to a desired str length
-	 *
-	 * If the string is already longer than the desired length, return the string.
-	 * Else returns the string, with extra spaces on the end, such that it reaches `length` characters.
-	 *
-	 * @param length the desired length of the string to return
-	 * @param str the input string
-	 */
-	function padString(length, str) {
-	    while (str.length < length)
-	        str += " ";
-	    return str;
-	}
-	exports.padString = padString;
-	function kebobString(camelCase) {
-	    return camelCase
-	        .replace(/^([A-Z])/, function ($1) { return $1.toLowerCase(); }) // replace first char
-	        .replace(/([A-Z])/g, function ($1) { return "-" + $1.toLowerCase(); }); // replace rest
-	}
-	exports.kebobString = kebobString;
-	function _toJson(obj) {
-	    return JSON.stringify(obj);
-	}
-	function _fromJson(json) {
-	    return predicates_1.isString(json) ? JSON.parse(json) : json;
-	}
-	function promiseToString(p) {
-	    return "Promise(" + JSON.stringify(p) + ")";
-	}
-	function functionToString(fn) {
-	    var fnStr = fnToString(fn);
-	    var namedFunctionMatch = fnStr.match(/^(function [^ ]+\([^)]*\))/);
-	    return namedFunctionMatch ? namedFunctionMatch[1] : fnStr;
-	}
-	exports.functionToString = functionToString;
-	function fnToString(fn) {
-	    var _fn = predicates_1.isArray(fn) ? fn.slice(-1)[0] : fn;
-	    return _fn && _fn.toString() || "undefined";
-	}
-	exports.fnToString = fnToString;
-	var stringifyPatternFn = null;
-	var stringifyPattern = function (value) {
-	    var isTransitionRejectionPromise = rejectFactory_1.Rejection.isTransitionRejectionPromise;
-	    stringifyPatternFn = stringifyPatternFn || hof_1.pattern([
-	        [hof_1.not(predicates_1.isDefined), hof_1.val("undefined")],
-	        [predicates_1.isNull, hof_1.val("null")],
-	        [predicates_1.isPromise, hof_1.val("[Promise]")],
-	        [isTransitionRejectionPromise, function (x) { return x._transitionRejection.toString(); }],
-	        [hof_1.is(rejectFactory_1.Rejection), hof_1.invoke("toString")],
-	        [hof_1.is(transition_1.Transition), hof_1.invoke("toString")],
-	        [hof_1.is(resolvable_1.Resolvable), hof_1.invoke("toString")],
-	        [predicates_1.isInjectable, functionToString],
-	        [hof_1.val(true), common_1.identity]
-	    ]);
-	    return stringifyPatternFn(value);
-	};
-	function stringify(o) {
-	    var seen = [];
-	    function format(val) {
-	        if (predicates_1.isObject(val)) {
-	            if (seen.indexOf(val) !== -1)
-	                return '[circular ref]';
-	            seen.push(val);
-	        }
-	        return stringifyPattern(val);
-	    }
-	    return JSON.stringify(o, function (key, val) { return format(val); }).replace(/\\"/g, '"');
-	}
-	exports.stringify = stringify;
-	/** Returns a function that splits a string on a character or substring */
-	exports.beforeAfterSubstr = function (char) { return function (str) {
-	    if (!str)
-	        return ["", ""];
-	    var idx = str.indexOf(char);
-	    if (idx === -1)
-	        return [str, ""];
-	    return [str.substr(0, idx), str.substr(idx + 1)];
-	}; };
-
-
-/***/ },
-/* 10 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/** @module transition */ /** for typedoc */
-	"use strict";
-	var common_1 = __webpack_require__(3);
-	var strings_1 = __webpack_require__(9);
-	(function (RejectType) {
-	    RejectType[RejectType["SUPERSEDED"] = 2] = "SUPERSEDED";
-	    RejectType[RejectType["ABORTED"] = 3] = "ABORTED";
-	    RejectType[RejectType["INVALID"] = 4] = "INVALID";
-	    RejectType[RejectType["IGNORED"] = 5] = "IGNORED";
-	    RejectType[RejectType["ERROR"] = 6] = "ERROR";
-	})(exports.RejectType || (exports.RejectType = {}));
-	var RejectType = exports.RejectType;
-	var Rejection = (function () {
-	    function Rejection(type, message, detail) {
-	        this.type = type;
-	        this.message = message;
-	        this.detail = detail;
-	    }
-	    Rejection.prototype.toString = function () {
-	        var detailString = function (d) { return d && d.toString !== Object.prototype.toString ? d.toString() : strings_1.stringify(d); };
-	        var type = this.type, message = this.message, detail = detailString(this.detail);
-	        return "TransitionRejection(type: " + type + ", message: " + message + ", detail: " + detail + ")";
-	    };
-	    Rejection.prototype.toPromise = function () {
-	        return common_1.extend(common_1.silentRejection(this), { _transitionRejection: this });
-	    };
-	    /** Returns true if the obj is a rejected promise created from the `asPromise` factory */
-	    Rejection.isTransitionRejectionPromise = function (obj) {
-	        return obj && (typeof obj.then === 'function') && obj._transitionRejection instanceof Rejection;
-	    };
-	    /** Returns a TransitionRejection due to transition superseded */
-	    Rejection.superseded = function (detail, options) {
-	        var message = "The transition has been superseded by a different transition (see detail).";
-	        var rejection = new Rejection(RejectType.SUPERSEDED, message, detail);
-	        if (options && options.redirected) {
-	            rejection.redirected = true;
-	        }
-	        return rejection;
-	    };
-	    /** Returns a TransitionRejection due to redirected transition */
-	    Rejection.redirected = function (detail) {
-	        return Rejection.superseded(detail, { redirected: true });
-	    };
-	    /** Returns a TransitionRejection due to invalid transition */
-	    Rejection.invalid = function (detail) {
-	        var message = "This transition is invalid (see detail)";
-	        return new Rejection(RejectType.INVALID, message, detail);
-	    };
-	    /** Returns a TransitionRejection due to ignored transition */
-	    Rejection.ignored = function (detail) {
-	        var message = "The transition was ignored.";
-	        return new Rejection(RejectType.IGNORED, message, detail);
-	    };
-	    /** Returns a TransitionRejection due to aborted transition */
-	    Rejection.aborted = function (detail) {
-	        // TODO think about how to encapsulate an Error() object
-	        var message = "The transition has been aborted.";
-	        return new Rejection(RejectType.ABORTED, message, detail);
-	    };
-	    /** Returns a TransitionRejection due to aborted transition */
-	    Rejection.errored = function (detail) {
-	        // TODO think about how to encapsulate an Error() object
-	        var message = "The transition errored.";
-	        return new Rejection(RejectType.ERROR, message, detail);
-	    };
-	    return Rejection;
-	}());
-	exports.Rejection = Rejection;
-
-
-/***/ },
-/* 11 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module transition */ /** for typedoc */
-	var trace_1 = __webpack_require__(12);
-	var coreservices_1 = __webpack_require__(6);
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var hof_1 = __webpack_require__(5);
-	var transitionHook_1 = __webpack_require__(13);
-	var hookRegistry_1 = __webpack_require__(15);
-	var hookBuilder_1 = __webpack_require__(16);
-	var node_1 = __webpack_require__(21);
-	var pathFactory_1 = __webpack_require__(20);
-	var targetState_1 = __webpack_require__(14);
-	var param_1 = __webpack_require__(22);
-	var resolvable_1 = __webpack_require__(19);
-	var rejectFactory_1 = __webpack_require__(10);
-	var resolveContext_1 = __webpack_require__(17);
-	var router_1 = __webpack_require__(26);
-	var transitionCount = 0;
-	var stateSelf = hof_1.prop("self");
-	/**
-	 * Represents a transition between two states.
-	 *
-	 * When navigating to a state, we are transitioning **from** the current state **to** the new state.
-	 *
-	 * This object contains all contextual information about the to/from states, parameters, resolves.
-	 * It has information about all states being entered and exited as a result of the transition.
-	 */
-	var Transition = (function () {
-	    /**
-	     * Creates a new Transition object.
-	     *
-	     * If the target state is not valid, an error is thrown.
-	     *
-	     * @param fromPath The path of [[PathNode]]s from which the transition is leaving.  The last node in the `fromPath`
-	     *        encapsulates the "from state".
-	     * @param targetState The target state and parameters being transitioned to (also, the transition options)
-	     * @param router The [[UIRouter]] instance
-	     */
-	    function Transition(fromPath, targetState, router) {
-	        var _this = this;
-	        /** @hidden */
-	        this._deferred = coreservices_1.services.$q.defer();
-	        /**
-	         * This promise is resolved or rejected based on the outcome of the Transition.
-	         *
-	         * When the transition is successful, the promise is resolved
-	         * When the transition is unsuccessful, the promise is rejected with the [[TransitionRejection]] or javascript error
-	         */
-	        this.promise = this._deferred.promise;
-	        this.treeChanges = function () { return _this._treeChanges; };
-	        this.isActive = function () { return _this === _this._options.current(); };
-	        this.router = router;
-	        if (!targetState.valid()) {
-	            throw new Error(targetState.error());
-	        }
-	        // Makes the Transition instance a hook registry (onStart, etc)
-	        hookRegistry_1.HookRegistry.mixin(new hookRegistry_1.HookRegistry(), this);
-	        // current() is assumed to come from targetState.options, but provide a naive implementation otherwise.
-	        this._options = common_1.extend({ current: hof_1.val(this) }, targetState.options());
-	        this.$id = transitionCount++;
-	        var toPath = pathFactory_1.PathFactory.buildToPath(fromPath, targetState);
-	        this._treeChanges = pathFactory_1.PathFactory.treeChanges(fromPath, toPath, this._options.reloadState);
-	        var enteringStates = this._treeChanges.entering.map(function (node) { return node.state; });
-	        pathFactory_1.PathFactory.applyViewConfigs(router.transitionService.$view, this._treeChanges.to, enteringStates);
-	        var rootResolvables = [
-	            new resolvable_1.Resolvable(router_1.UIRouter, function () { return router; }, [], undefined, router),
-	            new resolvable_1.Resolvable(Transition, function () { return _this; }, [], undefined, this),
-	            new resolvable_1.Resolvable('$transition$', function () { return _this; }, [], undefined, this),
-	            new resolvable_1.Resolvable('$stateParams', function () { return _this.params(); }, [], undefined, this.params())
-	        ];
-	        var rootNode = this._treeChanges.to[0];
-	        var context = new resolveContext_1.ResolveContext(this._treeChanges.to);
-	        context.addResolvables(rootResolvables, rootNode.state);
-	    }
-	    /** @inheritdoc */
-	    Transition.prototype.onBefore = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    Transition.prototype.onStart = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    Transition.prototype.onExit = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    Transition.prototype.onRetain = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    Transition.prototype.onEnter = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    Transition.prototype.onFinish = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    Transition.prototype.onSuccess = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    Transition.prototype.onError = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    Transition.prototype.$from = function () {
-	        return common_1.tail(this._treeChanges.from).state;
-	    };
-	    Transition.prototype.$to = function () {
-	        return common_1.tail(this._treeChanges.to).state;
-	    };
-	    /**
-	     * Returns the "from state"
-	     *
-	     * @returns The state object for the Transition's "from state".
-	     */
-	    Transition.prototype.from = function () {
-	        return this.$from().self;
-	    };
-	    /**
-	     * Returns the "to state"
-	     *
-	     * @returns The state object for the Transition's target state ("to state").
-	     */
-	    Transition.prototype.to = function () {
-	        return this.$to().self;
-	    };
-	    /**
-	     * Determines whether two transitions are equivalent.
-	     */
-	    Transition.prototype.is = function (compare) {
-	        if (compare instanceof Transition) {
-	            // TODO: Also compare parameters
-	            return this.is({ to: compare.$to().name, from: compare.$from().name });
-	        }
-	        return !((compare.to && !hookRegistry_1.matchState(this.$to(), compare.to)) ||
-	            (compare.from && !hookRegistry_1.matchState(this.$from(), compare.from)));
-	    };
-	    /**
-	     * Gets transition parameter values
-	     *
-	     * @param pathname Pick which treeChanges path to get parameters for:
-	     *   (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)
-	     * @returns transition parameter values for the desired path.
-	     */
-	    Transition.prototype.params = function (pathname) {
-	        if (pathname === void 0) { pathname = "to"; }
-	        return this._treeChanges[pathname].map(hof_1.prop("paramValues")).reduce(common_1.mergeR, {});
-	    };
-	    /**
-	     * Creates a [[UIInjector]] Dependency Injector
-	     *
-	     * Returns a Dependency Injector for the Transition's target state (to state).
-	     * The injector provides resolve values which the target state has access to.
-	     *
-	     * The `UIInjector` can also provide values from the native root/global injector (ng1/ng2).
-	     *
-	     * If a `state` is provided, the injector that is returned will be limited to resolve values that the provided state has access to.
-	     *
-	     * @param state Limits the resolves provided to only the resolves the provided state has access to.
-	     * @returns a [[UIInjector]]
-	     */
-	    Transition.prototype.injector = function (state) {
-	        var path = this.treeChanges().to;
-	        if (state)
-	            path = pathFactory_1.PathFactory.subPath(path, function (node) { return node.state === state || node.state.name === state; });
-	        return new resolveContext_1.ResolveContext(path).injector();
-	    };
-	    /**
-	     * Gets all available resolve tokens (keys)
-	     *
-	     * This method can be used in conjunction with [[getResolve]] to inspect the resolve values
-	     * available to the Transition.
-	     *
-	     * The returned tokens include those defined on [[StateDeclaration.resolve]] blocks, for the states
-	     * in the Transition's [[TreeChanges.to]] path.
-	     *
-	     * @returns an array of resolve tokens (keys)
-	     */
-	    Transition.prototype.getResolveTokens = function () {
-	        return new resolveContext_1.ResolveContext(this._treeChanges.to).getTokens();
-	    };
-	    /**
-	     * Gets resolved values
-	     *
-	     * This method can be used in conjunction with [[getResolveTokens]] to inspect what resolve values
-	     * are available to the Transition.
-	     *
-	     * Given a token, returns the resolved data for that token.
-	     * Given an array of tokens, returns an array of resolved data for those tokens.
-	     *
-	     * If a resolvable hasn't yet been fetched, returns `undefined` for that token
-	     * If a resolvable doesn't exist for the token, throws an error.
-	     *
-	     * @param token the token (or array of tokens)
-	     *
-	     * @returns an array of resolve tokens (keys)
-	     */
-	    Transition.prototype.getResolveValue = function (token) {
-	        var resolveContext = new resolveContext_1.ResolveContext(this._treeChanges.to);
-	        var getData = function (token) {
-	            var resolvable = resolveContext.getResolvable(token);
-	            if (resolvable === undefined) {
-	                throw new Error("Dependency Injection token not found: ${stringify(token)}");
-	            }
-	            return resolvable.data;
-	        };
-	        if (predicates_1.isArray(token)) {
-	            return token.map(getData);
-	        }
-	        return getData(token);
-	    };
-	    /**
-	     * Dynamically adds a new [[Resolvable]] (`resolve`) to this transition.
-	     *
-	     * @param resolvable an [[Resolvable]] object
-	     * @param state the state in the "to path" which should receive the new resolve (otherwise, the root state)
-	     */
-	    Transition.prototype.addResolvable = function (resolvable, state) {
-	        if (state === void 0) { state = ""; }
-	        var stateName = (typeof state === "string") ? state : state.name;
-	        var topath = this._treeChanges.to;
-	        var targetNode = common_1.find(topath, function (node) { return node.state.name === stateName; });
-	        var resolveContext = new resolveContext_1.ResolveContext(topath);
-	        resolveContext.addResolvables([resolvable], targetNode.state);
-	    };
-	    /**
-	     * Gets the previous transition, from which this transition was redirected.
-	     *
-	     * @returns The previous Transition, or null if this Transition is not the result of a redirection
-	     */
-	    Transition.prototype.previous = function () {
-	        return this._options.previous || null;
-	    };
-	    /**
-	     * Get the transition options
-	     *
-	     * @returns the options for this Transition.
-	     */
-	    Transition.prototype.options = function () {
-	        return this._options;
-	    };
-	    /**
-	     * Gets the states being entered.
-	     *
-	     * @returns an array of states that will be entered during this transition.
-	     */
-	    Transition.prototype.entering = function () {
-	        return common_1.map(this._treeChanges.entering, hof_1.prop('state')).map(stateSelf);
-	    };
-	    /**
-	     * Gets the states being exited.
-	     *
-	     * @returns an array of states that will be exited during this transition.
-	     */
-	    Transition.prototype.exiting = function () {
-	        return common_1.map(this._treeChanges.exiting, hof_1.prop('state')).map(stateSelf).reverse();
-	    };
-	    /**
-	     * Gets the states being retained.
-	     *
-	     * @returns an array of states that are already entered from a previous Transition, that will not be
-	     *    exited during this Transition
-	     */
-	    Transition.prototype.retained = function () {
-	        return common_1.map(this._treeChanges.retained, hof_1.prop('state')).map(stateSelf);
-	    };
-	    /**
-	     * Get the [[ViewConfig]]s associated with this Transition
-	     *
-	     * Each state can define one or more views (template/controller), which are encapsulated as `ViewConfig` objects.
-	     * This method fetches the `ViewConfigs` for a given path in the Transition (e.g., "to" or "entering").
-	     *
-	     * @param pathname the name of the path to fetch views for:
-	     *   (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)
-	     * @param state If provided, only returns the `ViewConfig`s for a single state in the path
-	     *
-	     * @returns a list of ViewConfig objects for the given path.
-	     */
-	    Transition.prototype.views = function (pathname, state) {
-	        if (pathname === void 0) { pathname = "entering"; }
-	        var path = this._treeChanges[pathname];
-	        path = !state ? path : path.filter(hof_1.propEq('state', state));
-	        return path.map(hof_1.prop("views")).filter(common_1.identity).reduce(common_1.unnestR, []);
-	    };
-	    /**
-	     * Creates a new transition that is a redirection of the current one.
-	     *
-	     * This transition can be returned from a [[TransitionService]] hook to
-	     * redirect a transition to a new state and/or set of parameters.
-	     *
-	     * @returns Returns a new [[Transition]] instance.
-	     */
-	    Transition.prototype.redirect = function (targetState) {
-	        var newOptions = common_1.extend({}, this.options(), targetState.options(), { previous: this });
-	        targetState = new targetState_1.TargetState(targetState.identifier(), targetState.$state(), targetState.params(), newOptions);
-	        var newTransition = this.router.transitionService.create(this._treeChanges.from, targetState);
-	        var originalEnteringNodes = this.treeChanges().entering;
-	        var redirectEnteringNodes = newTransition.treeChanges().entering;
-	        // --- Re-use resolve data from original transition ---
-	        // When redirecting from a parent state to a child state where the parent parameter values haven't changed
-	        // (because of the redirect), the resolves fetched by the original transition are still valid in the
-	        // redirected transition.
-	        //
-	        // This allows you to define a redirect on a parent state which depends on an async resolve value.
-	        // You can wait for the resolve, then redirect to a child state based on the result.
-	        // The redirected transition does not have to re-fetch the resolve.
-	        // ---------------------------------------------------------
-	        var nodeIsReloading = function (reloadState) { return function (node) {
-	            return reloadState && node.state.includes[reloadState.name];
-	        }; };
-	        // Find any "entering" nodes in the redirect path that match the original path and aren't being reloaded
-	        var matchingEnteringNodes = node_1.PathNode.matching(redirectEnteringNodes, originalEnteringNodes)
-	            .filter(hof_1.not(nodeIsReloading(targetState.options().reloadState)));
-	        // Use the existing (possibly pre-resolved) resolvables for the matching entering nodes.
-	        matchingEnteringNodes.forEach(function (node, idx) {
-	            node.resolvables = originalEnteringNodes[idx].resolvables;
-	        });
-	        return newTransition;
-	    };
-	    /** @hidden If a transition doesn't exit/enter any states, returns any [[Param]] whose value changed */
-	    Transition.prototype._changedParams = function () {
-	        var _a = this._treeChanges, to = _a.to, from = _a.from;
-	        if (this._options.reload || common_1.tail(to).state !== common_1.tail(from).state)
-	            return undefined;
-	        var nodeSchemas = to.map(function (node) { return node.paramSchema; });
-	        var _b = [to, from].map(function (path) { return path.map(function (x) { return x.paramValues; }); }), toValues = _b[0], fromValues = _b[1];
-	        var tuples = common_1.arrayTuples(nodeSchemas, toValues, fromValues);
-	        return tuples.map(function (_a) {
-	            var schema = _a[0], toVals = _a[1], fromVals = _a[2];
-	            return param_1.Param.changed(schema, toVals, fromVals);
-	        }).reduce(common_1.unnestR, []);
-	    };
-	    /**
-	     * Returns true if the transition is dynamic.
-	     *
-	     * A transition is dynamic if no states are entered nor exited, but at least one dynamic parameter has changed.
-	     *
-	     * @returns true if the Transition is dynamic
-	     */
-	    Transition.prototype.dynamic = function () {
-	        var changes = this._changedParams();
-	        return !changes ? false : changes.map(function (x) { return x.dynamic; }).reduce(common_1.anyTrueR, false);
-	    };
-	    /**
-	     * Returns true if the transition is ignored.
-	     *
-	     * A transition is ignored if no states are entered nor exited, and no parameter values have changed.
-	     *
-	     * @returns true if the Transition is ignored.
-	     */
-	    Transition.prototype.ignored = function () {
-	        var changes = this._changedParams();
-	        return !changes ? false : changes.length === 0;
-	    };
-	    /**
-	     * @hidden
-	     */
-	    Transition.prototype.hookBuilder = function () {
-	        return new hookBuilder_1.HookBuilder(this.router.transitionService, this, {
-	            transition: this,
-	            current: this._options.current
-	        });
-	    };
-	    /**
-	     * Runs the transition
-	     *
-	     * This method is generally called from the [[StateService.transitionTo]]
-	     *
-	     * @returns a promise for a successful transition.
-	     */
-	    Transition.prototype.run = function () {
-	        var _this = this;
-	        var runSynchronousHooks = transitionHook_1.TransitionHook.runSynchronousHooks;
-	        var hookBuilder = this.hookBuilder();
-	        var globals = this.router.globals;
-	        globals.transitionHistory.enqueue(this);
-	        var syncResult = runSynchronousHooks(hookBuilder.getOnBeforeHooks());
-	        if (rejectFactory_1.Rejection.isTransitionRejectionPromise(syncResult)) {
-	            syncResult.catch(function () { return 0; }); // issue #2676
-	            var rejectReason = syncResult._transitionRejection;
-	            this._deferred.reject(rejectReason);
-	            return this.promise;
-	        }
-	        if (!this.valid()) {
-	            var error = new Error(this.error());
-	            this._deferred.reject(error);
-	            return this.promise;
-	        }
-	        if (this.ignored()) {
-	            trace_1.trace.traceTransitionIgnored(this);
-	            this._deferred.reject(rejectFactory_1.Rejection.ignored());
-	            return this.promise;
-	        }
-	        // When the chain is complete, then resolve or reject the deferred
-	        var transitionSuccess = function () {
-	            trace_1.trace.traceSuccess(_this.$to(), _this);
-	            _this.success = true;
-	            _this._deferred.resolve(_this.to());
-	            runSynchronousHooks(hookBuilder.getOnSuccessHooks(), true);
-	        };
-	        var transitionError = function (error) {
-	            trace_1.trace.traceError(error, _this);
-	            _this.success = false;
-	            _this._deferred.reject(error);
-	            runSynchronousHooks(hookBuilder.getOnErrorHooks(), true);
-	        };
-	        trace_1.trace.traceTransitionStart(this);
-	        // Chain the next hook off the previous
-	        var appendHookToChain = function (prev, nextHook) {
-	            return prev.then(function () { return nextHook.invokeHook(); });
-	        };
-	        // Run the hooks, then resolve or reject the overall deferred in the .then() handler
-	        hookBuilder.asyncHooks()
-	            .reduce(appendHookToChain, syncResult)
-	            .then(transitionSuccess, transitionError);
-	        return this.promise;
-	    };
-	    /**
-	     * Checks if the Transition is valid
-	     *
-	     * @returns true if the Transition is valid
-	     */
-	    Transition.prototype.valid = function () {
-	        return !this.error();
-	    };
-	    /**
-	     * The reason the Transition is invalid
-	     *
-	     * @returns an error message explaining why the transition is invalid
-	     */
-	    Transition.prototype.error = function () {
-	        var state = this.$to();
-	        if (state.self[common_1.abstractKey])
-	            return "Cannot transition to abstract state '" + state.name + "'";
-	        if (!param_1.Param.validates(state.parameters(), this.params()))
-	            return "Param values not valid for state '" + state.name + "'";
-	    };
-	    /**
-	     * A string representation of the Transition
-	     *
-	     * @returns A string representation of the Transition
-	     */
-	    Transition.prototype.toString = function () {
-	        var fromStateOrName = this.from();
-	        var toStateOrName = this.to();
-	        var avoidEmptyHash = function (params) {
-	            return (params["#"] !== null && params["#"] !== undefined) ? params : common_1.omit(params, "#");
-	        };
-	        // (X) means the to state is invalid.
-	        var id = this.$id, from = predicates_1.isObject(fromStateOrName) ? fromStateOrName.name : fromStateOrName, fromParams = common_1.toJson(avoidEmptyHash(this._treeChanges.from.map(hof_1.prop('paramValues')).reduce(common_1.mergeR, {}))), toValid = this.valid() ? "" : "(X) ", to = predicates_1.isObject(toStateOrName) ? toStateOrName.name : toStateOrName, toParams = common_1.toJson(avoidEmptyHash(this.params()));
-	        return "Transition#" + id + "( '" + from + "'" + fromParams + " -> " + toValid + "'" + to + "'" + toParams + " )";
-	    };
-	    Transition.diToken = Transition;
-	    return Transition;
-	}());
-	exports.Transition = Transition;
-
-
-/***/ },
-/* 12 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/**
-	 * UI-Router Transition Tracing
-	 *
-	 * Enable transition tracing to print transition information to the console, in order to help debug your application.
-	 * Tracing logs detailed information about each Transition to your console.
-	 *
-	 * To enable tracing, import the [[trace]] singleton and enable one or more categories.
-	 *
-	 * ES6
-	 * ```
-	 *
-	 * import {trace} from "ui-router-ng2"; // or "angular-ui-router"
-	 * trace.enable(1, 5); // TRANSITION and VIEWCONFIG
-	 * ```
-	 *
-	 * CJS
-	 * ```
-	 *
-	 * let trace = require("angular-ui-router").trace; // or "ui-router-ng2"
-	 * trace.enable("TRANSITION", "VIEWCONFIG");
-	 * ```
-	 *
-	 * Globals
-	 * ```
-	 *
-	 * let trace = window["angular-ui-router"].trace; // or "ui-router-ng2"
-	 * trace.enable(); // Trace everything (very verbose)
-	 * ```
-	 *
-	 * @module trace
-	 */ /** for typedoc */
-	var hof_1 = __webpack_require__(5);
-	var predicates_1 = __webpack_require__(4);
-	var strings_1 = __webpack_require__(9);
-	/** @hidden */
-	function uiViewString(viewData) {
-	    if (!viewData)
-	        return 'ui-view (defunct)';
-	    return ("[ui-view#" + viewData.id + " tag ") +
-	        ("in template from '" + (viewData.creationContext && viewData.creationContext.name || '(root)') + "' state]: ") +
-	        ("fqn: '" + viewData.fqn + "', ") +
-	        ("name: '" + viewData.name + "@" + viewData.creationContext + "')");
-	}
-	/** @hidden */
-	var viewConfigString = function (viewConfig) {
-	    return ("[ViewConfig#" + viewConfig.$id + " from '" + (viewConfig.viewDecl.$context.name || '(root)') + "' state]: target ui-view: '" + viewConfig.viewDecl.$uiViewName + "@" + viewConfig.viewDecl.$uiViewContextAnchor + "'");
-	};
-	/** @hidden */
-	function normalizedCat(input) {
-	    return predicates_1.isNumber(input) ? Category[input] : Category[Category[input]];
-	}
-	/**
-	 * Trace categories
-	 *
-	 * [[Trace.enable]] or [[Trace.disable]] a category
-	 *
-	 * `trace.enable(Category.TRANSITION)`
-	 *
-	 * These can also be provided using a matching string, or position ordinal
-	 *
-	 * `trace.enable("TRANSITION")`
-	 *
-	 * `trace.enable(1)`
-	 */
-	(function (Category) {
-	    Category[Category["RESOLVE"] = 0] = "RESOLVE";
-	    Category[Category["TRANSITION"] = 1] = "TRANSITION";
-	    Category[Category["HOOK"] = 2] = "HOOK";
-	    Category[Category["INVOKE"] = 3] = "INVOKE";
-	    Category[Category["UIVIEW"] = 4] = "UIVIEW";
-	    Category[Category["VIEWCONFIG"] = 5] = "VIEWCONFIG";
-	})(exports.Category || (exports.Category = {}));
-	var Category = exports.Category;
-	/**
-	 * Prints UI-Router Transition trace information to the console.
-	 */
-	var Trace = (function () {
-	    function Trace() {
-	        /** @hidden */
-	        this._enabled = {};
-	        this.approximateDigests = 0;
-	    }
-	    /** @hidden */
-	    Trace.prototype._set = function (enabled, categories) {
-	        var _this = this;
-	        if (!categories.length) {
-	            categories = Object.keys(Category)
-	                .filter(function (k) { return isNaN(parseInt(k, 10)); })
-	                .map(function (key) { return Category[key]; });
-	        }
-	        categories.map(normalizedCat).forEach(function (category) { return _this._enabled[category] = enabled; });
-	    };
-	    /**
-	     * Enables a trace [[Category]]
-	     *
-	     * ```
-	     * trace.enable("TRANSITION");
-	     * ```
-	     *
-	     * @param categories categories to enable. If `categories` is omitted, all categories are enabled.
-	     *        Also takes strings (category name) or ordinal (category position)
-	     */
-	    Trace.prototype.enable = function () {
-	        var categories = [];
-	        for (var _i = 0; _i < arguments.length; _i++) {
-	            categories[_i - 0] = arguments[_i];
-	        }
-	        this._set(true, categories);
-	    };
-	    /**
-	     * Disables a trace [[Category]]
-	     *
-	     * ```
-	     * trace.disable("VIEWCONFIG");
-	     * ```
-	     *
-	     * @param categories categories to disable. If `categories` is omitted, all categories are disabled.
-	     *        Also takes strings (category name) or ordinal (category position)
-	     */
-	    Trace.prototype.disable = function () {
-	        var categories = [];
-	        for (var _i = 0; _i < arguments.length; _i++) {
-	            categories[_i - 0] = arguments[_i];
-	        }
-	        this._set(false, categories);
-	    };
-	    /**
-	     * Retrieves the enabled stateus of a [[Category]]
-	     *
-	     * ```
-	     * trace.enabled("VIEWCONFIG"); // true or false
-	     * ```
-	     *
-	     * @returns boolean true if the category is enabled
-	     */
-	    Trace.prototype.enabled = function (category) {
-	        return !!this._enabled[normalizedCat(category)];
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceTransitionStart = function (transition) {
-	        if (!this.enabled(Category.TRANSITION))
-	            return;
-	        var tid = transition.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(transition);
-	        console.log("Transition #" + tid + " Digest #" + digest + ": Started  -> " + transitionStr);
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceTransitionIgnored = function (trans) {
-	        if (!this.enabled(Category.TRANSITION))
-	            return;
-	        var tid = trans && trans.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(trans);
-	        console.log("Transition #" + tid + " Digest #" + digest + ": Ignored  <> " + transitionStr);
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceHookInvocation = function (step, options) {
-	        if (!this.enabled(Category.HOOK))
-	            return;
-	        var tid = hof_1.parse("transition.$id")(options), digest = this.approximateDigests, event = hof_1.parse("traceData.hookType")(options) || "internal", context = hof_1.parse("traceData.context.state.name")(options) || hof_1.parse("traceData.context")(options) || "unknown", name = strings_1.functionToString(step.fn);
-	        console.log("Transition #" + tid + " Digest #" + digest + ":   Hook -> " + event + " context: " + context + ", " + strings_1.maxLength(200, name));
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceHookResult = function (hookResult, transitionResult, transitionOptions) {
-	        if (!this.enabled(Category.HOOK))
-	            return;
-	        var tid = hof_1.parse("transition.$id")(transitionOptions), digest = this.approximateDigests, hookResultStr = strings_1.stringify(hookResult), transitionResultStr = strings_1.stringify(transitionResult);
-	        console.log("Transition #" + tid + " Digest #" + digest + ":   <- Hook returned: " + strings_1.maxLength(200, hookResultStr) + ", transition result: " + strings_1.maxLength(200, transitionResultStr));
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceResolvePath = function (path, when, trans) {
-	        if (!this.enabled(Category.RESOLVE))
-	            return;
-	        var tid = trans && trans.$id, digest = this.approximateDigests, pathStr = path && path.toString();
-	        console.log("Transition #" + tid + " Digest #" + digest + ":         Resolving " + pathStr + " (" + when + ")");
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceResolvableResolved = function (resolvable, trans) {
-	        if (!this.enabled(Category.RESOLVE))
-	            return;
-	        var tid = trans && trans.$id, digest = this.approximateDigests, resolvableStr = resolvable && resolvable.toString(), result = strings_1.stringify(resolvable.data);
-	        console.log("Transition #" + tid + " Digest #" + digest + ":               <- Resolved  " + resolvableStr + " to: " + strings_1.maxLength(200, result));
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceError = function (error, trans) {
-	        if (!this.enabled(Category.TRANSITION))
-	            return;
-	        var tid = trans && trans.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(trans);
-	        console.log("Transition #" + tid + " Digest #" + digest + ": <- Rejected " + transitionStr + ", reason: " + error);
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceSuccess = function (finalState, trans) {
-	        if (!this.enabled(Category.TRANSITION))
-	            return;
-	        var tid = trans && trans.$id, digest = this.approximateDigests, state = finalState.name, transitionStr = strings_1.stringify(trans);
-	        console.log("Transition #" + tid + " Digest #" + digest + ": <- Success  " + transitionStr + ", final state: " + state);
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceUIViewEvent = function (event, viewData, extra) {
-	        if (extra === void 0) { extra = ""; }
-	        if (!this.enabled(Category.UIVIEW))
-	            return;
-	        console.log("ui-view: " + strings_1.padString(30, event) + " " + uiViewString(viewData) + extra);
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceUIViewConfigUpdated = function (viewData, context) {
-	        if (!this.enabled(Category.UIVIEW))
-	            return;
-	        this.traceUIViewEvent("Updating", viewData, " with ViewConfig from context='" + context + "'");
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceUIViewScopeCreated = function (viewData, newScope) {
-	        if (!this.enabled(Category.UIVIEW))
-	            return;
-	        this.traceUIViewEvent("Created scope for", viewData, ", scope #" + newScope.$id);
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceUIViewFill = function (viewData, html) {
-	        if (!this.enabled(Category.UIVIEW))
-	            return;
-	        this.traceUIViewEvent("Fill", viewData, " with: " + strings_1.maxLength(200, html));
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceViewServiceEvent = function (event, viewConfig) {
-	        if (!this.enabled(Category.VIEWCONFIG))
-	            return;
-	        console.log("VIEWCONFIG: " + event + " " + viewConfigString(viewConfig));
-	    };
-	    /** called by ui-router code */
-	    Trace.prototype.traceViewServiceUIViewEvent = function (event, viewData) {
-	        if (!this.enabled(Category.VIEWCONFIG))
-	            return;
-	        console.log("VIEWCONFIG: " + event + " " + uiViewString(viewData));
-	    };
-	    return Trace;
-	}());
-	exports.Trace = Trace;
-	/**
-	 * The [[Trace]] singleton
-	 *
-	 * @example
-	 * ```js
-	 *
-	 * import {trace} from "angular-ui-router";
-	 * trace.enable(1, 5);
-	 * ```
-	 */
-	var trace = new Trace();
-	exports.trace = trace;
-
-
-/***/ },
-/* 13 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	var common_1 = __webpack_require__(3);
-	var strings_1 = __webpack_require__(9);
-	var predicates_1 = __webpack_require__(4);
-	var hof_1 = __webpack_require__(5);
-	var trace_1 = __webpack_require__(12);
-	var coreservices_1 = __webpack_require__(6);
-	var rejectFactory_1 = __webpack_require__(10);
-	var targetState_1 = __webpack_require__(14);
-	var defaultOptions = {
-	    async: true,
-	    rejectIfSuperseded: true,
-	    current: common_1.noop,
-	    transition: null,
-	    traceData: {},
-	    bind: null
-	};
-	/** @hidden */
-	var TransitionHook = (function () {
-	    function TransitionHook(transition, stateContext, hookFn, resolveContext, options) {
-	        var _this = this;
-	        this.transition = transition;
-	        this.stateContext = stateContext;
-	        this.hookFn = hookFn;
-	        this.resolveContext = resolveContext;
-	        this.options = options;
-	        this.isSuperseded = function () { return _this.options.current() !== _this.options.transition; };
-	        this.options = common_1.defaults(options, defaultOptions);
-	    }
-	    TransitionHook.prototype.invokeHook = function () {
-	        var _a = this, options = _a.options, hookFn = _a.hookFn, resolveContext = _a.resolveContext;
-	        trace_1.trace.traceHookInvocation(this, options);
-	        if (options.rejectIfSuperseded && this.isSuperseded()) {
-	            return rejectFactory_1.Rejection.superseded(options.current()).toPromise();
-	        }
-	        var hookResult = hookFn.call(options.bind, this.transition, this.stateContext);
-	        return this.handleHookResult(hookResult);
-	    };
-	    /**
-	     * This method handles the return value of a Transition Hook.
-	     *
-	     * A hook can return false, a redirect (TargetState), or a promise (which may resolve to false or a redirect)
-	     */
-	    TransitionHook.prototype.handleHookResult = function (hookResult) {
-	        var _this = this;
-	        if (!predicates_1.isDefined(hookResult))
-	            return undefined;
-	        /**
-	         * Handles transition superseded, transition aborted and transition redirect.
-	         */
-	        var mapHookResult = hof_1.pattern([
-	            // Transition is no longer current
-	            [this.isSuperseded, function () { return rejectFactory_1.Rejection.superseded(_this.options.current()).toPromise(); }],
-	            // If the hook returns false, abort the current Transition
-	            [hof_1.eq(false), function () { return rejectFactory_1.Rejection.aborted("Hook aborted transition").toPromise(); }],
-	            // If the hook returns a Transition, halt the current Transition and redirect to that Transition.
-	            [hof_1.is(targetState_1.TargetState), function (target) { return rejectFactory_1.Rejection.redirected(target).toPromise(); }],
-	            // A promise was returned, wait for the promise and then chain another hookHandler
-	            [predicates_1.isPromise, function (promise) { return promise.then(_this.handleHookResult.bind(_this)); }]
-	        ]);
-	        var transitionResult = mapHookResult(hookResult);
-	        if (transitionResult)
-	            trace_1.trace.traceHookResult(hookResult, transitionResult, this.options);
-	        return transitionResult;
-	    };
-	    TransitionHook.prototype.toString = function () {
-	        var _a = this, options = _a.options, hookFn = _a.hookFn;
-	        var event = hof_1.parse("traceData.hookType")(options) || "internal", context = hof_1.parse("traceData.context.state.name")(options) || hof_1.parse("traceData.context")(options) || "unknown", name = strings_1.fnToString(hookFn);
-	        return event + " context: " + context + ", " + strings_1.maxLength(200, name);
-	    };
-	    /**
-	     * Given an array of TransitionHooks, runs each one synchronously and sequentially.
-	     *
-	     * Returns a promise chain composed of any promises returned from each hook.invokeStep() call
-	     */
-	    TransitionHook.runSynchronousHooks = function (hooks, swallowExceptions) {
-	        if (swallowExceptions === void 0) { swallowExceptions = false; }
-	        var results = [];
-	        for (var i = 0; i < hooks.length; i++) {
-	            try {
-	                results.push(hooks[i].invokeHook());
-	            }
-	            catch (exception) {
-	                if (!swallowExceptions) {
-	                    return rejectFactory_1.Rejection.errored(exception).toPromise();
-	                }
-	                console.error("Swallowed exception during synchronous hook handler: " + exception); // TODO: What to do here?
-	            }
-	        }
-	        var rejections = results.filter(rejectFactory_1.Rejection.isTransitionRejectionPromise);
-	        if (rejections.length)
-	            return rejections[0];
-	        return results
-	            .filter(predicates_1.isPromise)
-	            .reduce(function (chain, promise) { return chain.then(hof_1.val(promise)); }, coreservices_1.services.$q.when());
-	    };
-	    return TransitionHook;
-	}());
-	exports.TransitionHook = TransitionHook;
-
-
-/***/ },
-/* 14 */
-/***/ function(module, exports) {
-
-	/** @module state */ /** for typedoc */
-	"use strict";
-	/**
-	 * @ngdoc object
-	 * @name ui.router.state.type:TargetState
-	 *
-	 * @description
-	 * Encapsulate the desired target of a transition.
-	 * Wraps an identifier for a state, a set of parameters, and transition options with the definition of the state.
-	 *
-	 * @param {StateOrName} _identifier  An identifier for a state. Either a fully-qualified path, or the object
-	 *            used to define the state.
-	 * @param {IState} _definition The `State` object definition.
-	 * @param {ParamsOrArray} _params Parameters for the target state
-	 * @param {TransitionOptions} _options Transition options.
-	 */
-	var TargetState = (function () {
-	    function TargetState(_identifier, _definition, _params, _options) {
-	        if (_params === void 0) { _params = {}; }
-	        if (_options === void 0) { _options = {}; }
-	        this._identifier = _identifier;
-	        this._definition = _definition;
-	        this._options = _options;
-	        this._params = _params || {};
-	    }
-	    TargetState.prototype.name = function () {
-	        return this._definition && this._definition.name || this._identifier;
-	    };
-	    TargetState.prototype.identifier = function () {
-	        return this._identifier;
-	    };
-	    TargetState.prototype.params = function () {
-	        return this._params;
-	    };
-	    TargetState.prototype.$state = function () {
-	        return this._definition;
-	    };
-	    TargetState.prototype.state = function () {
-	        return this._definition && this._definition.self;
-	    };
-	    TargetState.prototype.options = function () {
-	        return this._options;
-	    };
-	    TargetState.prototype.exists = function () {
-	        return !!(this._definition && this._definition.self);
-	    };
-	    TargetState.prototype.valid = function () {
-	        return !this.error();
-	    };
-	    TargetState.prototype.error = function () {
-	        var base = this.options().relative;
-	        if (!this._definition && !!base) {
-	            var stateName = base.name ? base.name : base;
-	            return "Could not resolve '" + this.name() + "' from state '" + stateName + "'";
-	        }
-	        if (!this._definition)
-	            return "No such state '" + this.name() + "'";
-	        if (!this._definition.self)
-	            return "State '" + this.name() + "' has an invalid definition";
-	    };
-	    return TargetState;
-	}());
-	exports.TargetState = TargetState;
-
-
-/***/ },
-/* 15 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module transition */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var glob_1 = __webpack_require__(7);
-	/**
-	 * Determines if the given state matches the matchCriteria
-	 *
-	 * @hidden
-	 *
-	 * @param state a State Object to test against
-	 * @param criterion
-	 * - If a string, matchState uses the string as a glob-matcher against the state name
-	 * - If an array (of strings), matchState uses each string in the array as a glob-matchers against the state name
-	 *   and returns a positive match if any of the globs match.
-	 * - If a function, matchState calls the function with the state and returns true if the function's result is truthy.
-	 * @returns {boolean}
-	 */
-	function matchState(state, criterion) {
-	    var toMatch = predicates_1.isString(criterion) ? [criterion] : criterion;
-	    function matchGlobs(_state) {
-	        var globStrings = toMatch;
-	        for (var i = 0; i < globStrings.length; i++) {
-	            var glob = glob_1.Glob.fromString(globStrings[i]);
-	            if ((glob && glob.matches(_state.name)) || (!glob && globStrings[i] === _state.name)) {
-	                return true;
-	            }
-	        }
-	        return false;
-	    }
-	    var matchFn = (predicates_1.isFunction(toMatch) ? toMatch : matchGlobs);
-	    return !!matchFn(state);
-	}
-	exports.matchState = matchState;
-	/** @hidden */
-	var EventHook = (function () {
-	    function EventHook(matchCriteria, callback, options) {
-	        if (options === void 0) { options = {}; }
-	        this.callback = callback;
-	        this.matchCriteria = common_1.extend({ to: true, from: true, exiting: true, retained: true, entering: true }, matchCriteria);
-	        this.priority = options.priority || 0;
-	        this.bind = options.bind || null;
-	    }
-	    EventHook._matchingNodes = function (nodes, criterion) {
-	        if (criterion === true)
-	            return nodes;
-	        var matching = nodes.filter(function (node) { return matchState(node.state, criterion); });
-	        return matching.length ? matching : null;
-	    };
-	    /**
-	     * Determines if this hook's [[matchCriteria]] match the given [[TreeChanges]]
-	     *
-	     * @returns an IMatchingNodes object, or null. If an IMatchingNodes object is returned, its values
-	     * are the matching [[PathNode]]s for each [[HookMatchCriterion]] (to, from, exiting, retained, entering)
-	     */
-	    EventHook.prototype.matches = function (treeChanges) {
-	        var mc = this.matchCriteria, _matchingNodes = EventHook._matchingNodes;
-	        var matches = {
-	            to: _matchingNodes([common_1.tail(treeChanges.to)], mc.to),
-	            from: _matchingNodes([common_1.tail(treeChanges.from)], mc.from),
-	            exiting: _matchingNodes(treeChanges.exiting, mc.exiting),
-	            retained: _matchingNodes(treeChanges.retained, mc.retained),
-	            entering: _matchingNodes(treeChanges.entering, mc.entering),
-	        };
-	        // Check if all the criteria matched the TreeChanges object
-	        var allMatched = ["to", "from", "exiting", "retained", "entering"]
-	            .map(function (prop) { return matches[prop]; })
-	            .reduce(common_1.allTrueR, true);
-	        return allMatched ? matches : null;
-	    };
-	    return EventHook;
-	}());
-	exports.EventHook = EventHook;
-	/** @hidden Return a registration function of the requested type. */
-	function makeHookRegistrationFn(hooks, name) {
-	    return function (matchObject, callback, options) {
-	        if (options === void 0) { options = {}; }
-	        var eventHook = new EventHook(matchObject, callback, options);
-	        hooks[name].push(eventHook);
-	        return function deregisterEventHook() {
-	            common_1.removeFrom(hooks[name])(eventHook);
-	        };
-	    };
-	}
-	/**
-	 * Mixin class acts as a Transition Hook registry.
-	 *
-	 * Holds the registered [[HookFn]] objects.
-	 * Exposes functions to register new hooks.
-	 *
-	 * This is a Mixin class which can be applied to other objects.
-	 *
-	 * The hook registration functions are [[onBefore]], [[onStart]], [[onEnter]], [[onRetain]], [[onExit]], [[onFinish]], [[onSuccess]], [[onError]].
-	 *
-	 * This class is mixed into both the [[TransitionService]] and every [[Transition]] object.
-	 * Global hooks are added to the [[TransitionService]].
-	 * Since each [[Transition]] is itself a `HookRegistry`, hooks can also be added to individual Transitions
-	 * (note: the hook criteria still must match the Transition).
-	 */
-	var HookRegistry = (function () {
-	    function HookRegistry() {
-	        var _this = this;
-	        this._transitionEvents = {
-	            onBefore: [], onStart: [], onEnter: [], onRetain: [], onExit: [], onFinish: [], onSuccess: [], onError: []
-	        };
-	        this.getHooks = function (name) { return _this._transitionEvents[name]; };
-	        /** @inheritdoc */
-	        this.onBefore = makeHookRegistrationFn(this._transitionEvents, "onBefore");
-	        /** @inheritdoc */
-	        this.onStart = makeHookRegistrationFn(this._transitionEvents, "onStart");
-	        /** @inheritdoc */
-	        this.onEnter = makeHookRegistrationFn(this._transitionEvents, "onEnter");
-	        /** @inheritdoc */
-	        this.onRetain = makeHookRegistrationFn(this._transitionEvents, "onRetain");
-	        /** @inheritdoc */
-	        this.onExit = makeHookRegistrationFn(this._transitionEvents, "onExit");
-	        /** @inheritdoc */
-	        this.onFinish = makeHookRegistrationFn(this._transitionEvents, "onFinish");
-	        /** @inheritdoc */
-	        this.onSuccess = makeHookRegistrationFn(this._transitionEvents, "onSuccess");
-	        /** @inheritdoc */
-	        this.onError = makeHookRegistrationFn(this._transitionEvents, "onError");
-	    }
-	    HookRegistry.mixin = function (source, target) {
-	        Object.keys(source._transitionEvents).concat(["getHooks"]).forEach(function (key) { return target[key] = source[key]; });
-	    };
-	    return HookRegistry;
-	}());
-	exports.HookRegistry = HookRegistry;
-
-
-/***/ },
-/* 16 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/** @module transition */ /** for typedoc */
-	"use strict";
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var transitionHook_1 = __webpack_require__(13);
-	var resolveContext_1 = __webpack_require__(17);
-	/**
-	 * This class returns applicable TransitionHooks for a specific Transition instance.
-	 *
-	 * Hooks (IEventHook) may be registered globally, e.g., $transitions.onEnter(...), or locally, e.g.
-	 * myTransition.onEnter(...).  The HookBuilder finds matching IEventHooks (where the match criteria is
-	 * determined by the type of hook)
-	 *
-	 * The HookBuilder also converts IEventHooks objects to TransitionHook objects, which are used to run a Transition.
-	 *
-	 * The HookBuilder constructor is given the $transitions service and a Transition instance.  Thus, a HookBuilder
-	 * instance may only be used for one specific Transition object. (side note: the _treeChanges accessor is private
-	 * in the Transition class, so we must also provide the Transition's _treeChanges)
-	 *
-	 */
-	var HookBuilder = (function () {
-	    function HookBuilder($transitions, transition, baseHookOptions) {
-	        var _this = this;
-	        this.$transitions = $transitions;
-	        this.transition = transition;
-	        this.baseHookOptions = baseHookOptions;
-	        this.getOnBeforeHooks = function () { return _this._buildNodeHooks("onBefore", "to", tupleSort(), { async: false }); };
-	        this.getOnStartHooks = function () { return _this._buildNodeHooks("onStart", "to", tupleSort()); };
-	        this.getOnExitHooks = function () { return _this._buildNodeHooks("onExit", "exiting", tupleSort(true), { stateHook: true }); };
-	        this.getOnRetainHooks = function () { return _this._buildNodeHooks("onRetain", "retained", tupleSort(false), { stateHook: true }); };
-	        this.getOnEnterHooks = function () { return _this._buildNodeHooks("onEnter", "entering", tupleSort(false), { stateHook: true }); };
-	        this.getOnFinishHooks = function () { return _this._buildNodeHooks("onFinish", "to", tupleSort()); };
-	        this.getOnSuccessHooks = function () { return _this._buildNodeHooks("onSuccess", "to", tupleSort(), { async: false, rejectIfSuperseded: false }); };
-	        this.getOnErrorHooks = function () { return _this._buildNodeHooks("onError", "to", tupleSort(), { async: false, rejectIfSuperseded: false }); };
-	        this.treeChanges = transition.treeChanges();
-	        this.toState = common_1.tail(this.treeChanges.to).state;
-	        this.fromState = common_1.tail(this.treeChanges.from).state;
-	        this.transitionOptions = transition.options();
-	    }
-	    HookBuilder.prototype.asyncHooks = function () {
-	        var onStartHooks = this.getOnStartHooks();
-	        var onExitHooks = this.getOnExitHooks();
-	        var onRetainHooks = this.getOnRetainHooks();
-	        var onEnterHooks = this.getOnEnterHooks();
-	        var onFinishHooks = this.getOnFinishHooks();
-	        var asyncHooks = [onStartHooks, onExitHooks, onRetainHooks, onEnterHooks, onFinishHooks];
-	        return asyncHooks.reduce(common_1.unnestR, []).filter(common_1.identity);
-	    };
-	    /**
-	     * Returns an array of newly built TransitionHook objects.
-	     *
-	     * - Finds all IEventHooks registered for the given `hookType` which matched the transition's [[TreeChanges]].
-	     * - Finds [[PathNode]] (or `PathNode[]`) to use as the TransitionHook context(s)
-	     * - For each of the [[PathNode]]s, creates a TransitionHook
-	     *
-	     * @param hookType the name of the hook registration function, e.g., 'onEnter', 'onFinish'.
-	     * @param matchingNodesProp selects which [[PathNode]]s from the [[IMatchingNodes]] object to create hooks for.
-	     * @param getLocals a function which accepts a [[PathNode]] and returns additional locals to provide to the hook as injectables
-	     * @param sortHooksFn a function which compares two HookTuple and returns <1, 0, or >1
-	     * @param options any specific Transition Hook Options
-	     */
-	    HookBuilder.prototype._buildNodeHooks = function (hookType, matchingNodesProp, sortHooksFn, options) {
-	        var _this = this;
-	        // Find all the matching registered hooks for a given hook type
-	        var matchingHooks = this._matchingHooks(hookType, this.treeChanges);
-	        if (!matchingHooks)
-	            return [];
-	        var makeTransitionHooks = function (hook) {
-	            // Fetch the Nodes that caused this hook to match.
-	            var matches = hook.matches(_this.treeChanges);
-	            // Select the PathNode[] that will be used as TransitionHook context objects
-	            var matchingNodes = matches[matchingNodesProp];
-	            // When invoking 'exiting' hooks, give them the "from path" for resolve data.
-	            // Everything else gets the "to path"
-	            var resolvePath = matchingNodesProp === 'exiting' ? _this.treeChanges.from : _this.treeChanges.to;
-	            var resolveContext = new resolveContext_1.ResolveContext(resolvePath);
-	            // Return an array of HookTuples
-	            return matchingNodes.map(function (node) {
-	                var _options = common_1.extend({ bind: hook.bind, traceData: { hookType: hookType, context: node } }, _this.baseHookOptions, options);
-	                var state = _options.stateHook ? node.state : null;
-	                var context = resolveContext.subContext(node.state);
-	                var transitionHook = new transitionHook_1.TransitionHook(_this.transition, state, hook.callback, context, _options);
-	                return { hook: hook, node: node, transitionHook: transitionHook };
-	            });
-	        };
-	        return matchingHooks.map(makeTransitionHooks)
-	            .reduce(common_1.unnestR, [])
-	            .sort(sortHooksFn)
-	            .map(function (tuple) { return tuple.transitionHook; });
-	    };
-	    /**
-	     * Finds all IEventHooks from:
-	     * - The Transition object instance hook registry
-	     * - The TransitionService ($transitions) global hook registry
-	     *
-	     * which matched:
-	     * - the eventType
-	     * - the matchCriteria (to, from, exiting, retained, entering)
-	     *
-	     * @returns an array of matched [[IEventHook]]s
-	     */
-	    HookBuilder.prototype._matchingHooks = function (hookName, treeChanges) {
-	        return [this.transition, this.$transitions] // Instance and Global hook registries
-	            .map(function (reg) { return reg.getHooks(hookName); }) // Get named hooks from registries
-	            .filter(common_1.assertPredicate(predicates_1.isArray, "broken event named: " + hookName)) // Sanity check
-	            .reduce(common_1.unnestR, []) // Un-nest IEventHook[][] to IEventHook[] array
-	            .filter(function (hook) { return hook.matches(treeChanges); }); // Only those satisfying matchCriteria
-	    };
-	    return HookBuilder;
-	}());
-	exports.HookBuilder = HookBuilder;
-	/**
-	 * A factory for a sort function for HookTuples.
-	 *
-	 * The sort function first compares the PathNode depth (how deep in the state tree a node is), then compares
-	 * the EventHook priority.
-	 *
-	 * @param reverseDepthSort a boolean, when true, reverses the sort order for the node depth
-	 * @returns a tuple sort function
-	 */
-	function tupleSort(reverseDepthSort) {
-	    if (reverseDepthSort === void 0) { reverseDepthSort = false; }
-	    return function nodeDepthThenPriority(l, r) {
-	        var factor = reverseDepthSort ? -1 : 1;
-	        var depthDelta = (l.node.state.path.length - r.node.state.path.length) * factor;
-	        return depthDelta !== 0 ? depthDelta : r.hook.priority - l.hook.priority;
-	    };
-	}
-
-
-/***/ },
-/* 17 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module resolve */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	var trace_1 = __webpack_require__(12);
-	var coreservices_1 = __webpack_require__(6);
-	var interface_1 = __webpack_require__(18);
-	var resolvable_1 = __webpack_require__(19);
-	var pathFactory_1 = __webpack_require__(20);
-	var strings_1 = __webpack_require__(9);
-	var when = interface_1.resolvePolicies.when;
-	var ALL_WHENS = [when.EAGER, when.LAZY];
-	var EAGER_WHENS = [when.EAGER];
-	/**
-	 * Encapsulates Depenency Injection for a path of nodes
-	 *
-	 * UI-Router states are organized as a tree.
-	 * A nested state has a path of ancestors to the root of the tree.
-	 * When a state is being activated, each element in the path is wrapped as a [[PathNode]].
-	 * A `PathNode` is a stateful object that holds things like parameters and resolvables for the state being activated.
-	 *
-	 * The ResolveContext closes over the [[PathNode]]s, and provides DI for the last node in the path.
-	 */
-	var ResolveContext = (function () {
-	    function ResolveContext(_path) {
-	        this._path = _path;
-	    }
-	    /** Gets all the tokens found in the resolve context, de-duplicated */
-	    ResolveContext.prototype.getTokens = function () {
-	        return this._path.reduce(function (acc, node) { return acc.concat(node.resolvables.map(function (r) { return r.token; })); }, []).reduce(common_1.uniqR, []);
-	    };
-	    /**
-	     * Gets the Resolvable that matches the token
-	     *
-	     * Gets the last Resolvable that matches the token in this context, or undefined.
-	     * Throws an error if it doesn't exist in the ResolveContext
-	     */
-	    ResolveContext.prototype.getResolvable = function (token) {
-	        var matching = this._path.map(function (node) { return node.resolvables; })
-	            .reduce(common_1.unnestR, [])
-	            .filter(function (r) { return r.token === token; });
-	        return common_1.tail(matching);
-	    };
-	    /**
-	     * Returns a ResolveContext that includes a portion of this one
-	     *
-	     * Given a state, this method creates a new ResolveContext from this one.
-	     * The new context starts at the first node (root) and stops at the node for the `state` parameter.
-	     *
-	     * #### Why
-	     *
-	     * When a transition is created, the nodes in the "To Path" are injected from a ResolveContext.
-	     * A ResolveContext closes over a path of [[PathNode]]s and processes the resolvables.
-	     * The "To State" can inject values from its own resolvables, as well as those from all its ancestor state's (node's).
-	     * This method is used to create a narrower context when injecting ancestor nodes.
-	     *
-	     * @example
-	     * `let ABCD = new ResolveContext([A, B, C, D]);`
-	     *
-	     * Given a path `[A, B, C, D]`, where `A`, `B`, `C` and `D` are nodes for states `a`, `b`, `c`, `d`:
-	     * When injecting `D`, `D` should have access to all resolvables from `A`, `B`, `C`, `D`.
-	     * However, `B` should only be able to access resolvables from `A`, `B`.
-	     *
-	     * When resolving for the `B` node, first take the full "To Path" Context `[A,B,C,D]` and limit to the subpath `[A,B]`.
-	     * `let AB = ABCD.subcontext(a)`
-	     */
-	    ResolveContext.prototype.subContext = function (state) {
-	        return new ResolveContext(pathFactory_1.PathFactory.subPath(this._path, function (node) { return node.state === state; }));
-	    };
-	    /**
-	     * Adds Resolvables to the node that matches the state
-	     *
-	     * This adds a [[Resolvable]] (generally one created on the fly; not declared on a [[StateDeclaration.resolve]] block).
-	     * The resolvable is added to the node matching the `state` parameter.
-	     *
-	     * These new resolvables are not automatically fetched.
-	     * The calling code should either fetch them, fetch something that depends on them,
-	     * or rely on [[resolvePath]] being called when some state is being entered.
-	     *
-	     * Note: each resolvable's [[ResolvePolicy]] is merged with the state's policy, and the global default.
-	     *
-	     * @param newResolvables the new Resolvables
-	     * @param state Used to find the node to put the resolvable on
-	     */
-	    ResolveContext.prototype.addResolvables = function (newResolvables, state) {
-	        var node = common_1.find(this._path, hof_1.propEq('state', state));
-	        var keys = newResolvables.map(function (r) { return r.token; });
-	        node.resolvables = node.resolvables.filter(function (r) { return keys.indexOf(r.token) === -1; }).concat(newResolvables);
-	    };
-	    /**
-	     * Returns a promise for an array of resolved path Element promises
-	     *
-	     * @param when
-	     * @param trans
-	     * @returns {Promise<any>|any}
-	     */
-	    ResolveContext.prototype.resolvePath = function (when, trans) {
-	        var _this = this;
-	        if (when === void 0) { when = "LAZY"; }
-	        // This option determines which 'when' policy Resolvables we are about to fetch.
-	        var whenOption = common_1.inArray(ALL_WHENS, when) ? when : "LAZY";
-	        // If the caller specified EAGER, only the EAGER Resolvables are fetched.
-	        // if the caller specified LAZY, both EAGER and LAZY Resolvables are fetched.`
-	        var matchedWhens = whenOption === interface_1.resolvePolicies.when.EAGER ? EAGER_WHENS : ALL_WHENS;
-	        // get the subpath to the state argument, if provided
-	        trace_1.trace.traceResolvePath(this._path, when, trans);
-	        var promises = this._path.reduce(function (acc, node) {
-	            var matchesRequestedPolicy = function (resolvable) {
-	                return common_1.inArray(matchedWhens, resolvable.getPolicy(node.state).when);
-	            };
-	            var nodeResolvables = node.resolvables.filter(matchesRequestedPolicy);
-	            var subContext = _this.subContext(node.state);
-	            // For the matching Resolvables, start their async fetch process.
-	            var getResult = function (r) { return r.get(subContext, trans)
-	                .then(function (value) { return ({ token: r.token, value: value }); }); };
-	            return acc.concat(nodeResolvables.map(getResult));
-	        }, []);
-	        return coreservices_1.services.$q.all(promises);
-	    };
-	    ResolveContext.prototype.injector = function () {
-	        return new UIInjectorImpl(this);
-	    };
-	    ResolveContext.prototype.findNode = function (resolvable) {
-	        return common_1.find(this._path, function (node) { return common_1.inArray(node.resolvables, resolvable); });
-	    };
-	    /**
-	     * Gets the async dependencies of a Resolvable
-	     *
-	     * Given a Resolvable, returns its dependencies as a Resolvable[]
-	     */
-	    ResolveContext.prototype.getDependencies = function (resolvable) {
-	        var node = this.findNode(resolvable);
-	        // Find which other resolvables are "visible" to the `resolvable` argument
-	        // subpath stopping at resolvable's node, or the whole path (if the resolvable isn't in the path)
-	        var subPath = pathFactory_1.PathFactory.subPath(this._path, function (x) { return x === node; }) || this._path;
-	        var availableResolvables = subPath
-	            .reduce(function (acc, node) { return acc.concat(node.resolvables); }, []) //all of subpath's resolvables
-	            .filter(function (res) { return res !== resolvable; }); // filter out the `resolvable` argument
-	        var getDependency = function (token) {
-	            var matching = availableResolvables.filter(function (r) { return r.token === token; });
-	            if (matching.length)
-	                return common_1.tail(matching);
-	            var fromInjector = coreservices_1.services.$injector.get(token);
-	            if (!fromInjector) {
-	                throw new Error("Could not find Dependency Injection token: " + strings_1.stringify(token));
-	            }
-	            return new resolvable_1.Resolvable(token, function () { return fromInjector; }, [], fromInjector);
-	        };
-	        return resolvable.deps.map(getDependency);
-	    };
-	    return ResolveContext;
-	}());
-	exports.ResolveContext = ResolveContext;
-	var UIInjectorImpl = (function () {
-	    function UIInjectorImpl(context) {
-	        this.context = context;
-	        /** The native injector ($injector on ng1, Root Injector on ng2, justjs injector for everything else) */
-	        this.native = coreservices_1.services.$injector;
-	    }
-	    UIInjectorImpl.prototype.get = function (token) {
-	        var resolvable = this.context.getResolvable(token);
-	        if (resolvable) {
-	            if (!resolvable.resolved) {
-	                throw new Error("Resolvable async .get() not complete:" + strings_1.stringify(resolvable.token));
-	            }
-	            return resolvable.data;
-	        }
-	        return coreservices_1.services.$injector.get(token);
-	    };
-	    UIInjectorImpl.prototype.getAsync = function (token) {
-	        var resolvable = this.context.getResolvable(token);
-	        if (resolvable)
-	            return resolvable.get(this.context);
-	        return coreservices_1.services.$q.when(coreservices_1.services.$injector.get(token));
-	    };
-	    return UIInjectorImpl;
-	}());
-
-
-/***/ },
-/* 18 */
-/***/ function(module, exports) {
-
-	"use strict";
-	exports.resolvePolicies = {
-	    when: {
-	        LAZY: "LAZY",
-	        EAGER: "EAGER"
-	    },
-	    async: {
-	        WAIT: "WAIT",
-	        NOWAIT: "NOWAIT",
-	        RXWAIT: "RXWAIT"
-	    }
-	};
-
-
-/***/ },
-/* 19 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module resolve */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var coreservices_1 = __webpack_require__(6);
-	var trace_1 = __webpack_require__(12);
-	var strings_1 = __webpack_require__(9);
-	var predicates_1 = __webpack_require__(4);
-	// TODO: explicitly make this user configurable
-	exports.defaultResolvePolicy = {
-	    when: "LAZY",
-	    async: "WAIT"
-	};
-	/**
-	 * The basic building block for the resolve system.
-	 *
-	 * Resolvables encapsulate a state's resolve's resolveFn, the resolveFn's declared dependencies, the wrapped (.promise),
-	 * and the unwrapped-when-complete (.data) result of the resolveFn.
-	 *
-	 * Resolvable.get() either retrieves the Resolvable's existing promise, or else invokes resolve() (which invokes the
-	 * resolveFn) and returns the resulting promise.
-	 *
-	 * Resolvable.get() and Resolvable.resolve() both execute within a context path, which is passed as the first
-	 * parameter to those fns.
-	 */
-	var Resolvable = (function () {
-	    function Resolvable(arg1, resolveFn, deps, policy, data) {
-	        this.resolved = false;
-	        this.promise = undefined;
-	        if (arg1 instanceof Resolvable) {
-	            common_1.extend(this, arg1);
-	        }
-	        else if (predicates_1.isFunction(resolveFn)) {
-	            if (arg1 == null || arg1 == undefined)
-	                throw new Error("new Resolvable(): token argument is required");
-	            if (!predicates_1.isFunction(resolveFn))
-	                throw new Error("new Resolvable(): resolveFn argument must be a function");
-	            this.token = arg1;
-	            this.policy = policy;
-	            this.resolveFn = resolveFn;
-	            this.deps = deps || [];
-	            this.data = data;
-	            this.resolved = data !== undefined;
-	            this.promise = this.resolved ? coreservices_1.services.$q.when(this.data) : undefined;
-	        }
-	        else if (predicates_1.isObject(arg1) && arg1.token && predicates_1.isFunction(arg1.resolveFn)) {
-	            var literal = arg1;
-	            return new Resolvable(literal.token, literal.resolveFn, literal.deps, literal.policy, literal.data);
-	        }
-	    }
-	    Resolvable.prototype.getPolicy = function (state) {
-	        var thisPolicy = this.policy || {};
-	        var statePolicy = state && state.resolvePolicy || {};
-	        return {
-	            when: thisPolicy.when || statePolicy.when || exports.defaultResolvePolicy.when,
-	            async: thisPolicy.async || statePolicy.async || exports.defaultResolvePolicy.async,
-	        };
-	    };
-	    /**
-	     * Asynchronously resolve this Resolvable's data
-	     *
-	     * Given a ResolveContext that this Resolvable is found in:
-	     * Wait for this Resolvable's dependencies, then invoke this Resolvable's function
-	     * and update the Resolvable's state
-	     */
-	    Resolvable.prototype.resolve = function (resolveContext, trans) {
-	        var _this = this;
-	        var $q = coreservices_1.services.$q;
-	        // Gets all dependencies from ResolveContext and wait for them to be resolved
-	        var getResolvableDependencies = function () {
-	            return $q.all(resolveContext.getDependencies(_this).map(function (r) {
-	                return r.get(resolveContext, trans);
-	            }));
-	        };
-	        // Invokes the resolve function passing the resolved dependencies as arguments
-	        var invokeResolveFn = function (resolvedDeps) {
-	            return _this.resolveFn.apply(null, resolvedDeps);
-	        };
-	        /**
-	         * For RXWAIT policy:
-	         *
-	         * Given an observable returned from a resolve function:
-	         * - enables .cache() mode (this allows multicast subscribers)
-	         * - then calls toPromise() (this triggers subscribe() and thus fetches)
-	         * - Waits for the promise, then return the cached observable (not the first emitted value).
-	         */
-	        var waitForRx = function (observable$) {
-	            var cached = observable$.cache();
-	            return cached.toPromise().then(function () { return cached; });
-	        };
-	        // If the resolve policy is RXWAIT, wait for the observable to emit something. otherwise pass through.
-	        var node = resolveContext.findNode(this);
-	        var state = node && node.state;
-	        var maybeWaitForRx = this.getPolicy(state).async === "RXWAIT" ? waitForRx : function (x) { return x; };
-	        // After the final value has been resolved, update the state of the Resolvable
-	        var applyResolvedValue = function (resolvedValue) {
-	            _this.data = resolvedValue;
-	            _this.resolved = true;
-	            trace_1.trace.traceResolvableResolved(_this, trans);
-	            return _this.data;
-	        };
-	        // Sets the promise property first, then getsResolvableDependencies in the context of the promise chain. Always waits one tick.
-	        return this.promise = $q.when()
-	            .then(getResolvableDependencies)
-	            .then(invokeResolveFn)
-	            .then(maybeWaitForRx)
-	            .then(applyResolvedValue);
-	    };
-	    /**
-	     * Gets a promise for this Resolvable's data.
-	     *
-	     * Fetches the data and returns a promise.
-	     * Returns the existing promise if it has already been fetched once.
-	     */
-	    Resolvable.prototype.get = function (resolveContext, trans) {
-	        return this.promise || this.resolve(resolveContext, trans);
-	    };
-	    Resolvable.prototype.toString = function () {
-	        return "Resolvable(token: " + strings_1.stringify(this.token) + ", requires: [" + this.deps.map(strings_1.stringify) + "])";
-	    };
-	    Resolvable.prototype.clone = function () {
-	        return new Resolvable(this);
-	    };
-	    return Resolvable;
-	}());
-	exports.Resolvable = Resolvable;
-
-
-/***/ },
-/* 20 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/** @module path */ /** for typedoc */
-	"use strict";
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	var targetState_1 = __webpack_require__(14);
-	var node_1 = __webpack_require__(21);
-	/**
-	 * This class contains functions which convert TargetStates, Nodes and paths from one type to another.
-	 */
-	var PathFactory = (function () {
-	    function PathFactory() {
-	    }
-	    /** Given a PathNode[], create an TargetState */
-	    PathFactory.makeTargetState = function (path) {
-	        var state = common_1.tail(path).state;
-	        return new targetState_1.TargetState(state, state, path.map(hof_1.prop("paramValues")).reduce(common_1.mergeR, {}));
-	    };
-	    PathFactory.buildPath = function (targetState) {
-	        var toParams = targetState.params();
-	        return targetState.$state().path.map(function (state) { return new node_1.PathNode(state).applyRawParams(toParams); });
-	    };
-	    /** Given a fromPath: PathNode[] and a TargetState, builds a toPath: PathNode[] */
-	    PathFactory.buildToPath = function (fromPath, targetState) {
-	        var toPath = PathFactory.buildPath(targetState);
-	        if (targetState.options().inherit) {
-	            return PathFactory.inheritParams(fromPath, toPath, Object.keys(targetState.params()));
-	        }
-	        return toPath;
-	    };
-	    /**
-	     * Creates ViewConfig objects and adds to nodes.
-	     *
-	     * On each [[PathNode]], creates ViewConfig objects from the views: property of the node's state
-	     */
-	    PathFactory.applyViewConfigs = function ($view, path, states) {
-	        // Only apply the viewConfigs to the nodes for the given states
-	        path.filter(function (node) { return common_1.inArray(states, node.state); }).forEach(function (node) {
-	            var viewDecls = common_1.values(node.state.views || {});
-	            var subPath = PathFactory.subPath(path, function (n) { return n === node; });
-	            var viewConfigs = viewDecls.map(function (view) { return $view.createViewConfig(subPath, view); });
-	            node.views = viewConfigs.reduce(common_1.unnestR, []);
-	        });
-	    };
-	    /**
-	     * Given a fromPath and a toPath, returns a new to path which inherits parameters from the fromPath
-	     *
-	     * For a parameter in a node to be inherited from the from path:
-	     * - The toPath's node must have a matching node in the fromPath (by state).
-	     * - The parameter name must not be found in the toKeys parameter array.
-	     *
-	     * Note: the keys provided in toKeys are intended to be those param keys explicitly specified by some
-	     * caller, for instance, $state.transitionTo(..., toParams).  If a key was found in toParams,
-	     * it is not inherited from the fromPath.
-	     */
-	    PathFactory.inheritParams = function (fromPath, toPath, toKeys) {
-	        if (toKeys === void 0) { toKeys = []; }
-	        function nodeParamVals(path, state) {
-	            var node = common_1.find(path, hof_1.propEq('state', state));
-	            return common_1.extend({}, node && node.paramValues);
-	        }
-	        /**
-	         * Given an [[PathNode]] "toNode", return a new [[PathNode]] with param values inherited from the
-	         * matching node in fromPath.  Only inherit keys that aren't found in "toKeys" from the node in "fromPath""
-	         */
-	        function makeInheritedParamsNode(toNode) {
-	            // All param values for the node (may include default key/vals, when key was not found in toParams)
-	            var toParamVals = common_1.extend({}, toNode && toNode.paramValues);
-	            // limited to only those keys found in toParams
-	            var incomingParamVals = common_1.pick(toParamVals, toKeys);
-	            toParamVals = common_1.omit(toParamVals, toKeys);
-	            var fromParamVals = nodeParamVals(fromPath, toNode.state) || {};
-	            // extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals
-	            var ownParamVals = common_1.extend(toParamVals, fromParamVals, incomingParamVals);
-	            return new node_1.PathNode(toNode.state).applyRawParams(ownParamVals);
-	        }
-	        // The param keys specified by the incoming toParams
-	        return toPath.map(makeInheritedParamsNode);
-	    };
-	    /**
-	     * Computes the tree changes (entering, exiting) between a fromPath and toPath.
-	     */
-	    PathFactory.treeChanges = function (fromPath, toPath, reloadState) {
-	        var keep = 0, max = Math.min(fromPath.length, toPath.length);
-	        var staticParams = function (state) { return state.parameters({ inherit: false }).filter(hof_1.not(hof_1.prop('dynamic'))).map(hof_1.prop('id')); };
-	        var nodesMatch = function (node1, node2) { return node1.equals(node2, staticParams(node1.state)); };
-	        while (keep < max && fromPath[keep].state !== reloadState && nodesMatch(fromPath[keep], toPath[keep])) {
-	            keep++;
-	        }
-	        /** Given a retained node, return a new node which uses the to node's param values */
-	        function applyToParams(retainedNode, idx) {
-	            var cloned = node_1.PathNode.clone(retainedNode);
-	            cloned.paramValues = toPath[idx].paramValues;
-	            return cloned;
-	        }
-	        var from, retained, exiting, entering, to;
-	        from = fromPath;
-	        retained = from.slice(0, keep);
-	        exiting = from.slice(keep);
-	        // Create a new retained path (with shallow copies of nodes) which have the params of the toPath mapped
-	        var retainedWithToParams = retained.map(applyToParams);
-	        entering = toPath.slice(keep);
-	        to = (retainedWithToParams).concat(entering);
-	        return { from: from, to: to, retained: retained, exiting: exiting, entering: entering };
-	    };
-	    /**
-	     * Return a subpath of a path, which stops at the first matching node
-	     *
-	     * Given an array of nodes, returns a subset of the array starting from the first node,
-	     * stopping when the first node matches the predicate.
-	     *
-	     * @param path a path of [[PathNode]]s
-	     * @param predicate a [[Predicate]] fn that matches [[PathNode]]s
-	     * @returns a subpath up to the matching node, or undefined if no match is found
-	     */
-	    PathFactory.subPath = function (path, predicate) {
-	        var node = common_1.find(path, predicate);
-	        var elementIdx = path.indexOf(node);
-	        return elementIdx === -1 ? undefined : path.slice(0, elementIdx + 1);
-	    };
-	    /** Gets the raw parameter values from a path */
-	    PathFactory.paramValues = function (path) { return path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {}); };
-	    return PathFactory;
-	}());
-	exports.PathFactory = PathFactory;
-
-
-/***/ },
-/* 21 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module path */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	var param_1 = __webpack_require__(22);
-	/**
-	 * A node in a [[TreeChanges]] path
-	 *
-	 * For a [[TreeChanges]] path, this class holds the stateful information for a single node in the path.
-	 * Each PathNode corresponds to a state being entered, exited, or retained.
-	 * The stateful information includes parameter values and resolve data.
-	 */
-	var PathNode = (function () {
-	    function PathNode(state) {
-	        if (state instanceof PathNode) {
-	            var node = state;
-	            this.state = node.state;
-	            this.paramSchema = node.paramSchema.slice();
-	            this.paramValues = common_1.extend({}, node.paramValues);
-	            this.resolvables = node.resolvables.slice();
-	            this.views = node.views && node.views.slice();
-	        }
-	        else {
-	            this.state = state;
-	            this.paramSchema = state.parameters({ inherit: false });
-	            this.paramValues = {};
-	            this.resolvables = state.resolvables.map(function (res) { return res.clone(); });
-	        }
-	    }
-	    /** Sets [[paramValues]] for the node, from the values of an object hash */
-	    PathNode.prototype.applyRawParams = function (params) {
-	        var getParamVal = function (paramDef) { return [paramDef.id, paramDef.value(params[paramDef.id])]; };
-	        this.paramValues = this.paramSchema.reduce(function (memo, pDef) { return common_1.applyPairs(memo, getParamVal(pDef)); }, {});
-	        return this;
-	    };
-	    /** Gets a specific [[Param]] metadata that belongs to the node */
-	    PathNode.prototype.parameter = function (name) {
-	        return common_1.find(this.paramSchema, hof_1.propEq("id", name));
-	    };
-	    /**
-	     * @returns true if the state and parameter values for another PathNode are
-	     * equal to the state and param values for this PathNode
-	     */
-	    PathNode.prototype.equals = function (node, keys) {
-	        var _this = this;
-	        if (keys === void 0) { keys = this.paramSchema.map(hof_1.prop('id')); }
-	        var paramValsEq = function (key) { return _this.parameter(key).type.equals(_this.paramValues[key], node.paramValues[key]); };
-	        return this.state === node.state && keys.map(paramValsEq).reduce(common_1.allTrueR, true);
-	    };
-	    /** Returns a clone of the PathNode */
-	    PathNode.clone = function (node) {
-	        return new PathNode(node);
-	    };
-	    /**
-	     * Returns a new path which is a subpath of the first path which matched the second path.
-	     *
-	     * The new path starts from root and contains any nodes that match the nodes in the second path.
-	     * Nodes are compared using their state property and parameter values.
-	     */
-	    PathNode.matching = function (pathA, pathB) {
-	        var matching = [];
-	        for (var i = 0; i < pathA.length && i < pathB.length; i++) {
-	            var a = pathA[i], b = pathB[i];
-	            if (a.state !== b.state)
-	                break;
-	            if (!param_1.Param.equals(a.paramSchema, a.paramValues, b.paramValues))
-	                break;
-	            matching.push(a);
-	        }
-	        return matching;
-	    };
-	    return PathNode;
-	}());
-	exports.PathNode = PathNode;
-
-
-/***/ },
-/* 22 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module params */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	var predicates_1 = __webpack_require__(4);
-	var coreservices_1 = __webpack_require__(6);
-	var urlMatcherConfig_1 = __webpack_require__(23);
-	var type_1 = __webpack_require__(24);
-	var paramTypes_1 = __webpack_require__(25);
-	var hasOwn = Object.prototype.hasOwnProperty;
-	var isShorthand = function (cfg) { return ["value", "type", "squash", "array", "dynamic"].filter(hasOwn.bind(cfg || {})).length === 0; };
-	(function (DefType) {
-	    DefType[DefType["PATH"] = 0] = "PATH";
-	    DefType[DefType["SEARCH"] = 1] = "SEARCH";
-	    DefType[DefType["CONFIG"] = 2] = "CONFIG";
-	})(exports.DefType || (exports.DefType = {}));
-	var DefType = exports.DefType;
-	function unwrapShorthand(cfg) {
-	    cfg = isShorthand(cfg) && { value: cfg } || cfg;
-	    return common_1.extend(cfg, {
-	        $$fn: predicates_1.isInjectable(cfg.value) ? cfg.value : function () { return cfg.value; }
-	    });
-	}
-	function getType(cfg, urlType, location, id) {
-	    if (cfg.type && urlType && urlType.name !== 'string')
-	        throw new Error("Param '" + id + "' has two type configurations.");
-	    if (cfg.type && urlType && urlType.name === 'string' && paramTypes_1.paramTypes.type(cfg.type))
-	        return paramTypes_1.paramTypes.type(cfg.type);
-	    if (urlType)
-	        return urlType;
-	    if (!cfg.type)
-	        return (location === DefType.CONFIG ? paramTypes_1.paramTypes.type("any") : paramTypes_1.paramTypes.type("string"));
-	    return cfg.type instanceof type_1.ParamType ? cfg.type : paramTypes_1.paramTypes.type(cfg.type);
-	}
-	/**
-	 * returns false, true, or the squash value to indicate the "default parameter url squash policy".
-	 */
-	function getSquashPolicy(config, isOptional) {
-	    var squash = config.squash;
-	    if (!isOptional || squash === false)
-	        return false;
-	    if (!predicates_1.isDefined(squash) || squash == null)
-	        return urlMatcherConfig_1.matcherConfig.defaultSquashPolicy();
-	    if (squash === true || predicates_1.isString(squash))
-	        return squash;
-	    throw new Error("Invalid squash policy: '" + squash + "'. Valid policies: false, true, or arbitrary string");
-	}
-	function getReplace(config, arrayMode, isOptional, squash) {
-	    var replace, configuredKeys, defaultPolicy = [
-	        { from: "", to: (isOptional || arrayMode ? undefined : "") },
-	        { from: null, to: (isOptional || arrayMode ? undefined : "") }
-	    ];
-	    replace = predicates_1.isArray(config.replace) ? config.replace : [];
-	    if (predicates_1.isString(squash))
-	        replace.push({ from: squash, to: undefined });
-	    configuredKeys = common_1.map(replace, hof_1.prop("from"));
-	    return common_1.filter(defaultPolicy, function (item) { return configuredKeys.indexOf(item.from) === -1; }).concat(replace);
-	}
-	var Param = (function () {
-	    function Param(id, type, config, location) {
-	        config = unwrapShorthand(config);
-	        type = getType(config, type, location, id);
-	        var arrayMode = getArrayMode();
-	        type = arrayMode ? type.$asArray(arrayMode, location === DefType.SEARCH) : type;
-	        var isOptional = config.value !== undefined;
-	        var dynamic = predicates_1.isDefined(config.dynamic) ? !!config.dynamic : !!type.dynamic;
-	        var squash = getSquashPolicy(config, isOptional);
-	        var replace = getReplace(config, arrayMode, isOptional, squash);
-	        // array config: param name (param[]) overrides default settings.  explicit config overrides param name.
-	        function getArrayMode() {
-	            var arrayDefaults = { array: (location === DefType.SEARCH ? "auto" : false) };
-	            var arrayParamNomenclature = id.match(/\[\]$/) ? { array: true } : {};
-	            return common_1.extend(arrayDefaults, arrayParamNomenclature, config).array;
-	        }
-	        common_1.extend(this, { id: id, type: type, location: location, squash: squash, replace: replace, isOptional: isOptional, dynamic: dynamic, config: config, array: arrayMode });
-	    }
-	    Param.prototype.isDefaultValue = function (value) {
-	        return this.isOptional && this.type.equals(this.value(), value);
-	    };
-	    /**
-	     * [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the
-	     * default value, which may be the result of an injectable function.
-	     */
-	    Param.prototype.value = function (value) {
-	        var _this = this;
-	        /**
-	         * [Internal] Get the default value of a parameter, which may be an injectable function.
-	         */
-	        var $$getDefaultValue = function () {
-	            if (!coreservices_1.services.$injector)
-	                throw new Error("Injectable functions cannot be called at configuration time");
-	            var defaultValue = coreservices_1.services.$injector.invoke(_this.config.$$fn);
-	            if (defaultValue !== null && defaultValue !== undefined && !_this.type.is(defaultValue))
-	                throw new Error("Default value (" + defaultValue + ") for parameter '" + _this.id + "' is not an instance of ParamType (" + _this.type.name + ")");
-	            return defaultValue;
-	        };
-	        var $replace = function (val) {
-	            var replacement = common_1.map(common_1.filter(_this.replace, hof_1.propEq('from', val)), hof_1.prop("to"));
-	            return replacement.length ? replacement[0] : val;
-	        };
-	        value = $replace(value);
-	        return !predicates_1.isDefined(value) ? $$getDefaultValue() : this.type.$normalize(value);
-	    };
-	    Param.prototype.isSearch = function () {
-	        return this.location === DefType.SEARCH;
-	    };
-	    Param.prototype.validates = function (value) {
-	        // There was no parameter value, but the param is optional
-	        if ((!predicates_1.isDefined(value) || value === null) && this.isOptional)
-	            return true;
-	        // The value was not of the correct ParamType, and could not be decoded to the correct ParamType
-	        var normalized = this.type.$normalize(value);
-	        if (!this.type.is(normalized))
-	            return false;
-	        // The value was of the correct type, but when encoded, did not match the ParamType's regexp
-	        var encoded = this.type.encode(normalized);
-	        return !(predicates_1.isString(encoded) && !this.type.pattern.exec(encoded));
-	    };
-	    Param.prototype.toString = function () {
-	        return "{Param:" + this.id + " " + this.type + " squash: '" + this.squash + "' optional: " + this.isOptional + "}";
-	    };
-	    /** Creates a new [[Param]] from a CONFIG block */
-	    Param.fromConfig = function (id, type, config) {
-	        return new Param(id, type, config, DefType.CONFIG);
-	    };
-	    /** Creates a new [[Param]] from a url PATH */
-	    Param.fromPath = function (id, type, config) {
-	        return new Param(id, type, config, DefType.PATH);
-	    };
-	    /** Creates a new [[Param]] from a url SEARCH */
-	    Param.fromSearch = function (id, type, config) {
-	        return new Param(id, type, config, DefType.SEARCH);
-	    };
-	    Param.values = function (params, values) {
-	        if (values === void 0) { values = {}; }
-	        return params.map(function (param) { return [param.id, param.value(values[param.id])]; }).reduce(common_1.applyPairs, {});
-	    };
-	    /**
-	     * Finds [[Param]] objects which have different param values
-	     *
-	     * Filters a list of [[Param]] objects to only those whose parameter values differ in two param value objects
-	     *
-	     * @param params: The list of Param objects to filter
-	     * @param values1: The first set of parameter values
-	     * @param values2: the second set of parameter values
-	     *
-	     * @returns any Param objects whose values were different between values1 and values2
-	     */
-	    Param.changed = function (params, values1, values2) {
-	        if (values1 === void 0) { values1 = {}; }
-	        if (values2 === void 0) { values2 = {}; }
-	        return params.filter(function (param) { return !param.type.equals(values1[param.id], values2[param.id]); });
-	    };
-	    /**
-	     * Checks if two param value objects are equal (for a set of [[Param]] objects)
-	     *
-	     * @param params The list of [[Param]] objects to check
-	     * @param values1 The first set of param values
-	     * @param values2 The second set of param values
-	     *
-	     * @returns true if the param values in values1 and values2 are equal
-	     */
-	    Param.equals = function (params, values1, values2) {
-	        if (values1 === void 0) { values1 = {}; }
-	        if (values2 === void 0) { values2 = {}; }
-	        return Param.changed(params, values1, values2).length === 0;
-	    };
-	    /** Returns true if a the parameter values are valid, according to the Param definitions */
-	    Param.validates = function (params, values) {
-	        if (values === void 0) { values = {}; }
-	        return params.map(function (param) { return param.validates(values[param.id]); }).reduce(common_1.allTrueR, true);
-	    };
-	    return Param;
-	}());
-	exports.Param = Param;
-
-
-/***/ },
-/* 23 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module url */ /** for typedoc */
-	var predicates_1 = __webpack_require__(4);
-	var MatcherConfig = (function () {
-	    function MatcherConfig() {
-	        this._isCaseInsensitive = false;
-	        this._isStrictMode = true;
-	        this._defaultSquashPolicy = false;
-	    }
-	    MatcherConfig.prototype.caseInsensitive = function (value) {
-	        return this._isCaseInsensitive = predicates_1.isDefined(value) ? value : this._isCaseInsensitive;
-	    };
-	    MatcherConfig.prototype.strictMode = function (value) {
-	        return this._isStrictMode = predicates_1.isDefined(value) ? value : this._isStrictMode;
-	    };
-	    MatcherConfig.prototype.defaultSquashPolicy = function (value) {
-	        if (predicates_1.isDefined(value) && value !== true && value !== false && !predicates_1.isString(value))
-	            throw new Error("Invalid squash policy: " + value + ". Valid policies: false, true, arbitrary-string");
-	        return this._defaultSquashPolicy = predicates_1.isDefined(value) ? value : this._defaultSquashPolicy;
-	    };
-	    return MatcherConfig;
-	}());
-	exports.MatcherConfig = MatcherConfig;
-	// TODO: Do not export global instance; create one in UIRouter() constructor
-	exports.matcherConfig = new MatcherConfig();
-
-
-/***/ },
-/* 24 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module params */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	/**
-	 * Wraps up a `ParamType` object to handle array values.
-	 */
-	function ArrayType(type, mode) {
-	    var _this = this;
-	    // Wrap non-array value as array
-	    function arrayWrap(val) { return predicates_1.isArray(val) ? val : (predicates_1.isDefined(val) ? [val] : []); }
-	    // Unwrap array value for "auto" mode. Return undefined for empty array.
-	    function arrayUnwrap(val) {
-	        switch (val.length) {
-	            case 0: return undefined;
-	            case 1: return mode === "auto" ? val[0] : val;
-	            default: return val;
-	        }
-	    }
-	    // Wraps type (.is/.encode/.decode) functions to operate on each value of an array
-	    function arrayHandler(callback, allTruthyMode) {
-	        return function handleArray(val) {
-	            if (predicates_1.isArray(val) && val.length === 0)
-	                return val;
-	            var arr = arrayWrap(val);
-	            var result = common_1.map(arr, callback);
-	            return (allTruthyMode === true) ? common_1.filter(result, function (x) { return !x; }).length === 0 : arrayUnwrap(result);
-	        };
-	    }
-	    // Wraps type (.equals) functions to operate on each value of an array
-	    function arrayEqualsHandler(callback) {
-	        return function handleArray(val1, val2) {
-	            var left = arrayWrap(val1), right = arrayWrap(val2);
-	            if (left.length !== right.length)
-	                return false;
-	            for (var i = 0; i < left.length; i++) {
-	                if (!callback(left[i], right[i]))
-	                    return false;
-	            }
-	            return true;
-	        };
-	    }
-	    ['encode', 'decode', 'equals', '$normalize'].map(function (name) {
-	        _this[name] = (name === 'equals' ? arrayEqualsHandler : arrayHandler)(type[name].bind(type));
-	    });
-	    common_1.extend(this, {
-	        dynamic: type.dynamic,
-	        name: type.name,
-	        pattern: type.pattern,
-	        is: arrayHandler(type.is.bind(type), true),
-	        $arrayMode: mode
-	    });
-	}
-	/**
-	 * A class that implements Custom Parameter Type functionality.
-	 *
-	 * This class has naive implementations for all the [[ParamTypeDefinition]] methods.
-	 *
-	 * An instance of this class is created when a custom [[ParamTypeDefinition]] object is registered with the [[UrlMatcherFactory.type]].
-	 *
-	 * Used by [[UrlMatcher]] when matching or formatting URLs, or comparing and validating parameter values.
-	 *
-	 * @example
-	 * ```
-	 *
-	 * {
-	 *   decode: function(val) { return parseInt(val, 10); },
-	 *   encode: function(val) { return val && val.toString(); },
-	 *   equals: function(a, b) { return this.is(a) && a === b; },
-	 *   is: function(val) { return angular.isNumber(val) && isFinite(val) && val % 1 === 0; },
-	 *   pattern: /\d+/
-	 * }
-	 * ```
-	 */
-	var ParamType = (function () {
-	    /**
-	     * @param def  A configuration object which contains the custom type definition.  The object's
-	     *        properties will override the default methods and/or pattern in `ParamType`'s public interface.
-	     * @returns a new ParamType object
-	     */
-	    function ParamType(def) {
-	        this.pattern = /.*/;
-	        common_1.extend(this, def);
-	    }
-	    // consider these four methods to be "abstract methods" that should be overridden
-	    /** @inheritdoc */
-	    ParamType.prototype.is = function (val, key) { return true; };
-	    /** @inheritdoc */
-	    ParamType.prototype.encode = function (val, key) { return val; };
-	    /** @inheritdoc */
-	    ParamType.prototype.decode = function (val, key) { return val; };
-	    /** @inheritdoc */
-	    ParamType.prototype.equals = function (a, b) { return a == b; };
-	    ParamType.prototype.$subPattern = function () {
-	        var sub = this.pattern.toString();
-	        return sub.substr(1, sub.length - 2);
-	    };
-	    ParamType.prototype.toString = function () {
-	        return "{ParamType:" + this.name + "}";
-	    };
-	    /** Given an encoded string, or a decoded object, returns a decoded object */
-	    ParamType.prototype.$normalize = function (val) {
-	        return this.is(val) ? val : this.decode(val);
-	    };
-	    /**
-	     * Wraps an existing custom ParamType as an array of ParamType, depending on 'mode'.
-	     * e.g.:
-	     * - urlmatcher pattern "/path?{queryParam[]:int}"
-	     * - url: "/path?queryParam=1&queryParam=2
-	     * - $stateParams.queryParam will be [1, 2]
-	     * if `mode` is "auto", then
-	     * - url: "/path?queryParam=1 will create $stateParams.queryParam: 1
-	     * - url: "/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]
-	     */
-	    ParamType.prototype.$asArray = function (mode, isSearch) {
-	        if (!mode)
-	            return this;
-	        if (mode === "auto" && !isSearch)
-	            throw new Error("'auto' array mode is for query parameters only");
-	        return new ArrayType(this, mode);
-	    };
-	    return ParamType;
-	}());
-	exports.ParamType = ParamType;
-
-
-/***/ },
-/* 25 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module params */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var hof_1 = __webpack_require__(5);
-	var coreservices_1 = __webpack_require__(6);
-	var type_1 = __webpack_require__(24);
-	// Use tildes to pre-encode slashes.
-	// If the slashes are simply URLEncoded, the browser can choose to pre-decode them,
-	// and bidirectional encoding/decoding fails.
-	// Tilde was chosen because it's not a RFC 3986 section 2.2 Reserved Character
-	function valToString(val) { return val != null ? val.toString().replace(/~/g, "~~").replace(/\//g, "~2F") : val; }
-	function valFromString(val) { return val != null ? val.toString().replace(/~2F/g, "/").replace(/~~/g, "~") : val; }
-	var ParamTypes = (function () {
-	    function ParamTypes() {
-	        this.enqueue = true;
-	        this.typeQueue = [];
-	        this.defaultTypes = {
-	            "hash": {
-	                encode: valToString,
-	                decode: valFromString,
-	                is: hof_1.is(String),
-	                pattern: /.*/,
-	                equals: function (a, b) { return a == b; } // allow coersion for null/undefined/""
-	            },
-	            "string": {
-	                encode: valToString,
-	                decode: valFromString,
-	                is: hof_1.is(String),
-	                pattern: /[^/]*/
-	            },
-	            "int": {
-	                encode: valToString,
-	                decode: function (val) { return parseInt(val, 10); },
-	                is: function (val) { return predicates_1.isDefined(val) && this.decode(val.toString()) === val; },
-	                pattern: /-?\d+/
-	            },
-	            "bool": {
-	                encode: function (val) { return val && 1 || 0; },
-	                decode: function (val) { return parseInt(val, 10) !== 0; },
-	                is: hof_1.is(Boolean),
-	                pattern: /0|1/
-	            },
-	            "date": {
-	                encode: function (val) {
-	                    return !this.is(val) ? undefined : [
-	                        val.getFullYear(),
-	                        ('0' + (val.getMonth() + 1)).slice(-2),
-	                        ('0' + val.getDate()).slice(-2)
-	                    ].join("-");
-	                },
-	                decode: function (val) {
-	                    if (this.is(val))
-	                        return val;
-	                    var match = this.capture.exec(val);
-	                    return match ? new Date(match[1], match[2] - 1, match[3]) : undefined;
-	                },
-	                is: function (val) { return val instanceof Date && !isNaN(val.valueOf()); },
-	                equals: function (l, r) {
-	                    return ['getFullYear', 'getMonth', 'getDate']
-	                        .reduce(function (acc, fn) { return acc && l[fn]() === r[fn](); }, true);
-	                },
-	                pattern: /[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,
-	                capture: /([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/
-	            },
-	            "json": {
-	                encode: common_1.toJson,
-	                decode: common_1.fromJson,
-	                is: hof_1.is(Object),
-	                equals: common_1.equals,
-	                pattern: /[^/]*/
-	            },
-	            "any": {
-	                encode: common_1.identity,
-	                decode: common_1.identity,
-	                equals: common_1.equals,
-	                pattern: /.*/
-	            }
-	        };
-	        // Register default types. Store them in the prototype of this.types.
-	        var makeType = function (definition, name) { return new type_1.ParamType(common_1.extend({ name: name }, definition)); };
-	        this.types = common_1.inherit(common_1.map(this.defaultTypes, makeType), {});
-	    }
-	    ParamTypes.prototype.type = function (name, definition, definitionFn) {
-	        if (!predicates_1.isDefined(definition))
-	            return this.types[name];
-	        if (this.types.hasOwnProperty(name))
-	            throw new Error("A type named '" + name + "' has already been defined.");
-	        this.types[name] = new type_1.ParamType(common_1.extend({ name: name }, definition));
-	        if (definitionFn) {
-	            this.typeQueue.push({ name: name, def: definitionFn });
-	            if (!this.enqueue)
-	                this._flushTypeQueue();
-	        }
-	        return this;
-	    };
-	    ParamTypes.prototype._flushTypeQueue = function () {
-	        while (this.typeQueue.length) {
-	            var type = this.typeQueue.shift();
-	            if (type.pattern)
-	                throw new Error("You cannot override a type's .pattern at runtime.");
-	            common_1.extend(this.types[type.name], coreservices_1.services.$injector.invoke(type.def));
-	        }
-	    };
-	    return ParamTypes;
-	}());
-	exports.ParamTypes = ParamTypes;
-	exports.paramTypes = new ParamTypes();
-
-
-/***/ },
-/* 26 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module core */ /** */
-	var urlMatcherFactory_1 = __webpack_require__(27);
-	var urlRouter_1 = __webpack_require__(29);
-	var state_1 = __webpack_require__(30);
-	var urlRouter_2 = __webpack_require__(29);
-	var transitionService_1 = __webpack_require__(31);
-	var view_1 = __webpack_require__(37);
-	var stateRegistry_1 = __webpack_require__(38);
-	var stateService_1 = __webpack_require__(43);
-	var globals_1 = __webpack_require__(44);
-	/**
-	 * The master class used to instantiate an instance of UI-Router.
-	 *
-	 * This class instantiates and wires the global UI-Router services.
-	 *
-	 * After instantiating a new instance of the Router class, configure it for your app.  For instance, register
-	 * your app states with the [[stateRegistry]] (and set url options using ...).  Then, tell UI-Router to monitor
-	 * the URL by calling `urlRouter.listen()` ([[URLRouter.listen]])
-	 */
-	var UIRouter = (function () {
-	    function UIRouter() {
-	        this.viewService = new view_1.ViewService();
-	        this.transitionService = new transitionService_1.TransitionService(this);
-	        this.globals = new globals_1.Globals(this.transitionService);
-	        this.urlMatcherFactory = new urlMatcherFactory_1.UrlMatcherFactory();
-	        this.urlRouterProvider = new urlRouter_1.UrlRouterProvider(this.urlMatcherFactory, this.globals.params);
-	        this.urlRouter = new urlRouter_2.UrlRouter(this.urlRouterProvider);
-	        this.stateRegistry = new stateRegistry_1.StateRegistry(this.urlMatcherFactory, this.urlRouterProvider);
-	        /** @hidden TODO: move this to ng1.ts */
-	        this.stateProvider = new state_1.StateProvider(this.stateRegistry);
-	        this.stateService = new stateService_1.StateService(this);
-	        this.viewService.rootContext(this.stateRegistry.root());
-	        this.globals.$current = this.stateRegistry.root();
-	        this.globals.current = this.globals.$current.self;
-	    }
-	    return UIRouter;
-	}());
-	exports.UIRouter = UIRouter;
-
-
-/***/ },
-/* 27 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module url */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var urlMatcher_1 = __webpack_require__(28);
-	var urlMatcherConfig_1 = __webpack_require__(23);
-	var param_1 = __webpack_require__(22);
-	var paramTypes_1 = __webpack_require__(25);
-	/** @hidden */
-	function getDefaultConfig() {
-	    return {
-	        strict: urlMatcherConfig_1.matcherConfig.strictMode(),
-	        caseInsensitive: urlMatcherConfig_1.matcherConfig.caseInsensitive()
-	    };
-	}
-	/**
-	 * Factory for [[UrlMatcher]] instances.
-	 *
-	 * The factory is available to ng1 services as
-	 * `$urlMatcherFactor` or ng1 providers as `$urlMatcherFactoryProvider`.
-	 */
-	var UrlMatcherFactory = (function () {
-	    function UrlMatcherFactory() {
-	        common_1.extend(this, { UrlMatcher: urlMatcher_1.UrlMatcher, Param: param_1.Param });
-	    }
-	    /**
-	     * Defines whether URL matching should be case sensitive (the default behavior), or not.
-	     *
-	     * @param value `false` to match URL in a case sensitive manner; otherwise `true`;
-	     * @returns the current value of caseInsensitive
-	     */
-	    UrlMatcherFactory.prototype.caseInsensitive = function (value) {
-	        return urlMatcherConfig_1.matcherConfig.caseInsensitive(value);
-	    };
-	    /**
-	     * Defines whether URLs should match trailing slashes, or not (the default behavior).
-	     *
-	     * @param value `false` to match trailing slashes in URLs, otherwise `true`.
-	     * @returns the current value of strictMode
-	     */
-	    UrlMatcherFactory.prototype.strictMode = function (value) {
-	        return urlMatcherConfig_1.matcherConfig.strictMode(value);
-	    };
-	    /**
-	     * Sets the default behavior when generating or matching URLs with default parameter values.
-	     *
-	     * @param value A string that defines the default parameter URL squashing behavior.
-	     *    - `nosquash`: When generating an href with a default parameter value, do not squash the parameter value from the URL
-	     *    - `slash`: When generating an href with a default parameter value, squash (remove) the parameter value, and, if the
-	     *             parameter is surrounded by slashes, squash (remove) one slash from the URL
-	     *    - any other string, e.g. "~": When generating an href with a default parameter value, squash (remove)
-	     *             the parameter value from the URL and replace it with this string.
-	     * @returns the current value of defaultSquashPolicy
-	     */
-	    UrlMatcherFactory.prototype.defaultSquashPolicy = function (value) {
-	        return urlMatcherConfig_1.matcherConfig.defaultSquashPolicy(value);
-	    };
-	    /**
-	     * Creates a [[UrlMatcher]] for the specified pattern.
-	     *
-	     * @param pattern  The URL pattern.
-	     * @param config  The config object hash.
-	     * @returns The UrlMatcher.
-	     */
-	    UrlMatcherFactory.prototype.compile = function (pattern, config) {
-	        return new urlMatcher_1.UrlMatcher(pattern, common_1.extend(getDefaultConfig(), config));
-	    };
-	    /**
-	     * Returns true if the specified object is a [[UrlMatcher]], or false otherwise.
-	     *
-	     * @param object  The object to perform the type check against.
-	     * @returns `true` if the object matches the `UrlMatcher` interface, by
-	     *          implementing all the same methods.
-	     */
-	    UrlMatcherFactory.prototype.isMatcher = function (object) {
-	        // TODO: typeof?
-	        if (!predicates_1.isObject(object))
-	            return false;
-	        var result = true;
-	        common_1.forEach(urlMatcher_1.UrlMatcher.prototype, function (val, name) {
-	            if (predicates_1.isFunction(val))
-	                result = result && (predicates_1.isDefined(object[name]) && predicates_1.isFunction(object[name]));
-	        });
-	        return result;
-	    };
-	    ;
-	    /**
-	     * Creates and registers a custom [[ParamType]] object that can be used to generate URLs with typed parameters.
-	     *
-	     * @param name  The type name.
-	     * @param definition The type definition. See [[ParamTypeDefinition]] for information on the values accepted.
-	     * @param definitionFn A function that is injected before the app
-	     *        runtime starts.  The result of this function is merged into the existing `definition`.
-	     *        See [[ParamType]] for information on the values accepted.
-	     *
-	     * @returns - if a type was registered: the [[UrlMatcherFactory]]
-	     *   - if only the `name` parameter was specified: the currently registered [[ParamType]] object, or undefined
-	     *
-	     * This is a simple example of a custom type that encodes and decodes items from an
-	     * array, using the array index as the URL-encoded value:
-	     */
-	    UrlMatcherFactory.prototype.type = function (name, definition, definitionFn) {
-	        var type = paramTypes_1.paramTypes.type(name, definition, definitionFn);
-	        return !predicates_1.isDefined(definition) ? type : this;
-	    };
-	    ;
-	    /** @hidden */
-	    UrlMatcherFactory.prototype.$get = function () {
-	        paramTypes_1.paramTypes.enqueue = false;
-	        paramTypes_1.paramTypes._flushTypeQueue();
-	        return this;
-	    };
-	    ;
-	    return UrlMatcherFactory;
-	}());
-	exports.UrlMatcherFactory = UrlMatcherFactory;
-
-
-/***/ },
-/* 28 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module url */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	var predicates_1 = __webpack_require__(4);
-	var param_1 = __webpack_require__(22);
-	var paramTypes_1 = __webpack_require__(25);
-	var predicates_2 = __webpack_require__(4);
-	var param_2 = __webpack_require__(22);
-	var common_2 = __webpack_require__(3);
-	var common_3 = __webpack_require__(3);
-	/** @hidden */
-	function quoteRegExp(string, param) {
-	    var surroundPattern = ['', ''], result = string.replace(/[\\\[\]\^$*+?.()|{}]/g, "\\$&");
-	    if (!param)
-	        return result;
-	    switch (param.squash) {
-	        case false:
-	            surroundPattern = ['(', ')' + (param.isOptional ? '?' : '')];
-	            break;
-	        case true:
-	            result = result.replace(/\/$/, '');
-	            surroundPattern = ['(?:\/(', ')|\/)?'];
-	            break;
-	        default:
-	            surroundPattern = [("(" + param.squash + "|"), ')?'];
-	            break;
-	    }
-	    return result + surroundPattern[0] + param.type.pattern.source + surroundPattern[1];
-	}
-	/** @hidden */
-	var memoizeTo = function (obj, prop, fn) { return obj[prop] = obj[prop] || fn(); };
-	/**
-	 * Matches URLs against patterns.
-	 *
-	 * Matches URLs against patterns and extracts named parameters from the path or the search
-	 * part of the URL.
-	 *
-	 * A URL pattern consists of a path pattern, optionally followed by '?' and a list of search (query)
-	 * parameters. Multiple search parameter names are separated by '&'. Search parameters
-	 * do not influence whether or not a URL is matched, but their values are passed through into
-	 * the matched parameters returned by [[UrlMatcher.exec]].
-	 *
-	 * - *Path parameters* are defined using curly brace placeholders (`/somepath/{param}`)
-	 * or colon placeholders (`/somePath/:param`).
-	 *
-	 * - *A parameter RegExp* may be defined for a param after a colon
-	 * (`/somePath/{param:[a-zA-Z0-9]+}`) in a curly brace placeholder.
-	 * The regexp must match for the url to be matched.
-	 * Should the regexp itself contain curly braces, they must be in matched pairs or escaped with a backslash.
-	 *
-	 * - *Custom parameter types* may also be specified after a colon (`/somePath/{param:int}`)
-	 * in curly brace parameters.  See [[UrlMatcherFactory.type]] for more information.
-	 *
-	 * - *Catch-all parameters* are defined using an asterisk placeholder (`/somepath/*catchallparam`).  A catch-all
-	 * parameter value will contain the remainder of the URL.
-	 *
-	 * ---
-	 *
-	 * Parameter names may contain only word characters (latin letters, digits, and underscore) and
-	 * must be unique within the pattern (across both path and search parameters).
-	 * A path parameter matches any number of characters other than '/'. For catch-all
-	 * placeholders the path parameter matches any number of characters.
-	 *
-	 * Examples:
-	 *
-	 * * `'/hello/'` - Matches only if the path is exactly '/hello/'. There is no special treatment for
-	 *   trailing slashes, and patterns have to match the entire path, not just a prefix.
-	 * * `'/user/:id'` - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or
-	 *   '/user/bob/details'. The second path segment will be captured as the parameter 'id'.
-	 * * `'/user/{id}'` - Same as the previous example, but using curly brace syntax.
-	 * * `'/user/{id:[^/]*}'` - Same as the previous example.
-	 * * `'/user/{id:[0-9a-fA-F]{1,8}}'` - Similar to the previous example, but only matches if the id
-	 *   parameter consists of 1 to 8 hex digits.
-	 * * `'/files/{path:.*}'` - Matches any URL starting with '/files/' and captures the rest of the
-	 *   path into the parameter 'path'.
-	 * * `'/files/*path'` - ditto.
-	 * * `'/calendar/{start:date}'` - Matches "/calendar/2014-11-12" (because the pattern defined
-	 *   in the built-in  `date` ParamType matches `2014-11-12`) and provides a Date object in $stateParams.start
-	 *
-	 */
-	var UrlMatcher = (function () {
-	    /**
-	     * @param pattern The pattern to compile into a matcher.
-	     * @param config  A configuration object hash
-	     * * `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`.
-	     * * `strict` - `false` if matching against a URL with a trailing slash should be treated as equivalent to a URL without a trailing slash, the default value is `true`.
-	     *
-	     * @property {string} pattern  The pattern that was passed into the constructor
-	     */
-	    function UrlMatcher(pattern, config) {
-	        var _this = this;
-	        this.config = config;
-	        /** @hidden */
-	        this._cache = { path: [], pattern: null };
-	        /** @hidden */
-	        this._children = [];
-	        /** @hidden */
-	        this._params = [];
-	        /** @hidden */
-	        this._segments = [];
-	        /** @hidden */
-	        this._compiled = [];
-	        this.pattern = pattern;
-	        this.config = common_1.defaults(this.config, {
-	            params: {},
-	            strict: true,
-	            caseInsensitive: false,
-	            paramMap: common_1.identity
-	        });
-	        // Find all placeholders and create a compiled pattern, using either classic or curly syntax:
-	        //   '*' name
-	        //   ':' name
-	        //   '{' name '}'
-	        //   '{' name ':' regexp '}'
-	        // The regular expression is somewhat complicated due to the need to allow curly braces
-	        // inside the regular expression. The placeholder regexp breaks down as follows:
-	        //    ([:*])([\w\[\]]+)              - classic placeholder ($1 / $2) (search version has - for snake-case)
-	        //    \{([\w\[\]]+)(?:\:\s*( ... ))?\}  - curly brace placeholder ($3) with optional regexp/type ... ($4) (search version has - for snake-case
-	        //    (?: ... | ... | ... )+         - the regexp consists of any number of atoms, an atom being either
-	        //    [^{}\\]+                       - anything other than curly braces or backslash
-	        //    \\.                            - a backslash escape
-	        //    \{(?:[^{}\\]+|\\.)*\}          - a matched set of curly braces containing other atoms
-	        var placeholder = /([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g, searchPlaceholder = /([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g, last = 0, m, patterns = [];
-	        var checkParamErrors = function (id) {
-	            if (!UrlMatcher.nameValidator.test(id))
-	                throw new Error("Invalid parameter name '" + id + "' in pattern '" + pattern + "'");
-	            if (common_1.find(_this._params, hof_1.propEq('id', id)))
-	                throw new Error("Duplicate parameter name '" + id + "' in pattern '" + pattern + "'");
-	        };
-	        // Split into static segments separated by path parameter placeholders.
-	        // The number of segments is always 1 more than the number of parameters.
-	        var matchDetails = function (m, isSearch) {
-	            // IE[78] returns '' for unmatched groups instead of null
-	            var id = m[2] || m[3], regexp = isSearch ? m[4] : m[4] || (m[1] === '*' ? '.*' : null);
-	            return {
-	                id: id,
-	                regexp: regexp,
-	                cfg: _this.config.params[id],
-	                segment: pattern.substring(last, m.index),
-	                type: !regexp ? null : paramTypes_1.paramTypes.type(regexp || "string") || common_1.inherit(paramTypes_1.paramTypes.type("string"), {
-	                    pattern: new RegExp(regexp, _this.config.caseInsensitive ? 'i' : undefined)
-	                })
-	            };
-	        };
-	        var p, segment;
-	        while ((m = placeholder.exec(pattern))) {
-	            p = matchDetails(m, false);
-	            if (p.segment.indexOf('?') >= 0)
-	                break; // we're into the search part
-	            checkParamErrors(p.id);
-	            this._params.push(param_1.Param.fromPath(p.id, p.type, this.config.paramMap(p.cfg, false)));
-	            this._segments.push(p.segment);
-	            patterns.push([p.segment, common_1.tail(this._params)]);
-	            last = placeholder.lastIndex;
-	        }
-	        segment = pattern.substring(last);
-	        // Find any search parameter names and remove them from the last segment
-	        var i = segment.indexOf('?');
-	        if (i >= 0) {
-	            var search = segment.substring(i);
-	            segment = segment.substring(0, i);
-	            if (search.length > 0) {
-	                last = 0;
-	                while ((m = searchPlaceholder.exec(search))) {
-	                    p = matchDetails(m, true);
-	                    checkParamErrors(p.id);
-	                    this._params.push(param_1.Param.fromSearch(p.id, p.type, this.config.paramMap(p.cfg, true)));
-	                    last = placeholder.lastIndex;
-	                }
-	            }
-	        }
-	        this._segments.push(segment);
-	        common_1.extend(this, {
-	            _compiled: patterns.map(function (pattern) { return quoteRegExp.apply(null, pattern); }).concat(quoteRegExp(segment)),
-	            prefix: this._segments[0]
-	        });
-	        Object.freeze(this);
-	    }
-	    /**
-	     * Creates a new concatenated UrlMatcher
-	     *
-	     * Builds a new UrlMatcher by appending another UrlMatcher to this one.
-	     *
-	     * @param url A `UrlMatcher` instance to append as a child of the current `UrlMatcher`.
-	     */
-	    UrlMatcher.prototype.append = function (url) {
-	        this._children.push(url);
-	        common_1.forEach(url._cache, function (val, key) { return url._cache[key] = predicates_1.isArray(val) ? [] : null; });
-	        url._cache.path = this._cache.path.concat(this);
-	        return url;
-	    };
-	    /** @hidden */
-	    UrlMatcher.prototype.isRoot = function () {
-	        return this._cache.path.length === 0;
-	    };
-	    /** Returns the input pattern string */
-	    UrlMatcher.prototype.toString = function () {
-	        return this.pattern;
-	    };
-	    /**
-	     * Tests the specified url/path against this matcher.
-	     *
-	     * Tests if the given url matches this matcher's pattern, and returns an object containing the captured
-	     * parameter values.  Returns null if the path does not match.
-	     *
-	     * The returned object contains the values
-	     * of any search parameters that are mentioned in the pattern, but their value may be null if
-	     * they are not present in `search`. This means that search parameters are always treated
-	     * as optional.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', {
-	     *   x: '1', q: 'hello'
-	     * });
-	     * // returns { id: 'bob', q: 'hello', r: null }
-	     * ```
-	     *
-	     * @param path    The URL path to match, e.g. `$location.path()`.
-	     * @param search  URL search parameters, e.g. `$location.search()`.
-	     * @param hash    URL hash e.g. `$location.hash()`.
-	     * @param options
-	     *
-	     * @returns The captured parameter values.
-	     */
-	    UrlMatcher.prototype.exec = function (path, search, hash, options) {
-	        var _this = this;
-	        if (search === void 0) { search = {}; }
-	        if (options === void 0) { options = {}; }
-	        var match = memoizeTo(this._cache, 'pattern', function () {
-	            return new RegExp([
-	                '^',
-	                common_1.unnest(_this._cache.path.concat(_this).map(hof_1.prop('_compiled'))).join(''),
-	                _this.config.strict === false ? '\/?' : '',
-	                '$'
-	            ].join(''), _this.config.caseInsensitive ? 'i' : undefined);
-	        }).exec(path);
-	        if (!match)
-	            return null;
-	        //options = defaults(options, { isolate: false });
-	        var allParams = this.parameters(), pathParams = allParams.filter(function (param) { return !param.isSearch(); }), searchParams = allParams.filter(function (param) { return param.isSearch(); }), nPathSegments = this._cache.path.concat(this).map(function (urlm) { return urlm._segments.length - 1; }).reduce(function (a, x) { return a + x; }), values = {};
-	        if (nPathSegments !== match.length - 1)
-	            throw new Error("Unbalanced capture group in route '" + this.pattern + "'");
-	        function decodePathArray(string) {
-	            var reverseString = function (str) { return str.split("").reverse().join(""); };
-	            var unquoteDashes = function (str) { return str.replace(/\\-/g, "-"); };
-	            var split = reverseString(string).split(/-(?!\\)/);
-	            var allReversed = common_1.map(split, reverseString);
-	            return common_1.map(allReversed, unquoteDashes).reverse();
-	        }
-	        for (var i = 0; i < nPathSegments; i++) {
-	            var param = pathParams[i];
-	            var value = match[i + 1];
-	            // if the param value matches a pre-replace pair, replace the value before decoding.
-	            for (var j = 0; j < param.replace.length; j++) {
-	                if (param.replace[j].from === value)
-	                    value = param.replace[j].to;
-	            }
-	            if (value && param.array === true)
-	                value = decodePathArray(value);
-	            if (predicates_2.isDefined(value))
-	                value = param.type.decode(value);
-	            values[param.id] = param.value(value);
-	        }
-	        common_1.forEach(searchParams, function (param) {
-	            var value = search[param.id];
-	            for (var j = 0; j < param.replace.length; j++) {
-	                if (param.replace[j].from === value)
-	                    value = param.replace[j].to;
-	            }
-	            if (predicates_2.isDefined(value))
-	                value = param.type.decode(value);
-	            values[param.id] = param.value(value);
-	        });
-	        if (hash)
-	            values["#"] = hash;
-	        return values;
-	    };
-	    /**
-	     * @hidden
-	     * Returns all the [[Param]] objects of all path and search parameters of this pattern in order of appearance.
-	     *
-	     * @returns {Array.<Param>}  An array of [[Param]] objects. Must be treated as read-only. If the
-	     *    pattern has no parameters, an empty array is returned.
-	     */
-	    UrlMatcher.prototype.parameters = function (opts) {
-	        if (opts === void 0) { opts = {}; }
-	        if (opts.inherit === false)
-	            return this._params;
-	        return common_1.unnest(this._cache.path.concat(this).map(hof_1.prop('_params')));
-	    };
-	    /**
-	     * @hidden
-	     * Returns a single parameter from this UrlMatcher by id
-	     *
-	     * @param id
-	     * @param opts
-	     * @returns {T|Param|any|boolean|UrlMatcher|null}
-	     */
-	    UrlMatcher.prototype.parameter = function (id, opts) {
-	        if (opts === void 0) { opts = {}; }
-	        var parent = common_1.tail(this._cache.path);
-	        return (common_1.find(this._params, hof_1.propEq('id', id)) ||
-	            (opts.inherit !== false && parent && parent.parameter(id)) ||
-	            null);
-	    };
-	    /**
-	     * Validates the input parameter values against this UrlMatcher
-	     *
-	     * Checks an object hash of parameters to validate their correctness according to the parameter
-	     * types of this `UrlMatcher`.
-	     *
-	     * @param params The object hash of parameters to validate.
-	     * @returns Returns `true` if `params` validates, otherwise `false`.
-	     */
-	    UrlMatcher.prototype.validates = function (params) {
-	        var _this = this;
-	        var validParamVal = function (param, val) { return !param || param.validates(val); };
-	        return common_1.pairs(params || {}).map(function (_a) {
-	            var key = _a[0], val = _a[1];
-	            return validParamVal(_this.parameter(key), val);
-	        }).reduce(common_1.allTrueR, true);
-	    };
-	    /**
-	     * Given a set of parameter values, creates a URL from this UrlMatcher.
-	     *
-	     * Creates a URL that matches this pattern by substituting the specified values
-	     * for the path and search parameters.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });
-	     * // returns '/user/bob?q=yes'
-	     * ```
-	     *
-	     * @param values  the values to substitute for the parameters in this pattern.
-	     * @returns the formatted URL (path and optionally search part).
-	     */
-	    UrlMatcher.prototype.format = function (values) {
-	        if (values === void 0) { values = {}; }
-	        if (!this.validates(values))
-	            return null;
-	        // Build the full path of UrlMatchers (including all parent UrlMatchers)
-	        var urlMatchers = this._cache.path.slice().concat(this);
-	        // Extract all the static segments and Params into an ordered array
-	        var pathSegmentsAndParams = urlMatchers.map(UrlMatcher.pathSegmentsAndParams).reduce(common_2.unnestR, []);
-	        // Extract the query params into a separate array
-	        var queryParams = urlMatchers.map(UrlMatcher.queryParams).reduce(common_2.unnestR, []);
-	        /**
-	         * Given a Param,
-	         * Applies the parameter value, then returns details about it
-	         */
-	        function getDetails(param) {
-	            // Normalize to typed value
-	            var value = param.value(values[param.id]);
-	            var isDefaultValue = param.isDefaultValue(value);
-	            // Check if we're in squash mode for the parameter
-	            var squash = isDefaultValue ? param.squash : false;
-	            // Allow the Parameter's Type to encode the value
-	            var encoded = param.type.encode(value);
-	            return { param: param, value: value, isDefaultValue: isDefaultValue, squash: squash, encoded: encoded };
-	        }
-	        // Build up the path-portion from the list of static segments and parameters
-	        var pathString = pathSegmentsAndParams.reduce(function (acc, x) {
-	            // The element is a static segment (a raw string); just append it
-	            if (predicates_1.isString(x))
-	                return acc + x;
-	            // Otherwise, it's a Param.  Fetch details about the parameter value
-	            var _a = getDetails(x), squash = _a.squash, encoded = _a.encoded, param = _a.param;
-	            // If squash is === true, try to remove a slash from the path
-	            if (squash === true)
-	                return (acc.match(/\/$/)) ? acc.slice(0, -1) : acc;
-	            // If squash is a string, use the string for the param value
-	            if (predicates_1.isString(squash))
-	                return acc + squash;
-	            if (squash !== false)
-	                return acc; // ?
-	            if (encoded == null)
-	                return acc;
-	            // If this parameter value is an array, encode the value using encodeDashes
-	            if (predicates_1.isArray(encoded))
-	                return acc + common_1.map(encoded, UrlMatcher.encodeDashes).join("-");
-	            // If the parameter type is "raw", then do not encodeURIComponent
-	            if (param.type.raw)
-	                return acc + encoded;
-	            // Encode the value
-	            return acc + encodeURIComponent(encoded);
-	        }, "");
-	        // Build the query string by applying parameter values (array or regular)
-	        // then mapping to key=value, then flattening and joining using "&"
-	        var queryString = queryParams.map(function (param) {
-	            var _a = getDetails(param), squash = _a.squash, encoded = _a.encoded, isDefaultValue = _a.isDefaultValue;
-	            if (encoded == null || (isDefaultValue && squash !== false))
-	                return;
-	            if (!predicates_1.isArray(encoded))
-	                encoded = [encoded];
-	            if (encoded.length === 0)
-	                return;
-	            if (!param.type.raw)
-	                encoded = common_1.map(encoded, encodeURIComponent);
-	            return encoded.map(function (val) { return (param.id + "=" + val); });
-	        }).filter(common_1.identity).reduce(common_2.unnestR, []).join("&");
-	        // Concat the pathstring with the queryString (if exists) and the hashString (if exists)
-	        return pathString + (queryString ? "?" + queryString : "") + (values["#"] ? "#" + values["#"] : "");
-	    };
-	    /** @hidden */
-	    UrlMatcher.encodeDashes = function (str) {
-	        return encodeURIComponent(str).replace(/-/g, function (c) { return ("%5C%" + c.charCodeAt(0).toString(16).toUpperCase()); });
-	    };
-	    /** @hidden Given a matcher, return an array with the matcher's path segments and path params, in order */
-	    UrlMatcher.pathSegmentsAndParams = function (matcher) {
-	        var staticSegments = matcher._segments;
-	        var pathParams = matcher._params.filter(function (p) { return p.location === param_2.DefType.PATH; });
-	        return common_3.arrayTuples(staticSegments, pathParams.concat(undefined)).reduce(common_2.unnestR, []).filter(function (x) { return x !== "" && predicates_2.isDefined(x); });
-	    };
-	    /** @hidden Given a matcher, return an array with the matcher's query params */
-	    UrlMatcher.queryParams = function (matcher) {
-	        return matcher._params.filter(function (p) { return p.location === param_2.DefType.SEARCH; });
-	    };
-	    /** @hidden */
-	    UrlMatcher.nameValidator = /^\w+([-.]+\w+)*(?:\[\])?$/;
-	    return UrlMatcher;
-	}());
-	exports.UrlMatcher = UrlMatcher;
-
-
-/***/ },
-/* 29 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module url */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var coreservices_1 = __webpack_require__(6);
-	/** @hidden */
-	var $location = coreservices_1.services.location;
-	/** @hidden Returns a string that is a prefix of all strings matching the RegExp */
-	function regExpPrefix(re) {
-	    var prefix = /^\^((?:\\[^a-zA-Z0-9]|[^\\\[\]\^$*+?.()|{}]+)*)/.exec(re.source);
-	    return (prefix != null) ? prefix[1].replace(/\\(.)/g, "$1") : '';
-	}
-	/** @hidden Interpolates matched values into a String.replace()-style pattern */
-	function interpolate(pattern, match) {
-	    return pattern.replace(/\$(\$|\d{1,2})/, function (m, what) {
-	        return match[what === '$' ? 0 : Number(what)];
-	    });
-	}
-	/** @hidden */
-	function handleIfMatch($injector, $stateParams, handler, match) {
-	    if (!match)
-	        return false;
-	    var result = $injector.invoke(handler, handler, { $match: match, $stateParams: $stateParams });
-	    return predicates_1.isDefined(result) ? result : true;
-	}
-	/** @hidden */
-	function appendBasePath(url, isHtml5, absolute) {
-	    var baseHref = coreservices_1.services.locationConfig.baseHref();
-	    if (baseHref === '/')
-	        return url;
-	    if (isHtml5)
-	        return baseHref.slice(0, -1) + url;
-	    if (absolute)
-	        return baseHref.slice(1) + url;
-	    return url;
-	}
-	// TODO: Optimize groups of rules with non-empty prefix into some sort of decision tree
-	/** @hidden */
-	function update(rules, otherwiseFn, evt) {
-	    if (evt && evt.defaultPrevented)
-	        return;
-	    function check(rule) {
-	        var handled = rule(coreservices_1.services.$injector, $location);
-	        if (!handled)
-	            return false;
-	        if (predicates_1.isString(handled)) {
-	            $location.replace();
-	            $location.url(handled);
-	        }
-	        return true;
-	    }
-	    var n = rules.length, i;
-	    for (i = 0; i < n; i++) {
-	        if (check(rules[i]))
-	            return;
-	    }
-	    // always check otherwise last to allow dynamic updates to the set of rules
-	    if (otherwiseFn)
-	        check(otherwiseFn);
-	}
-	/**
-	 * Manages rules for client-side URL
-	 *
-	 * This class manages the router rules for what to do when the URL changes.
-	 */
-	var UrlRouterProvider = (function () {
-	    function UrlRouterProvider($urlMatcherFactory, $stateParams) {
-	        /** @hidden */
-	        this.rules = [];
-	        /** @hidden */
-	        this.interceptDeferred = false;
-	        this.$urlMatcherFactory = $urlMatcherFactory;
-	        this.$stateParams = $stateParams;
-	    }
-	    /**
-	     * Registers a url handler function.
-	     *
-	     * Registers a low level url handler (a `rule`). A rule detects specific URL patterns and returns
-	     * a redirect, or performs some action.
-	     *
-	     * If a rule returns a string, the URL is replaced with the string, and all rules are fired again.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * var app = angular.module('app', ['ui.router.router']);
-	     *
-	     * app.config(function ($urlRouterProvider) {
-	     *   // Here's an example of how you might allow case insensitive urls
-	     *   $urlRouterProvider.rule(function ($injector, $location) {
-	     *     var path = $location.path(),
-	     *         normalized = path.toLowerCase();
-	     *
-	     *     if (path !== normalized) {
-	     *       return normalized;
-	     *     }
-	     *   });
-	     * });
-	     * ```
-	     *
-	     * @param rule
-	     * Handler function that takes `$injector` and `$location` services as arguments.
-	     * You can use them to detect a url and return a different url as a string.
-	     *
-	     * @return [[$urlRouterProvider]] (`this`)
-	     */
-	    UrlRouterProvider.prototype.rule = function (rule) {
-	        if (!predicates_1.isFunction(rule))
-	            throw new Error("'rule' must be a function");
-	        this.rules.push(rule);
-	        return this;
-	    };
-	    ;
-	    /**
-	     * Defines the path or behavior to use when no url can be matched.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * var app = angular.module('app', ['ui.router.router']);
-	     *
-	     * app.config(function ($urlRouterProvider) {
-	     *   // if the path doesn't match any of the urls you configured
-	     *   // otherwise will take care of routing the user to the
-	     *   // specified url
-	     *   $urlRouterProvider.otherwise('/index');
-	     *
-	     *   // Example of using function rule as param
-	     *   $urlRouterProvider.otherwise(function ($injector, $location) {
-	     *     return '/a/valid/url';
-	     *   });
-	     * });
-	     * ```
-	     *
-	     * @param rule
-	     * The url path you want to redirect to or a function rule that returns the url path or performs a `$state.go()`.
-	     * The function version is passed two params: `$injector` and `$location` services, and should return a url string.
-	     *
-	     * @return {object} `$urlRouterProvider` - `$urlRouterProvider` instance
-	     */
-	    UrlRouterProvider.prototype.otherwise = function (rule) {
-	        if (!predicates_1.isFunction(rule) && !predicates_1.isString(rule))
-	            throw new Error("'rule' must be a string or function");
-	        this.otherwiseFn = predicates_1.isString(rule) ? function () { return rule; } : rule;
-	        return this;
-	    };
-	    ;
-	    /**
-	     * Registers a handler for a given url matching.
-	     *
-	     * If the handler is a string, it is
-	     * treated as a redirect, and is interpolated according to the syntax of match
-	     * (i.e. like `String.replace()` for `RegExp`, or like a `UrlMatcher` pattern otherwise).
-	     *
-	     * If the handler is a function, it is injectable.
-	     * It gets invoked if `$location` matches.
-	     * You have the option of inject the match object as `$match`.
-	     *
-	     * The handler can return
-	     *
-	     * - **falsy** to indicate that the rule didn't match after all, then `$urlRouter`
-	     *   will continue trying to find another one that matches.
-	     * - **string** which is treated as a redirect and passed to `$location.url()`
-	     * - **void** or any **truthy** value tells `$urlRouter` that the url was handled.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * var app = angular.module('app', ['ui.router.router']);
-	     *
-	     * app.config(function ($urlRouterProvider) {
-	     *   $urlRouterProvider.when($state.url, function ($match, $stateParams) {
-	     *     if ($state.$current.navigable !== state ||
-	     *         !equalForKeys($match, $stateParams) {
-	     *      $state.transitionTo(state, $match, false);
-	     *     }
-	     *   });
-	     * });
-	     * ```
-	     *
-	     * @param what A pattern string to match, compiled as a [[UrlMatcher]].
-	     * @param handler The path (or function that returns a path) that you want to redirect your user to.
-	     *
-	     * Note: the handler may also invoke arbitrary code, such as `$state.go()`
-	     */
-	    UrlRouterProvider.prototype.when = function (what, handler) {
-	        var _a = this, $urlMatcherFactory = _a.$urlMatcherFactory, $stateParams = _a.$stateParams;
-	        var redirect, handlerIsString = predicates_1.isString(handler);
-	        // @todo Queue this
-	        if (predicates_1.isString(what))
-	            what = $urlMatcherFactory.compile(what);
-	        if (!handlerIsString && !predicates_1.isFunction(handler) && !predicates_1.isArray(handler))
-	            throw new Error("invalid 'handler' in when()");
-	        var strategies = {
-	            matcher: function (_what, _handler) {
-	                if (handlerIsString) {
-	                    redirect = $urlMatcherFactory.compile(_handler);
-	                    _handler = ['$match', redirect.format.bind(redirect)];
-	                }
-	                return common_1.extend(function () {
-	                    return handleIfMatch(coreservices_1.services.$injector, $stateParams, _handler, _what.exec($location.path(), $location.search(), $location.hash()));
-	                }, {
-	                    prefix: predicates_1.isString(_what.prefix) ? _what.prefix : ''
-	                });
-	            },
-	            regex: function (_what, _handler) {
-	                if (_what.global || _what.sticky)
-	                    throw new Error("when() RegExp must not be global or sticky");
-	                if (handlerIsString) {
-	                    redirect = _handler;
-	                    _handler = ['$match', function ($match) { return interpolate(redirect, $match); }];
-	                }
-	                return common_1.extend(function () {
-	                    return handleIfMatch(coreservices_1.services.$injector, $stateParams, _handler, _what.exec($location.path()));
-	                }, {
-	                    prefix: regExpPrefix(_what)
-	                });
-	            }
-	        };
-	        var check = {
-	            matcher: $urlMatcherFactory.isMatcher(what),
-	            regex: what instanceof RegExp
-	        };
-	        for (var n in check) {
-	            if (check[n])
-	                return this.rule(strategies[n](what, handler));
-	        }
-	        throw new Error("invalid 'what' in when()");
-	    };
-	    ;
-	    /**
-	     * Disables monitoring of the URL.
-	     *
-	     * Call this method before UI-Router has bootstrapped.
-	     * It will stop UI-Router from performing the initial url sync.
-	     *
-	     * This can be useful to perform some asynchronous initialization before the router starts.
-	     * Once the initialization is complete, call [[listen]] to tell UI-Router to start watching and synchronizing the URL.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * var app = angular.module('app', ['ui.router']);
-	     *
-	     * app.config(function ($urlRouterProvider) {
-	     *   // Prevent $urlRouter from automatically intercepting URL changes;
-	     *   $urlRouterProvider.deferIntercept();
-	     * })
-	     *
-	     * app.run(function (MyService, $urlRouter, $http) {
-	     *   $http.get("/stuff").then(function(resp) {
-	     *     MyService.doStuff(resp.data);
-	     *     $urlRouter.listen();
-	     *     $urlRouter.sync();
-	     *   });
-	     * });
-	     * ```
-	     *
-	     * @param defer Indicates whether to defer location change interception. Passing
-	     *        no parameter is equivalent to `true`.
-	     */
-	    UrlRouterProvider.prototype.deferIntercept = function (defer) {
-	        if (defer === undefined)
-	            defer = true;
-	        this.interceptDeferred = defer;
-	    };
-	    ;
-	    return UrlRouterProvider;
-	}());
-	exports.UrlRouterProvider = UrlRouterProvider;
-	var UrlRouter = (function () {
-	    /** @hidden */
-	    function UrlRouter(urlRouterProvider) {
-	        this.urlRouterProvider = urlRouterProvider;
-	        common_1.bindFunctions(UrlRouter.prototype, this, this);
-	    }
-	    /**
-	     * Checks the current URL for a matching rule
-	     *
-	     * Triggers an update; the same update that happens when the address bar url changes, aka `$locationChangeSuccess`.
-	     * This method is useful when you need to use `preventDefault()` on the `$locationChangeSuccess` event,
-	     * perform some custom logic (route protection, auth, config, redirection, etc) and then finally proceed
-	     * with the transition by calling `$urlRouter.sync()`.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * angular.module('app', ['ui.router'])
-	     *   .run(function($rootScope, $urlRouter) {
-	     *     $rootScope.$on('$locationChangeSuccess', function(evt) {
-	     *       // Halt state change from even starting
-	     *       evt.preventDefault();
-	     *       // Perform custom logic
-	     *       var meetsRequirement = ...
-	     *       // Continue with the update and state transition if logic allows
-	     *       if (meetsRequirement) $urlRouter.sync();
-	     *     });
-	     * });
-	     * ```
-	     */
-	    UrlRouter.prototype.sync = function () {
-	        update(this.urlRouterProvider.rules, this.urlRouterProvider.otherwiseFn);
-	    };
-	    /**
-	     * Starts listening for URL changes
-	     *
-	     * Call this sometime after calling [[deferIntercept]] to start monitoring the url.
-	     * This causes [[UrlRouter]] to start listening for changes to the URL, if it wasn't already listening.
-	     */
-	    UrlRouter.prototype.listen = function () {
-	        var _this = this;
-	        return this.listener = this.listener || $location.onChange(function (evt) { return update(_this.urlRouterProvider.rules, _this.urlRouterProvider.otherwiseFn, evt); });
-	    };
-	    /**
-	     * Internal API.
-	     */
-	    UrlRouter.prototype.update = function (read) {
-	        if (read) {
-	            this.location = $location.url();
-	            return;
-	        }
-	        if ($location.url() === this.location)
-	            return;
-	        $location.url(this.location);
-	        $location.replace();
-	    };
-	    /**
-	     * Internal API.
-	     *
-	     * Pushes a new location to the browser history.
-	     *
-	     * @param urlMatcher
-	     * @param params
-	     * @param options
-	     */
-	    UrlRouter.prototype.push = function (urlMatcher, params, options) {
-	        $location.url(urlMatcher.format(params || {}));
-	        if (options && options.replace)
-	            $location.replace();
-	    };
-	    /**
-	     * Builds and returns a URL with interpolated parameters
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * $bob = $urlRouter.href(new UrlMatcher("/about/:person"), {
-	     *   person: "bob"
-	     * });
-	     * // $bob == "/about/bob";
-	     * ```
-	     *
-	     * @param urlMatcher The [[UrlMatcher]] object which is used as the template of the URL to generate.
-	     * @param params An object of parameter values to fill the matcher's required parameters.
-	     * @param options Options object. The options are:
-	     *
-	     * - **`absolute`** - {boolean=false},  If true will generate an absolute url, e.g. "http://www.example.com/fullurl".
-	     *
-	     * @returns Returns the fully compiled URL, or `null` if `params` fail validation against `urlMatcher`
-	     */
-	    UrlRouter.prototype.href = function (urlMatcher, params, options) {
-	        if (!urlMatcher.validates(params))
-	            return null;
-	        var url = urlMatcher.format(params);
-	        options = options || { absolute: false };
-	        var cfg = coreservices_1.services.locationConfig;
-	        var isHtml5 = cfg.html5Mode();
-	        if (!isHtml5 && url !== null) {
-	            url = "#" + cfg.hashPrefix() + url;
-	        }
-	        url = appendBasePath(url, isHtml5, options.absolute);
-	        if (!options.absolute || !url) {
-	            return url;
-	        }
-	        var slash = (!isHtml5 && url ? '/' : ''), port = cfg.port();
-	        port = (port === 80 || port === 443 ? '' : ':' + port);
-	        return [cfg.protocol(), '://', cfg.host(), port, slash, url].join('');
-	    };
-	    return UrlRouter;
-	}());
-	exports.UrlRouter = UrlRouter;
-
-
-/***/ },
-/* 30 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module state */ /** for typedoc */
-	var predicates_1 = __webpack_require__(4);
-	var common_1 = __webpack_require__(3);
-	/**
-	 * @ngdoc object
-	 * @name ui.router.state.$stateProvider
-	 *
-	 * @requires ui.router.router.$urlRouterProvider
-	 * @requires ui.router.util.$urlMatcherFactoryProvider
-	 *
-	 * @description
-	 * The new `$stateProvider` works similar to Angular's v1 router, but it focuses purely
-	 * on state.
-	 *
-	 * A state corresponds to a "place" in the application in terms of the overall UI and
-	 * navigation. A state describes (via the controller / template / view properties) what
-	 * the UI looks like and does at that place.
-	 *
-	 * States often have things in common, and the primary way of factoring out these
-	 * commonalities in this model is via the state hierarchy, i.e. parent/child states aka
-	 * nested states.
-	 *
-	 * The `$stateProvider` provides interfaces to declare these states for your app.
-	 */
-	var StateProvider = (function () {
-	    function StateProvider(stateRegistry) {
-	        this.stateRegistry = stateRegistry;
-	        this.invalidCallbacks = [];
-	        common_1.bindFunctions(StateProvider.prototype, this, this);
-	    }
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$stateProvider#decorator
-	     * @methodOf ui.router.state.$stateProvider
-	     *
-	     * @description
-	     * Allows you to extend (carefully) or override (at your own peril) the
-	     * `stateBuilder` object used internally by `$stateProvider`. This can be used
-	     * to add custom functionality to ui-router, for example inferring templateUrl
-	     * based on the state name.
-	     *
-	     * When passing only a name, it returns the current (original or decorated) builder
-	     * function that matches `name`.
-	     *
-	     * The builder functions that can be decorated are listed below. Though not all
-	     * necessarily have a good use case for decoration, that is up to you to decide.
-	     *
-	     * In addition, users can attach custom decorators, which will generate new
-	     * properties within the state's internal definition. There is currently no clear
-	     * use-case for this beyond accessing internal states (i.e. $state.$current),
-	     * however, expect this to become increasingly relevant as we introduce additional
-	     * meta-programming features.
-	     *
-	     * **Warning**: Decorators should not be interdependent because the order of
-	     * execution of the builder functions in non-deterministic. Builder functions
-	     * should only be dependent on the state definition object and super function.
-	     *
-	     *
-	     * Existing builder functions and current return values:
-	     *
-	     * - **parent** `{object}` - returns the parent state object.
-	     * - **data** `{object}` - returns state data, including any inherited data that is not
-	     *   overridden by own values (if any).
-	     * - **url** `{object}` - returns a {@link ui.router.util.type:UrlMatcher UrlMatcher}
-	     *   or `null`.
-	     * - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is
-	     *   navigable).
-	     * - **params** `{object}` - returns an array of state params that are ensured to
-	     *   be a super-set of parent's params.
-	     * - **views** `{object}` - returns a views object where each key is an absolute view
-	     *   name (i.e. "viewName@stateName") and each value is the config object
-	     *   (template, controller) for the view. Even when you don't use the views object
-	     *   explicitly on a state config, one is still created for you internally.
-	     *   So by decorating this builder function you have access to decorating template
-	     *   and controller properties.
-	     * - **ownParams** `{object}` - returns an array of params that belong to the state,
-	     *   not including any params defined by ancestor states.
-	     * - **path** `{string}` - returns the full path from the root down to this state.
-	     *   Needed for state activation.
-	     * - **includes** `{object}` - returns an object that includes every state that
-	     *   would pass a `$state.includes()` test.
-	     *
-	     * @example
-	     * <pre>
-	     * // Override the internal 'views' builder with a function that takes the state
-	     * // definition, and a reference to the internal function being overridden:
-	     * $stateProvider.decorator('views', function (state, parent) {
-	     *   let result = {},
-	     *       views = parent(state);
-	     *
-	     *   angular.forEach(views, function (config, name) {
-	     *     let autoName = (state.name + '.' + name).replace('.', '/');
-	     *     config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html';
-	     *     result[name] = config;
-	     *   });
-	     *   return result;
-	     * });
-	     *
-	     * $stateProvider.state('home', {
-	     *   views: {
-	     *     'contact.list': { controller: 'ListController' },
-	     *     'contact.item': { controller: 'ItemController' }
-	     *   }
-	     * });
-	     *
-	     * // ...
-	     *
-	     * $state.go('home');
-	     * // Auto-populates list and item views with /partials/home/contact/list.html,
-	     * // and /partials/home/contact/item.html, respectively.
-	     * </pre>
-	     *
-	     * @param {string} name The name of the builder function to decorate.
-	     * @param {object} func A function that is responsible for decorating the original
-	     * builder function. The function receives two parameters:
-	     *
-	     *   - `{object}` - state - The state config object.
-	     *   - `{object}` - super - The original builder function.
-	     *
-	     * @return {object} $stateProvider - $stateProvider instance
-	     */
-	    StateProvider.prototype.decorator = function (name, func) {
-	        return this.stateRegistry.decorator(name, func) || this;
-	    };
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$stateProvider#state
-	     * @methodOf ui.router.state.$stateProvider
-	     *
-	     * @description
-	     * Registers a state configuration under a given state name. The stateConfig object
-	     * has the following acceptable properties.
-	     *
-	     * <a id='template'></a>
-	     *
-	     * - **`template`** - {string|function=} - html template as a string or a function that returns
-	     *   an html template as a string which should be used by the uiView directives. This property
-	     *   takes precedence over templateUrl.
-	     *
-	     *   If `template` is a function, it will be called with the following parameters:
-	     *
-	     *   - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
-	     *     applying the current state
-	     *
-	     * <a id='templateUrl'></a>
-	     *
-	     * - **`templateUrl`** - {string|function=} - path or function that returns a path to an html
-	     *   template that should be used by uiView.
-	     *
-	     *   If `templateUrl` is a function, it will be called with the following parameters:
-	     *
-	     *   - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
-	     *     applying the current state
-	     *
-	     * <a id='templateProvider'></a>
-	     *
-	     * - **`templateProvider`** - {function=} - Provider function that returns HTML content
-	     *   string.
-	     *
-	     * <a id='controller'></a>
-	     *
-	     * - **`controller`** - {string|function=} -  Controller fn that should be associated with newly
-	     *   related scope or the name of a registered controller if passed as a string.
-	     *
-	     * <a id='controllerProvider'></a>
-	     *
-	     * - **`controllerProvider`** - {function=} - Injectable provider function that returns
-	     *   the actual controller or string.
-	     *
-	     * <a id='controllerAs'></a>
-	     *
-	     * - **`controllerAs`** – {string=} – A controller alias name. If present the controller will be
-	     *   published to scope under the controllerAs name.
-	     *
-	     * <a id='resolve'></a>
-	     *
-	     * - **`resolve`** - {object.&lt;string, function&gt;=} - An optional map of dependencies which
-	     *   should be injected into the controller. If any of these dependencies are promises,
-	     *   the router will wait for them all to be resolved or one to be rejected before the
-	     *   controller is instantiated. If all the promises are resolved successfully, the values
-	     *   of the resolved promises are injected and $stateChangeSuccess event is fired. If any
-	     *   of the promises are rejected the $stateChangeError event is fired. The map object is:
-	     *
-	     *   - key - {string}: name of dependency to be injected into controller
-	     *   - factory - {string|function}: If string then it is alias for service. Otherwise if function,
-	     *     it is injected and return value it treated as dependency. If result is a promise, it is
-	     *     resolved before its value is injected into controller.
-	     *
-	     * <a id='url'></a>
-	     *
-	     * - **`url`** - {string=} - A url with optional parameters. When a state is navigated or
-	     *   transitioned to, the `$stateParams` service will be populated with any
-	     *   parameters that were passed.
-	     *
-	     * <a id='params'></a>
-	     *
-	     * - **`params`** - {object=} - An array of parameter names or regular expressions. Only
-	     *   use this within a state if you are not using url. Otherwise you can specify your
-	     *   parameters within the url. When a state is navigated or transitioned to, the
-	     *   $stateParams service will be populated with any parameters that were passed.
-	     *
-	     * <a id='views'></a>
-	     *
-	     * - **`views`** - {object=} - Use the views property to set up multiple views or to target views
-	     *   manually/explicitly.
-	     *
-	     * <a id='abstract'></a>
-	     *
-	     * - **`abstract`** - {boolean=} - An abstract state will never be directly activated,
-	     *   but can provide inherited properties to its common children states.
-	     *
-	     * <a id='onEnter'></a>
-	     *
-	     * - **`onEnter`** - {object=} - Callback function for when a state is entered. Good way
-	     *   to trigger an action or dispatch an event, such as opening a dialog.
-	     * If minifying your scripts, make sure to use the `['injection1', 'injection2', function(injection1, injection2){}]` syntax.
-	     *
-	     * <a id='onExit'></a>
-	     *
-	     * - **`onExit`** - {object=} - Callback function for when a state is exited. Good way to
-	     *   trigger an action or dispatch an event, such as opening a dialog.
-	     * If minifying your scripts, make sure to use the `['injection1', 'injection2', function(injection1, injection2){}]` syntax.
-	     *
-	     * <a id='reloadOnSearch'></a>
-	     *
-	     * - **`reloadOnSearch = true`** - {boolean=} - If `false`, will not retrigger the same state
-	     *   just because a search/query parameter has changed (via $location.search() or $location.hash()).
-	     *   Useful for when you'd like to modify $location.search() without triggering a reload.
-	     *
-	     * <a id='data'></a>
-	     *
-	     * - **`data`** - {object=} - Arbitrary data object, useful for custom configuration.
-	     *
-	     * @example
-	     * <pre>
-	     * // Some state name examples
-	     *
-	     * // stateName can be a single top-level name (must be unique).
-	     * $stateProvider.state("home", {});
-	     *
-	     * // Or it can be a nested state name. This state is a child of the
-	     * // above "home" state.
-	     * $stateProvider.state("home.newest", {});
-	     *
-	     * // Nest states as deeply as needed.
-	     * $stateProvider.state("home.newest.abc.xyz.inception", {});
-	     *
-	     * // state() returns $stateProvider, so you can chain state declarations.
-	     * $stateProvider
-	     *   .state("home", {})
-	     *   .state("about", {})
-	     *   .state("contacts", {});
-	     * </pre>
-	     *
-	     * @param {string} name A unique state name, e.g. "home", "about", "contacts".
-	     * To create a parent/child state use a dot, e.g. "about.sales", "home.newest".
-	     * @param {object} definition State configuration object.
-	     */
-	    StateProvider.prototype.state = function (name, definition) {
-	        if (predicates_1.isObject(name)) {
-	            definition = name;
-	        }
-	        else {
-	            definition.name = name;
-	        }
-	        this.stateRegistry.register(definition);
-	        return this;
-	    };
-	    /**
-	     * Registers an invalid state handler
-	     *
-	     * Registers a function to be injected and invoked when [[StateService.transitionTo]] has been called with an invalid
-	     * state reference parameter
-	     *
-	     * This function can be injected with one some special values:
-	     * - **`$to$`**: TargetState
-	     * - **`$from$`**: TargetState
-	     *
-	     * Note: This API is subject to change.
-	     * Replacement of dependency injection support with some alternative is likely.
-	     *
-	     * @param {function} callback
-	     *   The function which will be injected and invoked, when a matching transition is started.
-	     *   The function may optionally return a {TargetState} or a Promise for a TargetState.  If one
-	     *   is returned, it is treated as a redirect.
-	     */
-	    StateProvider.prototype.onInvalid = function (callback) {
-	        this.invalidCallbacks.push(callback);
-	    };
-	    return StateProvider;
-	}());
-	exports.StateProvider = StateProvider;
-
-
-/***/ },
-/* 31 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	var transition_1 = __webpack_require__(11);
-	var hookRegistry_1 = __webpack_require__(15);
-	var resolve_1 = __webpack_require__(32);
-	var views_1 = __webpack_require__(33);
-	var url_1 = __webpack_require__(34);
-	var redirectTo_1 = __webpack_require__(35);
-	var onEnterExitRetain_1 = __webpack_require__(36);
-	var hof_1 = __webpack_require__(5);
-	/**
-	 * The default [[Transition]] options.
-	 *
-	 * Include this object when applying custom defaults:
-	 * let reloadOpts = { reload: true, notify: true }
-	 * let options = defaults(theirOpts, customDefaults, defaultOptions);
-	 */
-	exports.defaultTransOpts = {
-	    location: true,
-	    relative: null,
-	    inherit: false,
-	    notify: true,
-	    reload: false,
-	    custom: {},
-	    current: function () { return null; }
-	};
-	/**
-	 * This class provides services related to Transitions.
-	 *
-	 * - Most importantly, it allows global Transition Hooks to be registered.
-	 * - It allows the default transition error handler to be set.
-	 * - It also has a factory function for creating new [[Transition]] objects, (used internally by the [[StateService]]).
-	 *
-	 * At bootstrap, [[UIRouter]] creates a single instance (singleton) of this class.
-	 */
-	var TransitionService = (function () {
-	    function TransitionService(_router) {
-	        this._router = _router;
-	        this.$view = _router.viewService;
-	        hookRegistry_1.HookRegistry.mixin(new hookRegistry_1.HookRegistry(), this);
-	        this._deregisterHookFns = {};
-	        this.registerTransitionHooks();
-	    }
-	    /** @hidden */
-	    TransitionService.prototype.registerTransitionHooks = function () {
-	        var fns = this._deregisterHookFns;
-	        // Wire up redirectTo hook
-	        fns.redirectTo = this.onStart({ to: function (state) { return !!state.redirectTo; } }, redirectTo_1.redirectToHook);
-	        // Wire up onExit/Retain/Enter state hooks
-	        fns.onExit = this.onExit({ exiting: function (state) { return !!state.onExit; } }, onEnterExitRetain_1.onExitHook);
-	        fns.onRetain = this.onRetain({ retained: function (state) { return !!state.onRetain; } }, onEnterExitRetain_1.onRetainHook);
-	        fns.onEnter = this.onEnter({ entering: function (state) { return !!state.onEnter; } }, onEnterExitRetain_1.onEnterHook);
-	        // Wire up Resolve hooks
-	        fns.eagerResolve = this.onStart({}, resolve_1.eagerResolvePath, { priority: 1000 });
-	        fns.lazyResolve = this.onEnter({ entering: hof_1.val(true) }, resolve_1.lazyResolveState, { priority: 1000 });
-	        // Wire up the View management hooks
-	        fns.loadViews = this.onStart({}, views_1.loadEnteringViews);
-	        fns.activateViews = this.onSuccess({}, views_1.activateViews);
-	        // After globals.current is updated at priority: 10000
-	        fns.updateUrl = this.onSuccess({}, url_1.updateUrl, { priority: 9999 });
-	    };
-	    /** @inheritdoc */
-	    TransitionService.prototype.onBefore = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    TransitionService.prototype.onStart = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    TransitionService.prototype.onExit = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    TransitionService.prototype.onRetain = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    TransitionService.prototype.onEnter = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    TransitionService.prototype.onFinish = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    TransitionService.prototype.onSuccess = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /** @inheritdoc */
-	    TransitionService.prototype.onError = function (matchCriteria, callback, options) { throw ""; };
-	    ;
-	    /**
-	     * Creates a new [[Transition]] object
-	     *
-	     * This is a factory function for creating new Transition objects.
-	     * It is used internally by the [[StateService]] and should generally not be called by application code.
-	     *
-	     * @param fromPath the path to the current state (the from state)
-	     * @param targetState the target state (destination)
-	     * @returns a Transition
-	     */
-	    TransitionService.prototype.create = function (fromPath, targetState) {
-	        return new transition_1.Transition(fromPath, targetState, this._router);
-	    };
-	    return TransitionService;
-	}());
-	exports.TransitionService = TransitionService;
-
-
-/***/ },
-/* 32 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module hooks */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var resolveContext_1 = __webpack_require__(17);
-	/**
-	 * A [[TransitionHookFn]] which resolves all EAGER Resolvables in the To Path
-	 *
-	 * Registered using `transitionService.onStart({}, eagerResolvePath);`
-	 *
-	 * When a Transition starts, this hook resolves all the EAGER Resolvables, which the transition then waits for.
-	 *
-	 * See [[StateDeclaration.resolve]]
-	 */
-	exports.eagerResolvePath = function (trans) {
-	    return new resolveContext_1.ResolveContext(trans.treeChanges().to)
-	        .resolvePath("EAGER", trans)
-	        .then(common_1.noop);
-	};
-	/**
-	 * A [[TransitionHookFn]] which resolves all LAZY Resolvables for the state (and all its ancestors) in the To Path
-	 *
-	 * Registered using `transitionService.onEnter({ entering: () => true }, lazyResolveState);`
-	 *
-	 * When a State is being entered, this hook resolves all the Resolvables for this state, which the transition then waits for.
-	 *
-	 * See [[StateDeclaration.resolve]]
-	 */
-	exports.lazyResolveState = function (trans, state) {
-	    return new resolveContext_1.ResolveContext(trans.treeChanges().to)
-	        .subContext(state)
-	        .resolvePath("LAZY", trans)
-	        .then(common_1.noop);
-	};
-
-
-/***/ },
-/* 33 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module hooks */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var coreservices_1 = __webpack_require__(6);
-	/**
-	 * A [[TransitionHookFn]] which waits for the views to load
-	 *
-	 * Registered using `transitionService.onStart({}, loadEnteringViews);`
-	 *
-	 * Allows the views to do async work in [[ViewConfig.load]] before the transition continues.
-	 * In angular 1, this includes loading the templates.
-	 */
-	function loadEnteringViews(transition) {
-	    var enteringViews = transition.views("entering");
-	    if (!enteringViews.length)
-	        return;
-	    return coreservices_1.services.$q.all(enteringViews.map(function (view) { return view.load(); })).then(common_1.noop);
-	}
-	exports.loadEnteringViews = loadEnteringViews;
-	/**
-	 * A [[TransitionHookFn]] which activates the new views when a transition is successful.
-	 *
-	 * Registered using `transitionService.onSuccess({}, activateViews);`
-	 *
-	 * After a transition is complete, this hook deactivates the old views from the previous state,
-	 * and activates the new views from the destination state.
-	 *
-	 * See [[ViewService]]
-	 */
-	function activateViews(transition) {
-	    var enteringViews = transition.views("entering");
-	    var exitingViews = transition.views("exiting");
-	    if (!enteringViews.length && !exitingViews.length)
-	        return;
-	    var $view = transition.router.viewService;
-	    exitingViews.forEach(function (vc) { return $view.deactivateViewConfig(vc); });
-	    enteringViews.forEach(function (vc) { return $view.activateViewConfig(vc); });
-	    $view.sync();
-	}
-	exports.activateViews = activateViews;
-
-
-/***/ },
-/* 34 */
-/***/ function(module, exports) {
-
-	"use strict";
-	/**
-	 * A [[TransitionHookFn]] which updates the URL after a successful transition
-	 *
-	 * Registered using `transitionService.onSuccess({}, updateUrl);`
-	 */
-	function updateUrl(transition) {
-	    var options = transition.options();
-	    var $state = transition.router.stateService;
-	    var $urlRouter = transition.router.urlRouter;
-	    if (options.location && $state.$current.navigable) {
-	        var urlOptions = { replace: options.location === 'replace' };
-	        $urlRouter.push($state.$current.navigable.url, $state.params, urlOptions);
-	    }
-	    $urlRouter.update(true);
-	}
-	exports.updateUrl = updateUrl;
-
-
-/***/ },
-/* 35 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module hooks */ /** */
-	var predicates_1 = __webpack_require__(4);
-	var coreservices_1 = __webpack_require__(6);
-	var targetState_1 = __webpack_require__(14);
-	/**
-	 * A [[TransitionHookFn]] that redirects to a different state or params
-	 *
-	 * Registered using `transitionService.onStart({ to: (state) => !!state.redirectTo }, redirectHook);`
-	 *
-	 * See [[StateDeclaration.redirectTo]]
-	 */
-	exports.redirectToHook = function (trans) {
-	    var redirect = trans.to().redirectTo;
-	    if (!redirect)
-	        return;
-	    function handleResult(result) {
-	        var $state = trans.router.stateService;
-	        if (result instanceof targetState_1.TargetState)
-	            return result;
-	        if (predicates_1.isString(result))
-	            return $state.target(result, trans.params(), trans.options());
-	        if (result['state'] || result['params'])
-	            return $state.target(result['state'] || trans.to(), result['params'] || trans.params(), trans.options());
-	    }
-	    if (predicates_1.isFunction(redirect)) {
-	        return coreservices_1.services.$q.when(redirect(trans)).then(handleResult);
-	    }
-	    return handleResult(redirect);
-	};
-
-
-/***/ },
-/* 36 */
-/***/ function(module, exports) {
-
-	"use strict";
-	/**
-	 * A factory which creates an onEnter, onExit or onRetain transition hook function
-	 *
-	 * The returned function invokes the (for instance) state.onEnter hook when the
-	 * state is being entered.
-	 *
-	 * @hidden
-	 */
-	function makeEnterExitRetainHook(hookName) {
-	    return function (transition, state) {
-	        return state[hookName](transition, state);
-	    };
-	}
-	/**
-	 * The [[TransitionStateHookFn]] for onExit
-	 *
-	 * When the state is being exited, the state's .onExit function is invoked.
-	 *
-	 * Registered using `transitionService.onExit({ exiting: (state) => !!state.onExit }, onExitHook);`
-	 */
-	exports.onExitHook = makeEnterExitRetainHook('onExit');
-	/**
-	 * The [[TransitionStateHookFn]] for onRetain
-	 *
-	 * When the state is being exited, the state's .onRetain function is invoked.
-	 *
-	 * Registered using `transitionService.onRetain({ retained: (state) => !!state.onRetain }, onRetainHook);`
-	 */
-	exports.onRetainHook = makeEnterExitRetainHook('onRetain');
-	/**
-	 * The [[TransitionStateHookFn]] for onEnter
-	 *
-	 * When the state is being exited, the state's .onEnter function is invoked.
-	 *
-	 * Registered using `transitionService.onEnter({ entering: (state) => !!state.onEnter }, onEnterHook);`
-	 */
-	exports.onEnterHook = makeEnterExitRetainHook('onEnter');
-
-
-/***/ },
-/* 37 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module view */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	var predicates_1 = __webpack_require__(4);
-	var trace_1 = __webpack_require__(12);
-	var match = function (obj1) {
-	    var keys = [];
-	    for (var _i = 1; _i < arguments.length; _i++) {
-	        keys[_i - 1] = arguments[_i];
-	    }
-	    return function (obj2) { return keys.reduce(function (memo, key) { return memo && obj1[key] === obj2[key]; }, true); };
-	};
-	/**
-	 * The View service
-	 */
-	var ViewService = (function () {
-	    function ViewService() {
-	        var _this = this;
-	        this.uiViews = [];
-	        this.viewConfigs = [];
-	        this._viewConfigFactories = {};
-	        this.sync = function () {
-	            var uiViewsByFqn = _this.uiViews.map(function (uiv) { return [uiv.fqn, uiv]; }).reduce(common_1.applyPairs, {});
-	            /**
-	             * Given a ui-view and a ViewConfig, determines if they "match".
-	             *
-	             * A ui-view has a fully qualified name (fqn) and a context object.  The fqn is built from its overall location in
-	             * the DOM, describing its nesting relationship to any parent ui-view tags it is nested inside of.
-	             *
-	             * A ViewConfig has a target ui-view name and a context anchor.  The ui-view name can be a simple name, or
-	             * can be a segmented ui-view path, describing a portion of a ui-view fqn.
-	             *
-	             * In order for a ui-view to match ViewConfig, ui-view's $type must match the ViewConfig's $type
-	             *
-	             * If the ViewConfig's target ui-view name is a simple name (no dots), then a ui-view matches if:
-	             * - the ui-view's name matches the ViewConfig's target name
-	             * - the ui-view's context matches the ViewConfig's anchor
-	             *
-	             * If the ViewConfig's target ui-view name is a segmented name (with dots), then a ui-view matches if:
-	             * - There exists a parent ui-view where:
-	             *    - the parent ui-view's name matches the first segment (index 0) of the ViewConfig's target name
-	             *    - the parent ui-view's context matches the ViewConfig's anchor
-	             * - And the remaining segments (index 1..n) of the ViewConfig's target name match the tail of the ui-view's fqn
-	             *
-	             * Example:
-	             *
-	             * DOM:
-	             * <div ui-view>                        <!-- created in the root context (name: "") -->
-	             *   <div ui-view="foo">                <!-- created in the context named: "A"      -->
-	             *     <div ui-view>                    <!-- created in the context named: "A.B"    -->
-	             *       <div ui-view="bar">            <!-- created in the context named: "A.B.C"  -->
-	             *       </div>
-	             *     </div>
-	             *   </div>
-	             * </div>
-	             *
-	             * uiViews: [
-	             *  { fqn: "$default",                  creationContext: { name: "" } },
-	             *  { fqn: "$default.foo",              creationContext: { name: "A" } },
-	             *  { fqn: "$default.foo.$default",     creationContext: { name: "A.B" } }
-	             *  { fqn: "$default.foo.$default.bar", creationContext: { name: "A.B.C" } }
-	             * ]
-	             *
-	             * These four view configs all match the ui-view with the fqn: "$default.foo.$default.bar":
-	             *
-	             * - ViewConfig1: { uiViewName: "bar",                       uiViewContextAnchor: "A.B.C" }
-	             * - ViewConfig2: { uiViewName: "$default.bar",              uiViewContextAnchor: "A.B" }
-	             * - ViewConfig3: { uiViewName: "foo.$default.bar",          uiViewContextAnchor: "A" }
-	             * - ViewConfig4: { uiViewName: "$default.foo.$default.bar", uiViewContextAnchor: "" }
-	             *
-	             * Using ViewConfig3 as an example, it matches the ui-view with fqn "$default.foo.$default.bar" because:
-	             * - The ViewConfig's segmented target name is: [ "foo", "$default", "bar" ]
-	             * - There exists a parent ui-view (which has fqn: "$default.foo") where:
-	             *    - the parent ui-view's name "foo" matches the first segment "foo" of the ViewConfig's target name
-	             *    - the parent ui-view's context "A" matches the ViewConfig's anchor context "A"
-	             * - And the remaining segments [ "$default", "bar" ].join("."_ of the ViewConfig's target name match
-	             *   the tail of the ui-view's fqn "default.bar"
-	             */
-	            var matches = function (uiView) { return function (viewConfig) {
-	                // Don't supply an ng1 ui-view with an ng2 ViewConfig, etc
-	                if (uiView.$type !== viewConfig.viewDecl.$type)
-	                    return false;
-	                // Split names apart from both viewConfig and uiView into segments
-	                var vc = viewConfig.viewDecl;
-	                var vcSegments = vc.$uiViewName.split(".");
-	                var uivSegments = uiView.fqn.split(".");
-	                // Check if the tails of the segment arrays match. ex, these arrays' tails match:
-	                // vc: ["foo", "bar"], uiv fqn: ["$default", "foo", "bar"]
-	                if (!common_1.equals(vcSegments, uivSegments.slice(0 - vcSegments.length)))
-	                    return false;
-	                // Now check if the fqn ending at the first segment of the viewConfig matches the context:
-	                // ["$default", "foo"].join(".") == "$default.foo", does the ui-view $default.foo context match?
-	                var negOffset = (1 - vcSegments.length) || undefined;
-	                var fqnToFirstSegment = uivSegments.slice(0, negOffset).join(".");
-	                var uiViewContext = uiViewsByFqn[fqnToFirstSegment].creationContext;
-	                return vc.$uiViewContextAnchor === (uiViewContext && uiViewContext.name);
-	            }; };
-	            // Return the number of dots in the fully qualified name
-	            function uiViewDepth(uiView) {
-	                return uiView.fqn.split(".").length;
-	            }
-	            // Return the ViewConfig's context's depth in the context tree.
-	            function viewConfigDepth(config) {
-	                var context = config.viewDecl.$context, count = 0;
-	                while (++count && context.parent)
-	                    context = context.parent;
-	                return count;
-	            }
-	            // Given a depth function, returns a compare function which can return either ascending or descending order
-	            var depthCompare = hof_1.curry(function (depthFn, posNeg, left, right) { return posNeg * (depthFn(left) - depthFn(right)); });
-	            var matchingConfigPair = function (uiView) {
-	                var matchingConfigs = _this.viewConfigs.filter(matches(uiView));
-	                if (matchingConfigs.length > 1)
-	                    matchingConfigs.sort(depthCompare(viewConfigDepth, -1)); // descending
-	                return [uiView, matchingConfigs[0]];
-	            };
-	            var configureUIView = function (_a) {
-	                var uiView = _a[0], viewConfig = _a[1];
-	                // If a parent ui-view is reconfigured, it could destroy child ui-views.
-	                // Before configuring a child ui-view, make sure it's still in the active uiViews array.
-	                if (_this.uiViews.indexOf(uiView) !== -1)
-	                    uiView.configUpdated(viewConfig);
-	            };
-	            _this.uiViews.sort(depthCompare(uiViewDepth, 1)).map(matchingConfigPair).forEach(configureUIView);
-	        };
-	    }
-	    ViewService.prototype.rootContext = function (context) {
-	        return this._rootContext = context || this._rootContext;
-	    };
-	    ;
-	    ViewService.prototype.viewConfigFactory = function (viewType, factory) {
-	        this._viewConfigFactories[viewType] = factory;
-	    };
-	    ViewService.prototype.createViewConfig = function (path, decl) {
-	        var cfgFactory = this._viewConfigFactories[decl.$type];
-	        if (!cfgFactory)
-	            throw new Error("ViewService: No view config factory registered for type " + decl.$type);
-	        var cfgs = cfgFactory(path, decl);
-	        return predicates_1.isArray(cfgs) ? cfgs : [cfgs];
-	    };
-	    /**
-	     * De-registers a ViewConfig.
-	     *
-	     * @param viewConfig The ViewConfig view to deregister.
-	     */
-	    ViewService.prototype.deactivateViewConfig = function (viewConfig) {
-	        trace_1.trace.traceViewServiceEvent("<- Removing", viewConfig);
-	        common_1.removeFrom(this.viewConfigs, viewConfig);
-	    };
-	    ;
-	    ViewService.prototype.activateViewConfig = function (viewConfig) {
-	        trace_1.trace.traceViewServiceEvent("-> Registering", viewConfig);
-	        this.viewConfigs.push(viewConfig);
-	    };
-	    ;
-	    /**
-	     * Allows a `ui-view` element to register its canonical name with a callback that allows it to
-	     * be updated with a template, controller, and local variables.
-	     *
-	     * @param {String} name The fully-qualified name of the `ui-view` object being registered.
-	     * @param {Function} configUpdatedCallback A callback that receives updates to the content & configuration
-	     *                   of the view.
-	     * @return {Function} Returns a de-registration function used when the view is destroyed.
-	     */
-	    ViewService.prototype.registerUIView = function (uiView) {
-	        trace_1.trace.traceViewServiceUIViewEvent("-> Registering", uiView);
-	        var uiViews = this.uiViews;
-	        var fqnMatches = function (uiv) { return uiv.fqn === uiView.fqn; };
-	        if (uiViews.filter(fqnMatches).length)
-	            trace_1.trace.traceViewServiceUIViewEvent("!!!! duplicate uiView named:", uiView);
-	        uiViews.push(uiView);
-	        this.sync();
-	        return function () {
-	            var idx = uiViews.indexOf(uiView);
-	            if (idx <= 0) {
-	                trace_1.trace.traceViewServiceUIViewEvent("Tried removing non-registered uiView", uiView);
-	                return;
-	            }
-	            trace_1.trace.traceViewServiceUIViewEvent("<- Deregistering", uiView);
-	            common_1.removeFrom(uiViews)(uiView);
-	        };
-	    };
-	    ;
-	    /**
-	     * Returns the list of views currently available on the page, by fully-qualified name.
-	     *
-	     * @return {Array} Returns an array of fully-qualified view names.
-	     */
-	    ViewService.prototype.available = function () {
-	        return this.uiViews.map(hof_1.prop("fqn"));
-	    };
-	    /**
-	     * Returns the list of views on the page containing loaded content.
-	     *
-	     * @return {Array} Returns an array of fully-qualified view names.
-	     */
-	    ViewService.prototype.active = function () {
-	        return this.uiViews.filter(hof_1.prop("$config")).map(hof_1.prop("name"));
-	    };
-	    /**
-	     * Normalizes a view's name from a state.views configuration block.
-	     *
-	     * @param context the context object (state declaration) that the view belongs to
-	     * @param rawViewName the name of the view, as declared in the [[StateDeclaration.views]]
-	     *
-	     * @returns the normalized uiViewName and uiViewContextAnchor that the view targets
-	     */
-	    ViewService.normalizeUIViewTarget = function (context, rawViewName) {
-	        if (rawViewName === void 0) { rawViewName = ""; }
-	        // TODO: Validate incoming view name with a regexp to allow:
-	        // ex: "view.name@foo.bar" , "^.^.view.name" , "view.name@^.^" , "" ,
-	        // "@" , "$default@^" , "!$default.$default" , "!foo.bar"
-	        var viewAtContext = rawViewName.split("@");
-	        var uiViewName = viewAtContext[0] || "$default"; // default to unnamed view
-	        var uiViewContextAnchor = predicates_1.isString(viewAtContext[1]) ? viewAtContext[1] : "^"; // default to parent context
-	        // Handle relative view-name sugar syntax.
-	        // Matches rawViewName "^.^.^.foo.bar" into array: ["^.^.^.foo.bar", "^.^.^", "foo.bar"],
-	        var relativeViewNameSugar = /^(\^(?:\.\^)*)\.(.*$)/.exec(uiViewName);
-	        if (relativeViewNameSugar) {
-	            // Clobbers existing contextAnchor (rawViewName validation will fix this)
-	            uiViewContextAnchor = relativeViewNameSugar[1]; // set anchor to "^.^.^"
-	            uiViewName = relativeViewNameSugar[2]; // set view-name to "foo.bar"
-	        }
-	        if (uiViewName.charAt(0) === '!') {
-	            uiViewName = uiViewName.substr(1);
-	            uiViewContextAnchor = ""; // target absolutely from root
-	        }
-	        // handle parent relative targeting "^.^.^"
-	        var relativeMatch = /^(\^(?:\.\^)*)$/;
-	        if (relativeMatch.exec(uiViewContextAnchor)) {
-	            var anchor = uiViewContextAnchor.split(".").reduce((function (anchor, x) { return anchor.parent; }), context);
-	            uiViewContextAnchor = anchor.name;
-	        }
-	        return { uiViewName: uiViewName, uiViewContextAnchor: uiViewContextAnchor };
-	    };
-	    return ViewService;
-	}());
-	exports.ViewService = ViewService;
-
-
-/***/ },
-/* 38 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/** @module state */ /** for typedoc */
-	"use strict";
-	var stateMatcher_1 = __webpack_require__(39);
-	var stateBuilder_1 = __webpack_require__(40);
-	var stateQueueManager_1 = __webpack_require__(41);
-	var StateRegistry = (function () {
-	    function StateRegistry(urlMatcherFactory, urlRouterProvider) {
-	        this.states = {};
-	        this.matcher = new stateMatcher_1.StateMatcher(this.states);
-	        this.builder = new stateBuilder_1.StateBuilder(this.matcher, urlMatcherFactory);
-	        this.stateQueue = new stateQueueManager_1.StateQueueManager(this.states, this.builder, urlRouterProvider);
-	        var rootStateDef = {
-	            name: '',
-	            url: '^',
-	            views: null,
-	            params: {
-	                '#': { value: null, type: 'hash', dynamic: true }
-	            },
-	            abstract: true
-	        };
-	        var _root = this._root = this.stateQueue.register(rootStateDef);
-	        _root.navigable = null;
-	    }
-	    StateRegistry.prototype.root = function () {
-	        return this._root;
-	    };
-	    StateRegistry.prototype.register = function (stateDefinition) {
-	        return this.stateQueue.register(stateDefinition);
-	    };
-	    StateRegistry.prototype.get = function (stateOrName, base) {
-	        var _this = this;
-	        if (arguments.length === 0)
-	            return Object.keys(this.states).map(function (name) { return _this.states[name].self; });
-	        var found = this.matcher.find(stateOrName, base);
-	        return found && found.self || null;
-	    };
-	    StateRegistry.prototype.decorator = function (name, func) {
-	        return this.builder.builder(name, func);
-	    };
-	    return StateRegistry;
-	}());
-	exports.StateRegistry = StateRegistry;
-
-
-/***/ },
-/* 39 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module state */ /** for typedoc */
-	var predicates_1 = __webpack_require__(4);
-	var StateMatcher = (function () {
-	    function StateMatcher(_states) {
-	        this._states = _states;
-	    }
-	    StateMatcher.prototype.isRelative = function (stateName) {
-	        stateName = stateName || "";
-	        return stateName.indexOf(".") === 0 || stateName.indexOf("^") === 0;
-	    };
-	    StateMatcher.prototype.find = function (stateOrName, base) {
-	        if (!stateOrName && stateOrName !== "")
-	            return undefined;
-	        var isStr = predicates_1.isString(stateOrName);
-	        var name = isStr ? stateOrName : stateOrName.name;
-	        if (this.isRelative(name))
-	            name = this.resolvePath(name, base);
-	        var state = this._states[name];
-	        if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) {
-	            return state;
-	        }
-	        return undefined;
-	    };
-	    StateMatcher.prototype.resolvePath = function (name, base) {
-	        if (!base)
-	            throw new Error("No reference point given for path '" + name + "'");
-	        var baseState = this.find(base);
-	        var splitName = name.split("."), i = 0, pathLength = splitName.length, current = baseState;
-	        for (; i < pathLength; i++) {
-	            if (splitName[i] === "" && i === 0) {
-	                current = baseState;
-	                continue;
-	            }
-	            if (splitName[i] === "^") {
-	                if (!current.parent)
-	                    throw new Error("Path '" + name + "' not valid for state '" + baseState.name + "'");
-	                current = current.parent;
-	                continue;
-	            }
-	            break;
-	        }
-	        var relName = splitName.slice(i).join(".");
-	        return current.name + (current.name && relName ? "." : "") + relName;
-	    };
-	    return StateMatcher;
-	}());
-	exports.StateMatcher = StateMatcher;
-
-
-/***/ },
-/* 40 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module state */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var strings_1 = __webpack_require__(9);
-	var hof_1 = __webpack_require__(5);
-	var param_1 = __webpack_require__(22);
-	var resolvable_1 = __webpack_require__(19);
-	var coreservices_1 = __webpack_require__(6);
-	var parseUrl = function (url) {
-	    if (!predicates_1.isString(url))
-	        return false;
-	    var root = url.charAt(0) === '^';
-	    return { val: root ? url.substring(1) : url, root: root };
-	};
-	function selfBuilder(state) {
-	    state.self.$$state = function () { return state; };
-	    return state.self;
-	}
-	function dataBuilder(state) {
-	    if (state.parent && state.parent.data) {
-	        state.data = state.self.data = common_1.inherit(state.parent.data, state.data);
-	    }
-	    return state.data;
-	}
-	var getUrlBuilder = function ($urlMatcherFactoryProvider, root) {
-	    return function urlBuilder(state) {
-	        var stateDec = state;
-	        var parsed = parseUrl(stateDec.url), parent = state.parent;
-	        var url = !parsed ? stateDec.url : $urlMatcherFactoryProvider.compile(parsed.val, {
-	            params: state.params || {},
-	            paramMap: function (paramConfig, isSearch) {
-	                if (stateDec.reloadOnSearch === false && isSearch)
-	                    paramConfig = common_1.extend(paramConfig || {}, { dynamic: true });
-	                return paramConfig;
-	            }
-	        });
-	        if (!url)
-	            return null;
-	        if (!$urlMatcherFactoryProvider.isMatcher(url))
-	            throw new Error("Invalid url '" + url + "' in state '" + state + "'");
-	        return (parsed && parsed.root) ? url : ((parent && parent.navigable) || root()).url.append(url);
-	    };
-	};
-	var getNavigableBuilder = function (isRoot) {
-	    return function navigableBuilder(state) {
-	        return !isRoot(state) && state.url ? state : (state.parent ? state.parent.navigable : null);
-	    };
-	};
-	function paramsBuilder(state) {
-	    var makeConfigParam = function (config, id) { return param_1.Param.fromConfig(id, null, config); };
-	    var urlParams = (state.url && state.url.parameters({ inherit: false })) || [];
-	    var nonUrlParams = common_1.values(common_1.map(common_1.omit(state.params || {}, urlParams.map(hof_1.prop('id'))), makeConfigParam));
-	    return urlParams.concat(nonUrlParams).map(function (p) { return [p.id, p]; }).reduce(common_1.applyPairs, {});
-	}
-	function pathBuilder(state) {
-	    return state.parent ? state.parent.path.concat(state) : [state];
-	}
-	function includesBuilder(state) {
-	    var includes = state.parent ? common_1.extend({}, state.parent.includes) : {};
-	    includes[state.name] = true;
-	    return includes;
-	}
-	/**
-	 * This is a [[StateBuilder.builder]] function for the `resolve:` block on a [[StateDeclaration]].
-	 *
-	 * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder
-	 * validates the `resolve` property and converts it to a [[Resolvable]] array.
-	 *
-	 * resolve: input value can be:
-	 *
-	 * {
-	 *   // analyzed but not injected
-	 *   myFooResolve: function() { return "myFooData"; },
-	 *
-	 *   // function.toString() parsed, "DependencyName" dep as string (not min-safe)
-	 *   myBarResolve: function(DependencyName) { return DependencyName.fetchSomethingAsPromise() },
-	 *
-	 *   // Array split; "DependencyName" dep as string
-	 *   myBazResolve: [ "DependencyName", function(dep) { return dep.fetchSomethingAsPromise() },
-	 *
-	 *   // Array split; DependencyType dep as token (compared using ===)
-	 *   myQuxResolve: [ DependencyType, function(dep) { return dep.fetchSometingAsPromise() },
-	 *
-	 *   // val.$inject used as deps
-	 *   // where:
-	 *   //     corgeResolve.$inject = ["DependencyName"];
-	 *   //     function corgeResolve(dep) { dep.fetchSometingAsPromise() }
-	 *   // then "DependencyName" dep as string
-	 *   myCorgeResolve: corgeResolve,
-	 *
-	 *  // inject service by name
-	 *  // When a string is found, desugar creating a resolve that injects the named service
-	 *   myGraultResolve: "SomeService"
-	 * }
-	 *
-	 * or:
-	 *
-	 * [
-	 *   new Resolvable("myFooResolve", function() { return "myFooData" }),
-	 *   new Resolvable("myBarResolve", function(dep) { return dep.fetchSomethingAsPromise() }, [ "DependencyName" ]),
-	 *   { provide: "myBazResolve", useFactory: function(dep) { dep.fetchSomethingAsPromise() }, deps: [ "DependencyName" ] }
-	 * ]
-	 */
-	function resolvablesBuilder(state) {
-	    /** convert a resolve: {} object to an array of tuples */
-	    var obj2Tuples = function (obj) { return Object.keys(obj || {}).map(function (token) { return ({ token: token, val: obj[token], deps: undefined }); }); };
-	    /** fetch DI annotations from a function or ng1-style array */
-	    var annotate = function (fn) { return fn.$inject || coreservices_1.services.$injector.annotate(fn, coreservices_1.services.$injector.strictDi); };
-	    /** true if the object has both `token` and `resolveFn`, and is probably a [[ResolveLiteral]] */
-	    var isResolveLiteral = function (obj) { return !!(obj.token && obj.resolveFn); };
-	    /** true if the object looks like a provide literal, or a ng2 Provider */
-	    var isLikeNg2Provider = function (obj) { return !!((obj.provide || obj.token) && (obj.useValue || obj.useFactory || obj.useExisting || obj.useClass)); };
-	    /** true if the object looks like a tuple from obj2Tuples */
-	    var isTupleFromObj = function (obj) { return !!(obj && obj.val && (predicates_1.isString(obj.val) || predicates_1.isArray(obj.val) || predicates_1.isFunction(obj.val))); };
-	    /** extracts the token from a Provider or provide literal */
-	    var token = function (p) { return p.provide || p.token; };
-	    /** Given a literal resolve or provider object, returns a Resolvable */
-	    var literal2Resolvable = hof_1.pattern([
-	        [hof_1.prop('resolveFn'), function (p) { return new resolvable_1.Resolvable(token(p), p.resolveFn, p.deps, p.policy); }],
-	        [hof_1.prop('useFactory'), function (p) { return new resolvable_1.Resolvable(token(p), p.useFactory, (p.deps || p.dependencies), p.policy); }],
-	        [hof_1.prop('useClass'), function (p) { return new resolvable_1.Resolvable(token(p), function () { return new p.useClass(); }, [], p.policy); }],
-	        [hof_1.prop('useValue'), function (p) { return new resolvable_1.Resolvable(token(p), function () { return p.useValue; }, [], p.policy, p.useValue); }],
-	        [hof_1.prop('useExisting'), function (p) { return new resolvable_1.Resolvable(token(p), function (x) { return x; }, [p.useExisting], p.policy); }],
-	    ]);
-	    var tuple2Resolvable = hof_1.pattern([
-	        [hof_1.pipe(hof_1.prop("val"), predicates_1.isString), function (tuple) { return new resolvable_1.Resolvable(tuple.token, function (x) { return x; }, [tuple.val], tuple.policy); }],
-	        [hof_1.pipe(hof_1.prop("val"), predicates_1.isArray), function (tuple) { return new resolvable_1.Resolvable(tuple.token, common_1.tail(tuple.val), tuple.val.slice(0, -1), tuple.policy); }],
-	        [hof_1.pipe(hof_1.prop("val"), predicates_1.isFunction), function (tuple) { return new resolvable_1.Resolvable(tuple.token, tuple.val, annotate(tuple.val), tuple.policy); }],
-	    ]);
-	    var item2Resolvable = hof_1.pattern([
-	        [hof_1.is(resolvable_1.Resolvable), function (r) { return r; }],
-	        [isResolveLiteral, literal2Resolvable],
-	        [isLikeNg2Provider, literal2Resolvable],
-	        [isTupleFromObj, tuple2Resolvable],
-	        [hof_1.val(true), function (tuple) { throw new Error("Invalid resolve value: " + strings_1.stringify(tuple)); }]
-	    ]);
-	    // If resolveBlock is already an array, use it as-is.
-	    // Otherwise, assume it's an object and convert to an Array of tuples
-	    var decl = state.resolve;
-	    var items = predicates_1.isArray(decl) ? decl : obj2Tuples(decl);
-	    return items.map(item2Resolvable);
-	}
-	exports.resolvablesBuilder = resolvablesBuilder;
-	/**
-	 * @internalapi A internal global service
-	 *
-	 * StateBuilder is a factory for the internal [[State]] objects.
-	 *
-	 * When you register a state with the [[StateRegistry]], you register a plain old javascript object which
-	 * conforms to the [[StateDeclaration]] interface.  This factory takes that object and builds the corresponding
-	 * [[State]] object, which has an API and is used internally.
-	 *
-	 * Custom properties or API may be added to the internal [[State]] object by registering a decorator function
-	 * using the [[builder]] method.
-	 */
-	var StateBuilder = (function () {
-	    function StateBuilder(matcher, $urlMatcherFactoryProvider) {
-	        this.matcher = matcher;
-	        var self = this;
-	        var root = function () { return matcher.find(""); };
-	        var isRoot = function (state) { return state.name === ""; };
-	        function parentBuilder(state) {
-	            if (isRoot(state))
-	                return null;
-	            return matcher.find(self.parentName(state)) || root();
-	        }
-	        this.builders = {
-	            self: [selfBuilder],
-	            parent: [parentBuilder],
-	            data: [dataBuilder],
-	            // Build a URLMatcher if necessary, either via a relative or absolute URL
-	            url: [getUrlBuilder($urlMatcherFactoryProvider, root)],
-	            // Keep track of the closest ancestor state that has a URL (i.e. is navigable)
-	            navigable: [getNavigableBuilder(isRoot)],
-	            params: [paramsBuilder],
-	            // Each framework-specific ui-router implementation should define its own `views` builder
-	            // e.g., src/ng1/statebuilders/views.ts
-	            views: [],
-	            // Keep a full path from the root down to this state as this is needed for state activation.
-	            path: [pathBuilder],
-	            // Speed up $state.includes() as it's used a lot
-	            includes: [includesBuilder],
-	            resolvables: [resolvablesBuilder]
-	        };
-	    }
-	    /**
-	     * Registers a [[BuilderFunction]] for a specific [[State]] property (e.g., `parent`, `url`, or `path`).
-	     * More than one BuilderFunction can be registered for a given property.
-	     *
-	     * The BuilderFunction(s) will be used to define the property on any subsequently built [[State]] objects.
-	     *
-	     * @param name The name of the State property being registered for.
-	     * @param fn The BuilderFunction which will be used to build the State property
-	     * @returns a function which deregisters the BuilderFunction
-	     */
-	    StateBuilder.prototype.builder = function (name, fn) {
-	        var builders = this.builders;
-	        var array = builders[name] || [];
-	        // Backwards compat: if only one builder exists, return it, else return whole arary.
-	        if (predicates_1.isString(name) && !predicates_1.isDefined(fn))
-	            return array.length > 1 ? array : array[0];
-	        if (!predicates_1.isString(name) || !predicates_1.isFunction(fn))
-	            return;
-	        builders[name] = array;
-	        builders[name].push(fn);
-	        return function () { return builders[name].splice(builders[name].indexOf(fn, 1)) && null; };
-	    };
-	    /**
-	     * Builds all of the properties on an essentially blank State object, returning a State object which has all its
-	     * properties and API built.
-	     *
-	     * @param state an uninitialized State object
-	     * @returns the built State object
-	     */
-	    StateBuilder.prototype.build = function (state) {
-	        var _a = this, matcher = _a.matcher, builders = _a.builders;
-	        var parent = this.parentName(state);
-	        if (parent && !matcher.find(parent))
-	            return null;
-	        for (var key in builders) {
-	            if (!builders.hasOwnProperty(key))
-	                continue;
-	            var chain = builders[key].reduce(function (parentFn, step) { return function (_state) { return step(_state, parentFn); }; }, common_1.noop);
-	            state[key] = chain(state);
-	        }
-	        return state;
-	    };
-	    StateBuilder.prototype.parentName = function (state) {
-	        var name = state.name || "";
-	        if (name.indexOf('.') !== -1)
-	            return name.substring(0, name.lastIndexOf('.'));
-	        if (!state.parent)
-	            return "";
-	        return predicates_1.isString(state.parent) ? state.parent : state.parent.name;
-	    };
-	    StateBuilder.prototype.name = function (state) {
-	        var name = state.name;
-	        if (name.indexOf('.') !== -1 || !state.parent)
-	            return name;
-	        var parentName = predicates_1.isString(state.parent) ? state.parent : state.parent.name;
-	        return parentName ? parentName + "." + name : name;
-	    };
-	    return StateBuilder;
-	}());
-	exports.StateBuilder = StateBuilder;
-
-
-/***/ },
-/* 41 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module state */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var stateObject_1 = __webpack_require__(42);
-	var StateQueueManager = (function () {
-	    function StateQueueManager(states, builder, $urlRouterProvider) {
-	        this.states = states;
-	        this.builder = builder;
-	        this.$urlRouterProvider = $urlRouterProvider;
-	        this.queue = [];
-	    }
-	    StateQueueManager.prototype.register = function (config) {
-	        var _a = this, states = _a.states, queue = _a.queue, $state = _a.$state;
-	        // Wrap a new object around the state so we can store our private details easily.
-	        // @TODO: state = new State(extend({}, config, { ... }))
-	        var state = common_1.inherit(new stateObject_1.State(), common_1.extend({}, config, {
-	            self: config,
-	            resolve: config.resolve || [],
-	            toString: function () { return config.name; }
-	        }));
-	        if (!predicates_1.isString(state.name))
-	            throw new Error("State must have a valid name");
-	        if (states.hasOwnProperty(state.name) || common_1.pluck(queue, 'name').indexOf(state.name) !== -1)
-	            throw new Error("State '" + state.name + "' is already defined");
-	        queue.push(state);
-	        if (this.$state) {
-	            this.flush($state);
-	        }
-	        return state;
-	    };
-	    StateQueueManager.prototype.flush = function ($state) {
-	        var _a = this, queue = _a.queue, states = _a.states, builder = _a.builder;
-	        var result, state, orphans = [], orphanIdx, previousQueueLength = {};
-	        while (queue.length > 0) {
-	            state = queue.shift();
-	            result = builder.build(state);
-	            orphanIdx = orphans.indexOf(state);
-	            if (result) {
-	                if (states.hasOwnProperty(state.name))
-	                    throw new Error("State '" + name + "' is already defined");
-	                states[state.name] = state;
-	                this.attachRoute($state, state);
-	                if (orphanIdx >= 0)
-	                    orphans.splice(orphanIdx, 1);
-	                continue;
-	            }
-	            var prev = previousQueueLength[state.name];
-	            previousQueueLength[state.name] = queue.length;
-	            if (orphanIdx >= 0 && prev === queue.length) {
-	                // Wait until two consecutive iterations where no additional states were dequeued successfully.
-	                // throw new Error(`Cannot register orphaned state '${state.name}'`);
-	                return states;
-	            }
-	            else if (orphanIdx < 0) {
-	                orphans.push(state);
-	            }
-	            queue.push(state);
-	        }
-	        return states;
-	    };
-	    StateQueueManager.prototype.autoFlush = function ($state) {
-	        this.$state = $state;
-	        this.flush($state);
-	    };
-	    StateQueueManager.prototype.attachRoute = function ($state, state) {
-	        var $urlRouterProvider = this.$urlRouterProvider;
-	        if (state[common_1.abstractKey] || !state.url)
-	            return;
-	        $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {
-	                if ($state.$current.navigable !== state || !common_1.equalForKeys($match, $stateParams)) {
-	                    $state.transitionTo(state, $match, { inherit: true, location: false });
-	                }
-	            }]);
-	    };
-	    return StateQueueManager;
-	}());
-	exports.StateQueueManager = StateQueueManager;
-
-
-/***/ },
-/* 42 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/** @module state */ /** for typedoc */
-	"use strict";
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	/**
-	 * @ngdoc object
-	 * @name ui.router.state.type:State
-	 *
-	 * @description
-	 * Definition object for states. Includes methods for manipulating the state heirarchy.
-	 *
-	 * @param {Object} config  A configuration object hash that includes the results of user-supplied
-	 *        values, as well as values from `StateBuilder`.
-	 *
-	 * @returns {Object}  Returns a new `State` object.
-	 */
-	var State = (function () {
-	    function State(config) {
-	        common_1.extend(this, config);
-	        // Object.freeze(this);
-	    }
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.type:State#is
-	     * @methodOf ui.router.state.type:State
-	     *
-	     * @description
-	     * Compares the identity of the state against the passed value, which is either an object
-	     * reference to the actual `State` instance, the original definition object passed to
-	     * `$stateProvider.state()`, or the fully-qualified name.
-	     *
-	     * @param {Object} ref Can be one of (a) a `State` instance, (b) an object that was passed
-	     *        into `$stateProvider.state()`, (c) the fully-qualified name of a state as a string.
-	     * @returns {boolean} Returns `true` if `ref` matches the current `State` instance.
-	     */
-	    State.prototype.is = function (ref) {
-	        return this === ref || this.self === ref || this.fqn() === ref;
-	    };
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.type:State#fqn
-	     * @methodOf ui.router.state.type:State
-	     *
-	     * @description
-	     * Returns the fully-qualified name of the state, based on its current position in the tree.
-	     *
-	     * @returns {string} Returns a dot-separated name of the state.
-	     */
-	    State.prototype.fqn = function () {
-	        if (!this.parent || !(this.parent instanceof this.constructor))
-	            return this.name;
-	        var name = this.parent.fqn();
-	        return name ? name + "." + this.name : this.name;
-	    };
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.type:State#root
-	     * @methodOf ui.router.state.type:State
-	     *
-	     * @description
-	     * Returns the root node of this state's tree.
-	     *
-	     * @returns {State} The root of this state's tree.
-	     */
-	    State.prototype.root = function () {
-	        return this.parent && this.parent.root() || this;
-	    };
-	    State.prototype.parameters = function (opts) {
-	        opts = common_1.defaults(opts, { inherit: true });
-	        var inherited = opts.inherit && this.parent && this.parent.parameters() || [];
-	        return inherited.concat(common_1.values(this.params));
-	    };
-	    State.prototype.parameter = function (id, opts) {
-	        if (opts === void 0) { opts = {}; }
-	        return (this.url && this.url.parameter(id, opts) ||
-	            common_1.find(common_1.values(this.params), hof_1.propEq('id', id)) ||
-	            opts.inherit && this.parent && this.parent.parameter(id));
-	    };
-	    State.prototype.toString = function () {
-	        return this.fqn();
-	    };
-	    return State;
-	}());
-	exports.State = State;
-
-
-/***/ },
-/* 43 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module state */ /** */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var queue_1 = __webpack_require__(8);
-	var coreservices_1 = __webpack_require__(6);
-	var pathFactory_1 = __webpack_require__(20);
-	var node_1 = __webpack_require__(21);
-	var transitionService_1 = __webpack_require__(31);
-	var rejectFactory_1 = __webpack_require__(10);
-	var targetState_1 = __webpack_require__(14);
-	var param_1 = __webpack_require__(22);
-	var glob_1 = __webpack_require__(7);
-	var common_2 = __webpack_require__(3);
-	var common_3 = __webpack_require__(3);
-	var StateService = (function () {
-	    /** @hidden */
-	    function StateService(router) {
-	        this.router = router;
-	        /** @hidden */
-	        this._defaultErrorHandler = function $defaultErrorHandler($error$) {
-	            if ($error$ instanceof Error && $error$.stack) {
-	                console.error($error$.stack);
-	            }
-	            else if ($error$ instanceof rejectFactory_1.Rejection) {
-	                console.error($error$);
-	                if ($error$.detail && $error$.detail.stack)
-	                    console.error($error$.detail.stack);
-	            }
-	            else {
-	                console.error($error$);
-	            }
-	        };
-	        var getters = ['current', '$current', 'params', 'transition'];
-	        var boundFns = Object.keys(StateService.prototype).filter(function (key) { return getters.indexOf(key) === -1; });
-	        common_3.bindFunctions(StateService.prototype, this, this, boundFns);
-	    }
-	    Object.defineProperty(StateService.prototype, "transition", {
-	        get: function () { return this.router.globals.transition; },
-	        enumerable: true,
-	        configurable: true
-	    });
-	    Object.defineProperty(StateService.prototype, "params", {
-	        get: function () { return this.router.globals.params; },
-	        enumerable: true,
-	        configurable: true
-	    });
-	    Object.defineProperty(StateService.prototype, "current", {
-	        get: function () { return this.router.globals.current; },
-	        enumerable: true,
-	        configurable: true
-	    });
-	    Object.defineProperty(StateService.prototype, "$current", {
-	        get: function () { return this.router.globals.$current; },
-	        enumerable: true,
-	        configurable: true
-	    });
-	    /**
-	     * Handler for when [[transitionTo]] is called with an invalid state.
-	     *
-	     * Invokes the [[onInvalid]] callbacks, in natural order.
-	     * Each callback's return value is checked in sequence until one of them returns an instance of TargetState.
-	     * The results of the callbacks are wrapped in $q.when(), so the callbacks may return promises.
-	     *
-	     * If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and the result returned.
-	     */
-	    StateService.prototype._handleInvalidTargetState = function (fromPath, $to$) {
-	        var _this = this;
-	        var globals = this.router.globals;
-	        var latestThing = function () { return globals.transitionHistory.peekTail(); };
-	        var latest = latestThing();
-	        var $from$ = pathFactory_1.PathFactory.makeTargetState(fromPath);
-	        var callbackQueue = new queue_1.Queue([].concat(this.router.stateProvider.invalidCallbacks));
-	        var $q = coreservices_1.services.$q, $injector = coreservices_1.services.$injector;
-	        var invokeCallback = function (callback) { return $q.when($injector.invoke(callback, null, { $to$: $to$, $from$: $from$ })); };
-	        var checkForRedirect = function (result) {
-	            if (!(result instanceof targetState_1.TargetState)) {
-	                return;
-	            }
-	            var target = result;
-	            // Recreate the TargetState, in case the state is now defined.
-	            target = _this.target(target.identifier(), target.params(), target.options());
-	            if (!target.valid())
-	                return rejectFactory_1.Rejection.invalid(target.error()).toPromise();
-	            if (latestThing() !== latest)
-	                return rejectFactory_1.Rejection.superseded().toPromise();
-	            return _this.transitionTo(target.identifier(), target.params(), target.options());
-	        };
-	        function invokeNextCallback() {
-	            var nextCallback = callbackQueue.dequeue();
-	            if (nextCallback === undefined)
-	                return rejectFactory_1.Rejection.invalid($to$.error()).toPromise();
-	            return invokeCallback(nextCallback).then(checkForRedirect).then(function (result) { return result || invokeNextCallback(); });
-	        }
-	        return invokeNextCallback();
-	    };
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$state#reload
-	     * @methodOf ui.router.state.$state
-	     *
-	     * @description
-	     * A method that force reloads the current state, or a partial state hierarchy. All resolves are re-resolved,
-	     * controllers reinstantiated, and events re-fired.
-	     *
-	     * @example
-	     * <pre>
-	     * let app angular.module('app', ['ui.router']);
-	     *
-	     * app.controller('ctrl', function ($scope, $state) {
-	     *   $scope.reload = function(){
-	     *     $state.reload();
-	     *   }
-	     * });
-	     * </pre>
-	     *
-	     * `reload()` is just an alias for:
-	     * <pre>
-	     * $state.transitionTo($state.current, $stateParams, {
-	     *   reload: true, inherit: false, notify: true
-	     * });
-	     * </pre>
-	     *
-	     * @param {string=|object=} reloadState - A state name or a state object, which is the root of the resolves to be re-resolved.
-	     * @example
-	     * <pre>
-	     * //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'
-	     * //and current state is 'contacts.detail.item'
-	     * let app angular.module('app', ['ui.router']);
-	     *
-	     * app.controller('ctrl', function ($scope, $state) {
-	     *   $scope.reload = function(){
-	     *     //will reload 'contact.detail' and nested 'contact.detail.item' states
-	     *     $state.reload('contact.detail');
-	     *   }
-	     * });
-	     * </pre>
-	     *
-	     * @returns {promise} A promise representing the state of the new transition. See
-	     * {@link ui.router.state.$state#methods_go $state.go}.
-	     */
-	    StateService.prototype.reload = function (reloadState) {
-	        return this.transitionTo(this.current, this.params, {
-	            reload: predicates_1.isDefined(reloadState) ? reloadState : true,
-	            inherit: false,
-	            notify: false
-	        });
-	    };
-	    ;
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$state#go
-	     * @methodOf ui.router.state.$state
-	     *
-	     * @description
-	     * Convenience method for transitioning to a new state. `$state.go` calls
-	     * `$state.transitionTo` internally but automatically sets options to
-	     * `{ location: true, inherit: true, relative: $state.$current, notify: true }`.
-	     * This allows you to easily use an absolute or relative to path and specify
-	     * only the parameters you'd like to update (while letting unspecified parameters
-	     * inherit from the currently active ancestor states).
-	     *
-	     * @example
-	     * <pre>
-	     * let app = angular.module('app', ['ui.router']);
-	     *
-	     * app.controller('ctrl', function ($scope, $state) {
-	     *   $scope.changeState = function () {
-	     *     $state.go('contact.detail');
-	     *   };
-	     * });
-	     * </pre>
-	     * <img src='../ngdoc_assets/StateGoExamples.png'/>
-	     *
-	     * @param {string} to Absolute state name or relative state path. Some examples:
-	     *
-	     * - `$state.go('contact.detail')` - will go to the `contact.detail` state
-	     * - `$state.go('^')` - will go to a parent state
-	     * - `$state.go('^.sibling')` - will go to a sibling state
-	     * - `$state.go('.child.grandchild')` - will go to grandchild state
-	     *
-	     * @param {object=} params A map of the parameters that will be sent to the state,
-	     * will populate $stateParams. Any parameters that are not specified will be inherited from currently
-	     * defined parameters. This allows, for example, going to a sibling state that shares parameters
-	     * specified in a parent state. Parameter inheritance only works between common ancestor states, I.e.
-	     * transitioning to a sibling will get you the parameters for all parents, transitioning to a child
-	     * will get you all current parameters, etc.
-	     * @param {object=} options Options object. The options are:
-	     *
-	     * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`
-	     *    will not. If string, must be `"replace"`, which will update url and also replace last history record.
-	     * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.
-	     * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
-	     *    defines which state to be relative from.
-	     * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.
-	     * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params
-	     *    have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd
-	     *    use this when you want to force a reload when *everything* is the same, including search params.
-	     *
-	     * @returns {promise} A promise representing the state of the new transition.
-	     *
-	     * Possible success values:
-	     *
-	     * - $state.current
-	     *
-	     * <br/>Possible rejection values:
-	     *
-	     * - 'transition superseded' - when a newer transition has been started after this one
-	     * - 'transition prevented' - when `event.preventDefault()` has been called in a `$stateChangeStart` listener
-	     * - 'transition aborted' - when `event.preventDefault()` has been called in a `$stateNotFound` listener or
-	     *   when a `$stateNotFound` `event.retry` promise errors.
-	     * - 'transition failed' - when a state has been unsuccessfully found after 2 tries.
-	     * - *resolve error* - when an error has occurred with a `resolve`
-	     *
-	     */
-	    StateService.prototype.go = function (to, params, options) {
-	        var defautGoOpts = { relative: this.$current, inherit: true };
-	        var transOpts = common_1.defaults(options, defautGoOpts, transitionService_1.defaultTransOpts);
-	        return this.transitionTo(to, params, transOpts);
-	    };
-	    ;
-	    /** Factory method for creating a TargetState */
-	    StateService.prototype.target = function (identifier, params, options) {
-	        if (options === void 0) { options = {}; }
-	        // If we're reloading, find the state object to reload from
-	        if (predicates_1.isObject(options.reload) && !options.reload.name)
-	            throw new Error('Invalid reload state object');
-	        var reg = this.router.stateRegistry;
-	        options.reloadState = options.reload === true ? reg.root() : reg.matcher.find(options.reload, options.relative);
-	        if (options.reload && !options.reloadState)
-	            throw new Error("No such reload state '" + (predicates_1.isString(options.reload) ? options.reload : options.reload.name) + "'");
-	        var stateDefinition = reg.matcher.find(identifier, options.relative);
-	        return new targetState_1.TargetState(identifier, stateDefinition, params, options);
-	    };
-	    ;
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$state#transitionTo
-	     * @methodOf ui.router.state.$state
-	     *
-	     * @description
-	     * Low-level method for transitioning to a new state. {@link ui.router.state.$state#methods_go $state.go}
-	     * uses `transitionTo` internally. `$state.go` is recommended in most situations.
-	     *
-	     * @example
-	     * <pre>
-	     * let app = angular.module('app', ['ui.router']);
-	     *
-	     * app.controller('ctrl', function ($scope, $state) {
-	     *   $scope.changeState = function () {
-	     *     $state.transitionTo('contact.detail');
-	     *   };
-	     * });
-	     * </pre>
-	     *
-	     * @param {string} to State name.
-	     * @param {object=} toParams A map of the parameters that will be sent to the state,
-	     * will populate $stateParams.
-	     * @param {object=} options Options object. The options are:
-	     *
-	     * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`
-	     *    will not. If string, must be `"replace"`, which will update url and also replace last history record.
-	     * - **`inherit`** - {boolean=false}, If `true` will inherit url parameters from current url.
-	     * - **`relative`** - {object=}, When transitioning with relative path (e.g '^'),
-	     *    defines which state to be relative from.
-	     * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.
-	     * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params
-	     *    have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd
-	     *    use this when you want to force a reload when *everything* is the same, including search params.
-	     *
-	     * @returns {promise} A promise representing the state of the new transition. See
-	     * {@link ui.router.state.$state#methods_go $state.go}.
-	     */
-	    StateService.prototype.transitionTo = function (to, toParams, options) {
-	        var _this = this;
-	        if (toParams === void 0) { toParams = {}; }
-	        if (options === void 0) { options = {}; }
-	        var router = this.router;
-	        var globals = router.globals;
-	        var transHistory = globals.transitionHistory;
-	        options = common_1.defaults(options, transitionService_1.defaultTransOpts);
-	        options = common_1.extend(options, { current: transHistory.peekTail.bind(transHistory) });
-	        var ref = this.target(to, toParams, options);
-	        var latestSuccess = globals.successfulTransitions.peekTail();
-	        var rootPath = function () { return [new node_1.PathNode(_this.router.stateRegistry.root())]; };
-	        var currentPath = latestSuccess ? latestSuccess.treeChanges().to : rootPath();
-	        if (!ref.exists())
-	            return this._handleInvalidTargetState(currentPath, ref);
-	        if (!ref.valid())
-	            return common_1.silentRejection(ref.error());
-	        /**
-	         * Special handling for Ignored, Aborted, and Redirected transitions
-	         *
-	         * The semantics for the transition.run() promise and the StateService.transitionTo()
-	         * promise differ. For instance, the run() promise may be rejected because it was
-	         * IGNORED, but the transitionTo() promise is resolved because from the user perspective
-	         * no error occurred.  Likewise, the transition.run() promise may be rejected because of
-	         * a Redirect, but the transitionTo() promise is chained to the new Transition's promise.
-	         */
-	        var rejectedTransitionHandler = function (transition) { return function (error) {
-	            if (error instanceof rejectFactory_1.Rejection) {
-	                if (error.type === rejectFactory_1.RejectType.IGNORED) {
-	                    router.urlRouter.update();
-	                    return globals.current;
-	                }
-	                if (error.type === rejectFactory_1.RejectType.SUPERSEDED && error.redirected && error.detail instanceof targetState_1.TargetState) {
-	                    var redirect = transition.redirect(error.detail);
-	                    return redirect.run().catch(rejectedTransitionHandler(redirect));
-	                }
-	                if (error.type === rejectFactory_1.RejectType.ABORTED) {
-	                    router.urlRouter.update();
-	                    return coreservices_1.services.$q.reject(error);
-	                }
-	            }
-	            var errorHandler = _this.defaultErrorHandler();
-	            errorHandler(error);
-	            return coreservices_1.services.$q.reject(error);
-	        }; };
-	        var transition = this.router.transitionService.create(currentPath, ref);
-	        var transitionToPromise = transition.run().catch(rejectedTransitionHandler(transition));
-	        common_1.silenceUncaughtInPromise(transitionToPromise); // issue #2676
-	        // Return a promise for the transition, which also has the transition object on it.
-	        return common_1.extend(transitionToPromise, { transition: transition });
-	    };
-	    ;
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$state#is
-	     * @methodOf ui.router.state.$state
-	     *
-	     * @description
-	     * Similar to {@link ui.router.state.$state#methods_includes $state.includes},
-	     * but only checks for the full state name. If params is supplied then it will be
-	     * tested for strict equality against the current active params object, so all params
-	     * must match with none missing and no extras.
-	     *
-	     * @example
-	     * <pre>
-	     * $state.$current.name = 'contacts.details.item';
-	     *
-	     * // absolute name
-	     * $state.is('contact.details.item'); // returns true
-	     * $state.is(contactDetailItemStateObject); // returns true
-	     *
-	     * // relative name (. and ^), typically from a template
-	     * // E.g. from the 'contacts.details' template
-	     * <div ng-class="{highlighted: $state.is('.item')}">Item</div>
-	     * </pre>
-	     *
-	     * @param {string|object} stateOrName The state name (absolute or relative) or state object you'd like to check.
-	     * @param {object=} params A param object, e.g. `{sectionId: section.id}`, that you'd like
-	     * to test against the current active state.
-	     * @param {object=} options An options object.  The options are:
-	     *
-	     * - **`relative`** - {string|object} -  If `stateOrName` is a relative state name and `options.relative` is set, .is will
-	     * test relative to `options.relative` state (or name).
-	     *
-	     * @returns {boolean} Returns true if it is the state.
-	     */
-	    StateService.prototype.is = function (stateOrName, params, options) {
-	        options = common_1.defaults(options, { relative: this.$current });
-	        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative);
-	        if (!predicates_1.isDefined(state))
-	            return undefined;
-	        if (this.$current !== state)
-	            return false;
-	        return predicates_1.isDefined(params) && params !== null ? param_1.Param.equals(state.parameters(), this.params, params) : true;
-	    };
-	    ;
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$state#includes
-	     * @methodOf ui.router.state.$state
-	     *
-	     * @description
-	     * A method to determine if the current active state is equal to or is the child of the
-	     * state stateName. If any params are passed then they will be tested for a match as well.
-	     * Not all the parameters need to be passed, just the ones you'd like to test for equality.
-	     *
-	     * @example
-	     * Partial and relative names
-	     * <pre>
-	     * $state.$current.name = 'contacts.details.item';
-	     *
-	     * // Using partial names
-	     * $state.includes("contacts"); // returns true
-	     * $state.includes("contacts.details"); // returns true
-	     * $state.includes("contacts.details.item"); // returns true
-	     * $state.includes("contacts.list"); // returns false
-	     * $state.includes("about"); // returns false
-	     *
-	     * // Using relative names (. and ^), typically from a template
-	     * // E.g. from the 'contacts.details' template
-	     * <div ng-class="{highlighted: $state.includes('.item')}">Item</div>
-	     * </pre>
-	     *
-	     * Basic globbing patterns
-	     * <pre>
-	     * $state.$current.name = 'contacts.details.item.url';
-	     *
-	     * $state.includes("*.details.*.*"); // returns true
-	     * $state.includes("*.details.**"); // returns true
-	     * $state.includes("**.item.**"); // returns true
-	     * $state.includes("*.details.item.url"); // returns true
-	     * $state.includes("*.details.*.url"); // returns true
-	     * $state.includes("*.details.*"); // returns false
-	     * $state.includes("item.**"); // returns false
-	     * </pre>
-	     *
-	     * @param {string} stateOrName A partial name, relative name, or glob pattern
-	     * to be searched for within the current state name.
-	     * @param {object=} params A param object, e.g. `{sectionId: section.id}`,
-	     * that you'd like to test against the current active state.
-	     * @param {object=} options An options object.  The options are:
-	     *
-	     * - **`relative`** - {string|object=} -  If `stateOrName` is a relative state reference and `options.relative` is set,
-	     * .includes will test relative to `options.relative` state (or name).
-	     *
-	     * @returns {boolean} Returns true if it does include the state
-	     */
-	    StateService.prototype.includes = function (stateOrName, params, options) {
-	        options = common_1.defaults(options, { relative: this.$current });
-	        var glob = predicates_1.isString(stateOrName) && glob_1.Glob.fromString(stateOrName);
-	        if (glob) {
-	            if (!glob.matches(this.$current.name))
-	                return false;
-	            stateOrName = this.$current.name;
-	        }
-	        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative), include = this.$current.includes;
-	        if (!predicates_1.isDefined(state))
-	            return undefined;
-	        if (!predicates_1.isDefined(include[state.name]))
-	            return false;
-	        // @TODO Replace with Param.equals() ?
-	        return params ? common_2.equalForKeys(param_1.Param.values(state.parameters(), params), this.params, Object.keys(params)) : true;
-	    };
-	    ;
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$state#href
-	     * @methodOf ui.router.state.$state
-	     *
-	     * @description
-	     * A url generation method that returns the compiled url for the given state populated with the given params.
-	     *
-	     * @example
-	     * <pre>
-	     * expect($state.href("about.person", { person: "bob" })).toEqual("/about/bob");
-	     * </pre>
-	     *
-	     * @param {string|object} stateOrName The state name or state object you'd like to generate a url from.
-	     * @param {object=} params An object of parameter values to fill the state's required parameters.
-	     * @param {object=} options Options object. The options are:
-	     *
-	     * - **`lossy`** - {boolean=true} -  If true, and if there is no url associated with the state provided in the
-	     *    first parameter, then the constructed href url will be built from the first navigable ancestor (aka
-	     *    ancestor with a valid url).
-	     * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.
-	     * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
-	     *    defines which state to be relative from.
-	     * - **`absolute`** - {boolean=false},  If true will generate an absolute url, e.g. "http://www.example.com/fullurl".
-	     *
-	     * @returns {string} compiled state url
-	     */
-	    StateService.prototype.href = function (stateOrName, params, options) {
-	        var defaultHrefOpts = {
-	            lossy: true,
-	            inherit: true,
-	            absolute: false,
-	            relative: this.$current
-	        };
-	        options = common_1.defaults(options, defaultHrefOpts);
-	        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative);
-	        if (!predicates_1.isDefined(state))
-	            return null;
-	        if (options.inherit)
-	            params = this.params.$inherit(params || {}, this.$current, state);
-	        var nav = (state && options.lossy) ? state.navigable : state;
-	        if (!nav || nav.url === undefined || nav.url === null) {
-	            return null;
-	        }
-	        return this.router.urlRouter.href(nav.url, param_1.Param.values(state.parameters(), params), {
-	            absolute: options.absolute
-	        });
-	    };
-	    ;
-	    /**
-	     * Sets or gets the default [[transitionTo]] error handler.
-	     *
-	     * The error handler is called when a [[Transition]] is rejected or when any error occurred during the Transition.
-	     * This includes errors caused by resolves and transition hooks.
-	     *
-	     * The built-in default error handler logs the error to the console.
-	     *
-	     * You can provide your own custom handler.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * stateService.defaultErrorHandler(function() {
-	     *   // Do not log transitionTo errors
-	     * });
-	     * ```
-	     *
-	     * @param handler a global error handler function
-	     * @returns the current global error handler
-	     */
-	    StateService.prototype.defaultErrorHandler = function (handler) {
-	        return this._defaultErrorHandler = handler || this._defaultErrorHandler;
-	    };
-	    StateService.prototype.get = function (stateOrName, base) {
-	        var reg = this.router.stateRegistry;
-	        if (arguments.length === 0)
-	            return reg.get();
-	        return reg.get(stateOrName, base || this.$current);
-	    };
-	    return StateService;
-	}());
-	exports.StateService = StateService;
-
-
-/***/ },
-/* 44 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module core */ /** */
-	var stateParams_1 = __webpack_require__(45);
-	var queue_1 = __webpack_require__(8);
-	var common_1 = __webpack_require__(3);
-	/**
-	 * Global mutable state
-	 */
-	var Globals = (function () {
-	    function Globals(transitionService) {
-	        var _this = this;
-	        this.params = new stateParams_1.StateParams();
-	        this.transitionHistory = new queue_1.Queue([], 1);
-	        this.successfulTransitions = new queue_1.Queue([], 1);
-	        var beforeNewTransition = function ($transition$) {
-	            _this.transition = $transition$;
-	            _this.transitionHistory.enqueue($transition$);
-	            var updateGlobalState = function () {
-	                _this.successfulTransitions.enqueue($transition$);
-	                _this.$current = $transition$.$to();
-	                _this.current = _this.$current.self;
-	                common_1.copy($transition$.params(), _this.params);
-	            };
-	            $transition$.onSuccess({}, updateGlobalState, { priority: 10000 });
-	            var clearCurrentTransition = function () { if (_this.transition === $transition$)
-	                _this.transition = null; };
-	            $transition$.promise.then(clearCurrentTransition, clearCurrentTransition);
-	        };
-	        transitionService.onBefore({}, beforeNewTransition);
-	    }
-	    return Globals;
-	}());
-	exports.Globals = Globals;
-
-
-/***/ },
-/* 45 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module params */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var StateParams = (function () {
-	    function StateParams(params) {
-	        if (params === void 0) { params = {}; }
-	        common_1.extend(this, params);
-	    }
-	    /**
-	     * Merges a set of parameters with all parameters inherited between the common parents of the
-	     * current state and a given destination state.
-	     *
-	     * @param {Object} newParams The set of parameters which will be composited with inherited params.
-	     * @param {Object} $current Internal definition of object representing the current state.
-	     * @param {Object} $to Internal definition of object representing state to transition to.
-	     */
-	    StateParams.prototype.$inherit = function (newParams, $current, $to) {
-	        var parents = common_1.ancestors($current, $to), parentParams, inherited = {}, inheritList = [];
-	        for (var i in parents) {
-	            if (!parents[i] || !parents[i].params)
-	                continue;
-	            parentParams = Object.keys(parents[i].params);
-	            if (!parentParams.length)
-	                continue;
-	            for (var j in parentParams) {
-	                if (inheritList.indexOf(parentParams[j]) >= 0)
-	                    continue;
-	                inheritList.push(parentParams[j]);
-	                inherited[parentParams[j]] = this[parentParams[j]];
-	            }
-	        }
-	        return common_1.extend({}, inherited, newParams);
-	    };
-	    ;
-	    return StateParams;
-	}());
-	exports.StateParams = StateParams;
-
-
-/***/ },
-/* 46 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	/**
-	 * This module contains code for State Parameters.
-	 *
-	 * See [[ParamDeclaration]]
-	 * @module params
-	 * @preferred doc
-	 */
-	/** for typedoc */
-	__export(__webpack_require__(22));
-	__export(__webpack_require__(25));
-	__export(__webpack_require__(45));
-	__export(__webpack_require__(24));
-
-
-/***/ },
-/* 47 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	/** @module path */ /** for typedoc */
-	__export(__webpack_require__(21));
-	__export(__webpack_require__(20));
-
-
-/***/ },
-/* 48 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	/** @module resolve */ /** for typedoc */
-	__export(__webpack_require__(18));
-	__export(__webpack_require__(19));
-	__export(__webpack_require__(17));
-
-
-/***/ },
-/* 49 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	/** @module state */ /** for typedoc */
-	__export(__webpack_require__(30));
-	__export(__webpack_require__(40));
-	__export(__webpack_require__(42));
-	__export(__webpack_require__(39));
-	__export(__webpack_require__(41));
-	__export(__webpack_require__(38));
-	__export(__webpack_require__(43));
-	__export(__webpack_require__(14));
-
-
-/***/ },
-/* 50 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	/**
-	 * This module contains APIs related to a Transition.
-	 *
-	 * See [[Transition]], [[$transitions]]
-	 *
-	 * @module transition
-	 * @preferred
-	 */
-	/** for typedoc */
-	__export(__webpack_require__(16));
-	__export(__webpack_require__(15));
-	__export(__webpack_require__(10));
-	__export(__webpack_require__(11));
-	__export(__webpack_require__(13));
-	__export(__webpack_require__(31));
-
-
-/***/ },
-/* 51 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	/** @module url */ /** for typedoc */
-	__export(__webpack_require__(28));
-	__export(__webpack_require__(23));
-	__export(__webpack_require__(27));
-	__export(__webpack_require__(29));
-
-
-/***/ },
-/* 52 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	function __export(m) {
-	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
-	}
-	/** @module view */ /** for typedoc */
-	__export(__webpack_require__(37));
-
-
-/***/ },
-/* 53 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/**
-	 * # UI-Router for Angular 1
-	 *
-	 * - Provides an implementation for the [[CoreServices]] API, based on angular 1 services.
-	 * - Also registers some services with the angular 1 injector.
-	 * - Creates and bootstraps a new [[UIRouter]] object.  Ties it to the the angular 1 lifecycle.
-	 *
-	 * @module ng1
-	 * @preferred
-	 */
-	"use strict";
-	/** for typedoc */
-	var router_1 = __webpack_require__(26);
-	var coreservices_1 = __webpack_require__(6);
-	var common_1 = __webpack_require__(3);
-	var hof_1 = __webpack_require__(5);
-	var predicates_1 = __webpack_require__(4);
-	var resolveService_1 = __webpack_require__(54);
-	var trace_1 = __webpack_require__(12);
-	var views_1 = __webpack_require__(55);
-	var templateFactory_1 = __webpack_require__(56);
-	var onEnterExitRetain_1 = __webpack_require__(57);
-	/** @hidden */
-	var app = angular.module("ui.router.angular1", []);
-	/**
-	 * @ngdoc overview
-	 * @name ui.router.util
-	 *
-	 * @description
-	 * # ui.router.util sub-module
-	 *
-	 * This module is a dependency of other sub-modules. Do not include this module as a dependency
-	 * in your angular app (use {@link ui.router} module instead).
-	 *
-	 */
-	angular.module('ui.router.util', ['ng', 'ui.router.init']);
-	/**
-	 * @ngdoc overview
-	 * @name ui.router.router
-	 *
-	 * @requires ui.router.util
-	 *
-	 * @description
-	 * # ui.router.router sub-module
-	 *
-	 * This module is a dependency of other sub-modules. Do not include this module as a dependency
-	 * in your angular app (use {@link ui.router} module instead).
-	 */
-	angular.module('ui.router.router', ['ui.router.util']);
-	/**
-	 * @ngdoc overview
-	 * @name ui.router.state
-	 *
-	 * @requires ui.router.router
-	 * @requires ui.router.util
-	 *
-	 * @description
-	 * # ui.router.state sub-module
-	 *
-	 * This module is a dependency of the main ui.router module. Do not include this module as a dependency
-	 * in your angular app (use {@link ui.router} module instead).
-	 *
-	 */
-	angular.module('ui.router.state', ['ui.router.router', 'ui.router.util', 'ui.router.angular1']);
-	/**
-	 * @ngdoc overview
-	 * @name ui.router
-	 *
-	 * @requires ui.router.state
-	 *
-	 * @description
-	 * # ui.router
-	 *
-	 * ## The main module for ui.router
-	 * There are several sub-modules included with the ui.router module, however only this module is needed
-	 * as a dependency within your angular app. The other modules are for organization purposes.
-	 *
-	 * The modules are:
-	 * * ui.router - the main "umbrella" module
-	 * * ui.router.router -
-	 *
-	 * *You'll need to include **only** this module as the dependency within your angular app.*
-	 *
-	 * <pre>
-	 * <!doctype html>
-	 * <html ng-app="myApp">
-	 * <head>
-	 *   <script src="js/angular.js"></script>
-	 *   <!-- Include the ui-router script -->
-	 *   <script src="js/angular-ui-router.min.js"></script>
-	 *   <script>
-	 *     // ...and add 'ui.router' as a dependency
-	 *     var myApp = angular.module('myApp', ['ui.router']);
-	 *   </script>
-	 * </head>
-	 * <body>
-	 * </body>
-	 * </html>
-	 * </pre>
-	 */
-	angular.module('ui.router', ['ui.router.init', 'ui.router.state', 'ui.router.angular1']);
-	angular.module('ui.router.compat', ['ui.router']);
-	/**
-	 * Annotates a controller expression (may be a controller function(), a "controllername",
-	 * or "controllername as name")
-	 *
-	 * - Temporarily decorates $injector.instantiate.
-	 * - Invokes $controller() service
-	 *   - Calls $injector.instantiate with controller constructor
-	 * - Annotate constructor
-	 * - Undecorate $injector
-	 *
-	 * returns an array of strings, which are the arguments of the controller expression
-	 */
-	function annotateController(controllerExpression) {
-	    var $injector = coreservices_1.services.$injector;
-	    var $controller = $injector.get("$controller");
-	    var oldInstantiate = $injector.instantiate;
-	    try {
-	        var deps_1;
-	        $injector.instantiate = function fakeInstantiate(constructorFunction) {
-	            $injector.instantiate = oldInstantiate; // Un-decorate ASAP
-	            deps_1 = $injector.annotate(constructorFunction);
-	        };
-	        $controller(controllerExpression, { $scope: {} });
-	        return deps_1;
-	    }
-	    finally {
-	        $injector.instantiate = oldInstantiate;
-	    }
-	}
-	exports.annotateController = annotateController;
-	runBlock.$inject = ['$injector', '$q'];
-	function runBlock($injector, $q) {
-	    coreservices_1.services.$injector = $injector;
-	    coreservices_1.services.$q = $q;
-	}
-	app.run(runBlock);
-	var router = null;
-	ng1UIRouter.$inject = ['$locationProvider'];
-	/** This angular 1 provider instantiates a Router and exposes its services via the angular injector */
-	function ng1UIRouter($locationProvider) {
-	    // Create a new instance of the Router when the ng1UIRouterProvider is initialized
-	    router = new router_1.UIRouter();
-	    // Apply ng1 specific StateBuilder code for `views`, `resolve`, and `onExit/Retain/Enter` properties
-	    router.stateRegistry.decorator("views", views_1.ng1ViewsBuilder);
-	    router.stateRegistry.decorator("onExit", onEnterExitRetain_1.getStateHookBuilder("onExit"));
-	    router.stateRegistry.decorator("onRetain", onEnterExitRetain_1.getStateHookBuilder("onRetain"));
-	    router.stateRegistry.decorator("onEnter", onEnterExitRetain_1.getStateHookBuilder("onEnter"));
-	    router.viewService.viewConfigFactory('ng1', views_1.ng1ViewConfigFactory);
-	    // Bind LocationConfig.hashPrefix to $locationProvider.hashPrefix
-	    common_1.bindFunctions($locationProvider, coreservices_1.services.locationConfig, $locationProvider, ['hashPrefix']);
-	    // Create a LocationService.onChange registry
-	    var urlListeners = [];
-	    coreservices_1.services.location.onChange = function (callback) {
-	        urlListeners.push(callback);
-	        return function () { return common_1.removeFrom(urlListeners)(callback); };
-	    };
-	    this.$get = $get;
-	    $get.$inject = ['$location', '$browser', '$sniffer', '$rootScope', '$http', '$templateCache'];
-	    function $get($location, $browser, $sniffer, $rootScope, $http, $templateCache) {
-	        // Bind $locationChangeSuccess to the listeners registered in LocationService.onChange
-	        $rootScope.$on("$locationChangeSuccess", function (evt) { return urlListeners.forEach(function (fn) { return fn(evt); }); });
-	        // Bind LocationConfig.html5Mode to $locationProvider.html5Mode and $sniffer.history
-	        coreservices_1.services.locationConfig.html5Mode = function () {
-	            var html5Mode = $locationProvider.html5Mode();
-	            html5Mode = predicates_1.isObject(html5Mode) ? html5Mode.enabled : html5Mode;
-	            return html5Mode && $sniffer.history;
-	        };
-	        coreservices_1.services.template.get = function (url) {
-	            return $http.get(url, { cache: $templateCache, headers: { Accept: 'text/html' } }).then(hof_1.prop("data"));
-	        };
-	        // Bind these LocationService functions to $location
-	        common_1.bindFunctions($location, coreservices_1.services.location, $location, ["replace", "url", "path", "search", "hash"]);
-	        // Bind these LocationConfig functions to $location
-	        common_1.bindFunctions($location, coreservices_1.services.locationConfig, $location, ['port', 'protocol', 'host']);
-	        // Bind these LocationConfig functions to $browser
-	        common_1.bindFunctions($browser, coreservices_1.services.locationConfig, $browser, ['baseHref']);
-	        return router;
-	    }
-	}
-	function $stateParamsFactory(ng1UIRouter) {
-	    return ng1UIRouter.globals.params;
-	}
-	// The 'ui.router' ng1 module depends on 'ui.router.init' module.
-	angular.module('ui.router.init', []).provider("ng1UIRouter", ng1UIRouter);
-	// This effectively calls $get() to init when we enter runtime
-	angular.module('ui.router.init').run(['ng1UIRouter', function (ng1UIRouter) { }]);
-	// $urlMatcherFactory service and $urlMatcherFactoryProvider
-	angular.module('ui.router.util').provider('$urlMatcherFactory', ['ng1UIRouterProvider', function () { return router.urlMatcherFactory; }]);
-	angular.module('ui.router.util').run(['$urlMatcherFactory', function ($urlMatcherFactory) { }]);
-	// $urlRouter service and $urlRouterProvider
-	function getUrlRouterProvider() {
-	    router.urlRouterProvider["$get"] = function () {
-	        router.urlRouter.update(true);
-	        if (!this.interceptDeferred)
-	            router.urlRouter.listen();
-	        return router.urlRouter;
-	    };
-	    return router.urlRouterProvider;
-	}
-	angular.module('ui.router.router').provider('$urlRouter', ['ng1UIRouterProvider', getUrlRouterProvider]);
-	angular.module('ui.router.router').run(['$urlRouter', function ($urlRouter) { }]);
-	// $state service and $stateProvider
-	// $urlRouter service and $urlRouterProvider
-	function getStateProvider() {
-	    router.stateProvider["$get"] = function () {
-	        // Autoflush once we are in runtime
-	        router.stateRegistry.stateQueue.autoFlush(router.stateService);
-	        return router.stateService;
-	    };
-	    return router.stateProvider;
-	}
-	angular.module('ui.router.state').provider('$state', ['ng1UIRouterProvider', getStateProvider]);
-	angular.module('ui.router.state').run(['$state', function ($state) { }]);
-	// $stateParams service
-	angular.module('ui.router.state').factory('$stateParams', ['ng1UIRouter', function (ng1UIRouter) {
-	        return ng1UIRouter.globals.params;
-	    }]);
-	// $transitions service and $transitionsProvider
-	function getTransitionsProvider() {
-	    router.transitionService["$get"] = function () { return router.transitionService; };
-	    return router.transitionService;
-	}
-	angular.module('ui.router.state').provider('$transitions', ['ng1UIRouterProvider', getTransitionsProvider]);
-	// $templateFactory service
-	angular.module('ui.router.util').factory('$templateFactory', ['ng1UIRouter', function () { return new templateFactory_1.TemplateFactory(); }]);
-	// The $view service
-	angular.module('ui.router').factory('$view', function () { return router.viewService; });
-	// The old $resolve service
-	angular.module('ui.router').factory('$resolve', resolveService_1.resolveFactory);
-	// $trace service
-	angular.module("ui.router").service("$trace", function () { return trace_1.trace; });
-	watchDigests.$inject = ['$rootScope'];
-	function watchDigests($rootScope) {
-	    $rootScope.$watch(function () { trace_1.trace.approximateDigests++; });
-	}
-	exports.watchDigests = watchDigests;
-	angular.module("ui.router").run(watchDigests);
-	exports.getLocals = function (ctx) {
-	    var tokens = ctx.getTokens().filter(predicates_1.isString);
-	    var tuples = tokens.map(function (key) { return [key, ctx.getResolvable(key).data]; });
-	    return tuples.reduce(common_1.applyPairs, {});
-	};
-	/** Injectable services */
-	/**
-	 * An injectable service object which has the current state parameters
-	 *
-	 * This angular service (singleton object) holds the current state parameters.
-	 * The values in `$stateParams` are not updated until *after* a [[Transition]] successfully completes.
-	 *
-	 * This object can be injected into other services.
-	 *
-	 * @example
-	 * ```js
-	 *
-	 * SomeService.$inject = ['$http', '$stateParams'];
-	 * function SomeService($http, $stateParams) {
-	 *   return {
-	 *     getUser: function() {
-	 *       return $http.get('/api/users/' + $stateParams.username);
-	 *     }
-	 *   }
-	 * };
-	 * angular.service('SomeService', SomeService);
-	 * ```
-	 *
-	 * ### Deprecation warning:
-	 *
-	 * When `$stateParams` is injected into transition hooks, resolves and view controllers, they receive a different
-	 * object than this global service object.  In those cases, the injected object has the parameter values for the
-	 * *pending* Transition.
-	 *
-	 * Because of these confusing details, this service is deprecated.
-	 *
-	 * @deprecated Instead of using `$stateParams, inject the current [[Transition]] as `$transition$` and use [[Transition.params]]
-	 * ```js
-	 * MyController.$inject = ['$transition$'];
-	 * function MyController($transition$) {
-	 *   var username = $transition$.params().username;
-	 *   // .. do something with username
-	 * }
-	 * ```
-	 */
-	var $stateParams;
-	/**
-	 * An injectable service primarily used to register transition hooks
-	 *
-	 * This angular service exposes the [[TransitionService]] singleton, which is primarily used to add transition hooks.
-	 *
-	 * The same object is also exposed as [[$transitionsProvider]] for injection during angular config time.
-	 */
-	var $transitions;
-	/**
-	 * A config-time injectable provider primarily used to register transition hooks
-	 *
-	 * This angular provider exposes the [[TransitionService]] singleton, which is primarily used to add transition hooks.
-	 *
-	 * The same object is also exposed as [[$transitions]] for injection at runtime.
-	 */
-	var $transitionsProvider;
-	/**
-	 * An injectable service used to query for current state information.
-	 *
-	 * This angular service exposes the [[StateService]] singleton.
-	 */
-	var $state;
-	/**
-	 * A config-time injectable provider used to register states.
-	 *
-	 * This angular service exposes the [[StateProvider]] singleton.
-	 */
-	var $stateProvider;
-	/**
-	 * A config-time injectable provider used to manage the URL.
-	 *
-	 * This angular service exposes the [[UrlRouterProvider]] singleton.
-	 */
-	var $urlRouterProvider;
-	/**
-	 * An injectable service used to configure URL redirects.
-	 *
-	 * This angular service exposes the [[UrlRouter]] singleton.
-	 */
-	var $urlRouter;
-	/**
-	 * An injectable service used to configure the URL.
-	 *
-	 * This service is used to set url mapping options, and create [[UrlMatcher]] objects.
-	 *
-	 * This angular service exposes the [[UrlMatcherFactory]] singleton.
-	 * The singleton is also exposed at config-time as the [[$urlMatcherFactoryProvider]].
-	 */
-	var $urlMatcherFactory;
-	/**
-	 * An injectable service used to configure the URL.
-	 *
-	 * This service is used to set url mapping options, and create [[UrlMatcher]] objects.
-	 *
-	 * This angular service exposes the [[UrlMatcherFactory]] singleton at config-time.
-	 * The singleton is also exposed at runtime as the [[$urlMatcherFactory]].
-	 */
-	var $urlMatcherFactoryProvider;
-
-
-/***/ },
-/* 54 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module ng1 */ /** */
-	var stateObject_1 = __webpack_require__(42);
-	var node_1 = __webpack_require__(21);
-	var resolveContext_1 = __webpack_require__(17);
-	var common_1 = __webpack_require__(3);
-	var stateBuilder_1 = __webpack_require__(40);
-	/**
-	 * Implementation of the legacy `$resolve` service for angular 1.
-	 */
-	var $resolve = {
-	    /**
-	     * Asynchronously injects a resolve block.
-	     *
-	     * This emulates most of the behavior of the ui-router 0.2.x $resolve.resolve() service API.
-	     *
-	     * Given an object `invocables`, where keys are strings and values are injectable functions,
-	     * injects each function, and waits for the resulting promise to resolve.
-	     * When all resulting promises are resolved, returns the results as an object.
-	     *
-	     * @example
-	     * ```js
-	     *
-	     * let invocables = {
-	     *   foo: [ '$http', ($http) =>
-	     *            $http.get('/api/foo').then(resp => resp.data) ],
-	     *   bar: [ 'foo', '$http', (foo, $http) =>
-	     *            $http.get('/api/bar/' + foo.barId).then(resp => resp.data) ]
-	     * }
-	     * $resolve.resolve(invocables)
-	     *     .then(results => console.log(results.foo, results.bar))
-	     * // Logs foo and bar:
-	     * // { id: 123, barId: 456, fooData: 'foo data' }
-	     * // { id: 456, barData: 'bar data' }
-	     * ```
-	     *
-	     * @param invocables an object which looks like an [[StateDefinition.resolve]] object; keys are resolve names and values are injectable functions
-	     * @param locals key/value pre-resolved data (locals)
-	     * @param parent a promise for a "parent resolve"
-	     */
-	    resolve: function (invocables, locals, parent) {
-	        if (locals === void 0) { locals = {}; }
-	        var parentNode = new node_1.PathNode(new stateObject_1.State({ params: {}, resolvables: [] }));
-	        var node = new node_1.PathNode(new stateObject_1.State({ params: {}, resolvables: [] }));
-	        var context = new resolveContext_1.ResolveContext([parentNode, node]);
-	        context.addResolvables(stateBuilder_1.resolvablesBuilder({ resolve: invocables }), node.state);
-	        var resolveData = function (parentLocals) {
-	            var rewrap = function (_locals) { return stateBuilder_1.resolvablesBuilder({ resolve: common_1.map(_locals, function (local) { return function () { return local; }; }) }); };
-	            context.addResolvables(rewrap(parentLocals), parentNode.state);
-	            context.addResolvables(rewrap(locals), node.state);
-	            var tuples2ObjR = function (acc, tuple) {
-	                acc[tuple.token] = tuple.value;
-	                return acc;
-	            };
-	            return context.resolvePath().then(function (results) { return results.reduce(tuples2ObjR, {}); });
-	        };
-	        return parent ? parent.then(resolveData) : resolveData({});
-	    }
-	};
-	/** @hidden */
-	exports.resolveFactory = function () { return $resolve; };
-
-
-/***/ },
-/* 55 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	var common_1 = __webpack_require__(3);
-	var strings_1 = __webpack_require__(9);
-	var view_1 = __webpack_require__(37);
-	var predicates_1 = __webpack_require__(4);
-	var coreservices_1 = __webpack_require__(6);
-	var trace_1 = __webpack_require__(12);
-	var templateFactory_1 = __webpack_require__(56);
-	var resolveContext_1 = __webpack_require__(17);
-	var resolvable_1 = __webpack_require__(19);
-	exports.ng1ViewConfigFactory = function (path, view) { return new Ng1ViewConfig(path, view); };
-	/**
-	 * This is a [[StateBuilder.builder]] function for angular1 `views`.
-	 *
-	 * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder
-	 * handles the `views` property with logic specific to angular-ui-router (ng1).
-	 *
-	 * If no `views: {}` property exists on the [[StateDeclaration]], then it creates the `views` object
-	 * and applies the state-level configuration to a view named `$default`.
-	 */
-	function ng1ViewsBuilder(state) {
-	    var tplKeys = ['templateProvider', 'templateUrl', 'template', 'notify', 'async'], ctrlKeys = ['controller', 'controllerProvider', 'controllerAs', 'resolveAs'], compKeys = ['component', 'bindings'], nonCompKeys = tplKeys.concat(ctrlKeys), allKeys = compKeys.concat(nonCompKeys);
-	    var views = {}, viewsObject = state.views || { "$default": common_1.pick(state, allKeys) };
-	    common_1.forEach(viewsObject, function (config, name) {
-	        // Account for views: { "": { template... } }
-	        name = name || "$default";
-	        // Account for views: { header: "headerComponent" }
-	        if (predicates_1.isString(config))
-	            config = { component: config };
-	        if (!Object.keys(config).length)
-	            return;
-	        // Configure this view for routing to an angular 1.5+ style .component (or any directive, really)
-	        if (config.component) {
-	            if (nonCompKeys.map(function (key) { return predicates_1.isDefined(config[key]); }).reduce(common_1.anyTrueR, false)) {
-	                throw new Error("Cannot combine: " + compKeys.join("|") + " with: " + nonCompKeys.join("|") + " in stateview: 'name@" + state.name + "'");
-	            }
-	            // Dynamically build a template like "<component-name input1='::$resolve.foo'></component-name>"
-	            config.templateProvider = ['$injector', function ($injector) {
-	                    var resolveFor = function (key) { return config.bindings && config.bindings[key] || key; };
-	                    var prefix = angular.version.minor >= 3 ? "::" : "";
-	                    var attributeTpl = function (input) {
-	                        var attrName = strings_1.kebobString(input.name);
-	                        var resolveName = resolveFor(input.name);
-	                        if (input.type === '@')
-	                            return attrName + "='{{" + prefix + "$resolve." + resolveName + "}}'";
-	                        return attrName + "='" + prefix + "$resolve." + resolveName + "'";
-	                    };
-	                    var attrs = getComponentInputs($injector, config.component).map(attributeTpl).join(" ");
-	                    var kebobName = strings_1.kebobString(config.component);
-	                    return "<" + kebobName + " " + attrs + "></" + kebobName + ">";
-	                }];
-	        }
-	        config.resolveAs = config.resolveAs || '$resolve';
-	        config.$type = "ng1";
-	        config.$context = state;
-	        config.$name = name;
-	        var normalized = view_1.ViewService.normalizeUIViewTarget(config.$context, config.$name);
-	        config.$uiViewName = normalized.uiViewName;
-	        config.$uiViewContextAnchor = normalized.uiViewContextAnchor;
-	        views[name] = config;
-	    });
-	    return views;
-	}
-	exports.ng1ViewsBuilder = ng1ViewsBuilder;
-	// for ng 1.2 style, process the scope: { input: "=foo" }
-	// for ng 1.3 through ng 1.5, process the component's bindToController: { input: "=foo" } object
-	var scopeBindings = function (bindingsObj) { return Object.keys(bindingsObj || {})
-	    .map(function (key) { return [key, /^([=<@])[?]?(.*)/.exec(bindingsObj[key])]; }) // [ 'input', [ '=foo', '=', 'foo' ] ]
-	    .filter(function (tuple) { return predicates_1.isDefined(tuple) && predicates_1.isDefined(tuple[1]); }) // skip malformed values
-	    .map(function (tuple) { return ({ name: tuple[1][2] || tuple[0], type: tuple[1][1] }); }); }; // { name: ('foo' || 'input'), type: '=' }
-	// Given a directive definition, find its object input attributes
-	// Use different properties, depending on the type of directive (component, bindToController, normal)
-	var getBindings = function (def) {
-	    if (predicates_1.isObject(def.bindToController))
-	        return scopeBindings(def.bindToController);
-	    return scopeBindings(def.scope);
-	};
-	// Gets all the directive(s)' inputs ('@', '=', and '<')
-	function getComponentInputs($injector, name) {
-	    var cmpDefs = $injector.get(name + "Directive"); // could be multiple
-	    if (!cmpDefs || !cmpDefs.length)
-	        throw new Error("Unable to find component named '" + name + "'");
-	    return cmpDefs.map(getBindings).reduce(common_1.unnestR, []);
-	}
-	var id = 0;
-	var Ng1ViewConfig = (function () {
-	    function Ng1ViewConfig(path, viewDecl) {
-	        this.path = path;
-	        this.viewDecl = viewDecl;
-	        this.$id = id++;
-	        this.loaded = false;
-	    }
-	    Ng1ViewConfig.prototype.load = function () {
-	        var _this = this;
-	        var $q = coreservices_1.services.$q;
-	        if (!this.hasTemplate())
-	            throw new Error("No template configuration specified for '" + this.viewDecl.$uiViewName + "@" + this.viewDecl.$uiViewContextAnchor + "'");
-	        var context = new resolveContext_1.ResolveContext(this.path);
-	        var params = this.path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {});
-	        var promises = {
-	            template: $q.when(this.getTemplate(params, new templateFactory_1.TemplateFactory(), context)),
-	            controller: $q.when(this.getController(context))
-	        };
-	        return $q.all(promises).then(function (results) {
-	            trace_1.trace.traceViewServiceEvent("Loaded", _this);
-	            _this.controller = results.controller;
-	            _this.template = results.template;
-	        });
-	    };
-	    /**
-	     * Checks a view configuration to ensure that it specifies a template.
-	     *
-	     * @return {boolean} Returns `true` if the configuration contains a valid template, otherwise `false`.
-	     */
-	    Ng1ViewConfig.prototype.hasTemplate = function () {
-	        return !!(this.viewDecl.template || this.viewDecl.templateUrl || this.viewDecl.templateProvider);
-	    };
-	    Ng1ViewConfig.prototype.getTemplate = function (params, $factory, context) {
-	        return $factory.fromConfig(this.viewDecl, params, context);
-	    };
-	    /**
-	     * Gets the controller for a view configuration.
-	     *
-	     * @returns {Function|Promise.<Function>} Returns a controller, or a promise that resolves to a controller.
-	     */
-	    Ng1ViewConfig.prototype.getController = function (context) {
-	        var provider = this.viewDecl.controllerProvider;
-	        if (!predicates_1.isInjectable(provider))
-	            return this.viewDecl.controller;
-	        var deps = coreservices_1.services.$injector.annotate(provider);
-	        var providerFn = predicates_1.isArray(provider) ? common_1.tail(provider) : provider;
-	        var resolvable = new resolvable_1.Resolvable("", providerFn, deps);
-	        return resolvable.get(context);
-	    };
-	    return Ng1ViewConfig;
-	}());
-	exports.Ng1ViewConfig = Ng1ViewConfig;
-
-
-/***/ },
-/* 56 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/** @module view */ /** for typedoc */
-	var predicates_1 = __webpack_require__(4);
-	var coreservices_1 = __webpack_require__(6);
-	var common_1 = __webpack_require__(3);
-	var resolvable_1 = __webpack_require__(19);
-	/**
-	 * Service which manages loading of templates from a ViewConfig.
-	 */
-	var TemplateFactory = (function () {
-	    function TemplateFactory() {
-	    }
-	    /**
-	     * Creates a template from a configuration object.
-	     *
-	     * @param config Configuration object for which to load a template.
-	     * The following properties are search in the specified order, and the first one
-	     * that is defined is used to create the template:
-	     *
-	     * @param params  Parameters to pass to the template function.
-	     * @param context The resolve context associated with the template's view
-	     *
-	     * @return {string|object}  The template html as a string, or a promise for
-	     * that string,or `null` if no template is configured.
-	     */
-	    TemplateFactory.prototype.fromConfig = function (config, params, context) {
-	        return (predicates_1.isDefined(config.template) ? this.fromString(config.template, params) :
-	            predicates_1.isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :
-	                predicates_1.isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, context) :
-	                    null);
-	    };
-	    ;
-	    /**
-	     * Creates a template from a string or a function returning a string.
-	     *
-	     * @param template html template as a string or function that returns an html template as a string.
-	     * @param params Parameters to pass to the template function.
-	     *
-	     * @return {string|object} The template html as a string, or a promise for that
-	     * string.
-	     */
-	    TemplateFactory.prototype.fromString = function (template, params) {
-	        return predicates_1.isFunction(template) ? template(params) : template;
-	    };
-	    ;
-	    /**
-	     * Loads a template from the a URL via `$http` and `$templateCache`.
-	     *
-	     * @param {string|Function} url url of the template to load, or a function
-	     * that returns a url.
-	     * @param {Object} params Parameters to pass to the url function.
-	     * @return {string|Promise.<string>} The template html as a string, or a promise
-	     * for that string.
-	     */
-	    TemplateFactory.prototype.fromUrl = function (url, params) {
-	        if (predicates_1.isFunction(url))
-	            url = url(params);
-	        if (url == null)
-	            return null;
-	        return coreservices_1.services.template.get(url);
-	    };
-	    ;
-	    /**
-	     * Creates a template by invoking an injectable provider function.
-	     *
-	     * @param provider Function to invoke via `locals`
-	     * @param {Function} injectFn a function used to invoke the template provider
-	     * @return {string|Promise.<string>} The template html as a string, or a promise
-	     * for that string.
-	     */
-	    TemplateFactory.prototype.fromProvider = function (provider, params, context) {
-	        var deps = coreservices_1.services.$injector.annotate(provider);
-	        var providerFn = predicates_1.isArray(provider) ? common_1.tail(provider) : provider;
-	        var resolvable = new resolvable_1.Resolvable("", providerFn, deps);
-	        return resolvable.get(context);
-	    };
-	    ;
-	    return TemplateFactory;
-	}());
-	exports.TemplateFactory = TemplateFactory;
-
-
-/***/ },
-/* 57 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	var coreservices_1 = __webpack_require__(6);
-	var services_1 = __webpack_require__(53);
-	var resolveContext_1 = __webpack_require__(17);
-	var common_1 = __webpack_require__(3);
-	/**
-	 * This is a [[StateBuilder.builder]] function for angular1 `onEnter`, `onExit`,
-	 * `onRetain` callback hooks on a [[Ng1StateDeclaration]].
-	 *
-	 * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder
-	 * ensures that those hooks are injectable for angular-ui-router (ng1).
-	 */
-	exports.getStateHookBuilder = function (hookName) {
-	    return function stateHookBuilder(state, parentFn) {
-	        var hook = state[hookName];
-	        function decoratedNg1Hook(trans, state) {
-	            var resolveContext = new resolveContext_1.ResolveContext(trans.treeChanges().to);
-	            return coreservices_1.services.$injector.invoke(hook, this, common_1.extend({ $state$: state }, services_1.getLocals(resolveContext)));
-	        }
-	        return hook ? decoratedNg1Hook : undefined;
-	    };
-	};
-
-
-/***/ },
-/* 58 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	/**
-	 * These are the UI-Router angular 1 directives.
-	 *
-	 * These directives are used in templates to create viewports and navigate to states
-	 *
-	 * @preferred @module ng1_directives
-	 */ /** for typedoc */
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var hof_1 = __webpack_require__(5);
-	/** @hidden */
-	function parseStateRef(ref, current) {
-	    var preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed;
-	    if (preparsed)
-	        ref = current + '(' + preparsed[1] + ')';
-	    parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/);
-	    if (!parsed || parsed.length !== 4)
-	        throw new Error("Invalid state ref '" + ref + "'");
-	    return { state: parsed[1], paramExpr: parsed[3] || null };
-	}
-	/** @hidden */
-	function stateContext(el) {
-	    var $uiView = el.parent().inheritedData('$uiView');
-	    var path = hof_1.parse('$cfg.path')($uiView);
-	    return path ? common_1.tail(path).state.name : undefined;
-	}
-	/** @hidden */
-	function getTypeInfo(el) {
-	    // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
-	    var isSvg = Object.prototype.toString.call(el.prop('href')) === '[object SVGAnimatedString]';
-	    var isForm = el[0].nodeName === "FORM";
-	    return {
-	        attr: isForm ? "action" : (isSvg ? 'xlink:href' : 'href'),
-	        isAnchor: el.prop("tagName").toUpperCase() === "A",
-	        clickable: !isForm
-	    };
-	}
-	/** @hidden */
-	function clickHook(el, $state, $timeout, type, current) {
-	    return function (e) {
-	        var button = e.which || e.button, target = current();
-	        if (!(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || el.attr('target'))) {
-	            // HACK: This is to allow ng-clicks to be processed before the transition is initiated:
-	            var transition = $timeout(function () {
-	                $state.go(target.state, target.params, target.options);
-	            });
-	            e.preventDefault();
-	            // if the state has no URL, ignore one preventDefault from the <a> directive.
-	            var ignorePreventDefaultCount = type.isAnchor && !target.href ? 1 : 0;
-	            e.preventDefault = function () {
-	                if (ignorePreventDefaultCount-- <= 0)
-	                    $timeout.cancel(transition);
-	            };
-	        }
-	    };
-	}
-	/** @hidden */
-	function defaultOpts(el, $state) {
-	    return { relative: stateContext(el) || $state.$current, inherit: true };
-	}
-	/**
-	 * `ui-sref`: A directive for linking to a state
-	 *
-	 * A directive that binds a link (`<a>` tag) to a state.
-	 * If the state has an associated URL, the directive will automatically generate and
-	 * update the `href` attribute via the [[StateService.href]]  method.
-	 * Clicking the link will trigger a state transition with optional parameters.
-	 *
-	 * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be
-	 * handled natively by the browser.
-	 *
-	 * You can also use relative state paths within ui-sref, just like the relative
-	 * paths passed to `$state.go()`.
-	 * You just need to be aware that the path is relative to the state that the link lives in.
-	 * In other words, the state that created the view containing the link.
-	 *
-	 * You can specify options to pass to [[StateService.go]] using the `ui-sref-opts` attribute.
-	 * Options are restricted to `location`, `inherit`, and `reload`.
-	 *
-	 * Here's an example of how you'd use ui-sref and how it would compile.
-	 * If you have the following template:
-	 *
-	 * @example
-	 * ```html
-	 *
-	 * <pre>
-	 * <a ui-sref="home">Home</a> | <a ui-sref="about">About</a> | <a ui-sref="{page: 2}">Next page</a>
-	 *
-	 * <ul>
-	 *     <li ng-repeat="contact in contacts">
-	 *         <a ui-sref="contacts.detail({ id: contact.id })">{{ contact.name }}</a>
-	 *     </li>
-	 * </ul>
-	 * </pre>
-	 * ```
-	 *
-	 * Then the compiled html would be (assuming Html5Mode is off and current state is contacts):
-	 *
-	 * ```html
-	 *
-	 * <pre>
-	 * <a href="#/home" ui-sref="home">Home</a> | <a href="#/about" ui-sref="about">About</a> | <a href="#/contacts?page=2" ui-sref="{page: 2}">Next page</a>
-	 *
-	 * <ul>
-	 *     <li ng-repeat="contact in contacts">
-	 *         <a href="#/contacts/1" ui-sref="contacts.detail({ id: contact.id })">Joe</a>
-	 *     </li>
-	 *     <li ng-repeat="contact in contacts">
-	 *         <a href="#/contacts/2" ui-sref="contacts.detail({ id: contact.id })">Alice</a>
-	 *     </li>
-	 *     <li ng-repeat="contact in contacts">
-	 *         <a href="#/contacts/3" ui-sref="contacts.detail({ id: contact.id })">Bob</a>
-	 *     </li>
-	 * </ul>
-	 *
-	 * <a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
-	 * </pre>
-	 * ```
-	 *
-	 * @param {string} ui-sref 'stateName' can be any valid absolute or relative state
-	 * @param {Object} ui-sref-opts options to pass to [[StateService.go]]
-	 */
-	var uiSref = ['$state', '$timeout',
-	    function $StateRefDirective($state, $timeout) {
-	        return {
-	            restrict: 'A',
-	            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
-	            link: function (scope, element, attrs, uiSrefActive) {
-	                var ref = parseStateRef(attrs.uiSref, $state.current.name);
-	                var def = { state: ref.state, href: null, params: null, options: null };
-	                var type = getTypeInfo(element);
-	                var active = uiSrefActive[1] || uiSrefActive[0];
-	                var unlinkInfoFn = null;
-	                def.options = common_1.extend(defaultOpts(element, $state), attrs.uiSrefOpts ? scope.$eval(attrs.uiSrefOpts) : {});
-	                var update = function (val) {
-	                    if (val)
-	                        def.params = angular.copy(val);
-	                    def.href = $state.href(ref.state, def.params, def.options);
-	                    if (unlinkInfoFn)
-	                        unlinkInfoFn();
-	                    if (active)
-	                        unlinkInfoFn = active.$$addStateInfo(ref.state, def.params);
-	                    if (def.href !== null)
-	                        attrs.$set(type.attr, def.href);
-	                };
-	                if (ref.paramExpr) {
-	                    scope.$watch(ref.paramExpr, function (val) { if (val !== def.params)
-	                        update(val); }, true);
-	                    def.params = angular.copy(scope.$eval(ref.paramExpr));
-	                }
-	                update();
-	                if (!type.clickable)
-	                    return;
-	                element.bind("click", clickHook(element, $state, $timeout, type, function () { return def; }));
-	            }
-	        };
-	    }];
-	/**
-	 * `ui-state`: A dynamic version of `ui-sref`
-	 *
-	 * Much like ui-sref, but will accept named $scope properties to evaluate for a state definition,
-	 * params and override options.
-	 *
-	 * @example
-	 * ```html
-	 *
-	 * <li ng-repeat="nav in navlinks">
-	 *   <a ui-state="nav.statename">{{nav.description}}</a>
-	 * </li>
-	 *
-	 * @param {string} ui-state 'stateName' can be any valid absolute or relative state
-	 * @param {Object} ui-state-params params to pass to [[StateService.href]]
-	 * @param {Object} ui-state-opts options to pass to [[StateService.go]]
-	 */
-	var uiState = ['$state', '$timeout',
-	    function $StateRefDynamicDirective($state, $timeout) {
-	        return {
-	            restrict: 'A',
-	            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
-	            link: function (scope, element, attrs, uiSrefActive) {
-	                var type = getTypeInfo(element);
-	                var active = uiSrefActive[1] || uiSrefActive[0];
-	                var group = [attrs.uiState, attrs.uiStateParams || null, attrs.uiStateOpts || null];
-	                var watch = '[' + group.map(function (val) { return val || 'null'; }).join(', ') + ']';
-	                var def = { state: null, params: null, options: null, href: null };
-	                var unlinkInfoFn = null;
-	                function runStateRefLink(group) {
-	                    def.state = group[0];
-	                    def.params = group[1];
-	                    def.options = group[2];
-	                    def.href = $state.href(def.state, def.params, def.options);
-	                    if (unlinkInfoFn)
-	                        unlinkInfoFn();
-	                    if (active)
-	                        unlinkInfoFn = active.$$addStateInfo(def.state, def.params);
-	                    if (def.href)
-	                        attrs.$set(type.attr, def.href);
-	                }
-	                scope.$watch(watch, runStateRefLink, true);
-	                runStateRefLink(scope.$eval(watch));
-	                if (!type.clickable)
-	                    return;
-	                element.bind("click", clickHook(element, $state, $timeout, type, function () { return def; }));
-	            }
-	        };
-	    }];
-	/**
-	 * `ui-sref-active` and `ui-sref-active-eq`: A directive that adds a CSS class when a `ui-sref` is active
-	 *
-	 * A directive working alongside ui-sref to add classes to an element when the
-	 * related ui-sref directive's state is active, and removing them when it is inactive.
-	 * The primary use-case is to simplify the special appearance of navigation menus
-	 * relying on `ui-sref`, by having the "active" state's menu button appear different,
-	 * distinguishing it from the inactive menu items.
-	 *
-	 * ui-sref-active can live on the same element as ui-sref or on a parent element. The first
-	 * ui-sref-active found at the same level or above the ui-sref will be used.
-	 *
-	 * Will activate when the ui-sref's target state or any child state is active. If you
-	 * need to activate only when the ui-sref target state is active and *not* any of
-	 * it's children, then you will use ui-sref-active-eq
-	 *
-	 * Given the following template:
-	 * @example
-	 * ```html
-	 *
-	 * <pre>
-	 * <ul>
-	 *   <li ui-sref-active="active" class="item">
-	 *     <a href ui-sref="app.user({user: 'bilbobaggins'})">@bilbobaggins</a>
-	 *   </li>
-	 * </ul>
-	 * </pre>
-	 * ```
-	 *
-	 *
-	 * When the app state is "app.user" (or any children states), and contains the state parameter "user" with value "bilbobaggins",
-	 * the resulting HTML will appear as (note the 'active' class):
-	 *
-	 * ```html
-	 *
-	 * <pre>
-	 * <ul>
-	 *   <li ui-sref-active="active" class="item active">
-	 *     <a ui-sref="app.user({user: 'bilbobaggins'})" href="/users/bilbobaggins">@bilbobaggins</a>
-	 *   </li>
-	 * </ul>
-	 * </pre>
-	 * ```
-	 *
-	 * The class name is interpolated **once** during the directives link time (any further changes to the
-	 * interpolated value are ignored).
-	 *
-	 * Multiple classes may be specified in a space-separated format:
-	 *
-	 * ```html
-	 * <pre>
-	 * <ul>
-	 *   <li ui-sref-active='class1 class2 class3'>
-	 *     <a ui-sref="app.user">link</a>
-	 *   </li>
-	 * </ul>
-	 * </pre>
-	 * ```
-	 *
-	 * It is also possible to pass ui-sref-active an expression that evaluates
-	 * to an object hash, whose keys represent active class names and whose
-	 * values represent the respective state names/globs.
-	 * ui-sref-active will match if the current active state **includes** any of
-	 * the specified state names/globs, even the abstract ones.
-	 *
-	 * Given the following template, with "admin" being an abstract state:
-	 * @example
-	 * ```html
-	 *
-	 * <pre>
-	 * <div ui-sref-active="{'active': 'admin.*'}">
-	 *   <a ui-sref-active="active" ui-sref="admin.roles">Roles</a>
-	 * </div>
-	 * </pre>
-	 * ```
-	 *
-	 * When the current state is "admin.roles" the "active" class will be applied
-	 * to both the <div> and <a> elements. It is important to note that the state
-	 * names/globs passed to ui-sref-active shadow the state provided by ui-sref.
-	 */
-	var uiSrefActive = ['$state', '$stateParams', '$interpolate', '$transitions',
-	    function $StateRefActiveDirective($state, $stateParams, $interpolate, $transitions) {
-	        return {
-	            restrict: "A",
-	            controller: ['$scope', '$element', '$attrs', '$timeout', function ($scope, $element, $attrs, $timeout) {
-	                    var states = [], activeClasses = {}, activeEqClass, uiSrefActive;
-	                    // There probably isn't much point in $observing this
-	                    // uiSrefActive and uiSrefActiveEq share the same directive object with some
-	                    // slight difference in logic routing
-	                    activeEqClass = $interpolate($attrs.uiSrefActiveEq || '', false)($scope);
-	                    try {
-	                        uiSrefActive = $scope.$eval($attrs.uiSrefActive);
-	                    }
-	                    catch (e) {
-	                    }
-	                    uiSrefActive = uiSrefActive || $interpolate($attrs.uiSrefActive || '', false)($scope);
-	                    if (predicates_1.isObject(uiSrefActive)) {
-	                        common_1.forEach(uiSrefActive, function (stateOrName, activeClass) {
-	                            if (predicates_1.isString(stateOrName)) {
-	                                var ref = parseStateRef(stateOrName, $state.current.name);
-	                                addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);
-	                            }
-	                        });
-	                    }
-	                    // Allow uiSref to communicate with uiSrefActive[Equals]
-	                    this.$$addStateInfo = function (newState, newParams) {
-	                        // we already got an explicit state provided by ui-sref-active, so we
-	                        // shadow the one that comes from ui-sref
-	                        if (predicates_1.isObject(uiSrefActive) && states.length > 0) {
-	                            return;
-	                        }
-	                        var deregister = addState(newState, newParams, uiSrefActive);
-	                        update();
-	                        return deregister;
-	                    };
-	                    $scope.$on('$stateChangeSuccess', update);
-	                    $scope.$on('$destroy', $transitions.onStart({}, function (trans) { return trans.promise.then(update) && null; }));
-	                    function addState(stateName, stateParams, activeClass) {
-	                        var state = $state.get(stateName, stateContext($element));
-	                        var stateHash = createStateHash(stateName, stateParams);
-	                        var stateInfo = {
-	                            state: state || { name: stateName },
-	                            params: stateParams,
-	                            hash: stateHash
-	                        };
-	                        states.push(stateInfo);
-	                        activeClasses[stateHash] = activeClass;
-	                        return function removeState() {
-	                            var idx = states.indexOf(stateInfo);
-	                            if (idx !== -1)
-	                                states.splice(idx, 1);
-	                        };
-	                    }
-	                    /**
-	                     * @param {string} state
-	                     * @param {Object|string} [params]
-	                     * @return {string}
-	                     */
-	                    function createStateHash(state, params) {
-	                        if (!predicates_1.isString(state)) {
-	                            throw new Error('state should be a string');
-	                        }
-	                        if (predicates_1.isObject(params)) {
-	                            return state + common_1.toJson(params);
-	                        }
-	                        params = $scope.$eval(params);
-	                        if (predicates_1.isObject(params)) {
-	                            return state + common_1.toJson(params);
-	                        }
-	                        return state;
-	                    }
-	                    // Update route state
-	                    function update() {
-	                        for (var i = 0; i < states.length; i++) {
-	                            if (anyMatch(states[i].state, states[i].params)) {
-	                                addClass($element, activeClasses[states[i].hash]);
-	                            }
-	                            else {
-	                                removeClass($element, activeClasses[states[i].hash]);
-	                            }
-	                            if (exactMatch(states[i].state, states[i].params)) {
-	                                addClass($element, activeEqClass);
-	                            }
-	                            else {
-	                                removeClass($element, activeEqClass);
-	                            }
-	                        }
-	                    }
-	                    function addClass(el, className) { $timeout(function () { el.addClass(className); }); }
-	                    function removeClass(el, className) { el.removeClass(className); }
-	                    function anyMatch(state, params) { return $state.includes(state.name, params); }
-	                    function exactMatch(state, params) { return $state.is(state.name, params); }
-	                    update();
-	                }]
-	        };
-	    }];
-	angular.module('ui.router.state')
-	    .directive('uiSref', uiSref)
-	    .directive('uiSrefActive', uiSrefActive)
-	    .directive('uiSrefActiveEq', uiSrefActive)
-	    .directive('uiState', uiState);
-
-
-/***/ },
-/* 59 */
-/***/ function(module, exports) {
-
-	/** @module state */ /** for typedoc */
-	"use strict";
-	/**
-	 * @ngdoc filter
-	 * @name ui.router.state.filter:isState
-	 *
-	 * @requires ui.router.state.$state
-	 *
-	 * @description
-	 * Translates to {@link ui.router.state.$state#methods_is $state.is("stateName")}.
-	 */
-	$IsStateFilter.$inject = ['$state'];
-	function $IsStateFilter($state) {
-	    var isFilter = function (state, params, options) {
-	        return $state.is(state, params, options);
-	    };
-	    isFilter.$stateful = true;
-	    return isFilter;
-	}
-	exports.$IsStateFilter = $IsStateFilter;
-	/**
-	 * @ngdoc filter
-	 * @name ui.router.state.filter:includedByState
-	 *
-	 * @requires ui.router.state.$state
-	 *
-	 * @description
-	 * Translates to {@link ui.router.state.$state#methods_includes $state.includes('fullOrPartialStateName')}.
-	 */
-	$IncludedByStateFilter.$inject = ['$state'];
-	function $IncludedByStateFilter($state) {
-	    var includesFilter = function (state, params, options) {
-	        return $state.includes(state, params, options);
-	    };
-	    includesFilter.$stateful = true;
-	    return includesFilter;
-	}
-	exports.$IncludedByStateFilter = $IncludedByStateFilter;
-	angular.module('ui.router.state')
-	    .filter('isState', $IsStateFilter)
-	    .filter('includedByState', $IncludedByStateFilter);
-
-
-/***/ },
-/* 60 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/** @module ng1_directives */ /** for typedoc */
-	"use strict";
-	var common_1 = __webpack_require__(3);
-	var predicates_1 = __webpack_require__(4);
-	var trace_1 = __webpack_require__(12);
-	var views_1 = __webpack_require__(55);
-	var hof_1 = __webpack_require__(5);
-	var resolveContext_1 = __webpack_require__(17);
-	var strings_1 = __webpack_require__(9);
-	var services_1 = __webpack_require__(53);
-	/**
-	 * `ui-view`: A viewport directive which is filled in by a view from the active state.
-	 *
-	 * @param {string=} name A view name. The name should be unique amongst the other views in the
-	 * same state. You can have views of the same name that live in different states.
-	 *
-	 * @param {string=} autoscroll It allows you to set the scroll behavior of the browser window
-	 * when a view is populated. By default, $anchorScroll is overridden by ui-router's custom scroll
-	 * service, {@link ui.router.state.$uiViewScroll}. This custom service let's you
-	 * scroll ui-view elements into view when they are populated during a state activation.
-	 *
-	 * *Note: To revert back to old [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll)
-	 * functionality, call `$uiViewScrollProvider.useAnchorScroll()`.*
-	 *
-	 * @param {string=} onload Expression to evaluate whenever the view updates.
-	 *
-	 * A view can be unnamed or named.
-	 * @example
-	 * ```html
-	 *
-	 * <!-- Unnamed -->
-	 * <div ui-view></div>
-	 *
-	 * <!-- Named -->
-	 * <div ui-view="viewName"></div>
-	 * ```
-	 *
-	 * You can only have one unnamed view within any template (or root html). If you are only using a
-	 * single view and it is unnamed then you can populate it like so:
-	 * ```
-	 *
-	 * <div ui-view></div>
-	 * $stateProvider.state("home", {
-	 *   template: "<h1>HELLO!</h1>"
-	 * })
-	 * ```
-	 *
-	 * The above is a convenient shortcut equivalent to specifying your view explicitly with the {@link ui.router.state.$stateProvider#views `views`}
-	 * config property, by name, in this case an empty name:
-	 * ```js
-	 *
-	 * $stateProvider.state("home", {
-	 *   views: {
-	 *     "": {
-	 *       template: "<h1>HELLO!</h1>"
-	 *     }
-	 *   }
-	 * })
-	 * ```
-	 *
-	 * But typically you'll only use the views property if you name your view or have more than one view
-	 * in the same template. There's not really a compelling reason to name a view if its the only one,
-	 * but you could if you wanted, like so:
-	 *
-	 * ```html
-	 *
-	 * <div ui-view="main"></div>
-	 * ```
-	 *
-	 * ```js
-	 *
-	 * $stateProvider.state("home", {
-	 *   views: {
-	 *     "main": {
-	 *       template: "<h1>HELLO!</h1>"
-	 *     }
-	 *   }
-	 * })
-	 * ```
-	 *
-	 * Really though, you'll use views to set up multiple views:
-	 * ```html
-	 *
-	 * <div ui-view></div>
-	 * <div ui-view="chart"></div>
-	 * <div ui-view="data"></div>
-	 * ```
-	 *
-	 * ```js
-	 * $stateProvider.state("home", {
-	 *   views: {
-	 *     "": {
-	 *       template: "<h1>HELLO!</h1>"
-	 *     },
-	 *     "chart": {
-	 *       template: "<chart_thing/>"
-	 *     },
-	 *     "data": {
-	 *       template: "<data_thing/>"
-	 *     }
-	 *   }
-	 * })
-	 * ```
-	 *
-	 * Examples for `autoscroll`:
-	 *
-	 * ```html
-	 *
-	 * <!-- If autoscroll present with no expression,
-	 *      then scroll ui-view into view -->
-	 * <ui-view autoscroll/>
-	 *
-	 * <!-- If autoscroll present with valid expression,
-	 *      then scroll ui-view into view if expression evaluates to true -->
-	 * <ui-view autoscroll='true'/>
-	 * <ui-view autoscroll='false'/>
-	 * <ui-view autoscroll='scopeVariable'/>
-	 * ```
-	 *
-	 * Resolve data:
-	 *
-	 * The resolved data from the state's `resolve` block is placed on the scope as `$resolve` (this
-	 * can be customized using [[ViewDeclaration.resolveAs]]).  This can be then accessed from the template.
-	 *
-	 * Note that when `controllerAs` is being used, `$resolve` is set on the controller instance *after* the
-	 * controller is instantiated.  The `$onInit()` hook can be used to perform initialization code which
-	 * depends on `$resolve` data.
-	 *
-	 * @example
-	 * ```js
-	 *
-	 * $stateProvider.state('home', {
-	 *   template: '<my-component user="$resolve.user"></my-component>',
-	 *   resolve: {
-	 *     user: function(UserService) { return UserService.fetchUser(); }
-	 *   }
-	 * });
-	 * ```
-	 */
-	var uiView = ['$view', '$animate', '$uiViewScroll', '$interpolate', '$q',
-	    function $ViewDirective($view, $animate, $uiViewScroll, $interpolate, $q) {
-	        function getRenderer(attrs, scope) {
-	            return {
-	                enter: function (element, target, cb) {
-	                    if (angular.version.minor > 2) {
-	                        $animate.enter(element, null, target).then(cb);
-	                    }
-	                    else {
-	                        $animate.enter(element, null, target, cb);
-	                    }
-	                },
-	                leave: function (element, cb) {
-	                    if (angular.version.minor > 2) {
-	                        $animate.leave(element).then(cb);
-	                    }
-	                    else {
-	                        $animate.leave(element, cb);
-	                    }
-	                }
-	            };
-	        }
-	        function configsEqual(config1, config2) {
-	            return config1 === config2;
-	        }
-	        var rootData = {
-	            $cfg: { viewDecl: { $context: $view.rootContext() } },
-	            $uiView: {}
-	        };
-	        var directive = {
-	            count: 0,
-	            restrict: 'ECA',
-	            terminal: true,
-	            priority: 400,
-	            transclude: 'element',
-	            compile: function (tElement, tAttrs, $transclude) {
-	                return function (scope, $element, attrs) {
-	                    var previousEl, currentEl, currentScope, unregister, onloadExp = attrs.onload || '', autoScrollExp = attrs.autoscroll, renderer = getRenderer(attrs, scope), viewConfig = undefined, inherited = $element.inheritedData('$uiView') || rootData, name = $interpolate(attrs.uiView || attrs.name || '')(scope) || '$default';
-	                    var activeUIView = {
-	                        $type: 'ng1',
-	                        id: directive.count++,
-	                        name: name,
-	                        fqn: inherited.$uiView.fqn ? inherited.$uiView.fqn + "." + name : name,
-	                        config: null,
-	                        configUpdated: configUpdatedCallback,
-	                        get creationContext() {
-	                            return hof_1.parse('$cfg.viewDecl.$context')(inherited);
-	                        }
-	                    };
-	                    trace_1.trace.traceUIViewEvent("Linking", activeUIView);
-	                    function configUpdatedCallback(config) {
-	                        if (config && !(config instanceof views_1.Ng1ViewConfig))
-	                            return;
-	                        if (configsEqual(viewConfig, config))
-	                            return;
-	                        trace_1.trace.traceUIViewConfigUpdated(activeUIView, config && config.viewDecl && config.viewDecl.$context);
-	                        viewConfig = config;
-	                        updateView(config);
-	                    }
-	                    $element.data('$uiView', { $uiView: activeUIView });
-	                    updateView();
-	                    unregister = $view.registerUIView(activeUIView);
-	                    scope.$on("$destroy", function () {
-	                        trace_1.trace.traceUIViewEvent("Destroying/Unregistering", activeUIView);
-	                        unregister();
-	                    });
-	                    function cleanupLastView() {
-	                        if (previousEl) {
-	                            trace_1.trace.traceUIViewEvent("Removing (previous) el", previousEl.data('$uiView'));
-	                            previousEl.remove();
-	                            previousEl = null;
-	                        }
-	                        if (currentScope) {
-	                            trace_1.trace.traceUIViewEvent("Destroying scope", activeUIView);
-	                            currentScope.$destroy();
-	                            currentScope = null;
-	                        }
-	                        if (currentEl) {
-	                            var _viewData_1 = currentEl.data('$uiView');
-	                            trace_1.trace.traceUIViewEvent("Animate out", _viewData_1);
-	                            renderer.leave(currentEl, function () {
-	                                _viewData_1.$$animLeave.resolve();
-	                                previousEl = null;
-	                            });
-	                            previousEl = currentEl;
-	                            currentEl = null;
-	                        }
-	                    }
-	                    function updateView(config) {
-	                        var newScope = scope.$new();
-	                        trace_1.trace.traceUIViewScopeCreated(activeUIView, newScope);
-	                        var animEnter = $q.defer(), animLeave = $q.defer();
-	                        var $uiViewData = {
-	                            $cfg: config,
-	                            $uiView: activeUIView,
-	                            $animEnter: animEnter.promise,
-	                            $animLeave: animLeave.promise,
-	                            $$animLeave: animLeave
-	                        };
-	                        var cloned = $transclude(newScope, function (clone) {
-	                            renderer.enter(clone.data('$uiView', $uiViewData), $element, function onUIViewEnter() {
-	                                animEnter.resolve();
-	                                if (currentScope)
-	                                    currentScope.$emit('$viewContentAnimationEnded');
-	                                if (predicates_1.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) {
-	                                    $uiViewScroll(clone);
-	                                }
-	                            });
-	                            cleanupLastView();
-	                        });
-	                        currentEl = cloned;
-	                        currentScope = newScope;
-	                        /**
-	                         * @ngdoc event
-	                         * @name ui.router.state.directive:ui-view#$viewContentLoaded
-	                         * @eventOf ui.router.state.directive:ui-view
-	                         * @eventType emits on ui-view directive scope
-	                         * @description           *
-	                         * Fired once the view is **loaded**, *after* the DOM is rendered.
-	                         *
-	                         * @param {Object} event Event object.
-	                         */
-	                        currentScope.$emit('$viewContentLoaded', config || viewConfig);
-	                        currentScope.$eval(onloadExp);
-	                    }
-	                };
-	            }
-	        };
-	        return directive;
-	    }];
-	$ViewDirectiveFill.$inject = ['$compile', '$controller', '$transitions', '$view', '$timeout'];
-	/** @hidden */
-	function $ViewDirectiveFill($compile, $controller, $transitions, $view, $timeout) {
-	    var getControllerAs = hof_1.parse('viewDecl.controllerAs');
-	    var getResolveAs = hof_1.parse('viewDecl.resolveAs');
-	    return {
-	        restrict: 'ECA',
-	        priority: -400,
-	        compile: function (tElement) {
-	            var initial = tElement.html();
-	            return function (scope, $element) {
-	                var data = $element.data('$uiView');
-	                if (!data)
-	                    return;
-	                var cfg = data.$cfg || { viewDecl: {} };
-	                $element.html(cfg.template || initial);
-	                trace_1.trace.traceUIViewFill(data.$uiView, $element.html());
-	                var link = $compile($element.contents());
-	                var controller = cfg.controller;
-	                var controllerAs = getControllerAs(cfg);
-	                var resolveAs = getResolveAs(cfg);
-	                var resolveCtx = cfg.path && new resolveContext_1.ResolveContext(cfg.path);
-	                var locals = resolveCtx && services_1.getLocals(resolveCtx);
-	                scope[resolveAs] = locals;
-	                if (controller) {
-	                    var controllerInstance = $controller(controller, common_1.extend({}, locals, { $scope: scope, $element: $element }));
-	                    if (controllerAs) {
-	                        scope[controllerAs] = controllerInstance;
-	                        scope[controllerAs][resolveAs] = locals;
-	                    }
-	                    // TODO: Use $view service as a central point for registering component-level hooks
-	                    // Then, when a component is created, tell the $view service, so it can invoke hooks
-	                    // $view.componentLoaded(controllerInstance, { $scope: scope, $element: $element });
-	                    // scope.$on('$destroy', () => $view.componentUnloaded(controllerInstance, { $scope: scope, $element: $element }));
-	                    $element.data('$ngControllerController', controllerInstance);
-	                    $element.children().data('$ngControllerController', controllerInstance);
-	                    registerControllerCallbacks($transitions, controllerInstance, scope, cfg);
-	                }
-	                // Wait for the component to appear in the DOM
-	                if (predicates_1.isString(cfg.viewDecl.component)) {
-	                    var cmp_1 = cfg.viewDecl.component;
-	                    var kebobName_1 = strings_1.kebobString(cmp_1);
-	                    var getComponentController = function () {
-	                        var directiveEl = [].slice.call($element[0].children)
-	                            .filter(function (el) { return el && el.tagName && el.tagName.toLowerCase() === kebobName_1; });
-	                        return directiveEl && angular.element(directiveEl).data("$" + cmp_1 + "Controller");
-	                    };
-	                    var deregisterWatch_1 = scope.$watch(getComponentController, function (ctrlInstance) {
-	                        if (!ctrlInstance)
-	                            return;
-	                        registerControllerCallbacks($transitions, ctrlInstance, scope, cfg);
-	                        deregisterWatch_1();
-	                    });
-	                }
-	                link(scope);
-	            };
-	        }
-	    };
-	}
-	/** @hidden */
-	var hasComponentImpl = typeof angular.module('ui.router')['component'] === 'function';
-	/** @hidden TODO: move these callbacks to $view and/or `/hooks/components.ts` or something */
-	function registerControllerCallbacks($transitions, controllerInstance, $scope, cfg) {
-	    // Call $onInit() ASAP
-	    if (predicates_1.isFunction(controllerInstance.$onInit) && !(cfg.viewDecl.component && hasComponentImpl))
-	        controllerInstance.$onInit();
-	    var viewState = common_1.tail(cfg.path).state.self;
-	    var hookOptions = { bind: controllerInstance };
-	    // Add component-level hook for onParamsChange
-	    if (predicates_1.isFunction(controllerInstance.uiOnParamsChanged)) {
-	        var resolveContext = new resolveContext_1.ResolveContext(cfg.path);
-	        var viewCreationTrans_1 = resolveContext.getResolvable('$transition$').data;
-	        // Fire callback on any successful transition
-	        var paramsUpdated = function ($transition$) {
-	            // Exit early if the $transition$ is the same as the view was created within.
-	            // Exit early if the $transition$ will exit the state the view is for.
-	            if ($transition$ === viewCreationTrans_1 || $transition$.exiting().indexOf(viewState) !== -1)
-	                return;
-	            var toParams = $transition$.params("to");
-	            var fromParams = $transition$.params("from");
-	            var toSchema = $transition$.treeChanges().to.map(function (node) { return node.paramSchema; }).reduce(common_1.unnestR, []);
-	            var fromSchema = $transition$.treeChanges().from.map(function (node) { return node.paramSchema; }).reduce(common_1.unnestR, []);
-	            // Find the to params that have different values than the from params
-	            var changedToParams = toSchema.filter(function (param) {
-	                var idx = fromSchema.indexOf(param);
-	                return idx === -1 || !fromSchema[idx].type.equals(toParams[param.id], fromParams[param.id]);
-	            });
-	            // Only trigger callback if a to param has changed or is new
-	            if (changedToParams.length) {
-	                var changedKeys_1 = changedToParams.map(function (x) { return x.id; });
-	                // Filter the params to only changed/new to params.  `$transition$.params()` may be used to get all params.
-	                controllerInstance.uiOnParamsChanged(common_1.filter(toParams, function (val, key) { return changedKeys_1.indexOf(key) !== -1; }), $transition$);
-	            }
-	        };
-	        $scope.$on('$destroy', $transitions.onSuccess({}, paramsUpdated, hookOptions));
-	    }
-	    // Add component-level hook for uiCanExit
-	    if (predicates_1.isFunction(controllerInstance.uiCanExit)) {
-	        var criteria = { exiting: viewState.name };
-	        $scope.$on('$destroy', $transitions.onBefore(criteria, controllerInstance.uiCanExit, hookOptions));
-	    }
-	}
-	angular.module('ui.router.state').directive('uiView', uiView);
-	angular.module('ui.router.state').directive('uiView', $ViewDirectiveFill);
-
-
-/***/ },
-/* 61 */
-/***/ function(module, exports) {
-
-	"use strict";
-	/**
-	 * @ngdoc object
-	 * @name ui.router.state.$uiViewScrollProvider
-	 *
-	 * @description
-	 * Provider that returns the {@link ui.router.state.$uiViewScroll} service function.
-	 */
-	function $ViewScrollProvider() {
-	    var useAnchorScroll = false;
-	    /**
-	     * @ngdoc function
-	     * @name ui.router.state.$uiViewScrollProvider#useAnchorScroll
-	     * @methodOf ui.router.state.$uiViewScrollProvider
-	     *
-	     * @description
-	     * Reverts back to using the core [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll) service for
-	     * scrolling based on the url anchor.
-	     */
-	    this.useAnchorScroll = function () {
-	        useAnchorScroll = true;
-	    };
-	    /**
-	     * @ngdoc object
-	     * @name ui.router.state.$uiViewScroll
-	     *
-	     * @requires $anchorScroll
-	     * @requires $timeout
-	     *
-	     * @description
-	     * When called with a jqLite element, it scrolls the element into view (after a
-	     * `$timeout` so the DOM has time to refresh).
-	     *
-	     * If you prefer to rely on `$anchorScroll` to scroll the view to the anchor,
-	     * this can be enabled by calling {@link ui.router.state.$uiViewScrollProvider#methods_useAnchorScroll `$uiViewScrollProvider.useAnchorScroll()`}.
-	     */
-	    this.$get = ['$anchorScroll', '$timeout', function ($anchorScroll, $timeout) {
-	            if (useAnchorScroll) {
-	                return $anchorScroll;
-	            }
-	            return function ($element) {
-	                return $timeout(function () {
-	                    $element[0].scrollIntoView();
-	                }, 0, false);
-	            };
-	        }];
-	}
-	angular.module('ui.router.state').provider('$uiViewScroll', $ViewScrollProvider);
-
-
-/***/ }
-/******/ ])
-});
-;
-//# sourceMappingURL=angular-ui-router.js.map
-
-/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
-"use strict";
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-"use strict";
-exports.__esModule = true;
-var self;
-var ElineSide = (function () {
-    function ElineSide(XosSidePanel, XosModelStore, $http, $log, toastr) {
-        this.XosSidePanel = XosSidePanel;
-        this.XosModelStore = XosModelStore;
-        this.$http = $http;
-        this.$log = $log;
-        this.toastr = toastr;
-        self = this;
-    }
-    ElineSide.prototype.saveEline = function (item) {
-        var _this = this;
-        var path = item.path;
-        delete item.path;
-        item.$save().then(function (res) {
-            item.path = path;
-            _this.toastr.success(item.name + " successfully saved!");
-        })["catch"](function (error) {
-            _this.toastr.error("Error while saving " + item.name + ": " + error.specific_error);
-        });
-    };
-    ElineSide.prototype.deleteEline = function (item) {
-        var _this = this;
-        var name = item.name;
-        item.$delete().then(function (res) {
-            _this.toastr.success(name + " successfully deleted!");
-        })["catch"](function (error) {
-            _this.toastr.error("Error while deleting " + name + ": " + error.specific_error);
-        });
-    };
-    return ElineSide;
-}());
-ElineSide.$inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];
-exports.elineSide = {
-    template: __webpack_require__(11),
-    controllerAs: 'vm',
-    controller: ElineSide,
-    bindings: {
-        eng: '='
-    }
-};
-
-
-/***/ },
-/* 5 */
-/***/ function(module, exports, __webpack_require__) {
-
-"use strict";
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-"use strict";
-exports.__esModule = true;
-var _ = __webpack_require__(13);
-var self;
-var EngMap = (function () {
-    function EngMap(NgMap, XosModelStore, AppConfig, $resource, XosSidePanel, XosModelDiscoverer, ModelRest, MapConfig) {
-        this.NgMap = NgMap;
-        this.XosModelStore = XosModelStore;
-        this.AppConfig = AppConfig;
-        this.$resource = $resource;
-        this.XosSidePanel = XosSidePanel;
-        this.XosModelDiscoverer = XosModelDiscoverer;
-        this.ModelRest = ModelRest;
-        this.MapConfig = MapConfig;
-        this.unis = [];
-        this.elines = [];
-        this.cpilatlng = new Map();
-        this.paths = [];
-        this.bwps = [];
-        this.panelOpen = false;
-        this.createMode = false;
-        this.canCreateEline = true;
-        this.mapStyles = [{ 'featureType': 'administrative', 'elementType': 'labels.text.fill', 'stylers': [{ 'color': '#444444' }] }, { 'featureType': 'landscape', 'elementType': 'all', 'stylers': [{ 'color': '#f2f2f2' }] }, { 'featureType': 'poi', 'elementType': 'all', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'road', 'elementType': 'all', 'stylers': [{ 'saturation': -100 }, { 'lightness': 45 }] }, { 'featureType': 'road.highway', 'elementType': 'all', 'stylers': [{ 'visibility': 'simplified' }] }, { 'featureType': 'road.arterial', 'elementType': 'labels.icon', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'transit', 'elementType': 'all', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'water', 'elementType': 'all', 'stylers': [{ 'color': '#9ce1fc' }, { 'visibility': 'on' }] }];
-        self = this;
-    }
-    EngMap.prototype.$onInit = function () {
-        var _this = this;
-        this.NgMap.getMap().then(function (map) {
-            _this.map = map;
-            _this.uniSubscription = _this.XosModelStore.query('UserNetworkInterface', '/vnaas/usernetworkinterfaces/').subscribe(function (res) {
-                _this.unis = res;
-                _this.renderMap(map);
-            });
-            _this.elineSubscription = _this.XosModelStore.query('ELine', '/vnaas/elines/').subscribe(function (res) {
-                _this.elines = res;
-                _this.createPaths();
-                _this.renderMap(map);
-            });
-            _this.bwpSubscription = _this.XosModelStore.query('BandwidthProfile', '/vnaas/bandwidthprofiles/').subscribe(function (res) {
-                _this.bwps = res;
-            });
-        });
-    };
-    EngMap.prototype.$onDestroy = function () {
-        if (this.uniSubscription) {
-            this.uniSubscription.unsubscribe();
-        }
-    };
-    EngMap.prototype.renderMap = function (map) {
-        var bounds = new google.maps.LatLngBounds();
-        for (var i = 0; i < self.unis.length; i++) {
-            self.unis[i].eline_start = false;
-            var curr = JSON.parse(self.unis[i].latlng);
-            this.cpilatlng.set(self.unis[i].cpe_id, curr);
-            var latlng = new google.maps.LatLng(curr[0], curr[1]);
-            bounds.extend(latlng);
-        }
-        map.setCenter(bounds.getCenter());
-        map.fitBounds(bounds);
-    };
-    EngMap.prototype.createPaths = function () {
-        var _this = this;
-        this.elines.forEach(function (eline) {
-            var latlng_start = _this.cpilatlng.get(eline.connect_point_1_id);
-            var latlng_end = _this.cpilatlng.get(eline.connect_point_2_id);
-            eline.path = [latlng_start, latlng_end];
-        });
-    };
-    EngMap.prototype.colorLine = function (eline_status) {
-        var status = parseInt(eline_status, 10);
-        switch (status) {
-            case 0:
-                return '#f39c12';
-            case 1:
-                return '#2ecc71';
-            default:
-                return '#e74c3c';
-        }
-    };
-    EngMap.prototype.showUni = function (e, uni) {
-        self.current_uni = uni;
-        self.map.showInfoWindow('uni-info', this);
-    };
-    // do not display backend status or ID in create mode
-    EngMap.prototype.elinePanel = function (e, eline, exists) {
-        self.panelOpen = !self.panelOpen;
-        if (exists) {
-            self.eline = _.find(self.elines, { id: eline.id });
-        }
-        self.XosSidePanel.toggleComponent('elineSide', { eline: self.eline, bwplist: self.bwps, eng: self }, false);
-        if (!self.panelOpen && self.createMode) {
-            self.createMode = false;
-            self.canCreateEline = true;
-            self.current_uni.eline_start = false;
-        }
-    };
-    EngMap.prototype.createConnection = function (uni) {
-        return function () {
-            self.canCreateEline = false;
-            self.createMode = true;
-            uni.eline_start = true;
-            self.current_uni = uni;
-            self.eline = {
-                name: uni.name,
-                uni1name: uni.name,
-                connect_point_1_id: uni.cpe_id
-            };
-            self.elinePanel({}, self.eline, false);
-        };
-    };
-    EngMap.prototype.finishConnection = function (uni) {
-        self.eline.connect_point_2_id = uni.cpe_id;
-        if (self.eline.name === self.eline.uni1name) {
-            self.eline.name = self.eline.name + uni.name;
-        }
-        delete self.eline.uni1name;
-        var resource = this.ModelRest.getResource('/vnaas/elines/');
-        var res = new resource({});
-        for (var attr in self.eline) {
-            if (true) {
-                res[attr] = self.eline[attr];
-            }
-        }
-        self.eline = res;
-    };
-    return EngMap;
-}());
-EngMap.$inject = [
-    'NgMap',
-    'XosModelStore',
-    'AppConfig',
-    '$resource',
-    'XosSidePanel',
-    'XosModelDiscoverer',
-    'ModelRest',
-    'MapConfig',
-];
-exports.EngMap = EngMap;
-exports.engMap = {
-    template: __webpack_require__(12),
-    controllerAs: 'vm',
-    controller: EngMap
-};
-
-
-/***/ },
-/* 6 */
-/***/ function(module, exports) {
-
-"use strict";
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-"use strict";
-exports.__esModule = true;
-exports["default"] = routesConfig;
-function routesConfig($stateProvider, $locationProvider) {
-    $locationProvider.html5Mode(false).hashPrefix('');
-    $stateProvider
-        .state('xos.vnaasgui', {
-        url: 'vnaasgui',
-        parent: 'xos',
-        component: 'engMap'
-    });
-}
-
-
-/***/ },
-/* 7 */
-/***/ function(module, exports, __webpack_require__) {
-
-(function(root, factory) {
-if (true) {
-module.exports = factory(__webpack_require__(0));
-} else if (typeof define === "function" && define.amd) {
-define(['angular'], factory);
-} else{
-factory(root.angular);
-}
-}(this, function(angular) {
-/**
- * AngularJS Google Maps Ver. 1.18.3
- *
- * The MIT License (MIT)
- * 
- * Copyright (c) 2014, 2015, 1016 Allen Kim
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-angular.module('ngMap', []);
-
-/**
- * @ngdoc controller
- * @name MapController
- */
-(function() {
-  'use strict';
-  var Attr2MapOptions;
-
-  var __MapController = function(
-      $scope, $element, $attrs, $parse, $interpolate, _Attr2MapOptions_, NgMap, NgMapPool, escapeRegExp
-    ) {
-    Attr2MapOptions = _Attr2MapOptions_;
-    var vm = this;
-    var exprStartSymbol = $interpolate.startSymbol();
-    var exprEndSymbol = $interpolate.endSymbol();
-
-    vm.mapOptions; /** @memberof __MapController */
-    vm.mapEvents;  /** @memberof __MapController */
-    vm.eventListeners;  /** @memberof __MapController */
-
-    /**
-     * Add an object to the collection of group
-     * @memberof __MapController
-     * @function addObject
-     * @param groupName the name of collection that object belongs to
-     * @param obj  an object to add into a collection, i.e. marker, shape
-     */
-    vm.addObject = function(groupName, obj) {
-      if (vm.map) {
-        vm.map[groupName] = vm.map[groupName] || {};
-        var len = Object.keys(vm.map[groupName]).length;
-        vm.map[groupName][obj.id || len] = obj;
-
-        if (vm.map instanceof google.maps.Map) {
-          //infoWindow.setMap works like infoWindow.open
-          if (groupName != "infoWindows" && obj.setMap) {
-            obj.setMap && obj.setMap(vm.map);
-          }
-          if (obj.centered && obj.position) {
-            vm.map.setCenter(obj.position);
-          }
-          (groupName == 'markers') && vm.objectChanged('markers');
-          (groupName == 'customMarkers') && vm.objectChanged('customMarkers');
-        }
-      }
-    };
-
-    /**
-     * Delete an object from the collection and remove from map
-     * @memberof __MapController
-     * @function deleteObject
-     * @param {Array} objs the collection of objects. i.e., map.markers
-     * @param {Object} obj the object to be removed. i.e., marker
-     */
-    vm.deleteObject = function(groupName, obj) {
-      /* delete from group */
-      if (obj.map) {
-        var objs = obj.map[groupName];
-        for (var name in objs) {
-          if (objs[name] === obj) {
-            void 0;
-            google.maps.event.clearInstanceListeners(obj);
-            delete objs[name];
-          }
-        }
-
-        /* delete from map */
-        obj.map && obj.setMap && obj.setMap(null);
-
-        (groupName == 'markers') && vm.objectChanged('markers');
-        (groupName == 'customMarkers') && vm.objectChanged('customMarkers');
-      }
-    };
-
-    /**
-     * @memberof __MapController
-     * @function observeAttrSetObj
-     * @param {Hash} orgAttrs attributes before its initialization
-     * @param {Hash} attrs    attributes after its initialization
-     * @param {Object} obj    map object that an action is to be done
-     * @description watch changes of attribute values and
-     * do appropriate action based on attribute name
-     */
-    vm.observeAttrSetObj = function(orgAttrs, attrs, obj) {
-      if (attrs.noWatcher) {
-        return false;
-      }
-      var attrsToObserve = Attr2MapOptions.getAttrsToObserve(orgAttrs);
-      for (var i=0; i<attrsToObserve.length; i++) {
-        var attrName = attrsToObserve[i];
-        attrs.$observe(attrName, NgMap.observeAndSet(attrName, obj));
-      }
-    };
-
-    /**
-     * @memberof __MapController
-     * @function zoomToIncludeMarkers
-     */
-    vm.zoomToIncludeMarkers = function() {
-      // Only fit to bounds if we have any markers
-      // object.keys is supported in all major browsers (IE9+)
-      if ((vm.map.markers != null && Object.keys(vm.map.markers).length > 0) || (vm.map.customMarkers != null && Object.keys(vm.map.customMarkers).length > 0)) {
-        var bounds = new google.maps.LatLngBounds();
-        for (var k1 in vm.map.markers) {
-          bounds.extend(vm.map.markers[k1].getPosition());
-        }
-        for (var k2 in vm.map.customMarkers) {
-          bounds.extend(vm.map.customMarkers[k2].getPosition());
-        }
-    	  if (vm.mapOptions.maximumZoom) {
-    		  vm.enableMaximumZoomCheck = true; //enable zoom check after resizing for markers
-    	  }
-        vm.map.fitBounds(bounds);
-      }
-    };
-
-    /**
-     * @memberof __MapController
-     * @function objectChanged
-     * @param {String} group name of group e.g., markers
-     */
-    vm.objectChanged = function(group) {
-      if ( vm.map &&
-        (group == 'markers' || group == 'customMarkers') &&
-        vm.map.zoomToIncludeMarkers == 'auto'
-      ) {
-        vm.zoomToIncludeMarkers();
-      }
-    };
-
-    /**
-     * @memberof __MapController
-     * @function initializeMap
-     * @description
-     *  . initialize Google map on <div> tag
-     *  . set map options, events, and observers
-     *  . reset zoom to include all (custom)markers
-     */
-    vm.initializeMap = function() {
-      var mapOptions = vm.mapOptions,
-          mapEvents = vm.mapEvents;
-
-      var lazyInitMap = vm.map; //prepared for lazy init
-      vm.map = NgMapPool.getMapInstance($element[0]);
-      NgMap.setStyle($element[0]);
-
-      // set objects for lazyInit
-      if (lazyInitMap) {
-
-        /**
-         * rebuild mapOptions for lazyInit
-         * because attributes values might have been changed
-         */
-        var filtered = Attr2MapOptions.filter($attrs);
-        var options = Attr2MapOptions.getOptions(filtered);
-        var controlOptions = Attr2MapOptions.getControlOptions(filtered);
-        mapOptions = angular.extend(options, controlOptions);
-        void 0;
-
-        for (var group in lazyInitMap) {
-          var groupMembers = lazyInitMap[group]; //e.g. markers
-          if (typeof groupMembers == 'object') {
-            for (var id in groupMembers) {
-              vm.addObject(group, groupMembers[id]);
-            }
-          }
-        }
-        vm.map.showInfoWindow = vm.showInfoWindow;
-        vm.map.hideInfoWindow = vm.hideInfoWindow;
-      }
-
-      // set options
-      mapOptions.zoom = mapOptions.zoom || 15;
-      var center = mapOptions.center;
-      var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '.*' + escapeRegExp(exprEndSymbol));
-
-      if (!mapOptions.center ||
-        ((typeof center === 'string') && center.match(exprRegExp))
-      ) {
-        mapOptions.center = new google.maps.LatLng(0, 0);
-      } else if( (typeof center === 'string') && center.match(/^[0-9.-]*,[0-9.-]*$/) ){
-        var lat = parseFloat(center.split(',')[0]);
-        var lng = parseFloat(center.split(',')[1]);
-        mapOptions.center = new google.maps.LatLng(lat, lng);
-      } else if (!(center instanceof google.maps.LatLng)) {
-        var geoCenter = mapOptions.center;
-        delete mapOptions.center;
-        NgMap.getGeoLocation(geoCenter, mapOptions.geoLocationOptions).
-          then(function (latlng) {
-            vm.map.setCenter(latlng);
-            var geoCallback = mapOptions.geoCallback;
-            geoCallback && $parse(geoCallback)($scope);
-          }, function () {
-            if (mapOptions.geoFallbackCenter) {
-              vm.map.setCenter(mapOptions.geoFallbackCenter);
-            }
-          });
-      }
-      vm.map.setOptions(mapOptions);
-
-      // set events
-      for (var eventName in mapEvents) {
-        var event = mapEvents[eventName];
-        var listener = google.maps.event.addListener(vm.map, eventName, event);
-        vm.eventListeners[eventName] = listener;
-      }
-
-      // set observers
-      vm.observeAttrSetObj(orgAttrs, $attrs, vm.map);
-      vm.singleInfoWindow = mapOptions.singleInfoWindow;
-
-      google.maps.event.trigger(vm.map, 'resize');
-
-      google.maps.event.addListenerOnce(vm.map, "idle", function () {
-        NgMap.addMap(vm);
-        if (mapOptions.zoomToIncludeMarkers) {
-          vm.zoomToIncludeMarkers();
-        }
-        //TODO: it's for backward compatibiliy. will be removed
-        $scope.map = vm.map;
-        $scope.$emit('mapInitialized', vm.map);
-
-        //callback
-        if ($attrs.mapInitialized) {
-          $parse($attrs.mapInitialized)($scope, {map: vm.map});
-        }
-      });
-
-	  //add maximum zoom listeners if zoom-to-include-markers and and maximum-zoom are valid attributes
-	  if (mapOptions.zoomToIncludeMarkers && mapOptions.maximumZoom) {
-	    google.maps.event.addListener(vm.map, 'zoom_changed', function() {
-          if (vm.enableMaximumZoomCheck == true) {
-			vm.enableMaximumZoomCheck = false;
-	        google.maps.event.addListenerOnce(vm.map, 'bounds_changed', function() {
-		      vm.map.setZoom(Math.min(mapOptions.maximumZoom, vm.map.getZoom()));
-		    });
-	  	  }
-	    });
-	  }
-    };
-
-    $scope.google = google; //used by $scope.eval to avoid eval()
-
-    /**
-     * get map options and events
-     */
-    var orgAttrs = Attr2MapOptions.orgAttributes($element);
-    var filtered = Attr2MapOptions.filter($attrs);
-    var options = Attr2MapOptions.getOptions(filtered, {scope: $scope});
-    var controlOptions = Attr2MapOptions.getControlOptions(filtered);
-    var mapOptions = angular.extend(options, controlOptions);
-    var mapEvents = Attr2MapOptions.getEvents($scope, filtered);
-    void 0;
-    Object.keys(mapEvents).length && void 0;
-
-    vm.mapOptions = mapOptions;
-    vm.mapEvents = mapEvents;
-    vm.eventListeners = {};
-
-    if (options.lazyInit) { // allows controlled initialization
-      // parse angular expression for dynamic ids
-      if (!!$attrs.id &&
-      	  // starts with, at position 0
-	  $attrs.id.indexOf(exprStartSymbol, 0) === 0 &&
-	  // ends with
-	  $attrs.id.indexOf(exprEndSymbol, $attrs.id.length - exprEndSymbol.length) !== -1) {
-        var idExpression = $attrs.id.slice(2,-2);
-        var mapId = $parse(idExpression)($scope);
-      } else {
-        var mapId = $attrs.id;
-      }
-      vm.map = {id: mapId}; //set empty, not real, map
-      NgMap.addMap(vm);
-    } else {
-      vm.initializeMap();
-    }
-
-    //Trigger Resize
-    if(options.triggerResize) {
-      google.maps.event.trigger(vm.map, 'resize');
-    }
-
-    $element.bind('$destroy', function() {
-      NgMapPool.returnMapInstance(vm.map);
-      NgMap.deleteMap(vm);
-    });
-  }; // __MapController
-
-  __MapController.$inject = [
-    '$scope', '$element', '$attrs', '$parse', '$interpolate', 'Attr2MapOptions', 'NgMap', 'NgMapPool', 'escapeRegexpFilter'
-  ];
-  angular.module('ngMap').controller('__MapController', __MapController);
-})();
-
-/**
- * @ngdoc directive
- * @name bicycling-layer
- * @param Attr2Options {service}
- *   convert html attribute to Google map api options
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- *
- *   <map zoom="13" center="34.04924594193164, -118.24104309082031">
- *     <bicycling-layer></bicycling-layer>
- *    </map>
- */
-(function() {
-  'use strict';
-  var parser;
-
-  var linkFunc = function(scope, element, attrs, mapController) {
-    mapController = mapController[0]||mapController[1];
-    var orgAttrs = parser.orgAttributes(element);
-    var filtered = parser.filter(attrs);
-    var options = parser.getOptions(filtered, {scope: scope});
-    var events = parser.getEvents(scope, filtered);
-
-    void 0;
-
-    var layer = getLayer(options, events);
-    mapController.addObject('bicyclingLayers', layer);
-    mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers
-    element.bind('$destroy', function() {
-      mapController.deleteObject('bicyclingLayers', layer);
-    });
-  };
-
-  var getLayer = function(options, events) {
-    var layer = new google.maps.BicyclingLayer(options);
-    for (var eventName in events) {
-      google.maps.event.addListener(layer, eventName, events[eventName]);
-    }
-    return layer;
-  };
-
-  var bicyclingLayer= function(Attr2MapOptions) {
-    parser = Attr2MapOptions;
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-      link: linkFunc
-     };
-  };
-  bicyclingLayer.$inject = ['Attr2MapOptions'];
-
-  angular.module('ngMap').directive('bicyclingLayer', bicyclingLayer);
-})();
-
-/**
- * @ngdoc directive
- * @name custom-control
- * @param Attr2Options {service} convert html attribute to Google map api options
- * @param $compile {service} AngularJS $compile service
- * @description
- *   Build custom control and set to the map with position
- *
- *   Requires:  map directive
- *
- *   Restrict To:  Element
- *
- * @attr {String} position position of this control
- *        i.e. TOP_RIGHT
- * @attr {Number} index index of the control
- * @example
- *
- * Example:
- *  <map center="41.850033,-87.6500523" zoom="3">
- *    <custom-control id="home" position="TOP_LEFT" index="1">
- *      <div style="background-color: white;">
- *        <b>Home</b>
- *      </div>
- *    </custom-control>
- *  </map>
- *
- */
-(function() {
-  'use strict';
-  var parser, NgMap;
-
-  var linkFunc = function(scope, element, attrs, mapController, $transclude) {
-    mapController = mapController[0]||mapController[1];
-    var filtered = parser.filter(attrs);
-    var options = parser.getOptions(filtered, {scope: scope});
-    var events = parser.getEvents(scope, filtered);
-
-    /**
-     * build a custom control element
-     */
-    var customControlEl = element[0].parentElement.removeChild(element[0]);
-    var content = $transclude();
-    angular.element(customControlEl).append(content);
-
-    /**
-     * set events
-     */
-    for (var eventName in events) {
-      google.maps.event.addDomListener(customControlEl, eventName, events[eventName]);
-    }
-
-    mapController.addObject('customControls', customControlEl);
-    var position = options.position;
-    mapController.map.controls[google.maps.ControlPosition[position]].push(customControlEl);
-
-    element.bind('$destroy', function() {
-      mapController.deleteObject('customControls', customControlEl);
-    });
-  };
-
-  var customControl =  function(Attr2MapOptions, _NgMap_)  {
-    parser = Attr2MapOptions, NgMap = _NgMap_;
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-      link: linkFunc,
-      transclude: true
-    }; // return
-  };
-  customControl.$inject = ['Attr2MapOptions', 'NgMap'];
-
-  angular.module('ngMap').directive('customControl', customControl);
-})();
-
-/**
- * @ngdoc directive
- * @memberof ngmap
- * @name custom-marker
- * @param Attr2Options {service} convert html attribute to Google map api options
- * @param $timeout {service} AngularJS $timeout
- * @description
- *   Marker with html
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @attr {String} position required, position on map
- * @attr {Number} z-index optional
- * @attr {Boolean} visible optional
- * @example
- *
- * Example:
- *   <map center="41.850033,-87.6500523" zoom="3">
- *     <custom-marker position="41.850033,-87.6500523">
- *       <div>
- *         <b>Home</b>
- *       </div>
- *     </custom-marker>
- *   </map>
- *
- */
-/* global document */
-(function() {
-  'use strict';
-  var parser, $timeout, $compile, NgMap;
-
-  var CustomMarker = function(options) {
-    options = options || {};
-
-    this.el = document.createElement('div');
-    this.el.style.display = 'inline-block';
-    this.el.style.visibility = "hidden";
-    this.visible = true;
-    for (var key in options) { /* jshint ignore:line */
-     this[key] = options[key];
-    }
-  };
-
-  var setCustomMarker = function() {
-
-    CustomMarker.prototype = new google.maps.OverlayView();
-
-    CustomMarker.prototype.setContent = function(html, scope) {
-      this.el.innerHTML = html;
-      this.el.style.position = 'absolute';
-      if (scope) {
-        $compile(angular.element(this.el).contents())(scope);
-      }
-    };
-
-    CustomMarker.prototype.getDraggable = function() {
-      return this.draggable;
-    };
-
-    CustomMarker.prototype.setDraggable = function(draggable) {
-      this.draggable = draggable;
-    };
-
-    CustomMarker.prototype.getPosition = function() {
-      return this.position;
-    };
-
-    CustomMarker.prototype.setPosition = function(position) {
-      position && (this.position = position); /* jshint ignore:line */
-      var _this = this;
-      if (this.getProjection() && typeof this.position.lng == 'function') {
-        void 0;
-        var setPosition = function() {
-          if (!_this.getProjection()) { return; }
-          var posPixel = _this.getProjection().fromLatLngToDivPixel(_this.position);
-          var x = Math.round(posPixel.x - (_this.el.offsetWidth/2));
-          var y = Math.round(posPixel.y - _this.el.offsetHeight - 10); // 10px for anchor
-          _this.el.style.left = x + "px";
-          _this.el.style.top = y + "px";
-          _this.el.style.visibility = "visible";
-        };
-        if (_this.el.offsetWidth && _this.el.offsetHeight) {
-          setPosition();
-        } else {
-          //delayed left/top calculation when width/height are not set instantly
-          $timeout(setPosition, 300);
-        }
-      }
-    };
-
-    CustomMarker.prototype.setZIndex = function(zIndex) {
-      zIndex && (this.zIndex = zIndex); /* jshint ignore:line */
-      this.el.style.zIndex = this.zIndex;
-    };
-
-    CustomMarker.prototype.getVisible = function() {
-      return this.visible;
-    };
-
-    CustomMarker.prototype.setVisible = function(visible) {
-      this.el.style.display = visible ? 'inline-block' : 'none';
-      this.visible = visible;
-    };
-
-    CustomMarker.prototype.addClass = function(className) {
-      var classNames = this.el.className.trim().split(' ');
-      (classNames.indexOf(className) == -1) && classNames.push(className); /* jshint ignore:line */
-      this.el.className = classNames.join(' ');
-    };
-
-    CustomMarker.prototype.removeClass = function(className) {
-      var classNames = this.el.className.split(' ');
-      var index = classNames.indexOf(className);
-      (index > -1) && classNames.splice(index, 1); /* jshint ignore:line */
-      this.el.className = classNames.join(' ');
-    };
-
-    CustomMarker.prototype.onAdd = function() {
-      this.getPanes().overlayMouseTarget.appendChild(this.el);
-    };
-
-    CustomMarker.prototype.draw = function() {
-      this.setPosition();
-      this.setZIndex(this.zIndex);
-      this.setVisible(this.visible);
-    };
-
-    CustomMarker.prototype.onRemove = function() {
-      this.el.parentNode.removeChild(this.el);
-      //this.el = null;
-    };
-  };
-
-  var linkFunc = function(orgHtml, varsToWatch) {
-    //console.log('orgHtml', orgHtml, 'varsToWatch', varsToWatch);
-
-    return function(scope, element, attrs, mapController) {
-      mapController = mapController[0]||mapController[1];
-      var orgAttrs = parser.orgAttributes(element);
-
-      var filtered = parser.filter(attrs);
-      var options = parser.getOptions(filtered, {scope: scope});
-      var events = parser.getEvents(scope, filtered);
-
-      /**
-       * build a custom marker element
-       */
-      element[0].style.display = 'none';
-      void 0;
-      var customMarker = new CustomMarker(options);
-
-      $timeout(function() { //apply contents, class, and location after it is compiled
-
-        scope.$watch('[' + varsToWatch.join(',') + ']', function() {
-          customMarker.setContent(orgHtml, scope);
-        }, true);
-
-        customMarker.setContent(element[0].innerHTML, scope);
-        var classNames = element[0].firstElementChild.className;
-        customMarker.addClass('custom-marker');
-        customMarker.addClass(classNames);
-        void 0;
-
-        if (!(options.position instanceof google.maps.LatLng)) {
-          NgMap.getGeoLocation(options.position).then(
-                function(latlng) {
-                  customMarker.setPosition(latlng);
-                }
-          );
-        }
-
-      });
-
-      void 0;
-      for (var eventName in events) { /* jshint ignore:line */
-        google.maps.event.addDomListener(
-          customMarker.el, eventName, events[eventName]);
-      }
-      mapController.addObject('customMarkers', customMarker);
-
-      //set observers
-      mapController.observeAttrSetObj(orgAttrs, attrs, customMarker);
-
-      element.bind('$destroy', function() {
-        //Is it required to remove event listeners when DOM is removed?
-        mapController.deleteObject('customMarkers', customMarker);
-      });
-
-    }; // linkFunc
-  };
-
-
-  var customMarkerDirective = function(
-      _$timeout_, _$compile_, $interpolate, Attr2MapOptions, _NgMap_, escapeRegExp
-    )  {
-    parser = Attr2MapOptions;
-    $timeout = _$timeout_;
-    $compile = _$compile_;
-    NgMap = _NgMap_;
-
-    var exprStartSymbol = $interpolate.startSymbol();
-    var exprEndSymbol = $interpolate.endSymbol();
-    var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '([^' + exprEndSymbol.substring(0, 1) + ']+)' + escapeRegExp(exprEndSymbol), 'g');
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-      compile: function(element) {
-        setCustomMarker();
-        element[0].style.display ='none';
-        var orgHtml = element.html();
-        var matches = orgHtml.match(exprRegExp);
-        var varsToWatch = [];
-        //filter out that contains '::', 'this.'
-        (matches || []).forEach(function(match) {
-          var toWatch = match.replace(exprStartSymbol,'').replace(exprEndSymbol,'');
-          if (match.indexOf('::') == -1 &&
-            match.indexOf('this.') == -1 &&
-            varsToWatch.indexOf(toWatch) == -1) {
-            varsToWatch.push(match.replace(exprStartSymbol,'').replace(exprEndSymbol,''));
-          }
-        });
-
-        return linkFunc(orgHtml, varsToWatch);
-      }
-    }; // return
-  };// function
-  customMarkerDirective.$inject =
-    ['$timeout', '$compile', '$interpolate', 'Attr2MapOptions', 'NgMap', 'escapeRegexpFilter'];
-
-  angular.module('ngMap').directive('customMarker', customMarkerDirective);
-})();
-
-/**
- * @ngdoc directive
- * @name directions
- * @description
- *   Enable directions on map.
- *   e.g., origin, destination, draggable, waypoints, etc
- *
- *   Requires:  map directive
- *
- *   Restrict To:  Element
- *
- * @attr {String} DirectionsRendererOptions
- *   [Any DirectionsRendererOptions](https://developers.google.com/maps/documentation/javascript/reference#DirectionsRendererOptions)
- * @attr {String} DirectionsRequestOptions
- *   [Any DirectionsRequest options](https://developers.google.com/maps/documentation/javascript/reference#DirectionsRequest)
- * @example
- *  <map zoom="14" center="37.7699298, -122.4469157">
- *    <directions
- *      draggable="true"
- *      panel="directions-panel"
- *      travel-mode="{{travelMode}}"
- *      waypoints="[{location:'kingston', stopover:true}]"
- *      origin="{{origin}}"
- *      destination="{{destination}}">
- *    </directions>
- *  </map>
- */
-/* global document */
-(function() {
-  'use strict';
-  var NgMap, $timeout, NavigatorGeolocation;
-
-  var getDirectionsRenderer = function(options, events) {
-    if (options.panel) {
-      options.panel = document.getElementById(options.panel) ||
-        document.querySelector(options.panel);
-    }
-    var renderer = new google.maps.DirectionsRenderer(options);
-    for (var eventName in events) {
-      google.maps.event.addListener(renderer, eventName, events[eventName]);
-    }
-    return renderer;
-  };
-
-  var updateRoute = function(renderer, options) {
-    var directionsService = new google.maps.DirectionsService();
-
-    /* filter out valid keys only for DirectionsRequest object*/
-    var request = options;
-    request.travelMode = request.travelMode || 'DRIVING';
-    var validKeys = [
-      'origin', 'destination', 'travelMode', 'transitOptions', 'unitSystem',
-      'durationInTraffic', 'waypoints', 'optimizeWaypoints', 
-      'provideRouteAlternatives', 'avoidHighways', 'avoidTolls', 'region'
-    ];
-    for(var key in request){
-      (validKeys.indexOf(key) === -1) && (delete request[key]);
-    }
-
-    if(request.waypoints) {
-      // Check fo valid values
-      if(request.waypoints == "[]" || request.waypoints === "") {
-        delete request.waypoints;
-      }
-    }
-
-    var showDirections = function(request) {
-      directionsService.route(request, function(response, status) {
-        if (status == google.maps.DirectionsStatus.OK) {
-          $timeout(function() {
-            renderer.setDirections(response);
-          });
-        }
-      });
-    };
-
-    if (request.origin && request.destination) {
-      if (request.origin == 'current-location') {
-        NavigatorGeolocation.getCurrentPosition().then(function(ll) {
-          request.origin = new google.maps.LatLng(ll.coords.latitude, ll.coords.longitude);
-          showDirections(request);
-        });
-      } else if (request.destination == 'current-location') {
-        NavigatorGeolocation.getCurrentPosition().then(function(ll) {
-          request.destination = new google.maps.LatLng(ll.coords.latitude, ll.coords.longitude);
-          showDirections(request);
-        });
-      } else {
-        showDirections(request);
-      }
-    }
-  };
-
-  var directions = function(
-      Attr2MapOptions, _$timeout_, _NavigatorGeolocation_, _NgMap_) {
-    var parser = Attr2MapOptions;
-    NgMap = _NgMap_;
-    $timeout = _$timeout_;
-    NavigatorGeolocation = _NavigatorGeolocation_;
-
-    var linkFunc = function(scope, element, attrs, mapController) {
-      mapController = mapController[0]||mapController[1];
-
-      var orgAttrs = parser.orgAttributes(element);
-      var filtered = parser.filter(attrs);
-      var options = parser.getOptions(filtered, {scope: scope});
-      var events = parser.getEvents(scope, filtered);
-      var attrsToObserve = parser.getAttrsToObserve(orgAttrs);
-
-      var renderer = getDirectionsRenderer(options, events);
-      mapController.addObject('directionsRenderers', renderer);
-
-      attrsToObserve.forEach(function(attrName) {
-        (function(attrName) {
-          attrs.$observe(attrName, function(val) {
-            if (attrName == 'panel') {
-              $timeout(function(){
-                var panel =
-                  document.getElementById(val) || document.querySelector(val);
-                void 0;
-                panel && renderer.setPanel(panel);
-              });
-            } else if (options[attrName] !== val) { //apply only if changed
-              var optionValue = parser.toOptionValue(val, {key: attrName});
-              void 0;
-              options[attrName] = optionValue;
-              updateRoute(renderer, options);
-            }
-          });
-        })(attrName);
-      });
-
-      NgMap.getMap().then(function() {
-        updateRoute(renderer, options);
-      });
-      element.bind('$destroy', function() {
-        mapController.deleteObject('directionsRenderers', renderer);
-      });
-    };
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-      link: linkFunc
-    };
-  }; // var directions
-  directions.$inject =
-    ['Attr2MapOptions', '$timeout', 'NavigatorGeolocation', 'NgMap'];
-
-  angular.module('ngMap').directive('directions', directions);
-})();
-
-
-/**
- * @ngdoc directive
- * @name drawing-manager
- * @param Attr2Options {service} convert html attribute to Google map api options
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- * Example:
- *
- *  <map zoom="13" center="37.774546, -122.433523" map-type-id="SATELLITE">
- *    <drawing-manager
- *      on-overlaycomplete="onMapOverlayCompleted()"
- *      position="ControlPosition.TOP_CENTER"
- *      drawingModes="POLYGON,CIRCLE"
- *      drawingControl="true"
- *      circleOptions="fillColor: '#FFFF00';fillOpacity: 1;strokeWeight: 5;clickable: false;zIndex: 1;editable: true;" >
- *    </drawing-manager>
- *  </map>
- *
- *  TODO: Add remove button.
- *  currently, for our solution, we have the shapes/markers in our own
- *  controller, and we use some css classes to change the shape button
- *  to a remove button (<div>X</div>) and have the remove operation in our own controller.
- */
-(function() {
-  'use strict';
-  angular.module('ngMap').directive('drawingManager', [
-    'Attr2MapOptions', function(Attr2MapOptions) {
-    var parser = Attr2MapOptions;
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var filtered = parser.filter(attrs);
-        var options = parser.getOptions(filtered, {scope: scope});
-        var controlOptions = parser.getControlOptions(filtered);
-        var events = parser.getEvents(scope, filtered);
-
-        /**
-         * set options
-         */
-        var drawingManager = new google.maps.drawing.DrawingManager({
-          drawingMode: options.drawingmode,
-          drawingControl: options.drawingcontrol,
-          drawingControlOptions: controlOptions.drawingControlOptions,
-          circleOptions:options.circleoptions,
-          markerOptions:options.markeroptions,
-          polygonOptions:options.polygonoptions,
-          polylineOptions:options.polylineoptions,
-          rectangleOptions:options.rectangleoptions
-        });
-
-        //Observers
-        attrs.$observe('drawingControlOptions', function (newValue) {
-          drawingManager.drawingControlOptions = parser.getControlOptions({drawingControlOptions: newValue}).drawingControlOptions;
-          drawingManager.setDrawingMode(null);
-          drawingManager.setMap(mapController.map);
-        });
-
-
-        /**
-         * set events
-         */
-        for (var eventName in events) {
-          google.maps.event.addListener(drawingManager, eventName, events[eventName]);
-        }
-
-        mapController.addObject('mapDrawingManager', drawingManager);
-
-        element.bind('$destroy', function() {
-          mapController.deleteObject('mapDrawingManager', drawingManager);
-        });
-      }
-    }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name dynamic-maps-engine-layer
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- * Example:
- *   <map zoom="14" center="[59.322506, 18.010025]">
- *     <dynamic-maps-engine-layer
- *       layer-id="06673056454046135537-08896501997766553811">
- *     </dynamic-maps-engine-layer>
- *    </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('dynamicMapsEngineLayer', [
-    'Attr2MapOptions', function(Attr2MapOptions) {
-    var parser = Attr2MapOptions;
-
-    var getDynamicMapsEngineLayer = function(options, events) {
-      var layer = new google.maps.visualization.DynamicMapsEngineLayer(options);
-
-      for (var eventName in events) {
-        google.maps.event.addListener(layer, eventName, events[eventName]);
-      }
-
-      return layer;
-    };
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var filtered = parser.filter(attrs);
-        var options = parser.getOptions(filtered, {scope: scope});
-        var events = parser.getEvents(scope, filtered, events);
-
-        var layer = getDynamicMapsEngineLayer(options, events);
-        mapController.addObject('mapsEngineLayers', layer);
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name fusion-tables-layer
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- * Example:
- *   <map zoom="11" center="41.850033, -87.6500523">
- *     <fusion-tables-layer query="{
- *       select: 'Geocodable address',
- *       from: '1mZ53Z70NsChnBMm-qEYmSDOvLXgrreLTkQUvvg'}">
- *     </fusion-tables-layer>
- *   </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('fusionTablesLayer', [
-    'Attr2MapOptions', function(Attr2MapOptions) {
-    var parser = Attr2MapOptions;
-
-    var getLayer = function(options, events) {
-      var layer = new google.maps.FusionTablesLayer(options);
-
-      for (var eventName in events) {
-        google.maps.event.addListener(layer, eventName, events[eventName]);
-      }
-
-      return layer;
-    };
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var filtered = parser.filter(attrs);
-        var options = parser.getOptions(filtered, {scope: scope});
-        var events = parser.getEvents(scope, filtered, events);
-        void 0;
-
-        var layer = getLayer(options, events);
-        mapController.addObject('fusionTablesLayers', layer);
-        element.bind('$destroy', function() {
-          mapController.deleteObject('fusionTablesLayers', layer);
-        });
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name heatmap-layer
- * @param Attr2Options {service} convert html attribute to Google map api options
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- *
- * <map zoom="11" center="[41.875696,-87.624207]">
- *   <heatmap-layer data="taxiData"></heatmap-layer>
- * </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('heatmapLayer', [
-    'Attr2MapOptions', '$window', function(Attr2MapOptions, $window) {
-    var parser = Attr2MapOptions;
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var filtered = parser.filter(attrs);
-
-        /**
-         * set options
-         */
-        var options = parser.getOptions(filtered, {scope: scope});
-        options.data = $window[attrs.data] || scope[attrs.data];
-        if (options.data instanceof Array) {
-          options.data = new google.maps.MVCArray(options.data);
-        } else {
-          throw "invalid heatmap data";
-        }
-        var layer = new google.maps.visualization.HeatmapLayer(options);
-
-        /**
-         * set events
-         */
-        var events = parser.getEvents(scope, filtered);
-        void 0;
-
-        mapController.addObject('heatmapLayers', layer);
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name info-window
- * @param Attr2MapOptions {service}
- *   convert html attribute to Google map api options
- * @param $compile {service} $compile service
- * @description
- *  Defines infoWindow and provides compile method
- *
- *  Requires:  map directive
- *
- *  Restrict To:  Element
- *
- *  NOTE: this directive should **NOT** be used with `ng-repeat`
- *  because InfoWindow itself is a template, and a template must be
- *  reused by each marker, thus, should not be redefined repeatedly
- *  by `ng-repeat`.
- *
- * @attr {Boolean} visible
- *   Indicates to show it when map is initialized
- * @attr {Boolean} visible-on-marker
- *   Indicates to show it on a marker when map is initialized
- * @attr {Expression} geo-callback
- *   if position is an address, the expression is will be performed
- *   when geo-lookup is successful. e.g., geo-callback="showDetail()"
- * @attr {String} &lt;InfoWindowOption> Any InfoWindow options,
- *   https://developers.google.com/maps/documentation/javascript/reference?csw=1#InfoWindowOptions
- * @attr {String} &lt;InfoWindowEvent> Any InfoWindow events,
- *   https://developers.google.com/maps/documentation/javascript/reference
- * @example
- * Usage:
- *   <map MAP_ATTRIBUTES>
- *    <info-window id="foo" ANY_OPTIONS ANY_EVENTS"></info-window>
- *   </map>
- *
- * Example:
- *  <map center="41.850033,-87.6500523" zoom="3">
- *    <info-window id="1" position="41.850033,-87.6500523" >
- *      <div ng-non-bindable>
- *        Chicago, IL<br/>
- *        LatLng: {{chicago.lat()}}, {{chicago.lng()}}, <br/>
- *        World Coordinate: {{worldCoordinate.x}}, {{worldCoordinate.y}}, <br/>
- *        Pixel Coordinate: {{pixelCoordinate.x}}, {{pixelCoordinate.y}}, <br/>
- *        Tile Coordinate: {{tileCoordinate.x}}, {{tileCoordinate.y}} at Zoom Level {{map.getZoom()}}
- *      </div>
- *    </info-window>
- *  </map>
- */
-/* global google */
-(function() {
-  'use strict';
-
-  var infoWindow = function(Attr2MapOptions, $compile, $q, $templateRequest, $timeout, $parse, NgMap)  {
-    var parser = Attr2MapOptions;
-
-    var getInfoWindow = function(options, events, element) {
-      var infoWindow;
-
-      /**
-       * set options
-       */
-      if (options.position && !(options.position instanceof google.maps.LatLng)) {
-        delete options.position;
-      }
-      infoWindow = new google.maps.InfoWindow(options);
-
-      /**
-       * set events
-       */
-      for (var eventName in events) {
-        if (eventName) {
-          google.maps.event.addListener(infoWindow, eventName, events[eventName]);
-        }
-      }
-
-      /**
-       * set template and template-related functions
-       * it must have a container element with ng-non-bindable
-       */
-      var templatePromise = $q(function(resolve) {
-        if (angular.isString(element)) {
-          $templateRequest(element).then(function (requestedTemplate) {
-            resolve(angular.element(requestedTemplate).wrap('<div>').parent());
-          }, function(message) {
-            throw "info-window template request failed: " + message;
-          });
-        }
-        else {
-          resolve(element);
-        }
-      }).then(function(resolvedTemplate) {
-        var template = resolvedTemplate.html().trim();
-        if (angular.element(template).length != 1) {
-          throw "info-window working as a template must have a container";
-        }
-        infoWindow.__template = template.replace(/\s?ng-non-bindable[='"]+/,"");
-      });
-
-      infoWindow.__open = function(map, scope, anchor) {
-        templatePromise.then(function() {
-          $timeout(function() {
-            anchor && (scope.anchor = anchor);
-            var el = $compile(infoWindow.__template)(scope);
-            infoWindow.setContent(el[0]);
-            scope.$apply();
-            if (anchor && anchor.getPosition) {
-              infoWindow.open(map, anchor);
-            } else if (anchor && anchor instanceof google.maps.LatLng) {
-              infoWindow.open(map);
-              infoWindow.setPosition(anchor);
-            } else {
-              infoWindow.open(map);
-            }
-            var infoWindowContainerEl = infoWindow.content.parentElement.parentElement.parentElement;
-            infoWindowContainerEl.className = "ng-map-info-window";
-          });
-        });
-      };
-
-      return infoWindow;
-    };
-
-    var linkFunc = function(scope, element, attrs, mapController) {
-      mapController = mapController[0]||mapController[1];
-
-      element.css('display','none');
-
-      var orgAttrs = parser.orgAttributes(element);
-      var filtered = parser.filter(attrs);
-      var options = parser.getOptions(filtered, {scope: scope});
-      var events = parser.getEvents(scope, filtered);
-
-      var infoWindow = getInfoWindow(options, events, options.template || element);
-      var address;
-      if (options.position && !(options.position instanceof google.maps.LatLng)) {
-        address = options.position;
-      }
-      if (address) {
-        NgMap.getGeoLocation(address).then(function(latlng) {
-          infoWindow.setPosition(latlng);
-          infoWindow.__open(mapController.map, scope, latlng);
-          var geoCallback = attrs.geoCallback;
-          geoCallback && $parse(geoCallback)(scope);
-        });
-      }
-
-      mapController.addObject('infoWindows', infoWindow);
-      mapController.observeAttrSetObj(orgAttrs, attrs, infoWindow);
-
-      mapController.showInfoWindow =
-      mapController.map.showInfoWindow = mapController.showInfoWindow ||
-        function(p1, p2, p3) { //event, id, marker
-          var id = typeof p1 == 'string' ? p1 : p2;
-          var marker = typeof p1 == 'string' ? p2 : p3;
-          if (typeof marker == 'string') {
-            //Check if markers if defined to avoid odd 'undefined' errors
-            if (
-              typeof mapController.map.markers != "undefined"
-              && typeof mapController.map.markers[marker] != "undefined") {
-                marker = mapController.map.markers[marker];
-            } else if (
-              //additionally check if that marker is a custom marker
-              typeof mapController.map.customMarkers !== "undefined"
-              && typeof mapController.map.customMarkers[marker] !== "undefined") {
-                marker = mapController.map.customMarkers[marker];
-            } else {
-              //Better error output if marker with that id is not defined
-              throw new Error("Cant open info window for id " + marker + ". Marker or CustomMarker is not defined")
-            }
-          }
-
-          var infoWindow = mapController.map.infoWindows[id];
-          var anchor = marker ? marker : (this.getPosition ? this : null);
-          infoWindow.__open(mapController.map, scope, anchor);
-          if(mapController.singleInfoWindow) {
-            if(mapController.lastInfoWindow) {
-              scope.hideInfoWindow(mapController.lastInfoWindow);
-            }
-            mapController.lastInfoWindow = id;
-          }
-        };
-
-      mapController.hideInfoWindow =
-      mapController.map.hideInfoWindow = mapController.hideInfoWindow ||
-        function(p1, p2) {
-          var id = typeof p1 == 'string' ? p1 : p2;
-          var infoWindow = mapController.map.infoWindows[id];
-          infoWindow.close();
-        };
-
-      //TODO DEPRECATED
-      scope.showInfoWindow = mapController.map.showInfoWindow;
-      scope.hideInfoWindow = mapController.map.hideInfoWindow;
-
-      var map = infoWindow.mapId ? {id:infoWindow.mapId} : 0;
-      NgMap.getMap(map).then(function(map) {
-        infoWindow.visible && infoWindow.__open(map, scope);
-        if (infoWindow.visibleOnMarker) {
-          var markerId = infoWindow.visibleOnMarker;
-          infoWindow.__open(map, scope, map.markers[markerId]);
-        }
-      });
-
-    }; //link
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-      link: linkFunc
-    };
-
-  }; // infoWindow
-  infoWindow.$inject =
-    ['Attr2MapOptions', '$compile', '$q', '$templateRequest', '$timeout', '$parse', 'NgMap'];
-
-  angular.module('ngMap').directive('infoWindow', infoWindow);
-})();
-
-/**
- * @ngdoc directive
- * @name kml-layer
- * @param Attr2MapOptions {service} convert html attribute to Google map api options
- * @description
- *   renders Kml layer on a map
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @attr {Url} url url of the kml layer
- * @attr {KmlLayerOptions} KmlLayerOptions
- *   (https://developers.google.com/maps/documentation/javascript/reference#KmlLayerOptions) 
- * @attr {String} &lt;KmlLayerEvent> Any KmlLayer events,
- *   https://developers.google.com/maps/documentation/javascript/reference
- * @example
- * Usage:
- *   <map MAP_ATTRIBUTES>
- *    <kml-layer ANY_KML_LAYER ANY_KML_LAYER_EVENTS"></kml-layer>
- *   </map>
- *
- * Example:
- *
- * <map zoom="11" center="[41.875696,-87.624207]">
- *   <kml-layer url="https://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml" >
- *   </kml-layer>
- * </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('kmlLayer', [
-    'Attr2MapOptions', function(Attr2MapOptions) {
-    var parser = Attr2MapOptions;
-
-    var getKmlLayer = function(options, events) {
-      var kmlLayer = new google.maps.KmlLayer(options);
-      for (var eventName in events) {
-        google.maps.event.addListener(kmlLayer, eventName, events[eventName]);
-      }
-      return kmlLayer;
-    };
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var orgAttrs = parser.orgAttributes(element);
-        var filtered = parser.filter(attrs);
-        var options = parser.getOptions(filtered, {scope: scope});
-        var events = parser.getEvents(scope, filtered);
-        void 0;
-
-        var kmlLayer = getKmlLayer(options, events);
-        mapController.addObject('kmlLayers', kmlLayer);
-        mapController.observeAttrSetObj(orgAttrs, attrs, kmlLayer);  //observers
-        element.bind('$destroy', function() {
-          mapController.deleteObject('kmlLayers', kmlLayer);
-        });
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name map-data
- * @param Attr2MapOptions {service}
- *   convert html attribute to Google map api options
- * @description
- *   set map data
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @wn {String} method-name, run map.data[method-name] with attribute value
- * @example
- * Example:
- *
- *  <map zoom="11" center="[41.875696,-87.624207]">
- *    <map-data load-geo-json="https://storage.googleapis.com/maps-devrel/google.json"></map-data>
- *   </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('mapData', [
-    'Attr2MapOptions', 'NgMap', function(Attr2MapOptions, NgMap) {
-    var parser = Attr2MapOptions;
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0] || mapController[1];
-        var filtered = parser.filter(attrs);
-        var options = parser.getOptions(filtered, {scope: scope});
-        var events = parser.getEvents(scope, filtered, events);
-
-        void 0;
-        NgMap.getMap(mapController.map.id).then(function(map) {
-          //options
-          for (var key in options) {
-            var val = options[key];
-            if (typeof scope[val] === "function") {
-              map.data[key](scope[val]);
-            } else {
-              map.data[key](val);
-            }
-          }
-
-          //events
-          for (var eventName in events) {
-            map.data.addListener(eventName, events[eventName]);
-          }
-        });
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name map-lazy-load
- * @param Attr2Options {service} convert html attribute to Google map api options
- * @description
- *  Requires: Delay the initialization of map directive
- *    until the map is ready to be rendered
- *  Restrict To: Attribute
- *
- * @attr {String} map-lazy-load
- *    Maps api script source file location.
- *    Example:
- *      'https://maps.google.com/maps/api/js'
- * @attr {String} map-lazy-load-params
- *   Maps api script source file location via angular scope variable.
- *   Also requires the map-lazy-load attribute to be present in the directive.
- *   Example: In your controller, set
- *     $scope.googleMapsURL = 'https://maps.google.com/maps/api/js?v=3.20&client=XXXXXenter-api-key-hereXXXX'
- *
- * @example
- * Example:
- *
- *   <div map-lazy-load="http://maps.google.com/maps/api/js">
- *     <map center="Brampton" zoom="10">
- *       <marker position="Brampton"></marker>
- *     </map>
- *   </div>
- *
- *   <div map-lazy-load="http://maps.google.com/maps/api/js"
- *        map-lazy-load-params="{{googleMapsUrl}}">
- *     <map center="Brampton" zoom="10">
- *       <marker position="Brampton"></marker>
- *     </map>
- *   </div>
- */
-/* global window, document */
-(function() {
-  'use strict';
-  var $timeout, $compile, src, savedHtml = [], elements = [];
-
-  var preLinkFunc = function(scope, element, attrs) {
-    var mapsUrl = attrs.mapLazyLoadParams || attrs.mapLazyLoad;
-
-    if(window.google === undefined || window.google.maps === undefined) {
-      elements.push({
-        scope: scope,
-        element: element,
-        savedHtml: savedHtml[elements.length],
-      });
-
-      window.lazyLoadCallback = function() {
-        void 0;
-        $timeout(function() { /* give some time to load */
-          elements.forEach(function(elm) {
-              elm.element.html(elm.savedHtml);
-              $compile(elm.element.contents())(elm.scope);
-          });
-        }, 100);
-      };
-
-      var scriptEl = document.createElement('script');
-      void 0;
-
-      scriptEl.src = mapsUrl +
-        (mapsUrl.indexOf('?') > -1 ? '&' : '?') +
-        'callback=lazyLoadCallback';
-
-        if (!document.querySelector('script[src="' + scriptEl.src + '"]')) {
-          document.body.appendChild(scriptEl);
-        }
-    } else {
-      element.html(savedHtml);
-      $compile(element.contents())(scope);
-    }
-  };
-
-  var compileFunc = function(tElement, tAttrs) {
-
-    (!tAttrs.mapLazyLoad) && void 0;
-    savedHtml.push(tElement.html());
-    src = tAttrs.mapLazyLoad;
-
-    /**
-     * if already loaded, stop processing it
-     */
-    if(window.google !== undefined && window.google.maps !== undefined) {
-      return false;
-    }
-
-    tElement.html('');  // will compile again after script is loaded
-
-    return {
-      pre: preLinkFunc
-    };
-  };
-
-  var mapLazyLoad = function(_$compile_, _$timeout_) {
-    $compile = _$compile_, $timeout = _$timeout_;
-    return {
-      compile: compileFunc
-    };
-  };
-  mapLazyLoad.$inject = ['$compile','$timeout'];
-
-  angular.module('ngMap').directive('mapLazyLoad', mapLazyLoad);
-})();
-
-/**
- * @ngdoc directive
- * @name map-type
- * @param Attr2MapOptions {service} 
- *   convert html attribute to Google map api options
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- * Example:
- *
- *   <map zoom="13" center="34.04924594193164, -118.24104309082031">
- *     <map-type name="coordinate" object="coordinateMapType"></map-type>
- *   </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('mapType', ['$parse', 'NgMap',
-    function($parse, NgMap) {
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var mapTypeName = attrs.name, mapTypeObject;
-        if (!mapTypeName) {
-          throw "invalid map-type name";
-        }
-        mapTypeObject = $parse(attrs.object)(scope);
-        if (!mapTypeObject) {
-          throw "invalid map-type object";
-        }
-
-        NgMap.getMap().then(function(map) {
-          map.mapTypes.set(mapTypeName, mapTypeObject);
-        });
-        mapController.addObject('mapTypes', mapTypeObject);
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @memberof ngMap
- * @name ng-map
- * @param Attr2Options {service}
- *  convert html attribute to Google map api options
- * @description
- * Implementation of {@link __MapController}
- * Initialize a Google map within a `<div>` tag
- *   with given options and register events
- *
- * @attr {Expression} map-initialized
- *   callback function when map is initialized
- *   e.g., map-initialized="mycallback(map)"
- * @attr {Expression} geo-callback if center is an address or current location,
- *   the expression is will be executed when geo-lookup is successful.
- *   e.g., geo-callback="showMyStoreInfo()"
- * @attr {Array} geo-fallback-center
- *   The center of map incase geolocation failed. i.e. [0,0]
- * @attr {Object} geo-location-options
- *  The navigator geolocation options.
- *  e.g., { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }.
- *  If none specified, { timeout: 5000 }.
- *  If timeout not specified, timeout: 5000 added
- * @attr {Boolean} zoom-to-include-markers
- *  When true, map boundary will be changed automatially
- *  to include all markers when initialized
- * @attr {Boolean} default-style
- *  When false, the default styling,
- *  `display:block;height:300px`, will be ignored.
- * @attr {String} &lt;MapOption> Any Google map options,
- *  https://developers.google.com/maps/documentation/javascript/reference?csw=1#MapOptions
- * @attr {String} &lt;MapEvent> Any Google map events,
- *  https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/map_events.html
- * @attr {Boolean} single-info-window
- *  When true the map will only display one info window at the time,
- *  if not set or false,
- *  everytime an info window is open it will be displayed with the othe one.
- * @attr {Boolean} trigger-resize
- *  Default to false.  Set to true to trigger resize of the map.  Needs to be done anytime you resize the map
- * @example
- * Usage:
- *   <map MAP_OPTIONS_OR_MAP_EVENTS ..>
- *     ... Any children directives
- *   </map>
- *
- * Example:
- *   <map center="[40.74, -74.18]" on-click="doThat()">
- *   </map>
- *
- *   <map geo-fallback-center="[40.74, -74.18]" zoom-to-inlude-markers="true">
- *   </map>
- */
-(function () {
-  'use strict';
-
-  var mapDirective = function () {
-    return {
-      restrict: 'AE',
-      controller: '__MapController',
-      controllerAs: 'ngmap'
-    };
-  };
-
-  angular.module('ngMap').directive('map', [mapDirective]);
-  angular.module('ngMap').directive('ngMap', [mapDirective]);
-})();
-
-/**
- * @ngdoc directive
- * @name maps-engine-layer
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- * Example:
- *  <map zoom="14" center="[59.322506, 18.010025]">
- *    <maps-engine-layer layer-id="06673056454046135537-08896501997766553811">
- *    </maps-engine-layer>
- *  </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('mapsEngineLayer', ['Attr2MapOptions', function(Attr2MapOptions) {
-    var parser = Attr2MapOptions;
-
-    var getMapsEngineLayer = function(options, events) {
-      var layer = new google.maps.visualization.MapsEngineLayer(options);
-
-      for (var eventName in events) {
-        google.maps.event.addListener(layer, eventName, events[eventName]);
-      }
-
-      return layer;
-    };
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var filtered = parser.filter(attrs);
-        var options = parser.getOptions(filtered, {scope: scope});
-        var events = parser.getEvents(scope, filtered, events);
-        void 0;
-
-        var layer = getMapsEngineLayer(options, events);
-        mapController.addObject('mapsEngineLayers', layer);
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name marker
- * @param Attr2Options {service} convert html attribute to Google map api options
- * @param NavigatorGeolocation It is used to find the current location
- * @description
- *  Draw a Google map marker on a map with given options and register events
- *
- *  Requires:  map directive
- *
- *  Restrict To:  Element
- *
- * @attr {String} position address, 'current', or [latitude, longitude]
- *  example:
- *    '1600 Pennsylvania Ave, 20500  Washingtion DC',
- *    'current position',
- *    '[40.74, -74.18]'
- * @attr {Boolean} centered if set, map will be centered with this marker
- * @attr {Expression} geo-callback if position is an address,
- *   the expression is will be performed when geo-lookup is successful.
- *   e.g., geo-callback="showStoreInfo()"
- * @attr {Boolean} no-watcher if true, no attribute observer is added.
- *   Useful for many ng-repeat
- * @attr {String} &lt;MarkerOption>
- *   [Any Marker options](https://developers.google.com/maps/documentation/javascript/reference?csw=1#MarkerOptions)
- * @attr {String} &lt;MapEvent>
- *   [Any Marker events](https://developers.google.com/maps/documentation/javascript/reference)
- * @example
- * Usage:
- *   <map MAP_ATTRIBUTES>
- *    <marker ANY_MARKER_OPTIONS ANY_MARKER_EVENTS"></MARKER>
- *   </map>
- *
- * Example:
- *   <map center="[40.74, -74.18]">
- *    <marker position="[40.74, -74.18]" on-click="myfunc()"></div>
- *   </map>
- *
- *   <map center="the cn tower">
- *    <marker position="the cn tower" on-click="myfunc()"></div>
- *   </map>
- */
-/* global google */
-(function() {
-  'use strict';
-  var parser, $parse, NgMap;
-
-  var getMarker = function(options, events) {
-    var marker;
-
-    if (NgMap.defaultOptions.marker) {
-      for (var key in NgMap.defaultOptions.marker) {
-        if (typeof options[key] == 'undefined') {
-          void 0;
-          options[key] = NgMap.defaultOptions.marker[key];
-        }
-      }
-    }
-
-    if (!(options.position instanceof google.maps.LatLng)) {
-      options.position = new google.maps.LatLng(0,0);
-    }
-    marker = new google.maps.Marker(options);
-
-    /**
-     * set events
-     */
-    if (Object.keys(events).length > 0) {
-      void 0;
-    }
-    for (var eventName in events) {
-      if (eventName) {
-        google.maps.event.addListener(marker, eventName, events[eventName]);
-      }
-    }
-
-    return marker;
-  };
-
-  var linkFunc = function(scope, element, attrs, mapController) {
-    mapController = mapController[0]||mapController[1];
-
-    var orgAttrs = parser.orgAttributes(element);
-    var filtered = parser.filter(attrs);
-    var markerOptions = parser.getOptions(filtered, scope, {scope: scope});
-    var markerEvents = parser.getEvents(scope, filtered);
-    void 0;
-
-    var address;
-    if (!(markerOptions.position instanceof google.maps.LatLng)) {
-      address = markerOptions.position;
-    }
-    var marker = getMarker(markerOptions, markerEvents);
-    mapController.addObject('markers', marker);
-    if (address) {
-      NgMap.getGeoLocation(address).then(function(latlng) {
-        marker.setPosition(latlng);
-        markerOptions.centered && marker.map.setCenter(latlng);
-        var geoCallback = attrs.geoCallback;
-        geoCallback && $parse(geoCallback)(scope);
-      });
-    }
-
-    //set observers
-    mapController.observeAttrSetObj(orgAttrs, attrs, marker); /* observers */
-
-    element.bind('$destroy', function() {
-      mapController.deleteObject('markers', marker);
-    });
-  };
-
-  var marker = function(Attr2MapOptions, _$parse_, _NgMap_) {
-    parser = Attr2MapOptions;
-    $parse = _$parse_;
-    NgMap = _NgMap_;
-
-    return {
-      restrict: 'E',
-      require: ['^?map','?^ngMap'],
-      link: linkFunc
-    };
-  };
-
-  marker.$inject = ['Attr2MapOptions', '$parse', 'NgMap'];
-  angular.module('ngMap').directive('marker', marker);
-
-})();
-
-/**
- * @ngdoc directive
- * @name overlay-map-type
- * @param Attr2MapOptions {service} convert html attribute to Google map api options
- * @param $window {service}
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- * Example:
- *
- * <map zoom="13" center="34.04924594193164, -118.24104309082031">
- *   <overlay-map-type index="0" object="coordinateMapType"></map-type>
- * </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('overlayMapType', [
-    'NgMap', function(NgMap) {
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var initMethod = attrs.initMethod || "insertAt";
-        var overlayMapTypeObject = scope[attrs.object];
-
-        NgMap.getMap().then(function(map) {
-          if (initMethod == "insertAt") {
-            var index = parseInt(attrs.index, 10);
-            map.overlayMapTypes.insertAt(index, overlayMapTypeObject);
-          } else if (initMethod == "push") {
-            map.overlayMapTypes.push(overlayMapTypeObject);
-          }
-        });
-        mapController.addObject('overlayMapTypes', overlayMapTypeObject);
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name places-auto-complete
- * @param Attr2MapOptions {service} convert html attribute to Google map api options
- * @description
- *   Provides address auto complete feature to an input element
- *   Requires: input tag
- *   Restrict To: Attribute
- *
- * @attr {AutoCompleteOptions}
- *   [Any AutocompleteOptions](https://developers.google.com/maps/documentation/javascript/3.exp/reference#AutocompleteOptions)
- *
- * @example
- * Example:
- *   <script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
- *   <input places-auto-complete types="['geocode']" on-place-changed="myCallback(place)" component-restrictions="{country:'au'}"/>
- */
-/* global google */
-(function() {
-  'use strict';
-
-  var placesAutoComplete = function(Attr2MapOptions, $timeout) {
-    var parser = Attr2MapOptions;
-
-    var linkFunc = function(scope, element, attrs, ngModelCtrl) {
-      if (attrs.placesAutoComplete ==='false') {
-        return false;
-      }
-      var filtered = parser.filter(attrs);
-      var options = parser.getOptions(filtered, {scope: scope});
-      var events = parser.getEvents(scope, filtered);
-      var autocomplete = new google.maps.places.Autocomplete(element[0], options);
-      for (var eventName in events) {
-        google.maps.event.addListener(autocomplete, eventName, events[eventName]);
-      }
-
-      var updateModel = function() {
-        $timeout(function(){
-          ngModelCtrl && ngModelCtrl.$setViewValue(element.val());
-        },100);
-      };
-      google.maps.event.addListener(autocomplete, 'place_changed', updateModel);
-      element[0].addEventListener('change', updateModel);
-
-      attrs.$observe('types', function(val) {
-        if (val) {
-          var optionValue = parser.toOptionValue(val, {key: 'types'});
-          autocomplete.setTypes(optionValue);
-        }
-      });
-	  
-	  attrs.$observe('componentRestrictions', function (val) {
-		 if (val) {
-		   autocomplete.setComponentRestrictions(scope.$eval(val));
-		 }
-	   });
-    };
-	
-    return {
-      restrict: 'A',
-      require: '?ngModel',
-      link: linkFunc
-    };
-  };
-
-  placesAutoComplete.$inject = ['Attr2MapOptions', '$timeout'];
-  angular.module('ngMap').directive('placesAutoComplete', placesAutoComplete);
-})();
-
-/**
- * @ngdoc directive
- * @name shape
- * @param Attr2MapOptions {service} convert html attribute to Google map api options
- * @description
- *   Initialize a Google map shape in map with given options and register events
- *   The shapes are:
- *     . circle
- *     . polygon
- *     . polyline
- *     . rectangle
- *     . groundOverlay(or image)
- *
- *   Requires:  map directive
- *
- *   Restrict To:  Element
- *
- * @attr {Boolean} centered if set, map will be centered with this marker
- * @attr {Expression} geo-callback if shape is a circle and the center is
- *   an address, the expression is will be performed when geo-lookup
- *   is successful. e.g., geo-callback="showDetail()"
- * @attr {String} &lt;OPTIONS>
- *   For circle, [any circle options](https://developers.google.com/maps/documentation/javascript/reference#CircleOptions)
- *   For polygon, [any polygon options](https://developers.google.com/maps/documentation/javascript/reference#PolygonOptions)
- *   For polyline, [any polyline options](https://developers.google.com/maps/documentation/javascript/reference#PolylineOptions)
- *   For rectangle, [any rectangle options](https://developers.google.com/maps/documentation/javascript/reference#RectangleOptions)
- *   For image, [any groundOverlay options](https://developers.google.com/maps/documentation/javascript/reference#GroundOverlayOptions)
- * @attr {String} &lt;MapEvent> [Any Shape events](https://developers.google.com/maps/documentation/javascript/reference)
- * @example
- * Usage:
- *   <map MAP_ATTRIBUTES>
- *    <shape name=SHAPE_NAME ANY_SHAPE_OPTIONS ANY_SHAPE_EVENTS"></MARKER>
- *   </map>
- *
- * Example:
- *
- *   <map zoom="11" center="[40.74, -74.18]">
- *     <shape id="polyline" name="polyline" geodesic="true"
- *       stroke-color="#FF0000" stroke-opacity="1.0" stroke-weight="2"
- *       path="[[40.74,-74.18],[40.64,-74.10],[40.54,-74.05],[40.44,-74]]" >
- *     </shape>
- *   </map>
- *
- *   <map zoom="11" center="[40.74, -74.18]">
- *     <shape id="polygon" name="polygon" stroke-color="#FF0000"
- *       stroke-opacity="1.0" stroke-weight="2"
- *       paths="[[40.74,-74.18],[40.64,-74.18],[40.84,-74.08],[40.74,-74.18]]" >
- *     </shape>
- *   </map>
- *
- *   <map zoom="11" center="[40.74, -74.18]">
- *     <shape id="rectangle" name="rectangle" stroke-color='#FF0000'
- *       stroke-opacity="0.8" stroke-weight="2"
- *       bounds="[[40.74,-74.18], [40.78,-74.14]]" editable="true" >
- *     </shape>
- *   </map>
- *
- *   <map zoom="11" center="[40.74, -74.18]">
- *     <shape id="circle" name="circle" stroke-color='#FF0000'
- *       stroke-opacity="0.8"stroke-weight="2"
- *       center="[40.70,-74.14]" radius="4000" editable="true" >
- *     </shape>
- *   </map>
- *
- *   <map zoom="11" center="[40.74, -74.18]">
- *     <shape id="image" name="image"
- *       url="https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg"
- *       bounds="[[40.71,-74.22],[40.77,-74.12]]" opacity="0.7"
- *       clickable="true">
- *     </shape>
- *   </map>
- *
- *  For full-working example, please visit
- *    [shape example](https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/shape.html)
- */
-/* global google */
-(function() {
-  'use strict';
-
-  var getShape = function(options, events) {
-    var shape;
-
-    var shapeName = options.name;
-    delete options.name;  //remove name bcoz it's not for options
-    void 0;
-
-    /**
-     * set options
-     */
-    switch(shapeName) {
-      case "circle":
-        if (!(options.center instanceof google.maps.LatLng)) {
-          options.center = new google.maps.LatLng(0,0);
-        } 
-        shape = new google.maps.Circle(options);
-        break;
-      case "polygon":
-        shape = new google.maps.Polygon(options);
-        break;
-      case "polyline":
-        shape = new google.maps.Polyline(options);
-        break;
-      case "rectangle":
-        shape = new google.maps.Rectangle(options);
-        break;
-      case "groundOverlay":
-      case "image":
-        var url = options.url;
-        var opts = {opacity: options.opacity, clickable: options.clickable, id:options.id};
-        shape = new google.maps.GroundOverlay(url, options.bounds, opts);
-        break;
-    }
-
-    /**
-     * set events
-     */
-    for (var eventName in events) {
-      if (events[eventName]) {
-        google.maps.event.addListener(shape, eventName, events[eventName]);
-      }
-    }
-    return shape;
-  };
-
-  var shape = function(Attr2MapOptions, $parse, NgMap) {
-    var parser = Attr2MapOptions;
-
-    var linkFunc = function(scope, element, attrs, mapController) {
-      mapController = mapController[0]||mapController[1];
-
-      var orgAttrs = parser.orgAttributes(element);
-      var filtered = parser.filter(attrs);
-      var shapeOptions = parser.getOptions(filtered, {scope: scope});
-      var shapeEvents = parser.getEvents(scope, filtered);
-
-      var address, shapeType;
-      shapeType = shapeOptions.name;
-      if (!(shapeOptions.center instanceof google.maps.LatLng)) {
-        address = shapeOptions.center;
-      }
-      var shape = getShape(shapeOptions, shapeEvents);
-      mapController.addObject('shapes', shape);
-
-      if (address && shapeType == 'circle') {
-        NgMap.getGeoLocation(address).then(function(latlng) {
-          shape.setCenter(latlng);
-          shape.centered && shape.map.setCenter(latlng);
-          var geoCallback = attrs.geoCallback;
-          geoCallback && $parse(geoCallback)(scope);
-        });
-      }
-
-      //set observers
-      mapController.observeAttrSetObj(orgAttrs, attrs, shape);
-      element.bind('$destroy', function() {
-        mapController.deleteObject('shapes', shape);
-      });
-    };
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-      link: linkFunc
-     }; // return
-  };
-  shape.$inject = ['Attr2MapOptions', '$parse', 'NgMap'];
-
-  angular.module('ngMap').directive('shape', shape);
-
-})();
-
-/**
- * @ngdoc directive
- * @name streetview-panorama
- * @param Attr2MapOptions {service} convert html attribute to Google map api options
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @attr container Optional, id or css selector, if given, streetview will be in the given html element
- * @attr {String} &lt;StreetViewPanoramaOption>
- *   [Any Google StreetViewPanorama options](https://developers.google.com/maps/documentation/javascript/reference?csw=1#StreetViewPanoramaOptions)
- * @attr {String} &lt;StreetViewPanoramaEvent>
- *   [Any Google StreetViewPanorama events](https://developers.google.com/maps/documentation/javascript/reference#StreetViewPanorama)
- *
- * @example
- *   <map zoom="11" center="[40.688738,-74.043871]" >
- *     <street-view-panorama
- *       click-to-go="true"
- *       disable-default-ui="true"
- *       disable-double-click-zoom="true"
- *       enable-close-button="true"
- *       pano="my-pano"
- *       position="40.688738,-74.043871"
- *       pov="{heading:0, pitch: 90}"
- *       scrollwheel="false"
- *       visible="true">
- *     </street-view-panorama>
- *   </map>
- */
-/* global google, document */
-(function() {
-  'use strict';
-
-  var streetViewPanorama = function(Attr2MapOptions, NgMap) {
-    var parser = Attr2MapOptions;
-
-    var getStreetViewPanorama = function(map, options, events) {
-      var svp, container;
-      if (options.container) {
-        container = document.getElementById(options.container);
-        container = container || document.querySelector(options.container);
-      }
-      if (container) {
-        svp = new google.maps.StreetViewPanorama(container, options);
-      } else {
-        svp = map.getStreetView();
-        svp.setOptions(options);
-      }
-
-      for (var eventName in events) {
-        eventName &&
-          google.maps.event.addListener(svp, eventName, events[eventName]);
-      }
-      return svp;
-    };
-
-    var linkFunc = function(scope, element, attrs) {
-      var filtered = parser.filter(attrs);
-      var options = parser.getOptions(filtered, {scope: scope});
-      var controlOptions = parser.getControlOptions(filtered);
-      var svpOptions = angular.extend(options, controlOptions);
-
-      var svpEvents = parser.getEvents(scope, filtered);
-      void 0;
-
-      NgMap.getMap().then(function(map) {
-        var svp = getStreetViewPanorama(map, svpOptions, svpEvents);
-
-        map.setStreetView(svp);
-        (!svp.getPosition()) && svp.setPosition(map.getCenter());
-        google.maps.event.addListener(svp, 'position_changed', function() {
-          if (svp.getPosition() !== map.getCenter()) {
-            map.setCenter(svp.getPosition());
-          }
-        });
-        //needed for geo-callback
-        var listener =
-          google.maps.event.addListener(map, 'center_changed', function() {
-            svp.setPosition(map.getCenter());
-            google.maps.event.removeListener(listener);
-          });
-      });
-
-    }; //link
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-      link: linkFunc
-    };
-
-  };
-  streetViewPanorama.$inject = ['Attr2MapOptions', 'NgMap'];
-
-  angular.module('ngMap').directive('streetViewPanorama', streetViewPanorama);
-})();
-
-/**
- * @ngdoc directive
- * @name traffic-layer
- * @param Attr2MapOptions {service} convert html attribute to Google map api options
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- * Example:
- *
- *   <map zoom="13" center="34.04924594193164, -118.24104309082031">
- *     <traffic-layer></traffic-layer>
- *    </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('trafficLayer', [
-    'Attr2MapOptions', function(Attr2MapOptions) {
-    var parser = Attr2MapOptions;
-
-    var getLayer = function(options, events) {
-      var layer = new google.maps.TrafficLayer(options);
-      for (var eventName in events) {
-        google.maps.event.addListener(layer, eventName, events[eventName]);
-      }
-      return layer;
-    };
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var orgAttrs = parser.orgAttributes(element);
-        var filtered = parser.filter(attrs);
-        var options = parser.getOptions(filtered, {scope: scope});
-        var events = parser.getEvents(scope, filtered);
-        void 0;
-
-        var layer = getLayer(options, events);
-        mapController.addObject('trafficLayers', layer);
-        mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers
-        element.bind('$destroy', function() {
-          mapController.deleteObject('trafficLayers', layer);
-        });
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc directive
- * @name transit-layer
- * @param Attr2MapOptions {service} convert html attribute to Google map api options
- * @description
- *   Requires:  map directive
- *   Restrict To:  Element
- *
- * @example
- * Example:
- *
- *  <map zoom="13" center="34.04924594193164, -118.24104309082031">
- *    <transit-layer></transit-layer>
- *  </map>
- */
-(function() {
-  'use strict';
-
-  angular.module('ngMap').directive('transitLayer', [
-    'Attr2MapOptions', function(Attr2MapOptions) {
-    var parser = Attr2MapOptions;
-
-    var getLayer = function(options, events) {
-      var layer = new google.maps.TransitLayer(options);
-      for (var eventName in events) {
-        google.maps.event.addListener(layer, eventName, events[eventName]);
-      }
-      return layer;
-    };
-
-    return {
-      restrict: 'E',
-      require: ['?^map','?^ngMap'],
-
-      link: function(scope, element, attrs, mapController) {
-        mapController = mapController[0]||mapController[1];
-
-        var orgAttrs = parser.orgAttributes(element);
-        var filtered = parser.filter(attrs);
-        var options = parser.getOptions(filtered, {scope: scope});
-        var events = parser.getEvents(scope, filtered);
-        void 0;
-
-        var layer = getLayer(options, events);
-        mapController.addObject('transitLayers', layer);
-        mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers
-        element.bind('$destroy', function() {
-          mapController.deleteObject('transitLayers', layer);
-        });
-      }
-     }; // return
-  }]);
-})();
-
-/**
- * @ngdoc filter
- * @name camel-case
- * @description
- *   Converts string to camel cased
- */
-(function() {
-  'use strict';
-
-  var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
-  var MOZ_HACK_REGEXP = /^moz([A-Z])/;
-
-  var camelCaseFilter = function() {
-    return function(name) {
-      return name.
-        replace(SPECIAL_CHARS_REGEXP,
-          function(_, separator, letter, offset) {
-            return offset ? letter.toUpperCase() : letter;
-        }).
-        replace(MOZ_HACK_REGEXP, 'Moz$1');
-    };
-  };
-
-  angular.module('ngMap').filter('camelCase', camelCaseFilter);
-})();
-
-/**
- * @ngdoc filter
- * @name escape-regex
- * @description
- *   Escapes all regex special characters in a string
- */
-(function() {
-  'use strict';
-
-
-
-  var escapeRegexpFilter = function() {
-    return function(string) {
-			return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
-		};
-  };
-
-  angular.module('ngMap').filter('escapeRegexp', escapeRegexpFilter);
-})();
-
-/**
- * @ngdoc filter
- * @name jsonize
- * @description
- *   Converts json-like string to json string
- */
-(function() {
-  'use strict';
-
-  var jsonizeFilter = function() {
-    return function(str) {
-      try {       // if parsable already, return as it is
-        JSON.parse(str);
-        return str;
-      } catch(e) { // if not parsable, change little
-        return str
-          // wrap keys without quote with valid double quote
-          .replace(/([\$\w]+)\s*:/g,
-            function(_, $1) {
-              return '"'+$1+'":';
-            }
-          )
-          // replacing single quote wrapped ones to double quote
-          .replace(/'([^']+)'/g,
-            function(_, $1) {
-              return '"'+$1+'"';
-            }
-          )
-          .replace(/''/g, '""');
-      }
-    };
-  };
-
-  angular.module('ngMap').filter('jsonize', jsonizeFilter);
-})();
-
-/**
- * @ngdoc service
- * @name Attr2MapOptions
- * @description
- *   Converts tag attributes to options used by google api v3 objects
- */
-/* global google */
-(function() {
-  'use strict';
-
-  //i.e. "2015-08-12T06:12:40.858Z"
-  var isoDateRE =
-    /^(\d{4}\-\d\d\-\d\d([tT][\d:\.]*)?)([zZ]|([+\-])(\d\d):?(\d\d))?$/;
-
-  var Attr2MapOptions = function(
-      $parse, $timeout, $log, $interpolate, NavigatorGeolocation, GeoCoder,
-      camelCaseFilter, jsonizeFilter, escapeRegExp
-    ) {
-
-    var exprStartSymbol = $interpolate.startSymbol();
-    var exprEndSymbol = $interpolate.endSymbol();
-
-    /**
-     * Returns the attributes of an element as hash
-     * @memberof Attr2MapOptions
-     * @param {HTMLElement} el html element
-     * @returns {Hash} attributes
-     */
-    var orgAttributes = function(el) {
-      (el.length > 0) && (el = el[0]);
-      var orgAttributes = {};
-      for (var i=0; i<el.attributes.length; i++) {
-        var attr = el.attributes[i];
-        orgAttributes[attr.name] = attr.value;
-      }
-      return orgAttributes;
-    };
-
-    var getJSON = function(input) {
-      var re =/^[\+\-]?[0-9\.]+,[ ]*\ ?[\+\-]?[0-9\.]+$/; //lat,lng
-      if (input.match(re)) {
-        input = "["+input+"]";
-      }
-      return JSON.parse(jsonizeFilter(input));
-    };
-    
-    var getLatLng = function(input) {
-      var output = input;
-      if (input[0].constructor == Array) { 
-        if ((input[0][0].constructor == Array && input[0][0].length == 2) || input[0][0].constructor == Object) {
-            var preoutput;
-            var outputArray = [];
-            for (var i = 0; i < input.length; i++) {
-                preoutput = input[i].map(function(el){
-                    return new google.maps.LatLng(el[0], el[1]);
-                });
-                outputArray.push(preoutput);
-            }
-            output = outputArray;
-        } else {
-            output = input.map(function(el) {
-                return new google.maps.LatLng(el[0], el[1]);
-            });
-        }
-      } else if (!isNaN(parseFloat(input[0])) && isFinite(input[0])) {
-        output = new google.maps.LatLng(output[0], output[1]);
-      }
-      return output;
-    };
-
-    var toOptionValue = function(input, options) {
-      var output;
-      try { // 1. Number?
-        output = getNumber(input);
-      } catch(err) {
-        try { // 2. JSON?
-          var output = getJSON(input);
-          if (output instanceof Array) {
-            if (output[0].constructor == Object) {
-              output = output;
-            } else if (output[0] instanceof Array) {
-              if (output[0][0].constructor == Object) {
-                output = output;
-              } else {
-                output = getLatLng(output);
-              }
-            } else {
-                output = getLatLng(output);
-            }
-          }
-          // JSON is an object (not array or null)
-          else if (output === Object(output)) {
-            // check for nested hashes and convert to Google API options
-            var newOptions = options;
-            newOptions.doNotConverStringToNumber = true;
-            output = getOptions(output, newOptions);
-          }
-        } catch(err2) {
-          // 3. Google Map Object function Expression. i.e. LatLng(80,-49)
-          if (input.match(/^[A-Z][a-zA-Z0-9]+\(.*\)$/)) {
-            try {
-              var exp = "new google.maps."+input;
-              output = eval(exp); /* jshint ignore:line */
-            } catch(e) {
-              output = input;
-            }
-          // 4. Google Map Object constant Expression. i.e. MayTypeId.HYBRID
-          } else if (input.match(/^([A-Z][a-zA-Z0-9]+)\.([A-Z]+)$/)) {
-            try {
-              var matches = input.match(/^([A-Z][a-zA-Z0-9]+)\.([A-Z]+)$/);
-              output = google.maps[matches[1]][matches[2]];
-            } catch(e) {
-              output = input;
-            }
-          // 5. Google Map Object constant Expression. i.e. HYBRID
-          } else if (input.match(/^[A-Z]+$/)) {
-            try {
-              var capitalizedKey = options.key.charAt(0).toUpperCase() +
-                options.key.slice(1);
-              if (options.key.match(/temperatureUnit|windSpeedUnit|labelColor/)) {
-                capitalizedKey = capitalizedKey.replace(/s$/,"");
-                output = google.maps.weather[capitalizedKey][input];
-              } else {
-                output = google.maps[capitalizedKey][input];
-              }
-            } catch(e) {
-              output = input;
-            }
-          // 6. Date Object as ISO String
-          } else if (input.match(isoDateRE)) {
-            try {
-              output = new Date(input);
-            } catch(e) {
-              output = input;
-            }
-          // 7. evaluate dynamically bound values
-        } else if (input.match(new RegExp('^' + escapeRegExp(exprStartSymbol))) && options.scope) {
-            try {
-              var expr = input.replace(new RegExp(escapeRegExp(exprStartSymbol)),'').replace(new RegExp(escapeRegExp(exprEndSymbol), 'g'),'');
-              output = options.scope.$eval(expr);
-            } catch (err) {
-              output = input;
-            }
-          } else {
-            output = input;
-          }
-        } // catch(err2)
-      } // catch(err)
-
-      // convert output more for center and position
-      if (
-        (options.key == 'center' || options.key == 'position') &&
-        output instanceof Array
-      ) {
-        output = new google.maps.LatLng(output[0], output[1]);
-      }
-
-      // convert output more for shape bounds
-      if (options.key == 'bounds' && output instanceof Array) {
-        output = new google.maps.LatLngBounds(output[0], output[1]);
-      }
-
-      // convert output more for shape icons
-      if (options.key == 'icons' && output instanceof Array) {
-
-        for (var i=0; i<output.length; i++) {
-          var el = output[i];
-          if (el.icon.path.match(/^[A-Z_]+$/)) {
-            el.icon.path =  google.maps.SymbolPath[el.icon.path];
-          }
-        }
-      }
-
-      // convert output more for marker icon
-      if (options.key == 'icon' && output instanceof Object) {
-        if ((""+output.path).match(/^[A-Z_]+$/)) {
-          output.path = google.maps.SymbolPath[output.path];
-        }
-        for (var key in output) { //jshint ignore:line
-          var arr = output[key];
-          if (key == "anchor" || key == "origin" || key == "labelOrigin") {
-            output[key] = new google.maps.Point(arr[0], arr[1]);
-          } else if (key == "size" || key == "scaledSize") {
-            output[key] = new google.maps.Size(arr[0], arr[1]);
-          }
-        }
-      }
-
-      return output;
-    };
-
-    var getAttrsToObserve = function(attrs) {
-      var attrsToObserve = [];
-      var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '.*' + escapeRegExp(exprEndSymbol), 'g');
-
-      if (!attrs.noWatcher) {
-        for (var attrName in attrs) { //jshint ignore:line
-          var attrValue = attrs[attrName];
-          if (attrValue && attrValue.match(exprRegExp)) { // if attr value is {{..}}
-            attrsToObserve.push(camelCaseFilter(attrName));
-          }
-        }
-      }
-
-      return attrsToObserve;
-    };
-
-    /**
-     * filters attributes by skipping angularjs methods $.. $$..
-     * @memberof Attr2MapOptions
-     * @param {Hash} attrs tag attributes
-     * @returns {Hash} filterd attributes
-     */
-    var filter = function(attrs) {
-      var options = {};
-      for(var key in attrs) {
-        if (key.match(/^\$/) || key.match(/^ng[A-Z]/)) {
-          void(0);
-        } else {
-          options[key] = attrs[key];
-        }
-      }
-      return options;
-    };
-
-    /**
-     * converts attributes hash to Google Maps API v3 options
-     * ```
-     *  . converts numbers to number
-     *  . converts class-like string to google maps instance
-     *    i.e. `LatLng(1,1)` to `new google.maps.LatLng(1,1)`
-     *  . converts constant-like string to google maps constant
-     *    i.e. `MapTypeId.HYBRID` to `google.maps.MapTypeId.HYBRID`
-     *    i.e. `HYBRID"` to `google.maps.MapTypeId.HYBRID`
-     * ```
-     * @memberof Attr2MapOptions
-     * @param {Hash} attrs tag attributes
-     * @param {Hash} options
-     * @returns {Hash} options converted attributess
-     */
-    var getOptions = function(attrs, params) {
-      params = params || {};
-      var options = {};
-      for(var key in attrs) {
-        if (attrs[key] || attrs[key] === 0) {
-          if (key.match(/^on[A-Z]/)) { //skip events, i.e. on-click
-            continue;
-          } else if (key.match(/ControlOptions$/)) { // skip controlOptions
-            continue;
-          } else {
-            // nested conversions need to be typechecked
-            // (non-strings are fully converted)
-            if (typeof attrs[key] !== 'string') {
-              options[key] = attrs[key];
-            } else {
-              if (params.doNotConverStringToNumber &&
-                attrs[key].match(/^[0-9]+$/)
-              ) {
-                options[key] = attrs[key];
-              } else {
-                options[key] = toOptionValue(attrs[key], {key: key, scope: params.scope});
-              }
-            }
-          }
-        } // if (attrs[key])
-      } // for(var key in attrs)
-      return options;
-    };
-
-    /**
-     * converts attributes hash to scope-specific event function
-     * @memberof Attr2MapOptions
-     * @param {scope} scope angularjs scope
-     * @param {Hash} attrs tag attributes
-     * @returns {Hash} events converted events
-     */
-    var getEvents = function(scope, attrs) {
-      var events = {};
-      var toLowercaseFunc = function($1){
-        return "_"+$1.toLowerCase();
-      };
-      var EventFunc = function(attrValue) {
-        // funcName(argsStr)
-        var matches = attrValue.match(/([^\(]+)\(([^\)]*)\)/);
-        var funcName = matches[1];
-        var argsStr = matches[2].replace(/event[ ,]*/,'');  //remove string 'event'
-        var argsExpr = $parse("["+argsStr+"]"); //for perf when triggering event
-        return function(event) {
-          var args = argsExpr(scope); //get args here to pass updated model values
-          function index(obj,i) {return obj[i];}
-          var f = funcName.split('.').reduce(index, scope);
-          f && f.apply(this, [event].concat(args));
-          $timeout( function() {
-            scope.$apply();
-          });
-        };
-      };
-
-      for(var key in attrs) {
-        if (attrs[key]) {
-          if (!key.match(/^on[A-Z]/)) { //skip if not events
-            continue;
-          }
-
-          //get event name as underscored. i.e. zoom_changed
-          var eventName = key.replace(/^on/,'');
-          eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1);
-          eventName = eventName.replace(/([A-Z])/g, toLowercaseFunc);
-
-          var attrValue = attrs[key];
-          events[eventName] = new EventFunc(attrValue);
-        }
-      }
-      return events;
-    };
-
-    /**
-     * control means map controls, i.e streetview, pan, etc, not a general control
-     * @memberof Attr2MapOptions
-     * @param {Hash} filtered filtered tag attributes
-     * @returns {Hash} Google Map options
-     */
-    var getControlOptions = function(filtered) {
-      var controlOptions = {};
-      if (typeof filtered != 'object') {
-        return false;
-      }
-
-      for (var attr in filtered) {
-        if (filtered[attr]) {
-          if (!attr.match(/(.*)ControlOptions$/)) {
-            continue; // if not controlOptions, skip it
-          }
-
-          //change invalid json to valid one, i.e. {foo:1} to {"foo": 1}
-          var orgValue = filtered[attr];
-          var newValue = orgValue.replace(/'/g, '"');
-          newValue = newValue.replace(/([^"]+)|("[^"]+")/g, function($0, $1, $2) {
-            if ($1) {
-              return $1.replace(/([a-zA-Z0-9]+?):/g, '"$1":');
-            } else {
-              return $2;
-            }
-          });
-          try {
-            var options = JSON.parse(newValue);
-            for (var key in options) { //assign the right values
-              if (options[key]) {
-                var value = options[key];
-                if (typeof value === 'string') {
-                  value = value.toUpperCase();
-                } else if (key === "mapTypeIds") {
-                  value = value.map( function(str) {
-                    if (str.match(/^[A-Z]+$/)) { // if constant
-                      return google.maps.MapTypeId[str.toUpperCase()];
-                    } else { // else, custom map-type
-                      return str;
-                    }
-                  });
-                }
-
-                if (key === "style") {
-                  var str = attr.charAt(0).toUpperCase() + attr.slice(1);
-                  var objName = str.replace(/Options$/,'')+"Style";
-                  options[key] = google.maps[objName][value];
-                } else if (key === "position") {
-                  options[key] = google.maps.ControlPosition[value];
-                } else {
-                  options[key] = value;
-                }
-              }
-            }
-            controlOptions[attr] = options;
-          } catch (e) {
-            void 0;
-          }
-        }
-      } // for
-
-      return controlOptions;
-    };
-
-    return {
-      filter: filter,
-      getOptions: getOptions,
-      getEvents: getEvents,
-      getControlOptions: getControlOptions,
-      toOptionValue: toOptionValue,
-      getAttrsToObserve: getAttrsToObserve,
-      orgAttributes: orgAttributes
-    }; // return
-
-  };
-  Attr2MapOptions.$inject= [
-    '$parse', '$timeout', '$log', '$interpolate', 'NavigatorGeolocation', 'GeoCoder',
-    'camelCaseFilter', 'jsonizeFilter', 'escapeRegexpFilter'
-  ];
-
-  angular.module('ngMap').service('Attr2MapOptions', Attr2MapOptions);
-})();
-
-/**
- * @ngdoc service
- * @name GeoCoder
- * @description
- *   Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)
- *   service for Google Geocoder service
- */
-(function() {
-  'use strict';
-  var $q;
-  /**
-   * @memberof GeoCoder
-   * @param {Hash} options
-   *   https://developers.google.com/maps/documentation/geocoding/#geocoding
-   * @example
-   * ```
-   *   GeoCoder.geocode({address: 'the cn tower'}).then(function(result) {
-   *     //... do something with result
-   *   });
-   * ```
-   * @returns {HttpPromise} Future object
-   */
-  var geocodeFunc = function(options) {
-    var deferred = $q.defer();
-    var geocoder = new google.maps.Geocoder();
-    geocoder.geocode(options, function (results, status) {
-      if (status == google.maps.GeocoderStatus.OK) {
-        deferred.resolve(results);
-      } else {
-        deferred.reject(status);
-      }
-    });
-    return deferred.promise;
-  };
-
-  var GeoCoder = function(_$q_) {
-    $q = _$q_;
-    return {
-      geocode : geocodeFunc
-    };
-  };
-  GeoCoder.$inject = ['$q'];
-
-  angular.module('ngMap').service('GeoCoder', GeoCoder);
-})();
-
-/**
- * @ngdoc service
- * @name GoogleMapsApi
- * @description
- *   Load Google Maps API Service
- */
-(function() {
-  'use strict';
-  var $q;
-  var $timeout;
-
-  var GoogleMapsApi = function(_$q_, _$timeout_) {
-    $q = _$q_;
-    $timeout = _$timeout_;
-
-    return {
-
-      /**
-       * Load google maps into document by creating a script tag
-       * @memberof GoogleMapsApi
-       * @param {string} mapsUrl
-       * @example
-       *   GoogleMapsApi.load(myUrl).then(function() {
-       *     console.log('google map has been loaded')
-       *   });
-       */
-      load: function (mapsUrl) {
-
-        var deferred = $q.defer();
-
-        if (window.google === undefined || window.google.maps === undefined) {
-
-          window.lazyLoadCallback = function() {
-            $timeout(function() { /* give some time to load */
-              deferred.resolve(window.google)
-            }, 100);
-          };
-
-          var scriptEl = document.createElement('script');
-          scriptEl.src = mapsUrl +
-            (mapsUrl.indexOf('?') > -1 ? '&' : '?') +
-            'callback=lazyLoadCallback';
-
-          if (!document.querySelector('script[src="' + scriptEl.src + '"]')) {
-            document.body.appendChild(scriptEl);
-          }
-        } else {
-          deferred.resolve(window.google)
-        }
-
-        return deferred.promise;
-      }
-
-    }
-  }
-  GoogleMapsApi.$inject = ['$q', '$timeout'];
-
-  angular.module('ngMap').service('GoogleMapsApi', GoogleMapsApi);
-})();
-
-
-
-/**
- * @ngdoc service
- * @name NavigatorGeolocation
- * @description
- *  Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)
- *  service for navigator.geolocation methods
- */
-/* global google */
-(function() {
-  'use strict';
-  var $q;
-
-  /**
-   * @memberof NavigatorGeolocation
-   * @param {Object} geoLocationOptions the navigator geolocations options.
-   *  i.e. { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }.
-   *  If none specified, { timeout: 5000 }. 
-   *  If timeout not specified, timeout: 5000 added
-   * @param {function} success success callback function
-   * @param {function} failure failure callback function
-   * @example
-   * ```
-   *  NavigatorGeolocation.getCurrentPosition()
-   *    .then(function(position) {
-   *      var lat = position.coords.latitude, lng = position.coords.longitude;
-   *      .. do something lat and lng
-   *    });
-   * ```
-   * @returns {HttpPromise} Future object
-   */
-  var getCurrentPosition = function(geoLocationOptions) {
-    var deferred = $q.defer();
-    if (navigator.geolocation) {
-
-      if (geoLocationOptions === undefined) {
-        geoLocationOptions = { timeout: 5000 };
-      }
-      else if (geoLocationOptions.timeout === undefined) {
-        geoLocationOptions.timeout = 5000;
-      }
-
-      navigator.geolocation.getCurrentPosition(
-        function(position) {
-          deferred.resolve(position);
-        }, function(evt) {
-          void 0;
-          deferred.reject(evt);
-        },
-        geoLocationOptions
-      );
-    } else {
-      deferred.reject("Browser Geolocation service failed.");
-    }
-    return deferred.promise;
-  };
-
-  var NavigatorGeolocation = function(_$q_) {
-    $q = _$q_;
-    return {
-      getCurrentPosition: getCurrentPosition
-    };
-  };
-  NavigatorGeolocation.$inject = ['$q'];
-
-  angular.module('ngMap').
-    service('NavigatorGeolocation', NavigatorGeolocation);
-})();
-
-/**
- * @ngdoc factory
- * @name NgMapPool
- * @description
- *   Provide map instance to avoid memory leak
- */
-(function() {
-  'use strict';
-  /**
-   * @memberof NgMapPool
-   * @desc map instance pool
-   */
-  var mapInstances = [];
-  var $window, $document, $timeout;
-
-  var add = function(el) {
-    var mapDiv = $document.createElement("div");
-    mapDiv.style.width = "100%";
-    mapDiv.style.height = "100%";
-    el.appendChild(mapDiv);
-    var map = new $window.google.maps.Map(mapDiv, {});
-    mapInstances.push(map);
-    return map;
-  };
-
-  var findById = function(el, id) {
-    var notInUseMap;
-    for (var i=0; i<mapInstances.length; i++) {
-      var map = mapInstances[i];
-      if (map.id == id && !map.inUse) {
-        var mapDiv = map.getDiv();
-        el.appendChild(mapDiv);
-        notInUseMap = map;
-        break;
-      }
-    }
-    return notInUseMap;
-  };
-
-  var findUnused = function(el) { //jshint ignore:line
-    var notInUseMap;
-    for (var i=0; i<mapInstances.length; i++) {
-      var map = mapInstances[i];
-      if (map.id) {
-        continue;
-      }
-      if (!map.inUse) {
-        var mapDiv = map.getDiv();
-        el.appendChild(mapDiv);
-        notInUseMap = map;
-        break;
-      }
-    }
-    return notInUseMap;
-  };
-
-  /**
-   * @memberof NgMapPool
-   * @function getMapInstance
-   * @param {HtmlElement} el map container element
-   * @return map instance for the given element
-   */
-  var getMapInstance = function(el) {
-    var map = findById(el, el.id) || findUnused(el);
-    if (!map) {
-      map = add(el);
-    } else {
-      /* firing map idle event, which is used by map controller */
-      $timeout(function() {
-        google.maps.event.trigger(map, 'idle');
-      }, 100);
-    }
-    map.inUse = true;
-    return map;
-  };
-
-  /**
-   * @memberof NgMapPool
-   * @function returnMapInstance
-   * @param {Map} an instance of google.maps.Map
-   * @desc sets the flag inUse of the given map instance to false, so that it 
-   * can be reused later
-   */
-  var returnMapInstance = function(map) {
-    map.inUse = false;
-  };
-  
-  /**
-   * @memberof NgMapPool
-   * @function resetMapInstances
-   * @desc resets mapInstance array
-   */
-  var resetMapInstances = function() {
-    for(var i = 0;i < mapInstances.length;i++) {
-        mapInstances[i] = null;
-    }
-    mapInstances = [];
-  };
-  
-  /**
-   * @memberof NgMapPool
-   * @function deleteMapInstance
-   * @desc delete a mapInstance
-   */
-  var deleteMapInstance= function(mapId) {
-	  for( var i=0; i<mapInstances.length; i++ ) {
-		  if( (mapInstances[i] !== null) && (mapInstances[i].id == mapId)) {
-			  mapInstances[i]= null;
-			  mapInstances.splice( i, 1 );
-		  }
-	  }
-  };
-
-  var NgMapPool = function(_$document_, _$window_, _$timeout_) {
-    $document = _$document_[0], $window = _$window_, $timeout = _$timeout_;
-
-    return {
-	  mapInstances: mapInstances,
-      resetMapInstances: resetMapInstances,
-      getMapInstance: getMapInstance,
-      returnMapInstance: returnMapInstance,
-      deleteMapInstance: deleteMapInstance
-    };
-  };
-
-  NgMapPool.$inject = [ '$document', '$window', '$timeout'];
-
-  angular.module('ngMap').factory('NgMapPool', NgMapPool);
-
-})();
-
-/**
- * @ngdoc provider
- * @name NgMap
- * @description
- *  common utility service for ng-map
- */
-(function() {
-  'use strict';
-  var $window, $document, $q;
-  var NavigatorGeolocation, Attr2MapOptions, GeoCoder, camelCaseFilter, NgMapPool;
-
-  var mapControllers = {};
-
-  var getStyle = function(el, styleProp) {
-    var y;
-    if (el.currentStyle) {
-      y = el.currentStyle[styleProp];
-    } else if ($window.getComputedStyle) {
-      y = $document.defaultView.
-        getComputedStyle(el, null).
-        getPropertyValue(styleProp);
-    }
-    return y;
-  };
-
-  /**
-   * @memberof NgMap
-   * @function initMap
-   * @param id optional, id of the map. default 0
-   */
-  var initMap = function(id) {
-    var ctrl = mapControllers[id || 0];
-    if (!(ctrl.map instanceof google.maps.Map)) {
-      ctrl.initializeMap();
-      return ctrl.map;
-    } else {
-      void 0;
-    }
-  };
-
-  /**
-   * @memberof NgMap
-   * @function getMap
-   * @param {String} optional, id e.g., 'foo'
-   * @returns promise
-   */
-  var getMap = function(id, options) {
-    options = options || {};
-    id = typeof id === 'object' ? id.id : id;
-
-    var deferred = $q.defer();
-    var timeout = options.timeout || 10000;
-
-    function waitForMap(timeElapsed){
-      var keys = Object.keys(mapControllers);
-      var theFirstController = mapControllers[keys[0]];
-      if(id && mapControllers[id]){
-        deferred.resolve(mapControllers[id].map);
-      } else if (!id && theFirstController && theFirstController.map) {
-        deferred.resolve(theFirstController.map);
-      } else if (timeElapsed > timeout) {
-        deferred.reject('could not find map');
-      } else {
-        $window.setTimeout( function(){
-          waitForMap(timeElapsed+100);
-        }, 100);
-      }
-    }
-    waitForMap(0);
-
-    return deferred.promise;
-  };
-
-  /**
-   * @memberof NgMap
-   * @function addMap
-   * @param mapController {__MapContoller} a map controller
-   * @returns promise
-   */
-  var addMap = function(mapCtrl) {
-    if (mapCtrl.map) {
-      var len = Object.keys(mapControllers).length;
-      mapControllers[mapCtrl.map.id || len] = mapCtrl;
-    }
-  };
-
-  /**
-   * @memberof NgMap
-   * @function deleteMap
-   * @param mapController {__MapContoller} a map controller
-   */
-  var deleteMap = function(mapCtrl) {
-    var len = Object.keys(mapControllers).length - 1;
-    var mapId = mapCtrl.map.id || len;
-    if (mapCtrl.map) {
-      for (var eventName in mapCtrl.eventListeners) {
-        void 0;
-        var listener = mapCtrl.eventListeners[eventName];
-        google.maps.event.removeListener(listener);
-      }
-      if (mapCtrl.map.controls) {
-        mapCtrl.map.controls.forEach(function(ctrl) {
-          ctrl.clear();
-        });
-      }
-    }
-
-    //Remove Heatmap Layers
-    if (mapCtrl.map.heatmapLayers) {
-      Object.keys(mapCtrl.map.heatmapLayers).forEach(function (layer) {
-        mapCtrl.deleteObject('heatmapLayers', mapCtrl.map.heatmapLayers[layer]);
-      });
-    }
-
-    NgMapPool.deleteMapInstance(mapId);
-
-    delete mapControllers[mapId];
-  };
-
-  /**
-   * @memberof NgMap
-   * @function getGeoLocation
-   * @param {String} address
-   * @param {Hash} options geo options
-   * @returns promise
-   */
-  var getGeoLocation = function(string, options) {
-    var deferred = $q.defer();
-    if (!string || string.match(/^current/i)) { // current location
-      NavigatorGeolocation.getCurrentPosition(options).then(
-        function(position) {
-          var lat = position.coords.latitude;
-          var lng = position.coords.longitude;
-          var latLng = new google.maps.LatLng(lat,lng);
-          deferred.resolve(latLng);
-        },
-        function(error) {
-          deferred.reject(error);
-        }
-      );
-    } else {
-      GeoCoder.geocode({address: string}).then(
-        function(results) {
-          deferred.resolve(results[0].geometry.location);
-        },
-        function(error) {
-          deferred.reject(error);
-        }
-      );
-      // var geocoder = new google.maps.Geocoder();
-      // geocoder.geocode(options, function (results, status) {
-      //   if (status == google.maps.GeocoderStatus.OK) {
-      //     deferred.resolve(results);
-      //   } else {
-      //     deferred.reject(status);
-      //   }
-      // });
-    }
-
-    return deferred.promise;
-  };
-
-  /**
-   * @memberof NgMap
-   * @function observeAndSet
-   * @param {String} attrName attribute name
-   * @param {Object} object A Google maps object to be changed
-   * @returns attribue observe function
-   */
-  var observeAndSet = function(attrName, object) {
-    void 0;
-    return function(val) {
-      if (val) {
-        var setMethod = camelCaseFilter('set-'+attrName);
-        var optionValue = Attr2MapOptions.toOptionValue(val, {key: attrName});
-        if (object[setMethod]) { //if set method does exist
-          void 0;
-          /* if an location is being observed */
-          if (attrName.match(/center|position/) &&
-            typeof optionValue == 'string') {
-            getGeoLocation(optionValue).then(function(latlng) {
-              object[setMethod](latlng);
-            });
-          } else {
-            object[setMethod](optionValue);
-          }
-        }
-      }
-    };
-  };
-
-  /**
-   * @memberof NgMap
-   * @function setStyle
-   * @param {HtmlElement} map contriner element
-   * @desc set display, width, height of map container element
-   */
-  var setStyle = function(el) {
-    //if style is not given to the map element, set display and height
-    var defaultStyle = el.getAttribute('default-style');
-    if (defaultStyle == "true") {
-      el.style.display = 'block';
-      el.style.height = '300px';
-    } else {
-      if (getStyle(el, 'display') != "block") {
-        el.style.display = 'block';
-      }
-      if (getStyle(el, 'height').match(/^(0|auto)/)) {
-        el.style.height = '300px';
-      }
-    }
-  };
-
-  angular.module('ngMap').provider('NgMap', function() {
-    var defaultOptions = {};
-
-    /**
-     * @memberof NgMap
-     * @function setDefaultOptions
-     * @param {Hash} options
-     * @example
-     *  app.config(function(NgMapProvider) {
-     *    NgMapProvider.setDefaultOptions({
-     *      marker: {
-     *        optimized: false
-     *      }
-     *    });
-     *  });
-     */
-    this.setDefaultOptions = function(options) {
-      defaultOptions = options;
-    };
-
-    var NgMap = function(
-        _$window_, _$document_, _$q_,
-        _NavigatorGeolocation_, _Attr2MapOptions_,
-        _GeoCoder_, _camelCaseFilter_, _NgMapPool_
-      ) {
-      $window = _$window_;
-      $document = _$document_[0];
-      $q = _$q_;
-      NavigatorGeolocation = _NavigatorGeolocation_;
-      Attr2MapOptions = _Attr2MapOptions_;
-      GeoCoder = _GeoCoder_;
-      camelCaseFilter = _camelCaseFilter_;
-      NgMapPool = _NgMapPool_;
-
-      return {
-        defaultOptions: defaultOptions,
-        addMap: addMap,
-        deleteMap: deleteMap,
-        getMap: getMap,
-        initMap: initMap,
-        setStyle: setStyle,
-        getGeoLocation: getGeoLocation,
-        observeAndSet: observeAndSet
-      };
-    };
-    NgMap.$inject = [
-      '$window', '$document', '$q',
-      'NavigatorGeolocation', 'Attr2MapOptions',
-      'GeoCoder', 'camelCaseFilter', 'NgMapPool'
-    ];
-
-    this.$get = NgMap;
-  });
-})();
-
-/**
- * @ngdoc service
- * @name StreetView
- * @description
- *  Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)
- *  service for [Google StreetViewService]
- *  (https://developers.google.com/maps/documentation/javascript/streetview)
- */
-(function() {
-  'use strict';
-  var $q;
-
-  /**
-   * Retrieves panorama id from the given map (and or position)
-   * @memberof StreetView
-   * @param {map} map Google map instance
-   * @param {LatLng} latlng Google LatLng instance
-   *   default: the center of the map
-   * @example
-   *   StreetView.getPanorama(map).then(function(panoId) {
-   *     $scope.panoId = panoId;
-   *   });
-   * @returns {HttpPromise} Future object
-   */
-  var getPanorama = function(map, latlng) {
-    latlng = latlng || map.getCenter();
-    var deferred = $q.defer();
-    var svs = new google.maps.StreetViewService();
-    svs.getPanoramaByLocation( (latlng||map.getCenter), 100,
-      function (data, status) {
-        // if streetView available
-        if (status === google.maps.StreetViewStatus.OK) {
-          deferred.resolve(data.location.pano);
-        } else {
-          // no street view available in this range, or some error occurred
-          deferred.resolve(false);
-          //deferred.reject('Geocoder failed due to: '+ status);
-        }
-      }
-    );
-    return deferred.promise;
-  };
-
-  /**
-   * Set panorama view on the given map with the panorama id
-   * @memberof StreetView
-   * @param {map} map Google map instance
-   * @param {String} panoId Panorama id fro getPanorama method
-   * @example
-   *   StreetView.setPanorama(map, panoId);
-   */
-  var setPanorama = function(map, panoId) {
-    var svp = new google.maps.StreetViewPanorama(
-      map.getDiv(), {enableCloseButton: true}
-    );
-    svp.setPano(panoId);
-  };
-
-  var StreetView = function(_$q_) {
-    $q = _$q_;
-
-    return {
-      getPanorama: getPanorama,
-      setPanorama: setPanorama
-    };
-  };
-  StreetView.$inject = ['$q'];
-
-  angular.module('ngMap').service('StreetView', StreetView);
-})();
-
-return 'ngMap';
-}));
-
-/***/ },
-/* 8 */
-/***/ function(module, exports) {
-
-/**
- * @license AngularJS v1.6.3
- * (c) 2010-2017 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular) {'use strict';
-
-/**
- * @ngdoc module
- * @name ngCookies
- * @description
- *
- * # ngCookies
- *
- * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
- *
- *
- * <div doc-module-components="ngCookies"></div>
- *
- * See {@link ngCookies.$cookies `$cookies`} for usage.
- */
-
-
-angular.module('ngCookies', ['ng']).
-  info({ angularVersion: '1.6.3' }).
-  /**
-   * @ngdoc provider
-   * @name $cookiesProvider
-   * @description
-   * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.
-   * */
-   provider('$cookies', [/** @this */function $CookiesProvider() {
-    /**
-     * @ngdoc property
-     * @name $cookiesProvider#defaults
-     * @description
-     *
-     * Object containing default options to pass when setting cookies.
-     *
-     * The object may have following properties:
-     *
-     * - **path** - `{string}` - The cookie will be available only for this path and its
-     *   sub-paths. By default, this is the URL that appears in your `<base>` tag.
-     * - **domain** - `{string}` - The cookie will be available only for this domain and
-     *   its sub-domains. For security reasons the user agent will not accept the cookie
-     *   if the current domain is not a sub-domain of this domain or equal to it.
-     * - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT"
-     *   or a Date object indicating the exact date/time this cookie will expire.
-     * - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a
-     *   secured connection.
-     *
-     * Note: By default, the address that appears in your `<base>` tag will be used as the path.
-     * This is important so that cookies will be visible for all routes when html5mode is enabled.
-     *
-     * @example
-     *
-     * ```js
-     * angular.module('cookiesProviderExample', ['ngCookies'])
-     *   .config(['$cookiesProvider', function($cookiesProvider) {
-     *     // Setting default options
-     *     $cookiesProvider.defaults.domain = 'foo.com';
-     *     $cookiesProvider.defaults.secure = true;
-     *   }]);
-     * ```
-     **/
-    var defaults = this.defaults = {};
-
-    function calcOptions(options) {
-      return options ? angular.extend({}, defaults, options) : defaults;
-    }
-
-    /**
-     * @ngdoc service
-     * @name $cookies
-     *
-     * @description
-     * Provides read/write access to browser's cookies.
-     *
-     * <div class="alert alert-info">
-     * Up until Angular 1.3, `$cookies` exposed properties that represented the
-     * current browser cookie values. In version 1.4, this behavior has changed, and
-     * `$cookies` now provides a standard api of getters, setters etc.
-     * </div>
-     *
-     * Requires the {@link ngCookies `ngCookies`} module to be installed.
-     *
-     * @example
-     *
-     * ```js
-     * angular.module('cookiesExample', ['ngCookies'])
-     *   .controller('ExampleController', ['$cookies', function($cookies) {
-     *     // Retrieving a cookie
-     *     var favoriteCookie = $cookies.get('myFavorite');
-     *     // Setting a cookie
-     *     $cookies.put('myFavorite', 'oatmeal');
-     *   }]);
-     * ```
-     */
-    this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {
-      return {
-        /**
-         * @ngdoc method
-         * @name $cookies#get
-         *
-         * @description
-         * Returns the value of given cookie key
-         *
-         * @param {string} key Id to use for lookup.
-         * @returns {string} Raw cookie value.
-         */
-        get: function(key) {
-          return $$cookieReader()[key];
-        },
-
-        /**
-         * @ngdoc method
-         * @name $cookies#getObject
-         *
-         * @description
-         * Returns the deserialized value of given cookie key
-         *
-         * @param {string} key Id to use for lookup.
-         * @returns {Object} Deserialized cookie value.
-         */
-        getObject: function(key) {
-          var value = this.get(key);
-          return value ? angular.fromJson(value) : value;
-        },
-
-        /**
-         * @ngdoc method
-         * @name $cookies#getAll
-         *
-         * @description
-         * Returns a key value object with all the cookies
-         *
-         * @returns {Object} All cookies
-         */
-        getAll: function() {
-          return $$cookieReader();
-        },
-
-        /**
-         * @ngdoc method
-         * @name $cookies#put
-         *
-         * @description
-         * Sets a value for given cookie key
-         *
-         * @param {string} key Id for the `value`.
-         * @param {string} value Raw value to be stored.
-         * @param {Object=} options Options object.
-         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
-         */
-        put: function(key, value, options) {
-          $$cookieWriter(key, value, calcOptions(options));
-        },
-
-        /**
-         * @ngdoc method
-         * @name $cookies#putObject
-         *
-         * @description
-         * Serializes and sets a value for given cookie key
-         *
-         * @param {string} key Id for the `value`.
-         * @param {Object} value Value to be stored.
-         * @param {Object=} options Options object.
-         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
-         */
-        putObject: function(key, value, options) {
-          this.put(key, angular.toJson(value), options);
-        },
-
-        /**
-         * @ngdoc method
-         * @name $cookies#remove
-         *
-         * @description
-         * Remove given cookie
-         *
-         * @param {string} key Id of the key-value pair to delete.
-         * @param {Object=} options Options object.
-         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
-         */
-        remove: function(key, options) {
-          $$cookieWriter(key, undefined, calcOptions(options));
-        }
-      };
-    }];
-  }]);
-
-angular.module('ngCookies').
-/**
- * @ngdoc service
- * @name $cookieStore
- * @deprecated
- * sinceVersion="v1.4.0"
- * Please use the {@link ngCookies.$cookies `$cookies`} service instead.
- *
- * @requires $cookies
- *
- * @description
- * Provides a key-value (string-object) storage, that is backed by session cookies.
- * Objects put or retrieved from this storage are automatically serialized or
- * deserialized by angular's toJson/fromJson.
- *
- * Requires the {@link ngCookies `ngCookies`} module to be installed.
- *
- * @example
- *
- * ```js
- * angular.module('cookieStoreExample', ['ngCookies'])
- *   .controller('ExampleController', ['$cookieStore', function($cookieStore) {
- *     // Put cookie
- *     $cookieStore.put('myFavorite','oatmeal');
- *     // Get cookie
- *     var favoriteCookie = $cookieStore.get('myFavorite');
- *     // Removing a cookie
- *     $cookieStore.remove('myFavorite');
- *   }]);
- * ```
- */
- factory('$cookieStore', ['$cookies', function($cookies) {
-
-    return {
-      /**
-       * @ngdoc method
-       * @name $cookieStore#get
-       *
-       * @description
-       * Returns the value of given cookie key
-       *
-       * @param {string} key Id to use for lookup.
-       * @returns {Object} Deserialized cookie value, undefined if the cookie does not exist.
-       */
-      get: function(key) {
-        return $cookies.getObject(key);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $cookieStore#put
-       *
-       * @description
-       * Sets a value for given cookie key
-       *
-       * @param {string} key Id for the `value`.
-       * @param {Object} value Value to be stored.
-       */
-      put: function(key, value) {
-        $cookies.putObject(key, value);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $cookieStore#remove
-       *
-       * @description
-       * Remove given cookie
-       *
-       * @param {string} key Id of the key-value pair to delete.
-       */
-      remove: function(key) {
-        $cookies.remove(key);
-      }
-    };
-
-  }]);
-
-/**
- * @name $$cookieWriter
- * @requires $document
- *
- * @description
- * This is a private service for writing cookies
- *
- * @param {string} name Cookie name
- * @param {string=} value Cookie value (if undefined, cookie will be deleted)
- * @param {Object=} options Object with options that need to be stored for the cookie.
- */
-function $$CookieWriter($document, $log, $browser) {
-  var cookiePath = $browser.baseHref();
-  var rawDocument = $document[0];
-
-  function buildCookieString(name, value, options) {
-    var path, expires;
-    options = options || {};
-    expires = options.expires;
-    path = angular.isDefined(options.path) ? options.path : cookiePath;
-    if (angular.isUndefined(value)) {
-      expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
-      value = '';
-    }
-    if (angular.isString(expires)) {
-      expires = new Date(expires);
-    }
-
-    var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);
-    str += path ? ';path=' + path : '';
-    str += options.domain ? ';domain=' + options.domain : '';
-    str += expires ? ';expires=' + expires.toUTCString() : '';
-    str += options.secure ? ';secure' : '';
-
-    // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
-    // - 300 cookies
-    // - 20 cookies per unique domain
-    // - 4096 bytes per cookie
-    var cookieLength = str.length + 1;
-    if (cookieLength > 4096) {
-      $log.warn('Cookie \'' + name +
-        '\' possibly not set or overflowed because it was too large (' +
-        cookieLength + ' > 4096 bytes)!');
-    }
-
-    return str;
-  }
-
-  return function(name, value, options) {
-    rawDocument.cookie = buildCookieString(name, value, options);
-  };
-}
-
-$$CookieWriter.$inject = ['$document', '$log', '$browser'];
-
-angular.module('ngCookies').provider('$$cookieWriter', /** @this */ function $$CookieWriterProvider() {
-  this.$get = $$CookieWriter;
-});
-
-
-})(window, window.angular);
-
-
-/***/ },
-/* 9 */
-/***/ function(module, exports) {
-
-/**
- * @license AngularJS v1.6.3
- * (c) 2010-2017 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular) {'use strict';
-
-var $resourceMinErr = angular.$$minErr('$resource');
-
-// Helper functions and regex to lookup a dotted path on an object
-// stopping at undefined/null.  The path must be composed of ASCII
-// identifiers (just like $parse)
-var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;
-
-function isValidDottedPath(path) {
-  return (path != null && path !== '' && path !== 'hasOwnProperty' &&
-      MEMBER_NAME_REGEX.test('.' + path));
-}
-
-function lookupDottedPath(obj, path) {
-  if (!isValidDottedPath(path)) {
-    throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
-  }
-  var keys = path.split('.');
-  for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {
-    var key = keys[i];
-    obj = (obj !== null) ? obj[key] : undefined;
-  }
-  return obj;
-}
-
-/**
- * Create a shallow copy of an object and clear other fields from the destination
- */
-function shallowClearAndCopy(src, dst) {
-  dst = dst || {};
-
-  angular.forEach(dst, function(value, key) {
-    delete dst[key];
-  });
-
-  for (var key in src) {
-    if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
-      dst[key] = src[key];
-    }
-  }
-
-  return dst;
-}
-
-/**
- * @ngdoc module
- * @name ngResource
- * @description
- *
- * # ngResource
- *
- * The `ngResource` module provides interaction support with RESTful services
- * via the $resource service.
- *
- *
- * <div doc-module-components="ngResource"></div>
- *
- * See {@link ngResource.$resourceProvider} and {@link ngResource.$resource} for usage.
- */
-
-/**
- * @ngdoc provider
- * @name $resourceProvider
- *
- * @description
- *
- * Use `$resourceProvider` to change the default behavior of the {@link ngResource.$resource}
- * service.
- *
- * ## Dependencies
- * Requires the {@link ngResource } module to be installed.
- *
- */
-
-/**
- * @ngdoc service
- * @name $resource
- * @requires $http
- * @requires ng.$log
- * @requires $q
- * @requires ng.$timeout
- *
- * @description
- * A factory which creates a resource object that lets you interact with
- * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
- *
- * The returned resource object has action methods which provide high-level behaviors without
- * the need to interact with the low level {@link ng.$http $http} service.
- *
- * Requires the {@link ngResource `ngResource`} module to be installed.
- *
- * By default, trailing slashes will be stripped from the calculated URLs,
- * which can pose problems with server backends that do not expect that
- * behavior.  This can be disabled by configuring the `$resourceProvider` like
- * this:
- *
- * ```js
-     app.config(['$resourceProvider', function($resourceProvider) {
-       // Don't strip trailing slashes from calculated URLs
-       $resourceProvider.defaults.stripTrailingSlashes = false;
-     }]);
- * ```
- *
- * @param {string} url A parameterized URL template with parameters prefixed by `:` as in
- *   `/user/:username`. If you are using a URL with a port number (e.g.
- *   `http://example.com:8080/api`), it will be respected.
- *
- *   If you are using a url with a suffix, just add the suffix, like this:
- *   `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
- *   or even `$resource('http://example.com/resource/:resource_id.:format')`
- *   If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
- *   collapsed down to a single `.`.  If you need this sequence to appear and not collapse then you
- *   can escape it with `/\.`.
- *
- * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
- *   `actions` methods. If a parameter value is a function, it will be called every time
- *   a param value needs to be obtained for a request (unless the param was overridden). The function
- *   will be passed the current data value as an argument.
- *
- *   Each key value in the parameter object is first bound to url template if present and then any
- *   excess keys are appended to the url search query after the `?`.
- *
- *   Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
- *   URL `/path/greet?salutation=Hello`.
- *
- *   If the parameter value is prefixed with `@`, then the value for that parameter will be
- *   extracted from the corresponding property on the `data` object (provided when calling a
- *   "non-GET" action method).
- *   For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of
- *   `someParam` will be `data.someProp`.
- *   Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action
- *   method that does not accept a request body)
- *
- * @param {Object.<Object>=} actions Hash with declaration of custom actions that will be available
- *   in addition to the default set of resource actions (see below). If a custom action has the same
- *   key as a default action (e.g. `save`), then the default action will be *overwritten*, and not
- *   extended.
- *
- *   The declaration should be created in the format of {@link ng.$http#usage $http.config}:
- *
- *       {action1: {method:?, params:?, isArray:?, headers:?, ...},
- *        action2: {method:?, params:?, isArray:?, headers:?, ...},
- *        ...}
- *
- *   Where:
- *
- *   - **`action`** – {string} – The name of action. This name becomes the name of the method on
- *     your resource object.
- *   - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`,
- *     `DELETE`, `JSONP`, etc).
- *   - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of
- *     the parameter value is a function, it will be called every time when a param value needs to
- *     be obtained for a request (unless the param was overridden). The function will be passed the
- *     current data value as an argument.
- *   - **`url`** – {string} – action specific `url` override. The url templating is supported just
- *     like for the resource-level urls.
- *   - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
- *     see `returns` section.
- *   - **`transformRequest`** –
- *     `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
- *     transform function or an array of such functions. The transform function takes the http
- *     request body and headers and returns its transformed (typically serialized) version.
- *     By default, transformRequest will contain one function that checks if the request data is
- *     an object and serializes it using `angular.toJson`. To prevent this behavior, set
- *     `transformRequest` to an empty array: `transformRequest: []`
- *   - **`transformResponse`** –
- *     `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –
- *     transform function or an array of such functions. The transform function takes the http
- *     response body, headers and status and returns its transformed (typically deserialized)
- *     version.
- *     By default, transformResponse will contain one function that checks if the response looks
- *     like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior,
- *     set `transformResponse` to an empty array: `transformResponse: []`
- *   - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
- *     GET request, otherwise if a cache instance built with
- *     {@link ng.$cacheFactory $cacheFactory} is supplied, this cache will be used for
- *     caching.
- *   - **`timeout`** – `{number}` – timeout in milliseconds.<br />
- *     **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are
- *     **not** supported in $resource, because the same value would be used for multiple requests.
- *     If you are looking for a way to cancel requests, you should use the `cancellable` option.
- *   - **`cancellable`** – `{boolean}` – if set to true, the request made by a "non-instance" call
- *     will be cancelled (if not already completed) by calling `$cancelRequest()` on the call's
- *     return value. Calling `$cancelRequest()` for a non-cancellable or an already
- *     completed/cancelled request will have no effect.<br />
- *   - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the
- *     XHR object. See
- *     [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)
- *     for more information.
- *   - **`responseType`** - `{string}` - see
- *     [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
- *   - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
- *     `response` and `responseError`. Both `response` and `responseError` interceptors get called
- *     with `http response` object. See {@link ng.$http $http interceptors}.
- *
- * @param {Object} options Hash with custom settings that should extend the
- *   default `$resourceProvider` behavior.  The supported options are:
- *
- *   - **`stripTrailingSlashes`** – {boolean} – If true then the trailing
- *   slashes from any calculated URL will be stripped. (Defaults to true.)
- *   - **`cancellable`** – {boolean} – If true, the request made by a "non-instance" call will be
- *   cancelled (if not already completed) by calling `$cancelRequest()` on the call's return value.
- *   This can be overwritten per action. (Defaults to false.)
- *
- * @returns {Object} A resource "class" object with methods for the default set of resource actions
- *   optionally extended with custom `actions`. The default set contains these actions:
- *   ```js
- *   { 'get':    {method:'GET'},
- *     'save':   {method:'POST'},
- *     'query':  {method:'GET', isArray:true},
- *     'remove': {method:'DELETE'},
- *     'delete': {method:'DELETE'} };
- *   ```
- *
- *   Calling these methods invoke an {@link ng.$http} with the specified http method,
- *   destination and parameters. When the data is returned from the server then the object is an
- *   instance of the resource class. The actions `save`, `remove` and `delete` are available on it
- *   as  methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
- *   read, update, delete) on server-side data like this:
- *   ```js
- *   var User = $resource('/user/:userId', {userId:'@id'});
- *   var user = User.get({userId:123}, function() {
- *     user.abc = true;
- *     user.$save();
- *   });
- *   ```
- *
- *   It is important to realize that invoking a $resource object method immediately returns an
- *   empty reference (object or array depending on `isArray`). Once the data is returned from the
- *   server the existing reference is populated with the actual data. This is a useful trick since
- *   usually the resource is assigned to a model which is then rendered by the view. Having an empty
- *   object results in no rendering, once the data arrives from the server then the object is
- *   populated with the data and the view automatically re-renders itself showing the new data. This
- *   means that in most cases one never has to write a callback function for the action methods.
- *
- *   The action methods on the class object or instance object can be invoked with the following
- *   parameters:
- *
- *   - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
- *   - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
- *   - non-GET instance actions:  `instance.$action([parameters], [success], [error])`
- *
- *
- *   Success callback is called with (value (Object|Array), responseHeaders (Function),
- *   status (number), statusText (string)) arguments, where the value is the populated resource
- *   instance or collection object. The error callback is called with (httpResponse) argument.
- *
- *   Class actions return empty instance (with additional properties below).
- *   Instance actions return promise of the action.
- *
- *   The Resource instances and collections have these additional properties:
- *
- *   - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
- *     instance or collection.
- *
- *     On success, the promise is resolved with the same resource instance or collection object,
- *     updated with data from server. This makes it easy to use in
- *     {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view
- *     rendering until the resource(s) are loaded.
- *
- *     On failure, the promise is rejected with the {@link ng.$http http response} object, without
- *     the `resource` property.
- *
- *     If an interceptor object was provided, the promise will instead be resolved with the value
- *     returned by the interceptor.
- *
- *   - `$resolved`: `true` after first server interaction is completed (either with success or
- *      rejection), `false` before that. Knowing if the Resource has been resolved is useful in
- *      data-binding.
- *
- *   The Resource instances and collections have these additional methods:
- *
- *   - `$cancelRequest`: If there is a cancellable, pending request related to the instance or
- *      collection, calling this method will abort the request.
- *
- *   The Resource instances have these additional methods:
- *
- *   - `toJSON`: It returns a simple object without any of the extra properties added as part of
- *     the Resource API. This object can be serialized through {@link angular.toJson} safely
- *     without attaching Angular-specific fields. Notice that `JSON.stringify` (and
- *     `angular.toJson`) automatically use this method when serializing a Resource instance
- *     (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior)).
- *
- * @example
- *
- * # Credit card resource
- *
- * ```js
-     // Define CreditCard class
-     var CreditCard = $resource('/user/:userId/card/:cardId',
-      {userId:123, cardId:'@id'}, {
-       charge: {method:'POST', params:{charge:true}}
-      });
-
-     // We can retrieve a collection from the server
-     var cards = CreditCard.query(function() {
-       // GET: /user/123/card
-       // server returns: [ {id:456, number:'1234', name:'Smith'} ];
-
-       var card = cards[0];
-       // each item is an instance of CreditCard
-       expect(card instanceof CreditCard).toEqual(true);
-       card.name = "J. Smith";
-       // non GET methods are mapped onto the instances
-       card.$save();
-       // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
-       // server returns: {id:456, number:'1234', name: 'J. Smith'};
-
-       // our custom method is mapped as well.
-       card.$charge({amount:9.99});
-       // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
-     });
-
-     // we can create an instance as well
-     var newCard = new CreditCard({number:'0123'});
-     newCard.name = "Mike Smith";
-     newCard.$save();
-     // POST: /user/123/card {number:'0123', name:'Mike Smith'}
-     // server returns: {id:789, number:'0123', name: 'Mike Smith'};
-     expect(newCard.id).toEqual(789);
- * ```
- *
- * The object returned from this function execution is a resource "class" which has "static" method
- * for each action in the definition.
- *
- * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and
- * `headers`.
- *
- * @example
- *
- * # User resource
- *
- * When the data is returned from the server then the object is an instance of the resource type and
- * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
- * operations (create, read, update, delete) on server-side data.
-
-   ```js
-     var User = $resource('/user/:userId', {userId:'@id'});
-     User.get({userId:123}, function(user) {
-       user.abc = true;
-       user.$save();
-     });
-   ```
- *
- * It's worth noting that the success callback for `get`, `query` and other methods gets passed
- * in the response that came from the server as well as $http header getter function, so one
- * could rewrite the above example and get access to http headers as:
- *
-   ```js
-     var User = $resource('/user/:userId', {userId:'@id'});
-     User.get({userId:123}, function(user, getResponseHeaders){
-       user.abc = true;
-       user.$save(function(user, putResponseHeaders) {
-         //user => saved user object
-         //putResponseHeaders => $http header getter
-       });
-     });
-   ```
- *
- * You can also access the raw `$http` promise via the `$promise` property on the object returned
- *
-   ```
-     var User = $resource('/user/:userId', {userId:'@id'});
-     User.get({userId:123})
-         .$promise.then(function(user) {
-           $scope.user = user;
-         });
-   ```
- *
- * @example
- *
- * # Creating a custom 'PUT' request
- *
- * In this example we create a custom method on our resource to make a PUT request
- * ```js
- *    var app = angular.module('app', ['ngResource', 'ngRoute']);
- *
- *    // Some APIs expect a PUT request in the format URL/object/ID
- *    // Here we are creating an 'update' method
- *    app.factory('Notes', ['$resource', function($resource) {
- *    return $resource('/notes/:id', null,
- *        {
- *            'update': { method:'PUT' }
- *        });
- *    }]);
- *
- *    // In our controller we get the ID from the URL using ngRoute and $routeParams
- *    // We pass in $routeParams and our Notes factory along with $scope
- *    app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
-                                      function($scope, $routeParams, Notes) {
- *    // First get a note object from the factory
- *    var note = Notes.get({ id:$routeParams.id });
- *    $id = note.id;
- *
- *    // Now call update passing in the ID first then the object you are updating
- *    Notes.update({ id:$id }, note);
- *
- *    // This will PUT /notes/ID with the note object in the request payload
- *    }]);
- * ```
- *
- * @example
- *
- * # Cancelling requests
- *
- * If an action's configuration specifies that it is cancellable, you can cancel the request related
- * to an instance or collection (as long as it is a result of a "non-instance" call):
- *
-   ```js
-     // ...defining the `Hotel` resource...
-     var Hotel = $resource('/api/hotel/:id', {id: '@id'}, {
-       // Let's make the `query()` method cancellable
-       query: {method: 'get', isArray: true, cancellable: true}
-     });
-
-     // ...somewhere in the PlanVacationController...
-     ...
-     this.onDestinationChanged = function onDestinationChanged(destination) {
-       // We don't care about any pending request for hotels
-       // in a different destination any more
-       this.availableHotels.$cancelRequest();
-
-       // Let's query for hotels in '<destination>'
-       // (calls: /api/hotel?location=<destination>)
-       this.availableHotels = Hotel.query({location: destination});
-     };
-   ```
- *
- */
-angular.module('ngResource', ['ng']).
-  info({ angularVersion: '1.6.3' }).
-  provider('$resource', function ResourceProvider() {
-    var PROTOCOL_AND_IPV6_REGEX = /^https?:\/\/\[[^\]]*][^/]*/;
-
-    var provider = this;
-
-    /**
-     * @ngdoc property
-     * @name $resourceProvider#defaults
-     * @description
-     * Object containing default options used when creating `$resource` instances.
-     *
-     * The default values satisfy a wide range of usecases, but you may choose to overwrite any of
-     * them to further customize your instances. The available properties are:
-     *
-     * - **stripTrailingSlashes** – `{boolean}` – If true, then the trailing slashes from any
-     *   calculated URL will be stripped.<br />
-     *   (Defaults to true.)
-     * - **cancellable** – `{boolean}` – If true, the request made by a "non-instance" call will be
-     *   cancelled (if not already completed) by calling `$cancelRequest()` on the call's return
-     *   value. For more details, see {@link ngResource.$resource}. This can be overwritten per
-     *   resource class or action.<br />
-     *   (Defaults to false.)
-     * - **actions** - `{Object.<Object>}` - A hash with default actions declarations. Actions are
-     *   high-level methods corresponding to RESTful actions/methods on resources. An action may
-     *   specify what HTTP method to use, what URL to hit, if the return value will be a single
-     *   object or a collection (array) of objects etc. For more details, see
-     *   {@link ngResource.$resource}. The actions can also be enhanced or overwritten per resource
-     *   class.<br />
-     *   The default actions are:
-     *   ```js
-     *   {
-     *     get: {method: 'GET'},
-     *     save: {method: 'POST'},
-     *     query: {method: 'GET', isArray: true},
-     *     remove: {method: 'DELETE'},
-     *     delete: {method: 'DELETE'}
-     *   }
-     *   ```
-     *
-     * #### Example
-     *
-     * For example, you can specify a new `update` action that uses the `PUT` HTTP verb:
-     *
-     * ```js
-     *   angular.
-     *     module('myApp').
-     *     config(['$resourceProvider', function ($resourceProvider) {
-     *       $resourceProvider.defaults.actions.update = {
-     *         method: 'PUT'
-     *       };
-     *     });
-     * ```
-     *
-     * Or you can even overwrite the whole `actions` list and specify your own:
-     *
-     * ```js
-     *   angular.
-     *     module('myApp').
-     *     config(['$resourceProvider', function ($resourceProvider) {
-     *       $resourceProvider.defaults.actions = {
-     *         create: {method: 'POST'},
-     *         get:    {method: 'GET'},
-     *         getAll: {method: 'GET', isArray:true},
-     *         update: {method: 'PUT'},
-     *         delete: {method: 'DELETE'}
-     *       };
-     *     });
-     * ```
-     *
-     */
-    this.defaults = {
-      // Strip slashes by default
-      stripTrailingSlashes: true,
-
-      // Make non-instance requests cancellable (via `$cancelRequest()`)
-      cancellable: false,
-
-      // Default actions configuration
-      actions: {
-        'get': {method: 'GET'},
-        'save': {method: 'POST'},
-        'query': {method: 'GET', isArray: true},
-        'remove': {method: 'DELETE'},
-        'delete': {method: 'DELETE'}
-      }
-    };
-
-    this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) {
-
-      var noop = angular.noop,
-          forEach = angular.forEach,
-          extend = angular.extend,
-          copy = angular.copy,
-          isArray = angular.isArray,
-          isDefined = angular.isDefined,
-          isFunction = angular.isFunction,
-          isNumber = angular.isNumber,
-          encodeUriQuery = angular.$$encodeUriQuery,
-          encodeUriSegment = angular.$$encodeUriSegment;
-
-      function Route(template, defaults) {
-        this.template = template;
-        this.defaults = extend({}, provider.defaults, defaults);
-        this.urlParams = {};
-      }
-
-      Route.prototype = {
-        setUrlParams: function(config, params, actionUrl) {
-          var self = this,
-            url = actionUrl || self.template,
-            val,
-            encodedVal,
-            protocolAndIpv6 = '';
-
-          var urlParams = self.urlParams = Object.create(null);
-          forEach(url.split(/\W/), function(param) {
-            if (param === 'hasOwnProperty') {
-              throw $resourceMinErr('badname', 'hasOwnProperty is not a valid parameter name.');
-            }
-            if (!(new RegExp('^\\d+$').test(param)) && param &&
-              (new RegExp('(^|[^\\\\]):' + param + '(\\W|$)').test(url))) {
-              urlParams[param] = {
-                isQueryParamValue: (new RegExp('\\?.*=:' + param + '(?:\\W|$)')).test(url)
-              };
-            }
-          });
-          url = url.replace(/\\:/g, ':');
-          url = url.replace(PROTOCOL_AND_IPV6_REGEX, function(match) {
-            protocolAndIpv6 = match;
-            return '';
-          });
-
-          params = params || {};
-          forEach(self.urlParams, function(paramInfo, urlParam) {
-            val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
-            if (isDefined(val) && val !== null) {
-              if (paramInfo.isQueryParamValue) {
-                encodedVal = encodeUriQuery(val, true);
-              } else {
-                encodedVal = encodeUriSegment(val);
-              }
-              url = url.replace(new RegExp(':' + urlParam + '(\\W|$)', 'g'), function(match, p1) {
-                return encodedVal + p1;
-              });
-            } else {
-              url = url.replace(new RegExp('(/?):' + urlParam + '(\\W|$)', 'g'), function(match,
-                  leadingSlashes, tail) {
-                if (tail.charAt(0) === '/') {
-                  return tail;
-                } else {
-                  return leadingSlashes + tail;
-                }
-              });
-            }
-          });
-
-          // strip trailing slashes and set the url (unless this behavior is specifically disabled)
-          if (self.defaults.stripTrailingSlashes) {
-            url = url.replace(/\/+$/, '') || '/';
-          }
-
-          // Collapse `/.` if found in the last URL path segment before the query.
-          // E.g. `http://url.com/id/.format?q=x` becomes `http://url.com/id.format?q=x`.
-          url = url.replace(/\/\.(?=\w+($|\?))/, '.');
-          // Replace escaped `/\.` with `/.`.
-          // (If `\.` comes from a param value, it will be encoded as `%5C.`.)
-          config.url = protocolAndIpv6 + url.replace(/\/(\\|%5C)\./, '/.');
-
-
-          // set params - delegate param encoding to $http
-          forEach(params, function(value, key) {
-            if (!self.urlParams[key]) {
-              config.params = config.params || {};
-              config.params[key] = value;
-            }
-          });
-        }
-      };
-
-
-      function resourceFactory(url, paramDefaults, actions, options) {
-        var route = new Route(url, options);
-
-        actions = extend({}, provider.defaults.actions, actions);
-
-        function extractParams(data, actionParams) {
-          var ids = {};
-          actionParams = extend({}, paramDefaults, actionParams);
-          forEach(actionParams, function(value, key) {
-            if (isFunction(value)) { value = value(data); }
-            ids[key] = value && value.charAt && value.charAt(0) === '@' ?
-              lookupDottedPath(data, value.substr(1)) : value;
-          });
-          return ids;
-        }
-
-        function defaultResponseInterceptor(response) {
-          return response.resource;
-        }
-
-        function Resource(value) {
-          shallowClearAndCopy(value || {}, this);
-        }
-
-        Resource.prototype.toJSON = function() {
-          var data = extend({}, this);
-          delete data.$promise;
-          delete data.$resolved;
-          delete data.$cancelRequest;
-          return data;
-        };
-
-        forEach(actions, function(action, name) {
-          var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
-          var numericTimeout = action.timeout;
-          var cancellable = isDefined(action.cancellable) ?
-              action.cancellable : route.defaults.cancellable;
-
-          if (numericTimeout && !isNumber(numericTimeout)) {
-            $log.debug('ngResource:\n' +
-                       '  Only numeric values are allowed as `timeout`.\n' +
-                       '  Promises are not supported in $resource, because the same value would ' +
-                       'be used for multiple requests. If you are looking for a way to cancel ' +
-                       'requests, you should use the `cancellable` option.');
-            delete action.timeout;
-            numericTimeout = null;
-          }
-
-          Resource[name] = function(a1, a2, a3, a4) {
-            var params = {}, data, success, error;
-
-            switch (arguments.length) {
-              case 4:
-                error = a4;
-                success = a3;
-                // falls through
-              case 3:
-              case 2:
-                if (isFunction(a2)) {
-                  if (isFunction(a1)) {
-                    success = a1;
-                    error = a2;
-                    break;
-                  }
-
-                  success = a2;
-                  error = a3;
-                  // falls through
-                } else {
-                  params = a1;
-                  data = a2;
-                  success = a3;
-                  break;
-                }
-                // falls through
-              case 1:
-                if (isFunction(a1)) success = a1;
-                else if (hasBody) data = a1;
-                else params = a1;
-                break;
-              case 0: break;
-              default:
-                throw $resourceMinErr('badargs',
-                  'Expected up to 4 arguments [params, data, success, error], got {0} arguments',
-                  arguments.length);
-            }
-
-            var isInstanceCall = this instanceof Resource;
-            var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
-            var httpConfig = {};
-            var responseInterceptor = action.interceptor && action.interceptor.response ||
-              defaultResponseInterceptor;
-            var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
-              undefined;
-            var hasError = !!error;
-            var hasResponseErrorInterceptor = !!responseErrorInterceptor;
-            var timeoutDeferred;
-            var numericTimeoutPromise;
-
-            forEach(action, function(value, key) {
-              switch (key) {
-                default:
-                  httpConfig[key] = copy(value);
-                  break;
-                case 'params':
-                case 'isArray':
-                case 'interceptor':
-                case 'cancellable':
-                  break;
-              }
-            });
-
-            if (!isInstanceCall && cancellable) {
-              timeoutDeferred = $q.defer();
-              httpConfig.timeout = timeoutDeferred.promise;
-
-              if (numericTimeout) {
-                numericTimeoutPromise = $timeout(timeoutDeferred.resolve, numericTimeout);
-              }
-            }
-
-            if (hasBody) httpConfig.data = data;
-            route.setUrlParams(httpConfig,
-              extend({}, extractParams(data, action.params || {}), params),
-              action.url);
-
-            var promise = $http(httpConfig).then(function(response) {
-              var data = response.data;
-
-              if (data) {
-                // Need to convert action.isArray to boolean in case it is undefined
-                if (isArray(data) !== (!!action.isArray)) {
-                  throw $resourceMinErr('badcfg',
-                      'Error in resource configuration for action `{0}`. Expected response to ' +
-                      'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',
-                    isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);
-                }
-                if (action.isArray) {
-                  value.length = 0;
-                  forEach(data, function(item) {
-                    if (typeof item === 'object') {
-                      value.push(new Resource(item));
-                    } else {
-                      // Valid JSON values may be string literals, and these should not be converted
-                      // into objects. These items will not have access to the Resource prototype
-                      // methods, but unfortunately there
-                      value.push(item);
-                    }
-                  });
-                } else {
-                  var promise = value.$promise;     // Save the promise
-                  shallowClearAndCopy(data, value);
-                  value.$promise = promise;         // Restore the promise
-                }
-              }
-              response.resource = value;
-
-              return response;
-            });
-
-            promise = promise['finally'](function() {
-              value.$resolved = true;
-              if (!isInstanceCall && cancellable) {
-                value.$cancelRequest = noop;
-                $timeout.cancel(numericTimeoutPromise);
-                timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null;
-              }
-            });
-
-            promise = promise.then(
-              function(response) {
-                var value = responseInterceptor(response);
-                (success || noop)(value, response.headers, response.status, response.statusText);
-                return value;
-              },
-              (hasError || hasResponseErrorInterceptor) ?
-                function(response) {
-                  if (hasError && !hasResponseErrorInterceptor) {
-                    // Avoid `Possibly Unhandled Rejection` error,
-                    // but still fulfill the returned promise with a rejection
-                    promise.catch(noop);
-                  }
-                  if (hasError) error(response);
-                  return hasResponseErrorInterceptor ?
-                    responseErrorInterceptor(response) :
-                    $q.reject(response);
-                } :
-                undefined);
-
-            if (!isInstanceCall) {
-              // we are creating instance / collection
-              // - set the initial promise
-              // - return the instance / collection
-              value.$promise = promise;
-              value.$resolved = false;
-              if (cancellable) value.$cancelRequest = cancelRequest;
-
-              return value;
-            }
-
-            // instance call
-            return promise;
-
-            function cancelRequest(value) {
-              promise.catch(noop);
-              timeoutDeferred.resolve(value);
-            }
-          };
-
-
-          Resource.prototype['$' + name] = function(params, success, error) {
-            if (isFunction(params)) {
-              error = success; success = params; params = {};
-            }
-            var result = Resource[name].call(this, params, this, success, error);
-            return result.$promise || result;
-          };
-        });
-
-        Resource.bind = function(additionalParamDefaults) {
-          var extendedParamDefaults = extend({}, paramDefaults, additionalParamDefaults);
-          return resourceFactory(url, extendedParamDefaults, actions, options);
-        };
-
-        return Resource;
-      }
-
-      return resourceFactory;
-    }];
-  });
-
-
-})(window, window.angular);
-
-
-/***/ },
-/* 10 */
-/***/ function(module, exports) {
-
-/**
- * @license AngularJS v1.6.3
- * (c) 2010-2017 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window) {'use strict';
-
-/**
- * @description
- *
- * This object provides a utility for producing rich Error messages within
- * Angular. It can be called as follows:
- *
- * var exampleMinErr = minErr('example');
- * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
- *
- * The above creates an instance of minErr in the example namespace. The
- * resulting error will have a namespaced error code of example.one.  The
- * resulting error will replace {0} with the value of foo, and {1} with the
- * value of bar. The object is not restricted in the number of arguments it can
- * take.
- *
- * If fewer arguments are specified than necessary for interpolation, the extra
- * interpolation markers will be preserved in the final string.
- *
- * Since data will be parsed statically during a build step, some restrictions
- * are applied with respect to how minErr instances are created and called.
- * Instances should have names of the form namespaceMinErr for a minErr created
- * using minErr('namespace') . Error codes, namespaces and template strings
- * should all be static strings, not variables or general expressions.
- *
- * @param {string} module The namespace to use for the new minErr instance.
- * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
- *   error from returned function, for cases when a particular type of error is useful.
- * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
- */
-
-function minErr(module, ErrorConstructor) {
-  ErrorConstructor = ErrorConstructor || Error;
-  return function() {
-    var code = arguments[0],
-      template = arguments[1],
-      message = '[' + (module ? module + ':' : '') + code + '] ',
-      templateArgs = sliceArgs(arguments, 2).map(function(arg) {
-        return toDebugString(arg, minErrConfig.objectMaxDepth);
-      }),
-      paramPrefix, i;
-
-    message += template.replace(/\{\d+\}/g, function(match) {
-      var index = +match.slice(1, -1);
-
-      if (index < templateArgs.length) {
-        return templateArgs[index];
-      }
-
-      return match;
-    });
-
-    message += '\nhttp://errors.angularjs.org/1.6.3/' +
-      (module ? module + '/' : '') + code;
-
-    for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
-      message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]);
-    }
-
-    return new ErrorConstructor(message);
-  };
-}
-
-/* We need to tell ESLint what variables are being exported */
-/* exported
-  angular,
-  msie,
-  jqLite,
-  jQuery,
-  slice,
-  splice,
-  push,
-  toString,
-  minErrConfig,
-  errorHandlingConfig,
-  isValidObjectMaxDepth,
-  ngMinErr,
-  angularModule,
-  uid,
-  REGEX_STRING_REGEXP,
-  VALIDITY_STATE_PROPERTY,
-
-  lowercase,
-  uppercase,
-  manualLowercase,
-  manualUppercase,
-  nodeName_,
-  isArrayLike,
-  forEach,
-  forEachSorted,
-  reverseParams,
-  nextUid,
-  setHashKey,
-  extend,
-  toInt,
-  inherit,
-  merge,
-  noop,
-  identity,
-  valueFn,
-  isUndefined,
-  isDefined,
-  isObject,
-  isBlankObject,
-  isString,
-  isNumber,
-  isNumberNaN,
-  isDate,
-  isArray,
-  isFunction,
-  isRegExp,
-  isWindow,
-  isScope,
-  isFile,
-  isFormData,
-  isBlob,
-  isBoolean,
-  isPromiseLike,
-  trim,
-  escapeForRegexp,
-  isElement,
-  makeMap,
-  includes,
-  arrayRemove,
-  copy,
-  equals,
-  csp,
-  jq,
-  concat,
-  sliceArgs,
-  bind,
-  toJsonReplacer,
-  toJson,
-  fromJson,
-  convertTimezoneToLocal,
-  timezoneToOffset,
-  startingTag,
-  tryDecodeURIComponent,
-  parseKeyValue,
-  toKeyValue,
-  encodeUriSegment,
-  encodeUriQuery,
-  angularInit,
-  bootstrap,
-  getTestability,
-  snake_case,
-  bindJQuery,
-  assertArg,
-  assertArgFn,
-  assertNotHasOwnProperty,
-  getter,
-  getBlockNodes,
-  hasOwnProperty,
-  createMap,
-  stringify,
-
-  NODE_TYPE_ELEMENT,
-  NODE_TYPE_ATTRIBUTE,
-  NODE_TYPE_TEXT,
-  NODE_TYPE_COMMENT,
-  NODE_TYPE_DOCUMENT,
-  NODE_TYPE_DOCUMENT_FRAGMENT
-*/
-
-////////////////////////////////////
-
-/**
- * @ngdoc module
- * @name ng
- * @module ng
- * @installation
- * @description
- *
- * # ng (core module)
- * The ng module is loaded by default when an AngularJS application is started. The module itself
- * contains the essential components for an AngularJS application to function. The table below
- * lists a high level breakdown of each of the services/factories, filters, directives and testing
- * components available within this core module.
- *
- * <div doc-module-components="ng"></div>
- */
-
-var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
-
-// The name of a form control's ValidityState property.
-// This is used so that it's possible for internal tests to create mock ValidityStates.
-var VALIDITY_STATE_PROPERTY = 'validity';
-
-
-var hasOwnProperty = Object.prototype.hasOwnProperty;
-
-var minErrConfig = {
-  objectMaxDepth: 5
-};
-
- /**
- * @ngdoc function
- * @name angular.errorHandlingConfig
- * @module ng
- * @kind function
- *
- * @description
- * Configure several aspects of error handling in AngularJS if used as a setter or return the
- * current configuration if used as a getter. The following options are supported:
- *
- * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.
- *
- * Omitted or undefined options will leave the corresponding configuration values unchanged.
- *
- * @param {Object=} config - The configuration object. May only contain the options that need to be
- *     updated. Supported keys:
- *
- * * `objectMaxDepth`  **{Number}** - The max depth for stringifying objects. Setting to a
- *   non-positive or non-numeric value, removes the max depth limit.
- *   Default: 5
- */
-function errorHandlingConfig(config) {
-  if (isObject(config)) {
-    if (isDefined(config.objectMaxDepth)) {
-      minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;
-    }
-  } else {
-    return minErrConfig;
-  }
-}
-
-/**
- * @private
- * @param {Number} maxDepth
- * @return {boolean}
- */
-function isValidObjectMaxDepth(maxDepth) {
-  return isNumber(maxDepth) && maxDepth > 0;
-}
-
-/**
- * @ngdoc function
- * @name angular.lowercase
- * @module ng
- * @kind function
- *
- * @deprecated
- * sinceVersion="1.5.0"
- * removeVersion="1.7.0"
- * Use [String.prototype.toLowerCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) instead.
- *
- * @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
- * @module ng
- * @kind function
- *
- * @deprecated
- * sinceVersion="1.5.0"
- * removeVersion="1.7.0"
- * Use [String.prototype.toUpperCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) instead.
- *
- * @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) {
-  /* eslint-disable no-bitwise */
-  return isString(s)
-      ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
-      : s;
-  /* eslint-enable */
-};
-var manualUppercase = function(s) {
-  /* eslint-disable no-bitwise */
-  return isString(s)
-      ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
-      : s;
-  /* eslint-enable */
-};
-
-
-// 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. See https://github.com/angular/angular.js/issues/11387
-if ('i' !== 'I'.toLowerCase()) {
-  lowercase = manualLowercase;
-  uppercase = manualUppercase;
-}
-
-
-var
-    msie,             // holds major version number for IE, or NaN if UA is not IE.
-    jqLite,           // delay binding since jQuery could be loaded after us.
-    jQuery,           // delay binding
-    slice             = [].slice,
-    splice            = [].splice,
-    push              = [].push,
-    toString          = Object.prototype.toString,
-    getPrototypeOf    = Object.getPrototypeOf,
-    ngMinErr          = minErr('ng'),
-
-    /** @name angular */
-    angular           = window.angular || (window.angular = {}),
-    angularModule,
-    uid               = 0;
-
-// Support: IE 9-11 only
-/**
- * documentMode is an IE-only property
- * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
- */
-msie = window.document.documentMode;
-
-
-/**
- * @private
- * @param {*} obj
- * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
- *                   String ...)
- */
-function isArrayLike(obj) {
-
-  // `null`, `undefined` and `window` are not array-like
-  if (obj == null || isWindow(obj)) return false;
-
-  // arrays, strings and jQuery/jqLite objects are array like
-  // * jqLite is either the jQuery or jqLite constructor function
-  // * we have to check the existence of jqLite first as this method is called
-  //   via the forEach method when constructing the jqLite object in the first place
-  if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;
-
-  // Support: iOS 8.2 (not reproducible in simulator)
-  // "length" in obj used to prevent JIT error (gh-11508)
-  var length = 'length' in Object(obj) && obj.length;
-
-  // NodeList objects (with `item` method) and
-  // other objects with suitable length characteristics are array-like
-  return isNumber(length) &&
-    (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item === 'function');
-
-}
-
-/**
- * @ngdoc function
- * @name angular.forEach
- * @module ng
- * @kind 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, obj)`, where `value`
- * is the value of an object property or an array element, `key` is the object property key or
- * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
- *
- * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
- * using the `hasOwnProperty` method.
- *
- * Unlike ES262's
- * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
- * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
- * return the value provided.
- *
-   ```js
-     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']);
-   ```
- *
- * @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, length;
-  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, obj);
-        }
-      }
-    } else if (isArray(obj) || isArrayLike(obj)) {
-      var isPrimitive = typeof obj !== 'object';
-      for (key = 0, length = obj.length; key < length; key++) {
-        if (isPrimitive || key in obj) {
-          iterator.call(context, obj[key], key, obj);
-        }
-      }
-    } else if (obj.forEach && obj.forEach !== forEach) {
-        obj.forEach(iterator, context, obj);
-    } else if (isBlankObject(obj)) {
-      // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
-      for (key in obj) {
-        iterator.call(context, obj[key], key, obj);
-      }
-    } else if (typeof obj.hasOwnProperty === 'function') {
-      // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
-      for (key in obj) {
-        if (obj.hasOwnProperty(key)) {
-          iterator.call(context, obj[key], key, obj);
-        }
-      }
-    } else {
-      // Slow path for objects which do not have a method `hasOwnProperty`
-      for (key in obj) {
-        if (hasOwnProperty.call(obj, key)) {
-          iterator.call(context, obj[key], key, obj);
-        }
-      }
-    }
-  }
-  return obj;
-}
-
-function forEachSorted(obj, iterator, context) {
-  var keys = Object.keys(obj).sort();
-  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.
- *
- * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
- * we hit number precision issues in JavaScript.
- *
- * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
- *
- * @returns {number} an unique alpha-numeric string
- */
-function nextUid() {
-  return ++uid;
-}
-
-
-/**
- * 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;
-  }
-}
-
-
-function baseExtend(dst, objs, deep) {
-  var h = dst.$$hashKey;
-
-  for (var i = 0, ii = objs.length; i < ii; ++i) {
-    var obj = objs[i];
-    if (!isObject(obj) && !isFunction(obj)) continue;
-    var keys = Object.keys(obj);
-    for (var j = 0, jj = keys.length; j < jj; j++) {
-      var key = keys[j];
-      var src = obj[key];
-
-      if (deep && isObject(src)) {
-        if (isDate(src)) {
-          dst[key] = new Date(src.valueOf());
-        } else if (isRegExp(src)) {
-          dst[key] = new RegExp(src);
-        } else if (src.nodeName) {
-          dst[key] = src.cloneNode(true);
-        } else if (isElement(src)) {
-          dst[key] = src.clone();
-        } else {
-          if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
-          baseExtend(dst[key], [src], true);
-        }
-      } else {
-        dst[key] = src;
-      }
-    }
-  }
-
-  setHashKey(dst, h);
-  return dst;
-}
-
-/**
- * @ngdoc function
- * @name angular.extend
- * @module ng
- * @kind function
- *
- * @description
- * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
- * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
- * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
- *
- * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use
- * {@link angular.merge} for this.
- *
- * @param {Object} dst Destination object.
- * @param {...Object} src Source object(s).
- * @returns {Object} Reference to `dst`.
- */
-function extend(dst) {
-  return baseExtend(dst, slice.call(arguments, 1), false);
-}
-
-
-/**
-* @ngdoc function
-* @name angular.merge
-* @module ng
-* @kind function
-*
-* @description
-* Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
-* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
-* by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.
-*
-* Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source
-* objects, performing a deep copy.
-*
-* @param {Object} dst Destination object.
-* @param {...Object} src Source object(s).
-* @returns {Object} Reference to `dst`.
-*/
-function merge(dst) {
-  return baseExtend(dst, slice.call(arguments, 1), true);
-}
-
-
-
-function toInt(str) {
-  return parseInt(str, 10);
-}
-
-var isNumberNaN = Number.isNaN || function isNumberNaN(num) {
-  // eslint-disable-next-line no-self-compare
-  return num !== num;
-};
-
-
-function inherit(parent, extra) {
-  return extend(Object.create(parent), extra);
-}
-
-/**
- * @ngdoc function
- * @name angular.noop
- * @module ng
- * @kind function
- *
- * @description
- * A function that performs no operations. This function can be useful when writing code in the
- * functional style.
-   ```js
-     function foo(callback) {
-       var result = calculateResult();
-       (callback || angular.noop)(result);
-     }
-   ```
- */
-function noop() {}
-noop.$inject = [];
-
-
-/**
- * @ngdoc function
- * @name angular.identity
- * @module ng
- * @kind function
- *
- * @description
- * A function that returns its first argument. This function is useful when writing code in the
- * functional style.
- *
-   ```js
-   function transformer(transformationFn, value) {
-     return (transformationFn || angular.identity)(value);
-   };
-
-   // E.g.
-   function getResult(fn, input) {
-     return (fn || angular.identity)(input);
-   };
-
-   getResult(function(n) { return n * 2; }, 21);   // returns 42
-   getResult(null, 21);                            // returns 21
-   getResult(undefined, 21);                       // returns 21
-   ```
- *
- * @param {*} value to be returned.
- * @returns {*} the value passed in.
- */
-function identity($) {return $;}
-identity.$inject = [];
-
-
-function valueFn(value) {return function valueRef() {return value;};}
-
-function hasCustomToString(obj) {
-  return isFunction(obj.toString) && obj.toString !== toString;
-}
-
-
-/**
- * @ngdoc function
- * @name angular.isUndefined
- * @module ng
- * @kind 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 === 'undefined';}
-
-
-/**
- * @ngdoc function
- * @name angular.isDefined
- * @module ng
- * @kind 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
- * @module ng
- * @kind function
- *
- * @description
- * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
- * considered to be objects. Note that JavaScript arrays are objects.
- *
- * @param {*} value Reference to check.
- * @returns {boolean} True if `value` is an `Object` but not `null`.
- */
-function isObject(value) {
-  // http://jsperf.com/isobject4
-  return value !== null && typeof value === 'object';
-}
-
-
-/**
- * Determine if a value is an object with a null prototype
- *
- * @returns {boolean} True if `value` is an `Object` with a null prototype
- */
-function isBlankObject(value) {
-  return value !== null && typeof value === 'object' && !getPrototypeOf(value);
-}
-
-
-/**
- * @ngdoc function
- * @name angular.isString
- * @module ng
- * @kind 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 === 'string';}
-
-
-/**
- * @ngdoc function
- * @name angular.isNumber
- * @module ng
- * @kind function
- *
- * @description
- * Determines if a reference is a `Number`.
- *
- * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
- *
- * If you wish to exclude these then you can use the native
- * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
- * method.
- *
- * @param {*} value Reference to check.
- * @returns {boolean} True if `value` is a `Number`.
- */
-function isNumber(value) {return typeof value === 'number';}
-
-
-/**
- * @ngdoc function
- * @name angular.isDate
- * @module ng
- * @kind 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.call(value) === '[object Date]';
-}
-
-
-/**
- * @ngdoc function
- * @name angular.isArray
- * @module ng
- * @kind function
- *
- * @description
- * Determines if a reference is an `Array`. Alias of Array.isArray.
- *
- * @param {*} value Reference to check.
- * @returns {boolean} True if `value` is an `Array`.
- */
-var isArray = Array.isArray;
-
-/**
- * @ngdoc function
- * @name angular.isFunction
- * @module ng
- * @kind 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 === '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.call(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.window === obj;
-}
-
-
-function isScope(obj) {
-  return obj && obj.$evalAsync && obj.$watch;
-}
-
-
-function isFile(obj) {
-  return toString.call(obj) === '[object File]';
-}
-
-
-function isFormData(obj) {
-  return toString.call(obj) === '[object FormData]';
-}
-
-
-function isBlob(obj) {
-  return toString.call(obj) === '[object Blob]';
-}
-
-
-function isBoolean(value) {
-  return typeof value === 'boolean';
-}
-
-
-function isPromiseLike(obj) {
-  return obj && isFunction(obj.then);
-}
-
-
-var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array]$/;
-function isTypedArray(value) {
-  return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));
-}
-
-function isArrayBuffer(obj) {
-  return toString.call(obj) === '[object ArrayBuffer]';
-}
-
-
-var trim = function(value) {
-  return isString(value) ? value.trim() : value;
-};
-
-// Copied from:
-// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
-// Prereq: s is a string.
-var escapeForRegexp = function(s) {
-  return s
-    .replace(/([-()[\]{}+?*.$^|,:#<!\\])/g, '\\$1')
-    // eslint-disable-next-line no-control-regex
-    .replace(/\x08/g, '\\x08');
-};
-
-
-/**
- * @ngdoc function
- * @name angular.isElement
- * @module ng
- * @kind 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.prop && node.attr && 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;
-}
-
-
-function nodeName_(element) {
-  return lowercase(element.nodeName || (element[0] && element[0].nodeName));
-}
-
-function includes(array, obj) {
-  return Array.prototype.indexOf.call(array, obj) !== -1;
-}
-
-function arrayRemove(array, value) {
-  var index = array.indexOf(value);
-  if (index >= 0) {
-    array.splice(index, 1);
-  }
-  return index;
-}
-
-/**
- * @ngdoc function
- * @name angular.copy
- * @module ng
- * @kind 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 arrays) 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.
- *
- * <br />
- * <div class="alert alert-warning">
- *   Only enumerable properties are taken into account. Non-enumerable properties (both on `source`
- *   and on `destination`) will be ignored.
- * </div>
- *
- * @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
-  <example module="copyExample" name="angular-copy">
-    <file name="index.html">
-      <div ng-controller="ExampleController">
-        <form novalidate class="simple-form">
-          <label>Name: <input type="text" ng-model="user.name" /></label><br />
-          <label>Age:  <input type="number" ng-model="user.age" /></label><br />
-          Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
-                  <label><input type="radio" ng-model="user.gender" value="female" />female</label><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>
-    </file>
-    <file name="script.js">
-      // Module: copyExample
-      angular.
-        module('copyExample', []).
-        controller('ExampleController', ['$scope', function($scope) {
-          $scope.master = {};
-
-          $scope.reset = function() {
-            // Example with 1 argument
-            $scope.user = angular.copy($scope.master);
-          };
-
-          $scope.update = function(user) {
-            // Example with 2 arguments
-            angular.copy(user, $scope.master);
-          };
-
-          $scope.reset();
-        }]);
-    </file>
-  </example>
- */
-function copy(source, destination, maxDepth) {
-  var stackSource = [];
-  var stackDest = [];
-  maxDepth = isValidObjectMaxDepth(maxDepth) ? maxDepth : NaN;
-
-  if (destination) {
-    if (isTypedArray(destination) || isArrayBuffer(destination)) {
-      throw ngMinErr('cpta', 'Can\'t copy! TypedArray destination cannot be mutated.');
-    }
-    if (source === destination) {
-      throw ngMinErr('cpi', 'Can\'t copy! Source and destination are identical.');
-    }
-
-    // Empty the destination object
-    if (isArray(destination)) {
-      destination.length = 0;
-    } else {
-      forEach(destination, function(value, key) {
-        if (key !== '$$hashKey') {
-          delete destination[key];
-        }
-      });
-    }
-
-    stackSource.push(source);
-    stackDest.push(destination);
-    return copyRecurse(source, destination, maxDepth);
-  }
-
-  return copyElement(source, maxDepth);
-
-  function copyRecurse(source, destination, maxDepth) {
-    maxDepth--;
-    if (maxDepth < 0) {
-      return '...';
-    }
-    var h = destination.$$hashKey;
-    var key;
-    if (isArray(source)) {
-      for (var i = 0, ii = source.length; i < ii; i++) {
-        destination.push(copyElement(source[i], maxDepth));
-      }
-    } else if (isBlankObject(source)) {
-      // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
-      for (key in source) {
-        destination[key] = copyElement(source[key], maxDepth);
-      }
-    } else if (source && typeof source.hasOwnProperty === 'function') {
-      // Slow path, which must rely on hasOwnProperty
-      for (key in source) {
-        if (source.hasOwnProperty(key)) {
-          destination[key] = copyElement(source[key], maxDepth);
-        }
-      }
-    } else {
-      // Slowest path --- hasOwnProperty can't be called as a method
-      for (key in source) {
-        if (hasOwnProperty.call(source, key)) {
-          destination[key] = copyElement(source[key], maxDepth);
-        }
-      }
-    }
-    setHashKey(destination, h);
-    return destination;
-  }
-
-  function copyElement(source, maxDepth) {
-    // Simple values
-    if (!isObject(source)) {
-      return source;
-    }
-
-    // Already copied values
-    var index = stackSource.indexOf(source);
-    if (index !== -1) {
-      return stackDest[index];
-    }
-
-    if (isWindow(source) || isScope(source)) {
-      throw ngMinErr('cpws',
-        'Can\'t copy! Making copies of Window or Scope instances is not supported.');
-    }
-
-    var needsRecurse = false;
-    var destination = copyType(source);
-
-    if (destination === undefined) {
-      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
-      needsRecurse = true;
-    }
-
-    stackSource.push(source);
-    stackDest.push(destination);
-
-    return needsRecurse
-      ? copyRecurse(source, destination, maxDepth)
-      : destination;
-  }
-
-  function copyType(source) {
-    switch (toString.call(source)) {
-      case '[object Int8Array]':
-      case '[object Int16Array]':
-      case '[object Int32Array]':
-      case '[object Float32Array]':
-      case '[object Float64Array]':
-      case '[object Uint8Array]':
-      case '[object Uint8ClampedArray]':
-      case '[object Uint16Array]':
-      case '[object Uint32Array]':
-        return new source.constructor(copyElement(source.buffer), source.byteOffset, source.length);
-
-      case '[object ArrayBuffer]':
-        // Support: IE10
-        if (!source.slice) {
-          // If we're in this case we know the environment supports ArrayBuffer
-          /* eslint-disable no-undef */
-          var copied = new ArrayBuffer(source.byteLength);
-          new Uint8Array(copied).set(new Uint8Array(source));
-          /* eslint-enable */
-          return copied;
-        }
-        return source.slice(0);
-
-      case '[object Boolean]':
-      case '[object Number]':
-      case '[object String]':
-      case '[object Date]':
-        return new source.constructor(source.valueOf());
-
-      case '[object RegExp]':
-        var re = new RegExp(source.source, source.toString().match(/[^/]*$/)[0]);
-        re.lastIndex = source.lastIndex;
-        return re;
-
-      case '[object Blob]':
-        return new source.constructor([source], {type: source.type});
-    }
-
-    if (isFunction(source.cloneNode)) {
-      return source.cloneNode(true);
-    }
-  }
-}
-
-
-/**
- * @ngdoc function
- * @name angular.equals
- * @module ng
- * @kind 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 JavaScript,
- *   /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.
- *
- * @example
-   <example module="equalsExample" name="equalsExample">
-     <file name="index.html">
-      <div ng-controller="ExampleController">
-        <form novalidate>
-          <h3>User 1</h3>
-          Name: <input type="text" ng-model="user1.name">
-          Age: <input type="number" ng-model="user1.age">
-
-          <h3>User 2</h3>
-          Name: <input type="text" ng-model="user2.name">
-          Age: <input type="number" ng-model="user2.age">
-
-          <div>
-            <br/>
-            <input type="button" value="Compare" ng-click="compare()">
-          </div>
-          User 1: <pre>{{user1 | json}}</pre>
-          User 2: <pre>{{user2 | json}}</pre>
-          Equal: <pre>{{result}}</pre>
-        </form>
-      </div>
-    </file>
-    <file name="script.js">
-        angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) {
-          $scope.user1 = {};
-          $scope.user2 = {};
-          $scope.compare = function() {
-            $scope.result = angular.equals($scope.user1, $scope.user2);
-          };
-        }]);
-    </file>
-  </example>
- */
-function equals(o1, o2) {
-  if (o1 === o2) return true;
-  if (o1 === null || o2 === null) return false;
-  // eslint-disable-next-line no-self-compare
-  if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
-  var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
-  if (t1 === t2 && 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)) {
-      if (!isDate(o2)) return false;
-      return equals(o1.getTime(), o2.getTime());
-    } else if (isRegExp(o1)) {
-      if (!isRegExp(o2)) return false;
-      return o1.toString() === o2.toString();
-    } else {
-      if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
-        isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
-      keySet = createMap();
-      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 (!(key in keySet) &&
-            key.charAt(0) !== '$' &&
-            isDefined(o2[key]) &&
-            !isFunction(o2[key])) return false;
-      }
-      return true;
-    }
-  }
-  return false;
-}
-
-var csp = function() {
-  if (!isDefined(csp.rules)) {
-
-
-    var ngCspElement = (window.document.querySelector('[ng-csp]') ||
-                    window.document.querySelector('[data-ng-csp]'));
-
-    if (ngCspElement) {
-      var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
-                    ngCspElement.getAttribute('data-ng-csp');
-      csp.rules = {
-        noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),
-        noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)
-      };
-    } else {
-      csp.rules = {
-        noUnsafeEval: noUnsafeEval(),
-        noInlineStyle: false
-      };
-    }
-  }
-
-  return csp.rules;
-
-  function noUnsafeEval() {
-    try {
-      // eslint-disable-next-line no-new, no-new-func
-      new Function('');
-      return false;
-    } catch (e) {
-      return true;
-    }
-  }
-};
-
-/**
- * @ngdoc directive
- * @module ng
- * @name ngJq
- *
- * @element ANY
- * @param {string=} ngJq the name of the library available under `window`
- * to be used for angular.element
- * @description
- * Use this directive to force the angular.element library.  This should be
- * used to force either jqLite by leaving ng-jq blank or setting the name of
- * the jquery variable under window (eg. jQuery).
- *
- * Since angular looks for this directive when it is loaded (doesn't wait for the
- * DOMContentLoaded event), it must be placed on an element that comes before the script
- * which loads angular. Also, only the first instance of `ng-jq` will be used and all
- * others ignored.
- *
- * @example
- * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
- ```html
- <!doctype html>
- <html ng-app ng-jq>
- ...
- ...
- </html>
- ```
- * @example
- * This example shows how to use a jQuery based library of a different name.
- * The library name must be available at the top most 'window'.
- ```html
- <!doctype html>
- <html ng-app ng-jq="jQueryLib">
- ...
- ...
- </html>
- ```
- */
-var jq = function() {
-  if (isDefined(jq.name_)) return jq.name_;
-  var el;
-  var i, ii = ngAttrPrefixes.length, prefix, name;
-  for (i = 0; i < ii; ++i) {
-    prefix = ngAttrPrefixes[i];
-    el = window.document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]');
-    if (el) {
-      name = el.getAttribute(prefix + 'jq');
-      break;
-    }
-  }
-
-  return (jq.name_ = name);
-};
-
-function concat(array1, array2, index) {
-  return array1.concat(slice.call(array2, index));
-}
-
-function sliceArgs(args, startIndex) {
-  return slice.call(args, startIndex || 0);
-}
-
-
-/**
- * @ngdoc function
- * @name angular.bind
- * @module ng
- * @kind 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.
- */
-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, concat(curryArgs, 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) === '$' && key.charAt(1) === '$') {
-    val = undefined;
-  } else if (isWindow(value)) {
-    val = '$WINDOW';
-  } else if (value &&  window.document === value) {
-    val = '$DOCUMENT';
-  } else if (isScope(value)) {
-    val = '$SCOPE';
-  }
-
-  return val;
-}
-
-
-/**
- * @ngdoc function
- * @name angular.toJson
- * @module ng
- * @kind 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|boolean} obj Input to be serialized into JSON.
- * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
- *    If set to an integer, the JSON output will contain that many spaces per indentation.
- * @returns {string|undefined} JSON-ified string representing `obj`.
- * @knownIssue
- *
- * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date`
- * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the
- * `Date.prototype.toJSON` method as follows:
- *
- * ```
- * var _DatetoJSON = Date.prototype.toJSON;
- * Date.prototype.toJSON = function() {
- *   try {
- *     return _DatetoJSON.call(this);
- *   } catch(e) {
- *     if (e instanceof RangeError) {
- *       return null;
- *     }
- *     throw e;
- *   }
- * };
- * ```
- *
- * See https://github.com/angular/angular.js/pull/14221 for more information.
- */
-function toJson(obj, pretty) {
-  if (isUndefined(obj)) return undefined;
-  if (!isNumber(pretty)) {
-    pretty = pretty ? 2 : null;
-  }
-  return JSON.stringify(obj, toJsonReplacer, pretty);
-}
-
-
-/**
- * @ngdoc function
- * @name angular.fromJson
- * @module ng
- * @kind function
- *
- * @description
- * Deserializes a JSON string.
- *
- * @param {string} json JSON string to deserialize.
- * @returns {Object|Array|string|number} Deserialized JSON string.
- */
-function fromJson(json) {
-  return isString(json)
-      ? JSON.parse(json)
-      : json;
-}
-
-
-var ALL_COLONS = /:/g;
-function timezoneToOffset(timezone, fallback) {
-  // Support: IE 9-11 only, Edge 13-14+
-  // IE/Edge do not "understand" colon (`:`) in timezone
-  timezone = timezone.replace(ALL_COLONS, '');
-  var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
-  return isNumberNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
-}
-
-
-function addDateMinutes(date, minutes) {
-  date = new Date(date.getTime());
-  date.setMinutes(date.getMinutes() + minutes);
-  return date;
-}
-
-
-function convertTimezoneToLocal(date, timezone, reverse) {
-  reverse = reverse ? -1 : 1;
-  var dateTimezoneOffset = date.getTimezoneOffset();
-  var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
-  return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));
-}
-
-
-/**
- * @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.empty();
-  } catch (e) { /* empty */ }
-  var elemHtml = jqLite('<div>').append(element).html();
-  try {
-    return element[0].nodeType === NODE_TYPE_TEXT ? 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|Array>}
- */
-function parseKeyValue(/**string*/keyValue) {
-  var obj = {};
-  forEach((keyValue || '').split('&'), function(keyValue) {
-    var splitPoint, key, val;
-    if (keyValue) {
-      key = keyValue = keyValue.replace(/\+/g,'%20');
-      splitPoint = keyValue.indexOf('=');
-      if (splitPoint !== -1) {
-        key = keyValue.substring(0, splitPoint);
-        val = keyValue.substring(splitPoint + 1);
-      }
-      key = tryDecodeURIComponent(key);
-      if (isDefined(key)) {
-        val = isDefined(val) ? tryDecodeURIComponent(val) : true;
-        if (!hasOwnProperty.call(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(/%3B/gi, ';').
-             replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
-}
-
-var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
-
-function getNgAttribute(element, ngAttr) {
-  var attr, i, ii = ngAttrPrefixes.length;
-  for (i = 0; i < ii; ++i) {
-    attr = ngAttrPrefixes[i] + ngAttr;
-    if (isString(attr = element.getAttribute(attr))) {
-      return attr;
-    }
-  }
-  return null;
-}
-
-function allowAutoBootstrap(document) {
-  var script = document.currentScript;
-
-  if (!script) {
-    // IE does not have `document.currentScript`
-    return true;
-  }
-
-  // If the `currentScript` property has been clobbered just return false, since this indicates a probable attack
-  if (!(script instanceof window.HTMLScriptElement || script instanceof window.SVGScriptElement)) {
-    return false;
-  }
-
-  var attributes = script.attributes;
-  var srcs = [attributes.getNamedItem('src'), attributes.getNamedItem('href'), attributes.getNamedItem('xlink:href')];
-
-  return srcs.every(function(src) {
-    if (!src) {
-      return true;
-    }
-    if (!src.value) {
-      return false;
-    }
-
-    var link = document.createElement('a');
-    link.href = src.value;
-
-    if (document.location.origin === link.origin) {
-      // Same-origin resources are always allowed, even for non-whitelisted schemes.
-      return true;
-    }
-    // Disabled bootstrapping unless angular.js was loaded from a known scheme used on the web.
-    // This is to prevent angular.js bundled with browser extensions from being used to bypass the
-    // content security policy in web pages and other browser extensions.
-    switch (link.protocol) {
-      case 'http:':
-      case 'https:':
-      case 'ftp:':
-      case 'blob:':
-      case 'file:':
-      case 'data:':
-        return true;
-      default:
-        return false;
-    }
-  });
-}
-
-// Cached as it has to run during loading so that document.currentScript is available.
-var isAutoBootstrapAllowed = allowAutoBootstrap(window.document);
-
-/**
- * @ngdoc directive
- * @name ngApp
- * @module ng
- *
- * @element ANY
- * @param {angular.Module} ngApp an optional application
- *   {@link angular.module module} name to load.
- * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be
- *   created in "strict-di" mode. This means that the application will fail to invoke functions which
- *   do not use explicit function annotation (and are thus unsuitable for minification), as described
- *   in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in
- *   tracking down the root of these bugs.
- *
- * @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.
- *
- * There are a few things to keep in mind when using `ngApp`:
- * - 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.
- * - Do not use a directive that uses {@link ng.$compile#transclusion transclusion} on the same element as `ngApp`.
- *   This includes directives such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and
- *   {@link ngRoute.ngView `ngView`}.
- *   Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
- *   causing animations to stop working and making the injector inaccessible from outside the app.
- *
- * 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. It
- * 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" name="ng-app">
-   <file name="index.html">
-   <div ng-controller="ngAppDemoController">
-     I can add: {{a}} + {{b}} =  {{ a+b }}
-   </div>
-   </file>
-   <file name="script.js">
-   angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
-     $scope.a = 1;
-     $scope.b = 2;
-   });
-   </file>
- </example>
- *
- * Using `ngStrictDi`, you would see something like this:
- *
- <example ng-app-included="true" name="strict-di">
-   <file name="index.html">
-   <div ng-app="ngAppStrictDemo" ng-strict-di>
-       <div ng-controller="GoodController1">
-           I can add: {{a}} + {{b}} =  {{ a+b }}
-
-           <p>This renders because the controller does not fail to
-              instantiate, by using explicit annotation style (see
-              script.js for details)
-           </p>
-       </div>
-
-       <div ng-controller="GoodController2">
-           Name: <input ng-model="name"><br />
-           Hello, {{name}}!
-
-           <p>This renders because the controller does not fail to
-              instantiate, by using explicit annotation style
-              (see script.js for details)
-           </p>
-       </div>
-
-       <div ng-controller="BadController">
-           I can add: {{a}} + {{b}} =  {{ a+b }}
-
-           <p>The controller could not be instantiated, due to relying
-              on automatic function annotations (which are disabled in
-              strict mode). As such, the content of this section is not
-              interpolated, and there should be an error in your web console.
-           </p>
-       </div>
-   </div>
-   </file>
-   <file name="script.js">
-   angular.module('ngAppStrictDemo', [])
-     // BadController will fail to instantiate, due to relying on automatic function annotation,
-     // rather than an explicit annotation
-     .controller('BadController', function($scope) {
-       $scope.a = 1;
-       $scope.b = 2;
-     })
-     // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
-     // due to using explicit annotations using the array style and $inject property, respectively.
-     .controller('GoodController1', ['$scope', function($scope) {
-       $scope.a = 1;
-       $scope.b = 2;
-     }])
-     .controller('GoodController2', GoodController2);
-     function GoodController2($scope) {
-       $scope.name = 'World';
-     }
-     GoodController2.$inject = ['$scope'];
-   </file>
-   <file name="style.css">
-   div[ng-controller] {
-       margin-bottom: 1em;
-       -webkit-border-radius: 4px;
-       border-radius: 4px;
-       border: 1px solid;
-       padding: .5em;
-   }
-   div[ng-controller^=Good] {
-       border-color: #d6e9c6;
-       background-color: #dff0d8;
-       color: #3c763d;
-   }
-   div[ng-controller^=Bad] {
-       border-color: #ebccd1;
-       background-color: #f2dede;
-       color: #a94442;
-       margin-bottom: 0;
-   }
-   </file>
- </example>
- */
-function angularInit(element, bootstrap) {
-  var appElement,
-      module,
-      config = {};
-
-  // The element `element` has priority over any other element.
-  forEach(ngAttrPrefixes, function(prefix) {
-    var name = prefix + 'app';
-
-    if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
-      appElement = element;
-      module = element.getAttribute(name);
-    }
-  });
-  forEach(ngAttrPrefixes, function(prefix) {
-    var name = prefix + 'app';
-    var candidate;
-
-    if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
-      appElement = candidate;
-      module = candidate.getAttribute(name);
-    }
-  });
-  if (appElement) {
-    if (!isAutoBootstrapAllowed) {
-      window.console.error('Angular: disabling automatic bootstrap. <script> protocol indicates ' +
-          'an extension, document.location.href does not match.');
-      return;
-    }
-    config.strictDi = getNgAttribute(appElement, 'strict-di') !== null;
-    bootstrap(appElement, module ? [module] : [], config);
-  }
-}
-
-/**
- * @ngdoc function
- * @name angular.bootstrap
- * @module ng
- * @description
- * Use this function to manually start up angular application.
- *
- * For more information, see the {@link guide/bootstrap Bootstrap guide}.
- *
- * Angular will detect if it has been loaded into the browser more than once and only allow the
- * first loaded script to be bootstrapped and will report a warning to the browser console for
- * each of the subsequent scripts. This prevents strange results in applications, where otherwise
- * multiple instances of Angular try to work on the DOM.
- *
- * <div class="alert alert-warning">
- * **Note:** Protractor based end-to-end tests cannot use this function to bootstrap manually.
- * They must use {@link ng.directive:ngApp ngApp}.
- * </div>
- *
- * <div class="alert alert-warning">
- * **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},
- * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.
- * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
- * causing animations to stop working and making the injector inaccessible from outside the app.
- * </div>
- *
- * ```html
- * <!doctype html>
- * <html>
- * <body>
- * <div ng-controller="WelcomeController">
- *   {{greeting}}
- * </div>
- *
- * <script src="angular.js"></script>
- * <script>
- *   var app = angular.module('demo', [])
- *   .controller('WelcomeController', function($scope) {
- *       $scope.greeting = 'Welcome!';
- *   });
- *   angular.bootstrap(document, ['demo']);
- * </script>
- * </body>
- * </html>
- * ```
- *
- * @param {DOMElement} 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 `config` block.
- *     See: {@link angular.module modules}
- * @param {Object=} config an object for defining configuration options for the application. The
- *     following keys are supported:
- *
- * * `strictDi` - disable automatic function annotation for the application. This is meant to
- *   assist in finding bugs which break minified code. Defaults to `false`.
- *
- * @returns {auto.$injector} Returns the newly created injector for this app.
- */
-function bootstrap(element, modules, config) {
-  if (!isObject(config)) config = {};
-  var defaultConfig = {
-    strictDi: false
-  };
-  config = extend(defaultConfig, config);
-  var doBootstrap = function() {
-    element = jqLite(element);
-
-    if (element.injector()) {
-      var tag = (element[0] === window.document) ? 'document' : startingTag(element);
-      // Encode angle brackets to prevent input from being sanitized to empty string #8683.
-      throw ngMinErr(
-          'btstrpd',
-          'App already bootstrapped with this element \'{0}\'',
-          tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
-    }
-
-    modules = modules || [];
-    modules.unshift(['$provide', function($provide) {
-      $provide.value('$rootElement', element);
-    }]);
-
-    if (config.debugInfoEnabled) {
-      // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
-      modules.push(['$compileProvider', function($compileProvider) {
-        $compileProvider.debugInfoEnabled(true);
-      }]);
-    }
-
-    modules.unshift('ng');
-    var injector = createInjector(modules, config.strictDi);
-    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
-       function bootstrapApply(scope, element, compile, injector) {
-        scope.$apply(function() {
-          element.data('$injector', injector);
-          compile(element)(scope);
-        });
-      }]
-    );
-    return injector;
-  };
-
-  var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
-  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
-
-  if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
-    config.debugInfoEnabled = true;
-    window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
-  }
-
-  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);
-    });
-    return doBootstrap();
-  };
-
-  if (isFunction(angular.resumeDeferredBootstrap)) {
-    angular.resumeDeferredBootstrap();
-  }
-}
-
-/**
- * @ngdoc function
- * @name angular.reloadWithDebugInfo
- * @module ng
- * @description
- * Use this function to reload the current application with debug information turned on.
- * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.
- *
- * See {@link ng.$compileProvider#debugInfoEnabled} for more.
- */
-function reloadWithDebugInfo() {
-  window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;
-  window.location.reload();
-}
-
-/**
- * @name angular.getTestability
- * @module ng
- * @description
- * Get the testability service for the instance of Angular on the given
- * element.
- * @param {DOMElement} element DOM element which is the root of angular application.
- */
-function getTestability(rootElement) {
-  var injector = angular.element(rootElement).injector();
-  if (!injector) {
-    throw ngMinErr('test',
-      'no injector found for element argument to getTestability');
-  }
-  return injector.get('$$testability');
-}
-
-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();
-  });
-}
-
-var bindJQueryFired = false;
-function bindJQuery() {
-  var originalCleanData;
-
-  if (bindJQueryFired) {
-    return;
-  }
-
-  // bind to jQuery if present;
-  var jqName = jq();
-  jQuery = isUndefined(jqName) ? window.jQuery :   // use jQuery (if present)
-           !jqName             ? undefined     :   // use jqLite
-                                 window[jqName];   // use jQuery specified by `ngJq`
-
-  // Use jQuery if it exists with proper functionality, otherwise default to us.
-  // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
-  // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
-  // versions. It will not work for sure with jQuery <1.7, though.
-  if (jQuery && jQuery.fn.on) {
-    jqLite = jQuery;
-    extend(jQuery.fn, {
-      scope: JQLitePrototype.scope,
-      isolateScope: JQLitePrototype.isolateScope,
-      controller: /** @type {?} */ (JQLitePrototype).controller,
-      injector: JQLitePrototype.injector,
-      inheritedData: JQLitePrototype.inheritedData
-    });
-
-    // All nodes removed from the DOM via various jQuery APIs like .remove()
-    // are passed through jQuery.cleanData. Monkey-patch this method to fire
-    // the $destroy event on all removed nodes.
-    originalCleanData = jQuery.cleanData;
-    jQuery.cleanData = function(elems) {
-      var events;
-      for (var i = 0, elem; (elem = elems[i]) != null; i++) {
-        events = jQuery._data(elem, 'events');
-        if (events && events.$destroy) {
-          jQuery(elem).triggerHandler('$destroy');
-        }
-      }
-      originalCleanData(elems);
-    };
-  } else {
-    jqLite = JQLite;
-  }
-
-  angular.element = jqLite;
-
-  // Prevent double-proxying.
-  bindJQueryFired = true;
-}
-
-/**
- * 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} [bindFnToScope=true]
- * @returns {Object} value as accessible by path
- */
-//TODO(misko): this function needs to be removed
-function 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 DOM siblings between the first and last node in the given array.
- * @param {Array} array like object
- * @returns {Array} the inputted object or a jqLite collection containing the nodes
- */
-function getBlockNodes(nodes) {
-  // TODO(perf): update `nodes` instead of creating a new object?
-  var node = nodes[0];
-  var endNode = nodes[nodes.length - 1];
-  var blockNodes;
-
-  for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {
-    if (blockNodes || nodes[i] !== node) {
-      if (!blockNodes) {
-        blockNodes = jqLite(slice.call(nodes, 0, i));
-      }
-      blockNodes.push(node);
-    }
-  }
-
-  return blockNodes || nodes;
-}
-
-
-/**
- * Creates a new object without a prototype. This object is useful for lookup without having to
- * guard against prototypically inherited properties via hasOwnProperty.
- *
- * Related micro-benchmarks:
- * - http://jsperf.com/object-create2
- * - http://jsperf.com/proto-map-lookup/2
- * - http://jsperf.com/for-in-vs-object-keys2
- *
- * @returns {Object}
- */
-function createMap() {
-  return Object.create(null);
-}
-
-function stringify(value) {
-  if (value == null) { // null || undefined
-    return '';
-  }
-  switch (typeof value) {
-    case 'string':
-      break;
-    case 'number':
-      value = '' + value;
-      break;
-    default:
-      if (hasCustomToString(value) && !isArray(value) && !isDate(value)) {
-        value = value.toString();
-      } else {
-        value = toJson(value);
-      }
-  }
-
-  return value;
-}
-
-var NODE_TYPE_ELEMENT = 1;
-var NODE_TYPE_ATTRIBUTE = 2;
-var NODE_TYPE_TEXT = 3;
-var NODE_TYPE_COMMENT = 8;
-var NODE_TYPE_DOCUMENT = 9;
-var NODE_TYPE_DOCUMENT_FRAGMENT = 11;
-
-/**
- * @ngdoc type
- * @name angular.Module
- * @module ng
- * @description
- *
- * Interface for configuring angular {@link angular.module modules}.
- */
-
-function setupModuleLoader(window) {
-
-  var $injectorMinErr = minErr('$injector');
-  var ngMinErr = minErr('ng');
-
-  function ensure(obj, name, factory) {
-    return obj[name] || (obj[name] = factory());
-  }
-
-  var angular = ensure(window, 'angular', Object);
-
-  // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
-  angular.$$minErr = angular.$$minErr || minErr;
-
-  return ensure(angular, 'module', function() {
-    /** @type {Object.<string, angular.Module>} */
-    var modules = {};
-
-    /**
-     * @ngdoc function
-     * @name angular.module
-     * @module ng
-     * @description
-     *
-     * The `angular.module` is a global place for creating, registering and retrieving Angular
-     * modules.
-     * All modules (angular core or 3rd party) that should be available to an application must be
-     * registered using this mechanism.
-     *
-     * Passing one argument retrieves an existing {@link angular.Module},
-     * whereas passing more than one argument creates a new {@link angular.Module}
-     *
-     *
-     * # Module
-     *
-     * A module is a collection of services, directives, controllers, filters, and configuration information.
-     * `angular.module` is used to configure the {@link auto.$injector $injector}.
-     *
-     * ```js
-     * // Create a new module
-     * var myModule = angular.module('myModule', []);
-     *
-     * // register a new service
-     * myModule.value('appName', 'MyCoolApp');
-     *
-     * // configure existing services inside initialization blocks.
-     * myModule.config(['$locationProvider', function($locationProvider) {
-     *   // Configure existing providers
-     *   $locationProvider.hashPrefix('!');
-     * }]);
-     * ```
-     *
-     * Then you can create an injector and load your modules like this:
-     *
-     * ```js
-     * var injector = angular.injector(['ng', 'myModule'])
-     * ```
-     *
-     * However it's more likely that you'll just use
-     * {@link ng.directive:ngApp ngApp} or
-     * {@link angular.bootstrap} to simplify this process for you.
-     *
-     * @param {!string} name The name of the module to create or retrieve.
-     * @param {!Array.<string>=} requires If specified then new module is being created. If
-     *        unspecified then the module is being retrieved for further configuration.
-     * @param {Function=} configFn Optional configuration function for the module. Same as
-     *        {@link angular.Module#config Module#config()}.
-     * @returns {angular.Module} new module with the {@link angular.Module} api.
-     */
-    return function module(name, requires, configFn) {
-
-      var info = {};
-
-      var assertNotHasOwnProperty = function(name, context) {
-        if (name === 'hasOwnProperty') {
-          throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
-        }
-      };
-
-      assertNotHasOwnProperty(name, 'module');
-      if (requires && modules.hasOwnProperty(name)) {
-        modules[name] = null;
-      }
-      return ensure(modules, name, function() {
-        if (!requires) {
-          throw $injectorMinErr('nomod', 'Module \'{0}\' is not available! You either misspelled ' +
-             'the module name or forgot to load it. If registering a module ensure that you ' +
-             'specify the dependencies as the second argument.', name);
-        }
-
-        /** @type {!Array.<Array.<*>>} */
-        var invokeQueue = [];
-
-        /** @type {!Array.<Function>} */
-        var configBlocks = [];
-
-        /** @type {!Array.<Function>} */
-        var runBlocks = [];
-
-        var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
-
-        /** @type {angular.Module} */
-        var moduleInstance = {
-          // Private state
-          _invokeQueue: invokeQueue,
-          _configBlocks: configBlocks,
-          _runBlocks: runBlocks,
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#info
-           * @module ng
-           *
-           * @param {Object=} info Information about the module
-           * @returns {Object|Module} The current info object for this module if called as a getter,
-           *                          or `this` if called as a setter.
-           *
-           * @description
-           * Read and write custom information about this module.
-           * For example you could put the version of the module in here.
-           *
-           * ```js
-           * angular.module('myModule', []).info({ version: '1.0.0' });
-           * ```
-           *
-           * The version could then be read back out by accessing the module elsewhere:
-           *
-           * ```
-           * var version = angular.module('myModule').info().version;
-           * ```
-           *
-           * You can also retrieve this information during runtime via the
-           * {@link $injector#modules `$injector.modules`} property:
-           *
-           * ```js
-           * var version = $injector.modules['myModule'].info().version;
-           * ```
-           */
-          info: function(value) {
-            if (isDefined(value)) {
-              if (!isObject(value)) throw ngMinErr('aobj', 'Argument \'{0}\' must be an object', 'value');
-              info = value;
-              return this;
-            }
-            return info;
-          },
-
-          /**
-           * @ngdoc property
-           * @name angular.Module#requires
-           * @module ng
-           *
-           * @description
-           * Holds the list of modules which the injector will load before the current module is
-           * loaded.
-           */
-          requires: requires,
-
-          /**
-           * @ngdoc property
-           * @name angular.Module#name
-           * @module ng
-           *
-           * @description
-           * Name of the module.
-           */
-          name: name,
-
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#provider
-           * @module ng
-           * @param {string} name service name
-           * @param {Function} providerType Construction function for creating new instance of the
-           *                                service.
-           * @description
-           * See {@link auto.$provide#provider $provide.provider()}.
-           */
-          provider: invokeLaterAndSetModuleName('$provide', 'provider'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#factory
-           * @module ng
-           * @param {string} name service name
-           * @param {Function} providerFunction Function for creating new instance of the service.
-           * @description
-           * See {@link auto.$provide#factory $provide.factory()}.
-           */
-          factory: invokeLaterAndSetModuleName('$provide', 'factory'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#service
-           * @module ng
-           * @param {string} name service name
-           * @param {Function} constructor A constructor function that will be instantiated.
-           * @description
-           * See {@link auto.$provide#service $provide.service()}.
-           */
-          service: invokeLaterAndSetModuleName('$provide', 'service'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#value
-           * @module ng
-           * @param {string} name service name
-           * @param {*} object Service instance object.
-           * @description
-           * See {@link auto.$provide#value $provide.value()}.
-           */
-          value: invokeLater('$provide', 'value'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#constant
-           * @module ng
-           * @param {string} name constant name
-           * @param {*} object Constant value.
-           * @description
-           * Because the constants are fixed, they get applied before other provide methods.
-           * See {@link auto.$provide#constant $provide.constant()}.
-           */
-          constant: invokeLater('$provide', 'constant', 'unshift'),
-
-           /**
-           * @ngdoc method
-           * @name angular.Module#decorator
-           * @module ng
-           * @param {string} name The name of the service to decorate.
-           * @param {Function} decorFn This function will be invoked when the service needs to be
-           *                           instantiated and should return the decorated service instance.
-           * @description
-           * See {@link auto.$provide#decorator $provide.decorator()}.
-           */
-          decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#animation
-           * @module ng
-           * @param {string} name animation name
-           * @param {Function} animationFactory Factory function for creating new instance of an
-           *                                    animation.
-           * @description
-           *
-           * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
-           *
-           *
-           * Defines an animation hook that can be later used with
-           * {@link $animate $animate} service and directives that use this service.
-           *
-           * ```js
-           * module.animation('.animation-name', function($inject1, $inject2) {
-           *   return {
-           *     eventName : function(element, done) {
-           *       //code to run the animation
-           *       //once complete, then run done()
-           *       return function cancellationFunction(element) {
-           *         //code to cancel the animation
-           *       }
-           *     }
-           *   }
-           * })
-           * ```
-           *
-           * See {@link ng.$animateProvider#register $animateProvider.register()} and
-           * {@link ngAnimate ngAnimate module} for more information.
-           */
-          animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#filter
-           * @module ng
-           * @param {string} name Filter name - this must be a valid angular expression identifier
-           * @param {Function} filterFactory Factory function for creating new instance of filter.
-           * @description
-           * See {@link ng.$filterProvider#register $filterProvider.register()}.
-           *
-           * <div class="alert alert-warning">
-           * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
-           * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
-           * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
-           * (`myapp_subsection_filterx`).
-           * </div>
-           */
-          filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#controller
-           * @module ng
-           * @param {string|Object} name Controller name, or an object map of controllers where the
-           *    keys are the names and the values are the constructors.
-           * @param {Function} constructor Controller constructor function.
-           * @description
-           * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
-           */
-          controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#directive
-           * @module ng
-           * @param {string|Object} name Directive name, or an object map of directives where the
-           *    keys are the names and the values are the factories.
-           * @param {Function} directiveFactory Factory function for creating new instance of
-           * directives.
-           * @description
-           * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
-           */
-          directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#component
-           * @module ng
-           * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp)
-           * @param {Object} options Component definition object (a simplified
-           *    {@link ng.$compile#directive-definition-object directive definition object})
-           *
-           * @description
-           * See {@link ng.$compileProvider#component $compileProvider.component()}.
-           */
-          component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#config
-           * @module ng
-           * @param {Function} configFn Execute this function on module load. Useful for service
-           *    configuration.
-           * @description
-           * Use this method to register work which needs to be performed on module loading.
-           * For more about how to configure services, see
-           * {@link providers#provider-recipe Provider Recipe}.
-           */
-          config: config,
-
-          /**
-           * @ngdoc method
-           * @name angular.Module#run
-           * @module ng
-           * @param {Function} initializationFn Execute this function after injector creation.
-           *    Useful for application initialization.
-           * @description
-           * Use this method to register work which should be performed when the injector is done
-           * loading all modules.
-           */
-          run: function(block) {
-            runBlocks.push(block);
-            return this;
-          }
-        };
-
-        if (configFn) {
-          config(configFn);
-        }
-
-        return moduleInstance;
-
-        /**
-         * @param {string} provider
-         * @param {string} method
-         * @param {String=} insertMethod
-         * @returns {angular.Module}
-         */
-        function invokeLater(provider, method, insertMethod, queue) {
-          if (!queue) queue = invokeQueue;
-          return function() {
-            queue[insertMethod || 'push']([provider, method, arguments]);
-            return moduleInstance;
-          };
-        }
-
-        /**
-         * @param {string} provider
-         * @param {string} method
-         * @returns {angular.Module}
-         */
-        function invokeLaterAndSetModuleName(provider, method, queue) {
-          if (!queue) queue = invokeQueue;
-          return function(recipeName, factoryFunction) {
-            if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
-            queue.push([provider, method, arguments]);
-            return moduleInstance;
-          };
-        }
-      });
-    };
-  });
-
-}
-
-/* global shallowCopy: true */
-
-/**
- * Creates a shallow copy of an object, an array or a primitive.
- *
- * Assumes that there are no proto properties for objects.
- */
-function shallowCopy(src, dst) {
-  if (isArray(src)) {
-    dst = dst || [];
-
-    for (var i = 0, ii = src.length; i < ii; i++) {
-      dst[i] = src[i];
-    }
-  } else if (isObject(src)) {
-    dst = dst || {};
-
-    for (var key in src) {
-      if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
-        dst[key] = src[key];
-      }
-    }
-  }
-
-  return dst || src;
-}
-
-/* global toDebugString: true */
-
-function serializeObject(obj, maxDepth) {
-  var seen = [];
-
-  // There is no direct way to stringify object until reaching a specific depth
-  // and a very deep object can cause a performance issue, so we copy the object
-  // based on this specific depth and then stringify it.
-  if (isValidObjectMaxDepth(maxDepth)) {
-    obj = copy(obj, null, maxDepth);
-  }
-  return JSON.stringify(obj, function(key, val) {
-    val = toJsonReplacer(key, val);
-    if (isObject(val)) {
-
-      if (seen.indexOf(val) >= 0) return '...';
-
-      seen.push(val);
-    }
-    return val;
-  });
-}
-
-function toDebugString(obj, maxDepth) {
-  if (typeof obj === 'function') {
-    return obj.toString().replace(/ \{[\s\S]*$/, '');
-  } else if (isUndefined(obj)) {
-    return 'undefined';
-  } else if (typeof obj !== 'string') {
-    return serializeObject(obj, maxDepth);
-  }
-  return obj;
-}
-
-/* global angularModule: true,
-  version: true,
-
-  $CompileProvider,
-
-  htmlAnchorDirective,
-  inputDirective,
-  inputDirective,
-  formDirective,
-  scriptDirective,
-  selectDirective,
-  optionDirective,
-  ngBindDirective,
-  ngBindHtmlDirective,
-  ngBindTemplateDirective,
-  ngClassDirective,
-  ngClassEvenDirective,
-  ngClassOddDirective,
-  ngCloakDirective,
-  ngControllerDirective,
-  ngFormDirective,
-  ngHideDirective,
-  ngIfDirective,
-  ngIncludeDirective,
-  ngIncludeFillContentDirective,
-  ngInitDirective,
-  ngNonBindableDirective,
-  ngPluralizeDirective,
-  ngRepeatDirective,
-  ngShowDirective,
-  ngStyleDirective,
-  ngSwitchDirective,
-  ngSwitchWhenDirective,
-  ngSwitchDefaultDirective,
-  ngOptionsDirective,
-  ngTranscludeDirective,
-  ngModelDirective,
-  ngListDirective,
-  ngChangeDirective,
-  patternDirective,
-  patternDirective,
-  requiredDirective,
-  requiredDirective,
-  minlengthDirective,
-  minlengthDirective,
-  maxlengthDirective,
-  maxlengthDirective,
-  ngValueDirective,
-  ngModelOptionsDirective,
-  ngAttributeAliasDirectives,
-  ngEventDirectives,
-
-  $AnchorScrollProvider,
-  $AnimateProvider,
-  $CoreAnimateCssProvider,
-  $$CoreAnimateJsProvider,
-  $$CoreAnimateQueueProvider,
-  $$AnimateRunnerFactoryProvider,
-  $$AnimateAsyncRunFactoryProvider,
-  $BrowserProvider,
-  $CacheFactoryProvider,
-  $ControllerProvider,
-  $DateProvider,
-  $DocumentProvider,
-  $$IsDocumentHiddenProvider,
-  $ExceptionHandlerProvider,
-  $FilterProvider,
-  $$ForceReflowProvider,
-  $InterpolateProvider,
-  $IntervalProvider,
-  $HttpProvider,
-  $HttpParamSerializerProvider,
-  $HttpParamSerializerJQLikeProvider,
-  $HttpBackendProvider,
-  $xhrFactoryProvider,
-  $jsonpCallbacksProvider,
-  $LocationProvider,
-  $LogProvider,
-  $$MapProvider,
-  $ParseProvider,
-  $RootScopeProvider,
-  $QProvider,
-  $$QProvider,
-  $$SanitizeUriProvider,
-  $SceProvider,
-  $SceDelegateProvider,
-  $SnifferProvider,
-  $TemplateCacheProvider,
-  $TemplateRequestProvider,
-  $$TestabilityProvider,
-  $TimeoutProvider,
-  $$RAFProvider,
-  $WindowProvider,
-  $$jqLiteProvider,
-  $$CookieReaderProvider
-*/
-
-
-/**
- * @ngdoc object
- * @name angular.version
- * @module ng
- * @description
- * An object that contains information about the current AngularJS version.
- *
- * This object has the following properties:
- *
- * - `full` – `{string}` – Full version string, such as "0.9.18".
- * - `major` – `{number}` – Major version number, such as "0".
- * - `minor` – `{number}` – Minor version number, such as "9".
- * - `dot` – `{number}` – Dot version number, such as "18".
- * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
- */
-var version = {
-  // These placeholder strings will be replaced by grunt's `build` task.
-  // They need to be double- or single-quoted.
-  full: '1.6.3',
-  major: 1,
-  minor: 6,
-  dot: 3,
-  codeName: 'scriptalicious-bootstrapping'
-};
-
-
-function publishExternalAPI(angular) {
-  extend(angular, {
-    'errorHandlingConfig': errorHandlingConfig,
-    'bootstrap': bootstrap,
-    'copy': copy,
-    'extend': extend,
-    'merge': merge,
-    'equals': equals,
-    'element': jqLite,
-    'forEach': forEach,
-    'injector': createInjector,
-    'noop': noop,
-    'bind': bind,
-    'toJson': toJson,
-    'fromJson': fromJson,
-    'identity': identity,
-    'isUndefined': isUndefined,
-    'isDefined': isDefined,
-    'isString': isString,
-    'isFunction': isFunction,
-    'isObject': isObject,
-    'isNumber': isNumber,
-    'isElement': isElement,
-    'isArray': isArray,
-    'version': version,
-    'isDate': isDate,
-    'lowercase': lowercase,
-    'uppercase': uppercase,
-    'callbacks': {$$counter: 0},
-    'getTestability': getTestability,
-    'reloadWithDebugInfo': reloadWithDebugInfo,
-    '$$minErr': minErr,
-    '$$csp': csp,
-    '$$encodeUriSegment': encodeUriSegment,
-    '$$encodeUriQuery': encodeUriQuery,
-    '$$stringify': stringify
-  });
-
-  angularModule = setupModuleLoader(window);
-
-  angularModule('ng', ['ngLocale'], ['$provide',
-    function ngModule($provide) {
-      // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
-      $provide.provider({
-        $$sanitizeUri: $$SanitizeUriProvider
-      });
-      $provide.provider('$compile', $CompileProvider).
-        directive({
-            a: htmlAnchorDirective,
-            input: inputDirective,
-            textarea: inputDirective,
-            form: formDirective,
-            script: scriptDirective,
-            select: selectDirective,
-            option: optionDirective,
-            ngBind: ngBindDirective,
-            ngBindHtml: ngBindHtmlDirective,
-            ngBindTemplate: ngBindTemplateDirective,
-            ngClass: ngClassDirective,
-            ngClassEven: ngClassEvenDirective,
-            ngClassOdd: ngClassOddDirective,
-            ngCloak: ngCloakDirective,
-            ngController: ngControllerDirective,
-            ngForm: ngFormDirective,
-            ngHide: ngHideDirective,
-            ngIf: ngIfDirective,
-            ngInclude: ngIncludeDirective,
-            ngInit: ngInitDirective,
-            ngNonBindable: ngNonBindableDirective,
-            ngPluralize: ngPluralizeDirective,
-            ngRepeat: ngRepeatDirective,
-            ngShow: ngShowDirective,
-            ngStyle: ngStyleDirective,
-            ngSwitch: ngSwitchDirective,
-            ngSwitchWhen: ngSwitchWhenDirective,
-            ngSwitchDefault: ngSwitchDefaultDirective,
-            ngOptions: ngOptionsDirective,
-            ngTransclude: ngTranscludeDirective,
-            ngModel: ngModelDirective,
-            ngList: ngListDirective,
-            ngChange: ngChangeDirective,
-            pattern: patternDirective,
-            ngPattern: patternDirective,
-            required: requiredDirective,
-            ngRequired: requiredDirective,
-            minlength: minlengthDirective,
-            ngMinlength: minlengthDirective,
-            maxlength: maxlengthDirective,
-            ngMaxlength: maxlengthDirective,
-            ngValue: ngValueDirective,
-            ngModelOptions: ngModelOptionsDirective
-        }).
-        directive({
-          ngInclude: ngIncludeFillContentDirective
-        }).
-        directive(ngAttributeAliasDirectives).
-        directive(ngEventDirectives);
-      $provide.provider({
-        $anchorScroll: $AnchorScrollProvider,
-        $animate: $AnimateProvider,
-        $animateCss: $CoreAnimateCssProvider,
-        $$animateJs: $$CoreAnimateJsProvider,
-        $$animateQueue: $$CoreAnimateQueueProvider,
-        $$AnimateRunner: $$AnimateRunnerFactoryProvider,
-        $$animateAsyncRun: $$AnimateAsyncRunFactoryProvider,
-        $browser: $BrowserProvider,
-        $cacheFactory: $CacheFactoryProvider,
-        $controller: $ControllerProvider,
-        $document: $DocumentProvider,
-        $$isDocumentHidden: $$IsDocumentHiddenProvider,
-        $exceptionHandler: $ExceptionHandlerProvider,
-        $filter: $FilterProvider,
-        $$forceReflow: $$ForceReflowProvider,
-        $interpolate: $InterpolateProvider,
-        $interval: $IntervalProvider,
-        $http: $HttpProvider,
-        $httpParamSerializer: $HttpParamSerializerProvider,
-        $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,
-        $httpBackend: $HttpBackendProvider,
-        $xhrFactory: $xhrFactoryProvider,
-        $jsonpCallbacks: $jsonpCallbacksProvider,
-        $location: $LocationProvider,
-        $log: $LogProvider,
-        $parse: $ParseProvider,
-        $rootScope: $RootScopeProvider,
-        $q: $QProvider,
-        $$q: $$QProvider,
-        $sce: $SceProvider,
-        $sceDelegate: $SceDelegateProvider,
-        $sniffer: $SnifferProvider,
-        $templateCache: $TemplateCacheProvider,
-        $templateRequest: $TemplateRequestProvider,
-        $$testability: $$TestabilityProvider,
-        $timeout: $TimeoutProvider,
-        $window: $WindowProvider,
-        $$rAF: $$RAFProvider,
-        $$jqLite: $$jqLiteProvider,
-        $$Map: $$MapProvider,
-        $$cookieReader: $$CookieReaderProvider
-      });
-    }
-  ])
-  .info({ angularVersion: '1.6.3' });
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *     Any commits to this file should be reviewed with security in mind.  *
- *   Changes to this file can potentially create security vulnerabilities. *
- *          An approval from 2 Core members with history of modifying      *
- *                         this file is required.                          *
- *                                                                         *
- *  Does the change somehow allow for arbitrary javascript to be executed? *
- *    Or allows for someone to change the prototype of built-in objects?   *
- *     Or gives undesired access to variables likes document or window?    *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/* global
-  JQLitePrototype: true,
-  BOOLEAN_ATTR: true,
-  ALIASED_ATTR: true
-*/
-
-//////////////////////////////////
-//JQLite
-//////////////////////////////////
-
-/**
- * @ngdoc function
- * @name angular.element
- * @module ng
- * @kind function
- *
- * @description
- * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.
- *
- * If jQuery is available, `angular.element` is an alias for the
- * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element`
- * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or **jqLite**.
- *
- * jqLite is a tiny, API-compatible subset of jQuery that allows
- * Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most
- * commonly needed functionality with the goal of having a very small footprint.
- *
- * To use `jQuery`, simply ensure it is loaded before the `angular.js` file. You can also use the
- * {@link ngJq `ngJq`} directive to specify that jqlite should be used over jQuery, or to use a
- * specific version of jQuery if multiple versions exist on the page.
- *
- * <div class="alert alert-info">**Note:** All element references in Angular are always wrapped with jQuery or
- * jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.</div>
- *
- * <div class="alert alert-warning">**Note:** Keep in mind that this function will not find elements
- * by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)`
- * or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.</div>
- *
- * ## Angular's jqLite
- * jqLite provides only the following jQuery methods:
- *
- * - [`addClass()`](http://api.jquery.com/addClass/) - Does not support a function as first argument
- * - [`after()`](http://api.jquery.com/after/)
- * - [`append()`](http://api.jquery.com/append/)
- * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
- * - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData
- * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
- * - [`clone()`](http://api.jquery.com/clone/)
- * - [`contents()`](http://api.jquery.com/contents/)
- * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`.
- *   As a setter, does not convert numbers to strings or append 'px', and also does not have automatic property prefixing.
- * - [`data()`](http://api.jquery.com/data/)
- * - [`detach()`](http://api.jquery.com/detach/)
- * - [`empty()`](http://api.jquery.com/empty/)
- * - [`eq()`](http://api.jquery.com/eq/)
- * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name
- * - [`hasClass()`](http://api.jquery.com/hasClass/)
- * - [`html()`](http://api.jquery.com/html/)
- * - [`next()`](http://api.jquery.com/next/) - Does not support selectors
- * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
- * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
- * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
- * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
- * - [`prepend()`](http://api.jquery.com/prepend/)
- * - [`prop()`](http://api.jquery.com/prop/)
- * - [`ready()`](http://api.jquery.com/ready/) (_deprecated_, use `angular.element(callback)` instead of `angular.element(document).ready(callback)`)
- * - [`remove()`](http://api.jquery.com/remove/)
- * - [`removeAttr()`](http://api.jquery.com/removeAttr/) - Does not support multiple attributes
- * - [`removeClass()`](http://api.jquery.com/removeClass/) - Does not support a function as first argument
- * - [`removeData()`](http://api.jquery.com/removeData/)
- * - [`replaceWith()`](http://api.jquery.com/replaceWith/)
- * - [`text()`](http://api.jquery.com/text/)
- * - [`toggleClass()`](http://api.jquery.com/toggleClass/) - Does not support a function as first argument
- * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers
- * - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter
- * - [`val()`](http://api.jquery.com/val/)
- * - [`wrap()`](http://api.jquery.com/wrap/)
- *
- * ## jQuery/jqLite Extras
- * Angular also provides the following additional methods and events to both jQuery and jqLite:
- *
- * ### Events
- * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
- *    on all DOM nodes being removed.  This can be used to clean up any 3rd party bindings to the DOM
- *    element before it is removed.
- *
- * ### Methods
- * - `controller(name)` - retrieves the controller of the current element or its parent. By default
- *   retrieves controller associated with the `ngController` directive. If `name` is provided as
- *   camelCase directive name, then the controller for this directive will be retrieved (e.g.
- *   `'ngModel'`).
- * - `injector()` - retrieves the injector of the current element or its parent.
- * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
- *   element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
- *   be enabled.
- * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
- *   current element. This getter should be used only on elements that contain a directive which starts a new isolate
- *   scope. Calling `scope()` on this element always returns the original non-isolate scope.
- *   Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
- * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
- *   parent element is reached.
- *
- * @knownIssue You cannot spy on `angular.element` if you are using Jasmine version 1.x. See
- * https://github.com/angular/angular.js/issues/14251 for more information.
- *
- * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
- * @returns {Object} jQuery object.
- */
-
-JQLite.expando = 'ng339';
-
-var jqCache = JQLite.cache = {},
-    jqId = 1;
-
-/*
- * !!! This is an undocumented "private" function !!!
- */
-JQLite._data = function(node) {
-  //jQuery always returns an object on cache miss
-  return this.cache[node[this.expando]] || {};
-};
-
-function jqNextId() { return ++jqId; }
-
-
-var DASH_LOWERCASE_REGEXP = /-([a-z])/g;
-var MS_HACK_REGEXP = /^-ms-/;
-var MOUSE_EVENT_MAP = { mouseleave: 'mouseout', mouseenter: 'mouseover' };
-var jqLiteMinErr = minErr('jqLite');
-
-/**
- * Converts kebab-case to camelCase.
- * There is also a special case for the ms prefix starting with a lowercase letter.
- * @param name Name to normalize
- */
-function cssKebabToCamel(name) {
-    return kebabToCamel(name.replace(MS_HACK_REGEXP, 'ms-'));
-}
-
-function fnCamelCaseReplace(all, letter) {
-  return letter.toUpperCase();
-}
-
-/**
- * Converts kebab-case to camelCase.
- * @param name Name to normalize
- */
-function kebabToCamel(name) {
-  return name
-    .replace(DASH_LOWERCASE_REGEXP, fnCamelCaseReplace);
-}
-
-var SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;
-var HTML_REGEXP = /<|&#?\w+;/;
-var TAG_NAME_REGEXP = /<([\w:-]+)/;
-var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi;
-
-var wrapMap = {
-  'option': [1, '<select multiple="multiple">', '</select>'],
-
-  'thead': [1, '<table>', '</table>'],
-  'col': [2, '<table><colgroup>', '</colgroup></table>'],
-  'tr': [2, '<table><tbody>', '</tbody></table>'],
-  'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
-  '_default': [0, '', '']
-};
-
-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-
-function jqLiteIsTextNode(html) {
-  return !HTML_REGEXP.test(html);
-}
-
-function jqLiteAcceptsData(node) {
-  // The window object can accept data but has no nodeType
-  // Otherwise we are only interested in elements (1) and documents (9)
-  var nodeType = node.nodeType;
-  return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
-}
-
-function jqLiteHasData(node) {
-  for (var key in jqCache[node.ng339]) {
-    return true;
-  }
-  return false;
-}
-
-function jqLiteCleanData(nodes) {
-  for (var i = 0, ii = nodes.length; i < ii; i++) {
-    jqLiteRemoveData(nodes[i]);
-  }
-}
-
-function jqLiteBuildFragment(html, context) {
-  var tmp, tag, wrap,
-      fragment = context.createDocumentFragment(),
-      nodes = [], i;
-
-  if (jqLiteIsTextNode(html)) {
-    // Convert non-html into a text node
-    nodes.push(context.createTextNode(html));
-  } else {
-    // Convert html into DOM nodes
-    tmp = fragment.appendChild(context.createElement('div'));
-    tag = (TAG_NAME_REGEXP.exec(html) || ['', ''])[1].toLowerCase();
-    wrap = wrapMap[tag] || wrapMap._default;
-    tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, '<$1></$2>') + wrap[2];
-
-    // Descend through wrappers to the right content
-    i = wrap[0];
-    while (i--) {
-      tmp = tmp.lastChild;
-    }
-
-    nodes = concat(nodes, tmp.childNodes);
-
-    tmp = fragment.firstChild;
-    tmp.textContent = '';
-  }
-
-  // Remove wrapper from fragment
-  fragment.textContent = '';
-  fragment.innerHTML = ''; // Clear inner HTML
-  forEach(nodes, function(node) {
-    fragment.appendChild(node);
-  });
-
-  return fragment;
-}
-
-function jqLiteParseHTML(html, context) {
-  context = context || window.document;
-  var parsed;
-
-  if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
-    return [context.createElement(parsed[1])];
-  }
-
-  if ((parsed = jqLiteBuildFragment(html, context))) {
-    return parsed.childNodes;
-  }
-
-  return [];
-}
-
-function jqLiteWrapNode(node, wrapper) {
-  var parent = node.parentNode;
-
-  if (parent) {
-    parent.replaceChild(wrapper, node);
-  }
-
-  wrapper.appendChild(node);
-}
-
-
-// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
-var jqLiteContains = window.Node.prototype.contains || /** @this */ function(arg) {
-  // eslint-disable-next-line no-bitwise
-  return !!(this.compareDocumentPosition(arg) & 16);
-};
-
-/////////////////////////////////////////////
-function JQLite(element) {
-  if (element instanceof JQLite) {
-    return element;
-  }
-
-  var argIsString;
-
-  if (isString(element)) {
-    element = trim(element);
-    argIsString = true;
-  }
-  if (!(this instanceof JQLite)) {
-    if (argIsString && element.charAt(0) !== '<') {
-      throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
-    }
-    return new JQLite(element);
-  }
-
-  if (argIsString) {
-    jqLiteAddNodes(this, jqLiteParseHTML(element));
-  } else if (isFunction(element)) {
-    jqLiteReady(element);
-  } else {
-    jqLiteAddNodes(this, element);
-  }
-}
-
-function jqLiteClone(element) {
-  return element.cloneNode(true);
-}
-
-function jqLiteDealoc(element, onlyDescendants) {
-  if (!onlyDescendants) jqLiteRemoveData(element);
-
-  if (element.querySelectorAll) {
-    var descendants = element.querySelectorAll('*');
-    for (var i = 0, l = descendants.length; i < l; i++) {
-      jqLiteRemoveData(descendants[i]);
-    }
-  }
-}
-
-function jqLiteOff(element, type, fn, unsupported) {
-  if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');
-
-  var expandoStore = jqLiteExpandoStore(element);
-  var events = expandoStore && expandoStore.events;
-  var handle = expandoStore && expandoStore.handle;
-
-  if (!handle) return; //no listeners registered
-
-  if (!type) {
-    for (type in events) {
-      if (type !== '$destroy') {
-        element.removeEventListener(type, handle);
-      }
-      delete events[type];
-    }
-  } else {
-
-    var removeHandler = function(type) {
-      var listenerFns = events[type];
-      if (isDefined(fn)) {
-        arrayRemove(listenerFns || [], fn);
-      }
-      if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) {
-        element.removeEventListener(type, handle);
-        delete events[type];
-      }
-    };
-
-    forEach(type.split(' '), function(type) {
-      removeHandler(type);
-      if (MOUSE_EVENT_MAP[type]) {
-        removeHandler(MOUSE_EVENT_MAP[type]);
-      }
-    });
-  }
-}
-
-function jqLiteRemoveData(element, name) {
-  var expandoId = element.ng339;
-  var expandoStore = expandoId && jqCache[expandoId];
-
-  if (expandoStore) {
-    if (name) {
-      delete expandoStore.data[name];
-      return;
-    }
-
-    if (expandoStore.handle) {
-      if (expandoStore.events.$destroy) {
-        expandoStore.handle({}, '$destroy');
-      }
-      jqLiteOff(element);
-    }
-    delete jqCache[expandoId];
-    element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it
-  }
-}
-
-
-function jqLiteExpandoStore(element, createIfNecessary) {
-  var expandoId = element.ng339,
-      expandoStore = expandoId && jqCache[expandoId];
-
-  if (createIfNecessary && !expandoStore) {
-    element.ng339 = expandoId = jqNextId();
-    expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined};
-  }
-
-  return expandoStore;
-}
-
-
-function jqLiteData(element, key, value) {
-  if (jqLiteAcceptsData(element)) {
-    var prop;
-
-    var isSimpleSetter = isDefined(value);
-    var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
-    var massGetter = !key;
-    var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
-    var data = expandoStore && expandoStore.data;
-
-    if (isSimpleSetter) { // data('key', value)
-      data[kebabToCamel(key)] = value;
-    } else {
-      if (massGetter) {  // data()
-        return data;
-      } else {
-        if (isSimpleGetter) { // data('key')
-          // don't force creation of expandoStore if it doesn't exist yet
-          return data && data[kebabToCamel(key)];
-        } else { // mass-setter: data({key1: val1, key2: val2})
-          for (prop in key) {
-            data[kebabToCamel(prop)] = key[prop];
-          }
-        }
-      }
-    }
-  }
-}
-
-function jqLiteHasClass(element, selector) {
-  if (!element.getAttribute) return false;
-  return ((' ' + (element.getAttribute('class') || '') + ' ').replace(/[\n\t]/g, ' ').
-      indexOf(' ' + selector + ' ') > -1);
-}
-
-function jqLiteRemoveClass(element, cssClasses) {
-  if (cssClasses && element.setAttribute) {
-    forEach(cssClasses.split(' '), function(cssClass) {
-      element.setAttribute('class', trim(
-          (' ' + (element.getAttribute('class') || '') + ' ')
-          .replace(/[\n\t]/g, ' ')
-          .replace(' ' + trim(cssClass) + ' ', ' '))
-      );
-    });
-  }
-}
-
-function jqLiteAddClass(element, cssClasses) {
-  if (cssClasses && element.setAttribute) {
-    var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
-                            .replace(/[\n\t]/g, ' ');
-
-    forEach(cssClasses.split(' '), function(cssClass) {
-      cssClass = trim(cssClass);
-      if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
-        existingClasses += cssClass + ' ';
-      }
-    });
-
-    element.setAttribute('class', trim(existingClasses));
-  }
-}
-
-
-function jqLiteAddNodes(root, elements) {
-  // THIS CODE IS VERY HOT. Don't make changes without benchmarking.
-
-  if (elements) {
-
-    // if a Node (the most common case)
-    if (elements.nodeType) {
-      root[root.length++] = elements;
-    } else {
-      var length = elements.length;
-
-      // if an Array or NodeList and not a Window
-      if (typeof length === 'number' && elements.window !== elements) {
-        if (length) {
-          for (var i = 0; i < length; i++) {
-            root[root.length++] = elements[i];
-          }
-        }
-      } else {
-        root[root.length++] = elements;
-      }
-    }
-  }
-}
-
-
-function jqLiteController(element, name) {
-  return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
-}
-
-function jqLiteInheritedData(element, name, value) {
-  // if element is the document object work with the html element instead
-  // this makes $(document).scope() possible
-  if (element.nodeType === NODE_TYPE_DOCUMENT) {
-    element = element.documentElement;
-  }
-  var names = isArray(name) ? name : [name];
-
-  while (element) {
-    for (var i = 0, ii = names.length; i < ii; i++) {
-      if (isDefined(value = jqLite.data(element, names[i]))) return value;
-    }
-
-    // If dealing with a document fragment node with a host element, and no parent, use the host
-    // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
-    // to lookup parent controllers.
-    element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);
-  }
-}
-
-function jqLiteEmpty(element) {
-  jqLiteDealoc(element, true);
-  while (element.firstChild) {
-    element.removeChild(element.firstChild);
-  }
-}
-
-function jqLiteRemove(element, keepData) {
-  if (!keepData) jqLiteDealoc(element);
-  var parent = element.parentNode;
-  if (parent) parent.removeChild(element);
-}
-
-
-function jqLiteDocumentLoaded(action, win) {
-  win = win || window;
-  if (win.document.readyState === 'complete') {
-    // Force the action to be run async for consistent behavior
-    // from the action's point of view
-    // i.e. it will definitely not be in a $apply
-    win.setTimeout(action);
-  } else {
-    // No need to unbind this handler as load is only ever called once
-    jqLite(win).on('load', action);
-  }
-}
-
-function jqLiteReady(fn) {
-  function trigger() {
-    window.document.removeEventListener('DOMContentLoaded', trigger);
-    window.removeEventListener('load', trigger);
-    fn();
-  }
-
-  // check if document is already loaded
-  if (window.document.readyState === 'complete') {
-    window.setTimeout(fn);
-  } else {
-    // We can not use jqLite since we are not done loading and jQuery could be loaded later.
-
-    // Works for modern browsers and IE9
-    window.document.addEventListener('DOMContentLoaded', trigger);
-
-    // Fallback to window.onload for others
-    window.addEventListener('load', trigger);
-  }
-}
-
-//////////////////////////////////////////
-// Functions which are declared directly.
-//////////////////////////////////////////
-var JQLitePrototype = JQLite.prototype = {
-  ready: jqLiteReady,
-  toString: function() {
-    var value = [];
-    forEach(this, function(e) { value.push('' + e);});
-    return '[' + value.join(', ') + ']';
-  },
-
-  eq: function(index) {
-      return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);
-  },
-
-  length: 0,
-  push: push,
-  sort: [].sort,
-  splice: [].splice
-};
-
-//////////////////////////////////////////
-// Functions iterating getter/setters.
-// these functions return self on setter and
-// value on get.
-//////////////////////////////////////////
-var BOOLEAN_ATTR = {};
-forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
-  BOOLEAN_ATTR[lowercase(value)] = value;
-});
-var BOOLEAN_ELEMENTS = {};
-forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
-  BOOLEAN_ELEMENTS[value] = true;
-});
-var ALIASED_ATTR = {
-  'ngMinlength': 'minlength',
-  'ngMaxlength': 'maxlength',
-  'ngMin': 'min',
-  'ngMax': 'max',
-  'ngPattern': 'pattern',
-  'ngStep': 'step'
-};
-
-function getBooleanAttrName(element, name) {
-  // check dom last since we will most likely fail on name
-  var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
-
-  // booleanAttr is here twice to minimize DOM access
-  return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
-}
-
-function getAliasedAttrName(name) {
-  return ALIASED_ATTR[name];
-}
-
-forEach({
-  data: jqLiteData,
-  removeData: jqLiteRemoveData,
-  hasData: jqLiteHasData,
-  cleanData: jqLiteCleanData
-}, function(fn, name) {
-  JQLite[name] = fn;
-});
-
-forEach({
-  data: jqLiteData,
-  inheritedData: jqLiteInheritedData,
-
-  scope: function(element) {
-    // Can't use jqLiteData here directly so we stay compatible with jQuery!
-    return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);
-  },
-
-  isolateScope: function(element) {
-    // Can't use jqLiteData here directly so we stay compatible with jQuery!
-    return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');
-  },
-
-  controller: jqLiteController,
-
-  injector: function(element) {
-    return jqLiteInheritedData(element, '$injector');
-  },
-
-  removeAttr: function(element, name) {
-    element.removeAttribute(name);
-  },
-
-  hasClass: jqLiteHasClass,
-
-  css: function(element, name, value) {
-    name = cssKebabToCamel(name);
-
-    if (isDefined(value)) {
-      element.style[name] = value;
-    } else {
-      return element.style[name];
-    }
-  },
-
-  attr: function(element, name, value) {
-    var ret;
-    var nodeType = element.nodeType;
-    if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT ||
-      !element.getAttribute) {
-      return;
-    }
-
-    var lowercasedName = lowercase(name);
-    var isBooleanAttr = BOOLEAN_ATTR[lowercasedName];
-
-    if (isDefined(value)) {
-      // setter
-
-      if (value === null || (value === false && isBooleanAttr)) {
-        element.removeAttribute(name);
-      } else {
-        element.setAttribute(name, isBooleanAttr ? lowercasedName : value);
-      }
-    } else {
-      // getter
-
-      ret = element.getAttribute(name);
-
-      if (isBooleanAttr && ret !== null) {
-        ret = lowercasedName;
-      }
-      // Normalize non-existing attributes to undefined (as jQuery).
-      return ret === null ? undefined : ret;
-    }
-  },
-
-  prop: function(element, name, value) {
-    if (isDefined(value)) {
-      element[name] = value;
-    } else {
-      return element[name];
-    }
-  },
-
-  text: (function() {
-    getText.$dv = '';
-    return getText;
-
-    function getText(element, value) {
-      if (isUndefined(value)) {
-        var nodeType = element.nodeType;
-        return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';
-      }
-      element.textContent = value;
-    }
-  })(),
-
-  val: function(element, value) {
-    if (isUndefined(value)) {
-      if (element.multiple && nodeName_(element) === 'select') {
-        var result = [];
-        forEach(element.options, function(option) {
-          if (option.selected) {
-            result.push(option.value || option.text);
-          }
-        });
-        return result;
-      }
-      return element.value;
-    }
-    element.value = value;
-  },
-
-  html: function(element, value) {
-    if (isUndefined(value)) {
-      return element.innerHTML;
-    }
-    jqLiteDealoc(element, true);
-    element.innerHTML = value;
-  },
-
-  empty: jqLiteEmpty
-}, function(fn, name) {
-  /**
-   * Properties: writes return selection, reads return first value
-   */
-  JQLite.prototype[name] = function(arg1, arg2) {
-    var i, key;
-    var nodeCount = this.length;
-
-    // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
-    // in a way that survives minification.
-    // jqLiteEmpty takes no arguments but is a setter.
-    if (fn !== jqLiteEmpty &&
-        (isUndefined((fn.length === 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) {
-      if (isObject(arg1)) {
-
-        // we are a write, but the object properties are the key/values
-        for (i = 0; i < nodeCount; i++) {
-          if (fn === jqLiteData) {
-            // data() takes the whole object in jQuery
-            fn(this[i], arg1);
-          } else {
-            for (key in arg1) {
-              fn(this[i], key, arg1[key]);
-            }
-          }
-        }
-        // return self for chaining
-        return this;
-      } else {
-        // we are a read, so read the first child.
-        // TODO: do we still need this?
-        var value = fn.$dv;
-        // Only if we have $dv do we iterate over all, otherwise it is just the first element.
-        var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount;
-        for (var j = 0; j < jj; j++) {
-          var nodeValue = fn(this[j], arg1, arg2);
-          value = value ? value + nodeValue : nodeValue;
-        }
-        return value;
-      }
-    } else {
-      // we are a write, so apply to all children
-      for (i = 0; i < nodeCount; i++) {
-        fn(this[i], arg1, arg2);
-      }
-      // return self for chaining
-      return this;
-    }
-  };
-});
-
-function createEventHandler(element, events) {
-  var eventHandler = function(event, type) {
-    // jQuery specific api
-    event.isDefaultPrevented = function() {
-      return event.defaultPrevented;
-    };
-
-    var eventFns = events[type || event.type];
-    var eventFnsLength = eventFns ? eventFns.length : 0;
-
-    if (!eventFnsLength) return;
-
-    if (isUndefined(event.immediatePropagationStopped)) {
-      var originalStopImmediatePropagation = event.stopImmediatePropagation;
-      event.stopImmediatePropagation = function() {
-        event.immediatePropagationStopped = true;
-
-        if (event.stopPropagation) {
-          event.stopPropagation();
-        }
-
-        if (originalStopImmediatePropagation) {
-          originalStopImmediatePropagation.call(event);
-        }
-      };
-    }
-
-    event.isImmediatePropagationStopped = function() {
-      return event.immediatePropagationStopped === true;
-    };
-
-    // Some events have special handlers that wrap the real handler
-    var handlerWrapper = eventFns.specialHandlerWrapper || defaultHandlerWrapper;
-
-    // Copy event handlers in case event handlers array is modified during execution.
-    if ((eventFnsLength > 1)) {
-      eventFns = shallowCopy(eventFns);
-    }
-
-    for (var i = 0; i < eventFnsLength; i++) {
-      if (!event.isImmediatePropagationStopped()) {
-        handlerWrapper(element, event, eventFns[i]);
-      }
-    }
-  };
-
-  // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
-  //       events on `element`
-  eventHandler.elem = element;
-  return eventHandler;
-}
-
-function defaultHandlerWrapper(element, event, handler) {
-  handler.call(element, event);
-}
-
-function specialMouseHandlerWrapper(target, event, handler) {
-  // Refer to jQuery's implementation of mouseenter & mouseleave
-  // Read about mouseenter and mouseleave:
-  // http://www.quirksmode.org/js/events_mouse.html#link8
-  var related = event.relatedTarget;
-  // For mousenter/leave call the handler if related is outside the target.
-  // NB: No relatedTarget if the mouse left/entered the browser window
-  if (!related || (related !== target && !jqLiteContains.call(target, related))) {
-    handler.call(target, event);
-  }
-}
-
-//////////////////////////////////////////
-// Functions iterating traversal.
-// These functions chain results into a single
-// selector.
-//////////////////////////////////////////
-forEach({
-  removeData: jqLiteRemoveData,
-
-  on: function jqLiteOn(element, type, fn, unsupported) {
-    if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
-
-    // Do not add event handlers to non-elements because they will not be cleaned up.
-    if (!jqLiteAcceptsData(element)) {
-      return;
-    }
-
-    var expandoStore = jqLiteExpandoStore(element, true);
-    var events = expandoStore.events;
-    var handle = expandoStore.handle;
-
-    if (!handle) {
-      handle = expandoStore.handle = createEventHandler(element, events);
-    }
-
-    // http://jsperf.com/string-indexof-vs-split
-    var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type];
-    var i = types.length;
-
-    var addHandler = function(type, specialHandlerWrapper, noEventListener) {
-      var eventFns = events[type];
-
-      if (!eventFns) {
-        eventFns = events[type] = [];
-        eventFns.specialHandlerWrapper = specialHandlerWrapper;
-        if (type !== '$destroy' && !noEventListener) {
-          element.addEventListener(type, handle);
-        }
-      }
-
-      eventFns.push(fn);
-    };
-
-    while (i--) {
-      type = types[i];
-      if (MOUSE_EVENT_MAP[type]) {
-        addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);
-        addHandler(type, undefined, true);
-      } else {
-        addHandler(type);
-      }
-    }
-  },
-
-  off: jqLiteOff,
-
-  one: function(element, type, fn) {
-    element = jqLite(element);
-
-    //add the listener twice so that when it is called
-    //you can remove the original function and still be
-    //able to call element.off(ev, fn) normally
-    element.on(type, function onFn() {
-      element.off(type, fn);
-      element.off(type, onFn);
-    });
-    element.on(type, fn);
-  },
-
-  replaceWith: function(element, replaceNode) {
-    var index, parent = element.parentNode;
-    jqLiteDealoc(element);
-    forEach(new JQLite(replaceNode), function(node) {
-      if (index) {
-        parent.insertBefore(node, index.nextSibling);
-      } else {
-        parent.replaceChild(node, element);
-      }
-      index = node;
-    });
-  },
-
-  children: function(element) {
-    var children = [];
-    forEach(element.childNodes, function(element) {
-      if (element.nodeType === NODE_TYPE_ELEMENT) {
-        children.push(element);
-      }
-    });
-    return children;
-  },
-
-  contents: function(element) {
-    return element.contentDocument || element.childNodes || [];
-  },
-
-  append: function(element, node) {
-    var nodeType = element.nodeType;
-    if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return;
-
-    node = new JQLite(node);
-
-    for (var i = 0, ii = node.length; i < ii; i++) {
-      var child = node[i];
-      element.appendChild(child);
-    }
-  },
-
-  prepend: function(element, node) {
-    if (element.nodeType === NODE_TYPE_ELEMENT) {
-      var index = element.firstChild;
-      forEach(new JQLite(node), function(child) {
-        element.insertBefore(child, index);
-      });
-    }
-  },
-
-  wrap: function(element, wrapNode) {
-    jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);
-  },
-
-  remove: jqLiteRemove,
-
-  detach: function(element) {
-    jqLiteRemove(element, true);
-  },
-
-  after: function(element, newElement) {
-    var index = element, parent = element.parentNode;
-
-    if (parent) {
-      newElement = new JQLite(newElement);
-
-      for (var i = 0, ii = newElement.length; i < ii; i++) {
-        var node = newElement[i];
-        parent.insertBefore(node, index.nextSibling);
-        index = node;
-      }
-    }
-  },
-
-  addClass: jqLiteAddClass,
-  removeClass: jqLiteRemoveClass,
-
-  toggleClass: function(element, selector, condition) {
-    if (selector) {
-      forEach(selector.split(' '), function(className) {
-        var classCondition = condition;
-        if (isUndefined(classCondition)) {
-          classCondition = !jqLiteHasClass(element, className);
-        }
-        (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className);
-      });
-    }
-  },
-
-  parent: function(element) {
-    var parent = element.parentNode;
-    return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null;
-  },
-
-  next: function(element) {
-    return element.nextElementSibling;
-  },
-
-  find: function(element, selector) {
-    if (element.getElementsByTagName) {
-      return element.getElementsByTagName(selector);
-    } else {
-      return [];
-    }
-  },
-
-  clone: jqLiteClone,
-
-  triggerHandler: function(element, event, extraParameters) {
-
-    var dummyEvent, eventFnsCopy, handlerArgs;
-    var eventName = event.type || event;
-    var expandoStore = jqLiteExpandoStore(element);
-    var events = expandoStore && expandoStore.events;
-    var eventFns = events && events[eventName];
-
-    if (eventFns) {
-      // Create a dummy event to pass to the handlers
-      dummyEvent = {
-        preventDefault: function() { this.defaultPrevented = true; },
-        isDefaultPrevented: function() { return this.defaultPrevented === true; },
-        stopImmediatePropagation: function() { this.immediatePropagationStopped = true; },
-        isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; },
-        stopPropagation: noop,
-        type: eventName,
-        target: element
-      };
-
-      // If a custom event was provided then extend our dummy event with it
-      if (event.type) {
-        dummyEvent = extend(dummyEvent, event);
-      }
-
-      // Copy event handlers in case event handlers array is modified during execution.
-      eventFnsCopy = shallowCopy(eventFns);
-      handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];
-
-      forEach(eventFnsCopy, function(fn) {
-        if (!dummyEvent.isImmediatePropagationStopped()) {
-          fn.apply(element, handlerArgs);
-        }
-      });
-    }
-  }
-}, function(fn, name) {
-  /**
-   * chaining functions
-   */
-  JQLite.prototype[name] = function(arg1, arg2, arg3) {
-    var value;
-
-    for (var i = 0, ii = this.length; i < ii; i++) {
-      if (isUndefined(value)) {
-        value = fn(this[i], arg1, arg2, arg3);
-        if (isDefined(value)) {
-          // any function which returns a value needs to be wrapped
-          value = jqLite(value);
-        }
-      } else {
-        jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
-      }
-    }
-    return isDefined(value) ? value : this;
-  };
-});
-
-// bind legacy bind/unbind to on/off
-JQLite.prototype.bind = JQLite.prototype.on;
-JQLite.prototype.unbind = JQLite.prototype.off;
-
-
-// Provider for private $$jqLite service
-/** @this */
-function $$jqLiteProvider() {
-  this.$get = function $$jqLite() {
-    return extend(JQLite, {
-      hasClass: function(node, classes) {
-        if (node.attr) node = node[0];
-        return jqLiteHasClass(node, classes);
-      },
-      addClass: function(node, classes) {
-        if (node.attr) node = node[0];
-        return jqLiteAddClass(node, classes);
-      },
-      removeClass: function(node, classes) {
-        if (node.attr) node = node[0];
-        return jqLiteRemoveClass(node, classes);
-      }
-    });
-  };
-}
-
-/**
- * Computes a hash of an 'obj'.
- * Hash of a:
- *  string is string
- *  number is number as string
- *  object is either result of calling $$hashKey function on the object or uniquely generated id,
- *         that is also assigned to the $$hashKey property of the object.
- *
- * @param obj
- * @returns {string} hash string such that the same input will have the same hash string.
- *         The resulting string key is in 'type:hashKey' format.
- */
-function hashKey(obj, nextUidFn) {
-  var key = obj && obj.$$hashKey;
-
-  if (key) {
-    if (typeof key === 'function') {
-      key = obj.$$hashKey();
-    }
-    return key;
-  }
-
-  var objType = typeof obj;
-  if (objType === 'function' || (objType === 'object' && obj !== null)) {
-    key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)();
-  } else {
-    key = objType + ':' + obj;
-  }
-
-  return key;
-}
-
-// A minimal ES2015 Map implementation.
-// Should be bug/feature equivalent to the native implementations of supported browsers
-// (for the features required in Angular).
-// See https://kangax.github.io/compat-table/es6/#test-Map
-var nanKey = Object.create(null);
-function NgMapShim() {
-  this._keys = [];
-  this._values = [];
-  this._lastKey = NaN;
-  this._lastIndex = -1;
-}
-NgMapShim.prototype = {
-  _idx: function(key) {
-    if (key === this._lastKey) {
-      return this._lastIndex;
-    }
-    this._lastKey = key;
-    this._lastIndex = this._keys.indexOf(key);
-    return this._lastIndex;
-  },
-  _transformKey: function(key) {
-    return isNumberNaN(key) ? nanKey : key;
-  },
-  get: function(key) {
-    key = this._transformKey(key);
-    var idx = this._idx(key);
-    if (idx !== -1) {
-      return this._values[idx];
-    }
-  },
-  set: function(key, value) {
-    key = this._transformKey(key);
-    var idx = this._idx(key);
-    if (idx === -1) {
-      idx = this._lastIndex = this._keys.length;
-    }
-    this._keys[idx] = key;
-    this._values[idx] = value;
-
-    // Support: IE11
-    // Do not `return this` to simulate the partial IE11 implementation
-  },
-  delete: function(key) {
-    key = this._transformKey(key);
-    var idx = this._idx(key);
-    if (idx === -1) {
-      return false;
-    }
-    this._keys.splice(idx, 1);
-    this._values.splice(idx, 1);
-    this._lastKey = NaN;
-    this._lastIndex = -1;
-    return true;
-  }
-};
-
-// For now, always use `NgMapShim`, even if `window.Map` is available. Some native implementations
-// are still buggy (often in subtle ways) and can cause hard-to-debug failures. When native `Map`
-// implementations get more stable, we can reconsider switching to `window.Map` (when available).
-var NgMap = NgMapShim;
-
-var $$MapProvider = [/** @this */function() {
-  this.$get = [function() {
-    return NgMap;
-  }];
-}];
-
-/**
- * @ngdoc function
- * @module ng
- * @name angular.injector
- * @kind function
- *
- * @description
- * Creates an injector object that can be used for retrieving services as well as for
- * dependency injection (see {@link guide/di dependency injection}).
- *
- * @param {Array.<string|Function>} modules A list of module functions or their aliases. See
- *     {@link angular.module}. The `ng` module must be explicitly added.
- * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which
- *     disallows argument name annotation inference.
- * @returns {injector} Injector object. See {@link auto.$injector $injector}.
- *
- * @example
- * Typical usage
- * ```js
- *   // create an injector
- *   var $injector = angular.injector(['ng']);
- *
- *   // use the injector to kick off your application
- *   // use the type inference to auto inject arguments, or use implicit injection
- *   $injector.invoke(function($rootScope, $compile, $document) {
- *     $compile($document)($rootScope);
- *     $rootScope.$digest();
- *   });
- * ```
- *
- * Sometimes you want to get access to the injector of a currently running Angular app
- * from outside Angular. Perhaps, you want to inject and compile some markup after the
- * application has been bootstrapped. You can do this using the extra `injector()` added
- * to JQuery/jqLite elements. See {@link angular.element}.
- *
- * *This is fairly rare but could be the case if a third party library is injecting the
- * markup.*
- *
- * In the following example a new block of HTML containing a `ng-controller`
- * directive is added to the end of the document body by JQuery. We then compile and link
- * it into the current AngularJS scope.
- *
- * ```js
- * var $div = $('<div ng-controller="MyCtrl">{{content.label}}</div>');
- * $(document.body).append($div);
- *
- * angular.element(document).injector().invoke(function($compile) {
- *   var scope = angular.element($div).scope();
- *   $compile($div)(scope);
- * });
- * ```
- */
-
-
-/**
- * @ngdoc module
- * @name auto
- * @installation
- * @description
- *
- * Implicit module which gets automatically added to each {@link auto.$injector $injector}.
- */
-
-var ARROW_ARG = /^([^(]+?)=>/;
-var FN_ARGS = /^[^(]*\(\s*([^)]*)\)/m;
-var FN_ARG_SPLIT = /,/;
-var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
-var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
-var $injectorMinErr = minErr('$injector');
-
-function stringifyFn(fn) {
-  return Function.prototype.toString.call(fn);
-}
-
-function extractArgs(fn) {
-  var fnText = stringifyFn(fn).replace(STRIP_COMMENTS, ''),
-      args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
-  return args;
-}
-
-function anonFn(fn) {
-  // For anonymous functions, showing at the very least the function signature can help in
-  // debugging.
-  var args = extractArgs(fn);
-  if (args) {
-    return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')';
-  }
-  return 'fn';
-}
-
-function annotate(fn, strictDi, name) {
-  var $inject,
-      argDecl,
-      last;
-
-  if (typeof fn === 'function') {
-    if (!($inject = fn.$inject)) {
-      $inject = [];
-      if (fn.length) {
-        if (strictDi) {
-          if (!isString(name) || !name) {
-            name = fn.name || anonFn(fn);
-          }
-          throw $injectorMinErr('strictdi',
-            '{0} is not using explicit annotation and cannot be invoked in strict mode', name);
-        }
-        argDecl = extractArgs(fn);
-        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
-          arg.replace(FN_ARG, function(all, underscore, name) {
-            $inject.push(name);
-          });
-        });
-      }
-      fn.$inject = $inject;
-    }
-  } else if (isArray(fn)) {
-    last = fn.length - 1;
-    assertArgFn(fn[last], 'fn');
-    $inject = fn.slice(0, last);
-  } else {
-    assertArgFn(fn, 'fn', true);
-  }
-  return $inject;
-}
-
-///////////////////////////////////////
-
-/**
- * @ngdoc service
- * @name $injector
- *
- * @description
- *
- * `$injector` is used to retrieve object instances as defined by
- * {@link auto.$provide provider}, instantiate types, invoke methods,
- * and load modules.
- *
- * The following always holds true:
- *
- * ```js
- *   var $injector = angular.injector();
- *   expect($injector.get('$injector')).toBe($injector);
- *   expect($injector.invoke(function($injector) {
- *     return $injector;
- *   })).toBe($injector);
- * ```
- *
- * # Injection Function Annotation
- *
- * JavaScript does not have annotations, and annotations are needed for dependency injection. The
- * following are all valid ways of annotating function with injection arguments and are equivalent.
- *
- * ```js
- *   // inferred (only works if code not minified/obfuscated)
- *   $injector.invoke(function(serviceA){});
- *
- *   // annotated
- *   function explicit(serviceA) {};
- *   explicit.$inject = ['serviceA'];
- *   $injector.invoke(explicit);
- *
- *   // inline
- *   $injector.invoke(['serviceA', function(serviceA){}]);
- * ```
- *
- * ## Inference
- *
- * In JavaScript calling `toString()` on a function returns the function definition. The definition
- * can then be parsed and the function arguments can be extracted. This method of discovering
- * annotations is disallowed when the injector is in strict mode.
- * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the
- * argument names.
- *
- * ## `$inject` Annotation
- * By adding an `$inject` property onto a function the injection parameters can be specified.
- *
- * ## Inline
- * As an array of injection names, where the last item in the array is the function to call.
- */
-
-/**
- * @ngdoc property
- * @name $injector#modules
- * @type {Object}
- * @description
- * A hash containing all the modules that have been loaded into the
- * $injector.
- *
- * You can use this property to find out information about a module via the
- * {@link angular.Module#info `myModule.info(...)`} method.
- *
- * For example:
- *
- * ```
- * var info = $injector.modules['ngAnimate'].info();
- * ```
- *
- * **Do not use this property to attempt to modify the modules after the application
- * has been bootstrapped.**
- */
-
-
-/**
- * @ngdoc method
- * @name $injector#get
- *
- * @description
- * Return an instance of the service.
- *
- * @param {string} name The name of the instance to retrieve.
- * @param {string=} caller An optional string to provide the origin of the function call for error messages.
- * @return {*} The instance.
- */
-
-/**
- * @ngdoc method
- * @name $injector#invoke
- *
- * @description
- * Invoke the method and supply the method arguments from the `$injector`.
- *
- * @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are
- *   injected according to the {@link guide/di $inject Annotation} rules.
- * @param {Object=} self The `this` for the invoked method.
- * @param {Object=} locals Optional object. If preset then any argument names are read from this
- *                         object first, before the `$injector` is consulted.
- * @returns {*} the value returned by the invoked `fn` function.
- */
-
-/**
- * @ngdoc method
- * @name $injector#has
- *
- * @description
- * Allows the user to query if the particular service exists.
- *
- * @param {string} name Name of the service to query.
- * @returns {boolean} `true` if injector has given service.
- */
-
-/**
- * @ngdoc method
- * @name $injector#instantiate
- * @description
- * Create a new instance of JS type. The method takes a constructor function, invokes the new
- * operator, and supplies all of the arguments to the constructor function as specified by the
- * constructor annotation.
- *
- * @param {Function} Type Annotated constructor function.
- * @param {Object=} locals Optional object. If preset then any argument names are read from this
- * object first, before the `$injector` is consulted.
- * @returns {Object} new instance of `Type`.
- */
-
-/**
- * @ngdoc method
- * @name $injector#annotate
- *
- * @description
- * Returns an array of service names which the function is requesting for injection. This API is
- * used by the injector to determine which services need to be injected into the function when the
- * function is invoked. There are three ways in which the function can be annotated with the needed
- * dependencies.
- *
- * # Argument names
- *
- * The simplest form is to extract the dependencies from the arguments of the function. This is done
- * by converting the function into a string using `toString()` method and extracting the argument
- * names.
- * ```js
- *   // Given
- *   function MyController($scope, $route) {
- *     // ...
- *   }
- *
- *   // Then
- *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
- * ```
- *
- * You can disallow this method by using strict injection mode.
- *
- * This method does not work with code minification / obfuscation. For this reason the following
- * annotation strategies are supported.
- *
- * # The `$inject` property
- *
- * If a function has an `$inject` property and its value is an array of strings, then the strings
- * represent names of services to be injected into the function.
- * ```js
- *   // Given
- *   var MyController = function(obfuscatedScope, obfuscatedRoute) {
- *     // ...
- *   }
- *   // Define function dependencies
- *   MyController['$inject'] = ['$scope', '$route'];
- *
- *   // Then
- *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
- * ```
- *
- * # The array notation
- *
- * It is often desirable to inline Injected functions and that's when setting the `$inject` property
- * is very inconvenient. In these situations using the array notation to specify the dependencies in
- * a way that survives minification is a better choice:
- *
- * ```js
- *   // We wish to write this (not minification / obfuscation safe)
- *   injector.invoke(function($compile, $rootScope) {
- *     // ...
- *   });
- *
- *   // We are forced to write break inlining
- *   var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) {
- *     // ...
- *   };
- *   tmpFn.$inject = ['$compile', '$rootScope'];
- *   injector.invoke(tmpFn);
- *
- *   // To better support inline function the inline annotation is supported
- *   injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
- *     // ...
- *   }]);
- *
- *   // Therefore
- *   expect(injector.annotate(
- *      ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])
- *    ).toEqual(['$compile', '$rootScope']);
- * ```
- *
- * @param {Function|Array.<string|Function>} fn Function for which dependent service names need to
- * be retrieved as described above.
- *
- * @param {boolean=} [strictDi=false] Disallow argument name annotation inference.
- *
- * @returns {Array.<string>} The names of the services which the function requires.
- */
-
-
-
-/**
- * @ngdoc service
- * @name $provide
- *
- * @description
- *
- * The {@link auto.$provide $provide} service has a number of methods for registering components
- * with the {@link auto.$injector $injector}. Many of these functions are also exposed on
- * {@link angular.Module}.
- *
- * An Angular **service** is a singleton object created by a **service factory**.  These **service
- * factories** are functions which, in turn, are created by a **service provider**.
- * The **service providers** are constructor functions. When instantiated they must contain a
- * property called `$get`, which holds the **service factory** function.
- *
- * When you request a service, the {@link auto.$injector $injector} is responsible for finding the
- * correct **service provider**, instantiating it and then calling its `$get` **service factory**
- * function to get the instance of the **service**.
- *
- * Often services have no configuration options and there is no need to add methods to the service
- * provider.  The provider will be no more than a constructor function with a `$get` property. For
- * these cases the {@link auto.$provide $provide} service has additional helper methods to register
- * services without specifying a provider.
- *
- * * {@link auto.$provide#provider provider(name, provider)} - registers a **service provider** with the
- *     {@link auto.$injector $injector}
- * * {@link auto.$provide#constant constant(name, obj)} - registers a value/object that can be accessed by
- *     providers and services.
- * * {@link auto.$provide#value value(name, obj)} - registers a value/object that can only be accessed by
- *     services, not providers.
- * * {@link auto.$provide#factory factory(name, fn)} - registers a service **factory function**
- *     that will be wrapped in a **service provider** object, whose `$get` property will contain the
- *     given factory function.
- * * {@link auto.$provide#service service(name, Fn)} - registers a **constructor function**
- *     that will be wrapped in a **service provider** object, whose `$get` property will instantiate
- *      a new object using the given constructor function.
- * * {@link auto.$provide#decorator decorator(name, decorFn)} - registers a **decorator function** that
- *      will be able to modify or replace the implementation of another service.
- *
- * See the individual methods for more information and examples.
- */
-
-/**
- * @ngdoc method
- * @name $provide#provider
- * @description
- *
- * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions
- * are constructor functions, whose instances are responsible for "providing" a factory for a
- * service.
- *
- * Service provider names start with the name of the service they provide followed by `Provider`.
- * For example, the {@link ng.$log $log} service has a provider called
- * {@link ng.$logProvider $logProvider}.
- *
- * Service provider objects can have additional methods which allow configuration of the provider
- * and its service. Importantly, you can configure what kind of service is created by the `$get`
- * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a
- * method {@link ng.$logProvider#debugEnabled debugEnabled}
- * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the
- * console or not.
- *
- * @param {string} name The name of the instance. NOTE: the provider will be available under `name +
-                        'Provider'` key.
- * @param {(Object|function())} provider If the provider is:
- *
- *   - `Object`: then it should have a `$get` method. The `$get` method will be invoked using
- *     {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created.
- *   - `Constructor`: a new instance of the provider will be created using
- *     {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`.
- *
- * @returns {Object} registered provider instance
-
- * @example
- *
- * The following example shows how to create a simple event tracking service and register it using
- * {@link auto.$provide#provider $provide.provider()}.
- *
- * ```js
- *  // Define the eventTracker provider
- *  function EventTrackerProvider() {
- *    var trackingUrl = '/track';
- *
- *    // A provider method for configuring where the tracked events should been saved
- *    this.setTrackingUrl = function(url) {
- *      trackingUrl = url;
- *    };
- *
- *    // The service factory function
- *    this.$get = ['$http', function($http) {
- *      var trackedEvents = {};
- *      return {
- *        // Call this to track an event
- *        event: function(event) {
- *          var count = trackedEvents[event] || 0;
- *          count += 1;
- *          trackedEvents[event] = count;
- *          return count;
- *        },
- *        // Call this to save the tracked events to the trackingUrl
- *        save: function() {
- *          $http.post(trackingUrl, trackedEvents);
- *        }
- *      };
- *    }];
- *  }
- *
- *  describe('eventTracker', function() {
- *    var postSpy;
- *
- *    beforeEach(module(function($provide) {
- *      // Register the eventTracker provider
- *      $provide.provider('eventTracker', EventTrackerProvider);
- *    }));
- *
- *    beforeEach(module(function(eventTrackerProvider) {
- *      // Configure eventTracker provider
- *      eventTrackerProvider.setTrackingUrl('/custom-track');
- *    }));
- *
- *    it('tracks events', inject(function(eventTracker) {
- *      expect(eventTracker.event('login')).toEqual(1);
- *      expect(eventTracker.event('login')).toEqual(2);
- *    }));
- *
- *    it('saves to the tracking url', inject(function(eventTracker, $http) {
- *      postSpy = spyOn($http, 'post');
- *      eventTracker.event('login');
- *      eventTracker.save();
- *      expect(postSpy).toHaveBeenCalled();
- *      expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');
- *      expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');
- *      expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });
- *    }));
- *  });
- * ```
- */
-
-/**
- * @ngdoc method
- * @name $provide#factory
- * @description
- *
- * Register a **service factory**, which will be called to return the service instance.
- * This is short for registering a service where its provider consists of only a `$get` property,
- * which is the given service factory function.
- * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to
- * configure your service in a provider.
- *
- * @param {string} name The name of the instance.
- * @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation.
- *                      Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`.
- * @returns {Object} registered provider instance
- *
- * @example
- * Here is an example of registering a service
- * ```js
- *   $provide.factory('ping', ['$http', function($http) {
- *     return function ping() {
- *       return $http.send('/ping');
- *     };
- *   }]);
- * ```
- * You would then inject and use this service like this:
- * ```js
- *   someModule.controller('Ctrl', ['ping', function(ping) {
- *     ping();
- *   }]);
- * ```
- */
-
-
-/**
- * @ngdoc method
- * @name $provide#service
- * @description
- *
- * Register a **service constructor**, which will be invoked with `new` to create the service
- * instance.
- * This is short for registering a service where its provider's `$get` property is a factory
- * function that returns an instance instantiated by the injector from the service constructor
- * function.
- *
- * Internally it looks a bit like this:
- *
- * ```
- * {
- *   $get: function() {
- *     return $injector.instantiate(constructor);
- *   }
- * }
- * ```
- *
- *
- * You should use {@link auto.$provide#service $provide.service(class)} if you define your service
- * as a type/class.
- *
- * @param {string} name The name of the instance.
- * @param {Function|Array.<string|Function>} constructor An injectable class (constructor function)
- *     that will be instantiated.
- * @returns {Object} registered provider instance
- *
- * @example
- * Here is an example of registering a service using
- * {@link auto.$provide#service $provide.service(class)}.
- * ```js
- *   var Ping = function($http) {
- *     this.$http = $http;
- *   };
- *
- *   Ping.$inject = ['$http'];
- *
- *   Ping.prototype.send = function() {
- *     return this.$http.get('/ping');
- *   };
- *   $provide.service('ping', Ping);
- * ```
- * You would then inject and use this service like this:
- * ```js
- *   someModule.controller('Ctrl', ['ping', function(ping) {
- *     ping.send();
- *   }]);
- * ```
- */
-
-
-/**
- * @ngdoc method
- * @name $provide#value
- * @description
- *
- * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a
- * number, an array, an object or a function. This is short for registering a service where its
- * provider's `$get` property is a factory function that takes no arguments and returns the **value
- * service**. That also means it is not possible to inject other services into a value service.
- *
- * Value services are similar to constant services, except that they cannot be injected into a
- * module configuration function (see {@link angular.Module#config}) but they can be overridden by
- * an Angular {@link auto.$provide#decorator decorator}.
- *
- * @param {string} name The name of the instance.
- * @param {*} value The value.
- * @returns {Object} registered provider instance
- *
- * @example
- * Here are some examples of creating value services.
- * ```js
- *   $provide.value('ADMIN_USER', 'admin');
- *
- *   $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
- *
- *   $provide.value('halfOf', function(value) {
- *     return value / 2;
- *   });
- * ```
- */
-
-
-/**
- * @ngdoc method
- * @name $provide#constant
- * @description
- *
- * Register a **constant service** with the {@link auto.$injector $injector}, such as a string,
- * a number, an array, an object or a function. Like the {@link auto.$provide#value value}, it is not
- * possible to inject other services into a constant.
- *
- * But unlike {@link auto.$provide#value value}, a constant can be
- * injected into a module configuration function (see {@link angular.Module#config}) and it cannot
- * be overridden by an Angular {@link auto.$provide#decorator decorator}.
- *
- * @param {string} name The name of the constant.
- * @param {*} value The constant value.
- * @returns {Object} registered instance
- *
- * @example
- * Here a some examples of creating constants:
- * ```js
- *   $provide.constant('SHARD_HEIGHT', 306);
- *
- *   $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);
- *
- *   $provide.constant('double', function(value) {
- *     return value * 2;
- *   });
- * ```
- */
-
-
-/**
- * @ngdoc method
- * @name $provide#decorator
- * @description
- *
- * Register a **decorator function** with the {@link auto.$injector $injector}. A decorator function
- * intercepts the creation of a service, allowing it to override or modify the behavior of the
- * service. The return value of the decorator function may be the original service, or a new service
- * that replaces (or wraps and delegates to) the original service.
- *
- * You can find out more about using decorators in the {@link guide/decorators} guide.
- *
- * @param {string} name The name of the service to decorate.
- * @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be
- *    provided and should return the decorated service instance. The function is called using
- *    the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.
- *    Local injection arguments:
- *
- *    * `$delegate` - The original service instance, which can be replaced, monkey patched, configured,
- *      decorated or delegated to.
- *
- * @example
- * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
- * calls to {@link ng.$log#error $log.warn()}.
- * ```js
- *   $provide.decorator('$log', ['$delegate', function($delegate) {
- *     $delegate.warn = $delegate.error;
- *     return $delegate;
- *   }]);
- * ```
- */
-
-
-function createInjector(modulesToLoad, strictDi) {
-  strictDi = (strictDi === true);
-  var INSTANTIATING = {},
-      providerSuffix = 'Provider',
-      path = [],
-      loadedModules = new NgMap(),
-      providerCache = {
-        $provide: {
-            provider: supportObject(provider),
-            factory: supportObject(factory),
-            service: supportObject(service),
-            value: supportObject(value),
-            constant: supportObject(constant),
-            decorator: decorator
-          }
-      },
-      providerInjector = (providerCache.$injector =
-          createInternalInjector(providerCache, function(serviceName, caller) {
-            if (angular.isString(caller)) {
-              path.push(caller);
-            }
-            throw $injectorMinErr('unpr', 'Unknown provider: {0}', path.join(' <- '));
-          })),
-      instanceCache = {},
-      protoInstanceInjector =
-          createInternalInjector(instanceCache, function(serviceName, caller) {
-            var provider = providerInjector.get(serviceName + providerSuffix, caller);
-            return instanceInjector.invoke(
-                provider.$get, provider, undefined, serviceName);
-          }),
-      instanceInjector = protoInstanceInjector;
-
-  providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
-  instanceInjector.modules = providerInjector.modules = createMap();
-  var runBlocks = loadModules(modulesToLoad);
-  instanceInjector = protoInstanceInjector.get('$injector');
-  instanceInjector.strictDi = strictDi;
-  forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });
-
-  return instanceInjector;
-
-  ////////////////////////////////////
-  // $provider
-  ////////////////////////////////////
-
-  function supportObject(delegate) {
-    return function(key, value) {
-      if (isObject(key)) {
-        forEach(key, reverseParams(delegate));
-      } else {
-        return delegate(key, value);
-      }
-    };
-  }
-
-  function provider(name, provider_) {
-    assertNotHasOwnProperty(name, 'service');
-    if (isFunction(provider_) || isArray(provider_)) {
-      provider_ = providerInjector.instantiate(provider_);
-    }
-    if (!provider_.$get) {
-      throw $injectorMinErr('pget', 'Provider \'{0}\' must define $get factory method.', name);
-    }
-    return (providerCache[name + providerSuffix] = provider_);
-  }
-
-  function enforceReturnValue(name, factory) {
-    return /** @this */ function enforcedReturnValue() {
-      var result = instanceInjector.invoke(factory, this);
-      if (isUndefined(result)) {
-        throw $injectorMinErr('undef', 'Provider \'{0}\' must return a value from $get factory method.', name);
-      }
-      return result;
-    };
-  }
-
-  function factory(name, factoryFn, enforce) {
-    return provider(name, {
-      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
-    });
-  }
-
-  function service(name, constructor) {
-    return factory(name, ['$injector', function($injector) {
-      return $injector.instantiate(constructor);
-    }]);
-  }
-
-  function value(name, val) { return factory(name, valueFn(val), false); }
-
-  function constant(name, value) {
-    assertNotHasOwnProperty(name, 'constant');
-    providerCache[name] = value;
-    instanceCache[name] = value;
-  }
-
-  function decorator(serviceName, decorFn) {
-    var origProvider = providerInjector.get(serviceName + providerSuffix),
-        orig$get = origProvider.$get;
-
-    origProvider.$get = function() {
-      var origInstance = instanceInjector.invoke(orig$get, origProvider);
-      return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});
-    };
-  }
-
-  ////////////////////////////////////
-  // Module Loading
-  ////////////////////////////////////
-  function loadModules(modulesToLoad) {
-    assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array');
-    var runBlocks = [], moduleFn;
-    forEach(modulesToLoad, function(module) {
-      if (loadedModules.get(module)) return;
-      loadedModules.set(module, true);
-
-      function runInvokeQueue(queue) {
-        var i, ii;
-        for (i = 0, ii = queue.length; i < ii; i++) {
-          var invokeArgs = queue[i],
-              provider = providerInjector.get(invokeArgs[0]);
-
-          provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
-        }
-      }
-
-      try {
-        if (isString(module)) {
-          moduleFn = angularModule(module);
-          instanceInjector.modules[module] = moduleFn;
-          runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
-          runInvokeQueue(moduleFn._invokeQueue);
-          runInvokeQueue(moduleFn._configBlocks);
-        } else if (isFunction(module)) {
-            runBlocks.push(providerInjector.invoke(module));
-        } else if (isArray(module)) {
-            runBlocks.push(providerInjector.invoke(module));
-        } else {
-          assertArgFn(module, 'module');
-        }
-      } catch (e) {
-        if (isArray(module)) {
-          module = module[module.length - 1];
-        }
-        if (e.message && e.stack && e.stack.indexOf(e.message) === -1) {
-          // Safari & FF's stack traces don't contain error.message content
-          // unlike those of Chrome and IE
-          // So if stack doesn't contain message, we create a new string that contains both.
-          // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.
-          // eslint-disable-next-line no-ex-assign
-          e = e.message + '\n' + e.stack;
-        }
-        throw $injectorMinErr('modulerr', 'Failed to instantiate module {0} due to:\n{1}',
-                  module, e.stack || e.message || e);
-      }
-    });
-    return runBlocks;
-  }
-
-  ////////////////////////////////////
-  // internal Injector
-  ////////////////////////////////////
-
-  function createInternalInjector(cache, factory) {
-
-    function getService(serviceName, caller) {
-      if (cache.hasOwnProperty(serviceName)) {
-        if (cache[serviceName] === INSTANTIATING) {
-          throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
-                    serviceName + ' <- ' + path.join(' <- '));
-        }
-        return cache[serviceName];
-      } else {
-        try {
-          path.unshift(serviceName);
-          cache[serviceName] = INSTANTIATING;
-          cache[serviceName] = factory(serviceName, caller);
-          return cache[serviceName];
-        } catch (err) {
-          if (cache[serviceName] === INSTANTIATING) {
-            delete cache[serviceName];
-          }
-          throw err;
-        } finally {
-          path.shift();
-        }
-      }
-    }
-
-
-    function injectionArgs(fn, locals, serviceName) {
-      var args = [],
-          $inject = createInjector.$$annotate(fn, strictDi, serviceName);
-
-      for (var i = 0, length = $inject.length; i < length; i++) {
-        var key = $inject[i];
-        if (typeof key !== 'string') {
-          throw $injectorMinErr('itkn',
-                  'Incorrect injection token! Expected service name as string, got {0}', key);
-        }
-        args.push(locals && locals.hasOwnProperty(key) ? locals[key] :
-                                                         getService(key, serviceName));
-      }
-      return args;
-    }
-
-    function isClass(func) {
-      // Support: IE 9-11 only
-      // IE 9-11 do not support classes and IE9 leaks with the code below.
-      if (msie || typeof func !== 'function') {
-        return false;
-      }
-      var result = func.$$ngIsClass;
-      if (!isBoolean(result)) {
-        // Support: Edge 12-13 only
-        // See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6156135/
-        result = func.$$ngIsClass = /^(?:class\b|constructor\()/.test(stringifyFn(func));
-      }
-      return result;
-    }
-
-    function invoke(fn, self, locals, serviceName) {
-      if (typeof locals === 'string') {
-        serviceName = locals;
-        locals = null;
-      }
-
-      var args = injectionArgs(fn, locals, serviceName);
-      if (isArray(fn)) {
-        fn = fn[fn.length - 1];
-      }
-
-      if (!isClass(fn)) {
-        // http://jsperf.com/angularjs-invoke-apply-vs-switch
-        // #5388
-        return fn.apply(self, args);
-      } else {
-        args.unshift(null);
-        return new (Function.prototype.bind.apply(fn, args))();
-      }
-    }
-
-
-    function instantiate(Type, locals, serviceName) {
-      // Check if Type is annotated and use just the given function at n-1 as parameter
-      // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
-      var ctor = (isArray(Type) ? Type[Type.length - 1] : Type);
-      var args = injectionArgs(Type, locals, serviceName);
-      // Empty object at position 0 is ignored for invocation with `new`, but required.
-      args.unshift(null);
-      return new (Function.prototype.bind.apply(ctor, args))();
-    }
-
-
-    return {
-      invoke: invoke,
-      instantiate: instantiate,
-      get: getService,
-      annotate: createInjector.$$annotate,
-      has: function(name) {
-        return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
-      }
-    };
-  }
-}
-
-createInjector.$$annotate = annotate;
-
-/**
- * @ngdoc provider
- * @name $anchorScrollProvider
- * @this
- *
- * @description
- * Use `$anchorScrollProvider` to disable automatic scrolling whenever
- * {@link ng.$location#hash $location.hash()} changes.
- */
-function $AnchorScrollProvider() {
-
-  var autoScrollingEnabled = true;
-
-  /**
-   * @ngdoc method
-   * @name $anchorScrollProvider#disableAutoScrolling
-   *
-   * @description
-   * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to
-   * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />
-   * Use this method to disable automatic scrolling.
-   *
-   * If automatic scrolling is disabled, one must explicitly call
-   * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the
-   * current hash.
-   */
-  this.disableAutoScrolling = function() {
-    autoScrollingEnabled = false;
-  };
-
-  /**
-   * @ngdoc service
-   * @name $anchorScroll
-   * @kind function
-   * @requires $window
-   * @requires $location
-   * @requires $rootScope
-   *
-   * @description
-   * When called, it scrolls to the element related to the specified `hash` or (if omitted) to the
-   * current value of {@link ng.$location#hash $location.hash()}, according to the rules specified
-   * in the
-   * [HTML5 spec](http://www.w3.org/html/wg/drafts/html/master/browsers.html#an-indicated-part-of-the-document).
-   *
-   * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to
-   * match any anchor whenever it changes. This can be disabled by calling
-   * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}.
-   *
-   * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a
-   * vertical scroll-offset (either fixed or dynamic).
-   *
-   * @param {string=} hash The hash specifying the element to scroll to. If omitted, the value of
-   *                       {@link ng.$location#hash $location.hash()} will be used.
-   *
-   * @property {(number|function|jqLite)} yOffset
-   * If set, specifies a vertical scroll-offset. This is often useful when there are fixed
-   * positioned elements at the top of the page, such as navbars, headers etc.
-   *
-   * `yOffset` can be specified in various ways:
-   * - **number**: A fixed number of pixels to be used as offset.<br /><br />
-   * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return
-   *   a number representing the offset (in pixels).<br /><br />
-   * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from
-   *   the top of the page to the element's bottom will be used as offset.<br />
-   *   **Note**: The element will be taken into account only as long as its `position` is set to
-   *   `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust
-   *   their height and/or positioning according to the viewport's size.
-   *
-   * <br />
-   * <div class="alert alert-warning">
-   * In order for `yOffset` to work properly, scrolling should take place on the document's root and
-   * not some child element.
-   * </div>
-   *
-   * @example
-     <example module="anchorScrollExample" name="anchor-scroll">
-       <file name="index.html">
-         <div id="scrollArea" ng-controller="ScrollController">
-           <a ng-click="gotoBottom()">Go to bottom</a>
-           <a id="bottom"></a> You're at the bottom!
-         </div>
-       </file>
-       <file name="script.js">
-         angular.module('anchorScrollExample', [])
-           .controller('ScrollController', ['$scope', '$location', '$anchorScroll',
-             function($scope, $location, $anchorScroll) {
-               $scope.gotoBottom = function() {
-                 // set the location.hash to the id of
-                 // the element you wish to scroll to.
-                 $location.hash('bottom');
-
-                 // call $anchorScroll()
-                 $anchorScroll();
-               };
-             }]);
-       </file>
-       <file name="style.css">
-         #scrollArea {
-           height: 280px;
-           overflow: auto;
-         }
-
-         #bottom {
-           display: block;
-           margin-top: 2000px;
-         }
-       </file>
-     </example>
-   *
-   * <hr />
-   * The example below illustrates the use of a vertical scroll-offset (specified as a fixed value).
-   * See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details.
-   *
-   * @example
-     <example module="anchorScrollOffsetExample" name="anchor-scroll-offset">
-       <file name="index.html">
-         <div class="fixed-header" ng-controller="headerCtrl">
-           <a href="" ng-click="gotoAnchor(x)" ng-repeat="x in [1,2,3,4,5]">
-             Go to anchor {{x}}
-           </a>
-         </div>
-         <div id="anchor{{x}}" class="anchor" ng-repeat="x in [1,2,3,4,5]">
-           Anchor {{x}} of 5
-         </div>
-       </file>
-       <file name="script.js">
-         angular.module('anchorScrollOffsetExample', [])
-           .run(['$anchorScroll', function($anchorScroll) {
-             $anchorScroll.yOffset = 50;   // always scroll by 50 extra pixels
-           }])
-           .controller('headerCtrl', ['$anchorScroll', '$location', '$scope',
-             function($anchorScroll, $location, $scope) {
-               $scope.gotoAnchor = function(x) {
-                 var newHash = 'anchor' + x;
-                 if ($location.hash() !== newHash) {
-                   // set the $location.hash to `newHash` and
-                   // $anchorScroll will automatically scroll to it
-                   $location.hash('anchor' + x);
-                 } else {
-                   // call $anchorScroll() explicitly,
-                   // since $location.hash hasn't changed
-                   $anchorScroll();
-                 }
-               };
-             }
-           ]);
-       </file>
-       <file name="style.css">
-         body {
-           padding-top: 50px;
-         }
-
-         .anchor {
-           border: 2px dashed DarkOrchid;
-           padding: 10px 10px 200px 10px;
-         }
-
-         .fixed-header {
-           background-color: rgba(0, 0, 0, 0.2);
-           height: 50px;
-           position: fixed;
-           top: 0; left: 0; right: 0;
-         }
-
-         .fixed-header > a {
-           display: inline-block;
-           margin: 5px 15px;
-         }
-       </file>
-     </example>
-   */
-  this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
-    var document = $window.document;
-
-    // Helper function to get first anchor from a NodeList
-    // (using `Array#some()` instead of `angular#forEach()` since it's more performant
-    //  and working in all supported browsers.)
-    function getFirstAnchor(list) {
-      var result = null;
-      Array.prototype.some.call(list, function(element) {
-        if (nodeName_(element) === 'a') {
-          result = element;
-          return true;
-        }
-      });
-      return result;
-    }
-
-    function getYOffset() {
-
-      var offset = scroll.yOffset;
-
-      if (isFunction(offset)) {
-        offset = offset();
-      } else if (isElement(offset)) {
-        var elem = offset[0];
-        var style = $window.getComputedStyle(elem);
-        if (style.position !== 'fixed') {
-          offset = 0;
-        } else {
-          offset = elem.getBoundingClientRect().bottom;
-        }
-      } else if (!isNumber(offset)) {
-        offset = 0;
-      }
-
-      return offset;
-    }
-
-    function scrollTo(elem) {
-      if (elem) {
-        elem.scrollIntoView();
-
-        var offset = getYOffset();
-
-        if (offset) {
-          // `offset` is the number of pixels we should scroll UP in order to align `elem` properly.
-          // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the
-          // top of the viewport.
-          //
-          // IF the number of pixels from the top of `elem` to the end of the page's content is less
-          // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some
-          // way down the page.
-          //
-          // This is often the case for elements near the bottom of the page.
-          //
-          // In such cases we do not need to scroll the whole `offset` up, just the difference between
-          // the top of the element and the offset, which is enough to align the top of `elem` at the
-          // desired position.
-          var elemTop = elem.getBoundingClientRect().top;
-          $window.scrollBy(0, elemTop - offset);
-        }
-      } else {
-        $window.scrollTo(0, 0);
-      }
-    }
-
-    function scroll(hash) {
-      // Allow numeric hashes
-      hash = isString(hash) ? hash : isNumber(hash) ? hash.toString() : $location.hash();
-      var elm;
-
-      // empty hash, scroll to the top of the page
-      if (!hash) scrollTo(null);
-
-      // element with given id
-      else if ((elm = document.getElementById(hash))) scrollTo(elm);
-
-      // first anchor with given name :-D
-      else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);
-
-      // no element and hash === 'top', scroll to the top of the page
-      else if (hash === 'top') scrollTo(null);
-    }
-
-    // does not scroll when user clicks on anchor link that is currently on
-    // (no url change, no $location.hash() change), browser native does scroll
-    if (autoScrollingEnabled) {
-      $rootScope.$watch(function autoScrollWatch() {return $location.hash();},
-        function autoScrollWatchAction(newVal, oldVal) {
-          // skip the initial scroll if $location.hash is empty
-          if (newVal === oldVal && newVal === '') return;
-
-          jqLiteDocumentLoaded(function() {
-            $rootScope.$evalAsync(scroll);
-          });
-        });
-    }
-
-    return scroll;
-  }];
-}
-
-var $animateMinErr = minErr('$animate');
-var ELEMENT_NODE = 1;
-var NG_ANIMATE_CLASSNAME = 'ng-animate';
-
-function mergeClasses(a,b) {
-  if (!a && !b) return '';
-  if (!a) return b;
-  if (!b) return a;
-  if (isArray(a)) a = a.join(' ');
-  if (isArray(b)) b = b.join(' ');
-  return a + ' ' + b;
-}
-
-function extractElementNode(element) {
-  for (var i = 0; i < element.length; i++) {
-    var elm = element[i];
-    if (elm.nodeType === ELEMENT_NODE) {
-      return elm;
-    }
-  }
-}
-
-function splitClasses(classes) {
-  if (isString(classes)) {
-    classes = classes.split(' ');
-  }
-
-  // Use createMap() to prevent class assumptions involving property names in
-  // Object.prototype
-  var obj = createMap();
-  forEach(classes, function(klass) {
-    // sometimes the split leaves empty string values
-    // incase extra spaces were applied to the options
-    if (klass.length) {
-      obj[klass] = true;
-    }
-  });
-  return obj;
-}
-
-// if any other type of options value besides an Object value is
-// passed into the $animate.method() animation then this helper code
-// will be run which will ignore it. While this patch is not the
-// greatest solution to this, a lot of existing plugins depend on
-// $animate to either call the callback (< 1.2) or return a promise
-// that can be changed. This helper function ensures that the options
-// are wiped clean incase a callback function is provided.
-function prepareAnimateOptions(options) {
-  return isObject(options)
-      ? options
-      : {};
-}
-
-var $$CoreAnimateJsProvider = /** @this */ function() {
-  this.$get = noop;
-};
-
-// this is prefixed with Core since it conflicts with
-// the animateQueueProvider defined in ngAnimate/animateQueue.js
-var $$CoreAnimateQueueProvider = /** @this */ function() {
-  var postDigestQueue = new NgMap();
-  var postDigestElements = [];
-
-  this.$get = ['$$AnimateRunner', '$rootScope',
-       function($$AnimateRunner,   $rootScope) {
-    return {
-      enabled: noop,
-      on: noop,
-      off: noop,
-      pin: noop,
-
-      push: function(element, event, options, domOperation) {
-        if (domOperation) {
-          domOperation();
-        }
-
-        options = options || {};
-        if (options.from) {
-          element.css(options.from);
-        }
-        if (options.to) {
-          element.css(options.to);
-        }
-
-        if (options.addClass || options.removeClass) {
-          addRemoveClassesPostDigest(element, options.addClass, options.removeClass);
-        }
-
-        var runner = new $$AnimateRunner();
-
-        // since there are no animations to run the runner needs to be
-        // notified that the animation call is complete.
-        runner.complete();
-        return runner;
-      }
-    };
-
-
-    function updateData(data, classes, value) {
-      var changed = false;
-      if (classes) {
-        classes = isString(classes) ? classes.split(' ') :
-                  isArray(classes) ? classes : [];
-        forEach(classes, function(className) {
-          if (className) {
-            changed = true;
-            data[className] = value;
-          }
-        });
-      }
-      return changed;
-    }
-
-    function handleCSSClassChanges() {
-      forEach(postDigestElements, function(element) {
-        var data = postDigestQueue.get(element);
-        if (data) {
-          var existing = splitClasses(element.attr('class'));
-          var toAdd = '';
-          var toRemove = '';
-          forEach(data, function(status, className) {
-            var hasClass = !!existing[className];
-            if (status !== hasClass) {
-              if (status) {
-                toAdd += (toAdd.length ? ' ' : '') + className;
-              } else {
-                toRemove += (toRemove.length ? ' ' : '') + className;
-              }
-            }
-          });
-
-          forEach(element, function(elm) {
-            if (toAdd) {
-              jqLiteAddClass(elm, toAdd);
-            }
-            if (toRemove) {
-              jqLiteRemoveClass(elm, toRemove);
-            }
-          });
-          postDigestQueue.delete(element);
-        }
-      });
-      postDigestElements.length = 0;
-    }
-
-
-    function addRemoveClassesPostDigest(element, add, remove) {
-      var data = postDigestQueue.get(element) || {};
-
-      var classesAdded = updateData(data, add, true);
-      var classesRemoved = updateData(data, remove, false);
-
-      if (classesAdded || classesRemoved) {
-
-        postDigestQueue.set(element, data);
-        postDigestElements.push(element);
-
-        if (postDigestElements.length === 1) {
-          $rootScope.$$postDigest(handleCSSClassChanges);
-        }
-      }
-    }
-  }];
-};
-
-/**
- * @ngdoc provider
- * @name $animateProvider
- *
- * @description
- * Default implementation of $animate that doesn't perform any animations, instead just
- * synchronously performs DOM updates and resolves the returned runner promise.
- *
- * In order to enable animations the `ngAnimate` module has to be loaded.
- *
- * To see the functional implementation check out `src/ngAnimate/animate.js`.
- */
-var $AnimateProvider = ['$provide', /** @this */ function($provide) {
-  var provider = this;
-  var classNameFilter = null;
-
-  this.$$registeredAnimations = Object.create(null);
-
-   /**
-   * @ngdoc method
-   * @name $animateProvider#register
-   *
-   * @description
-   * Registers a new injectable animation factory function. The factory function produces the
-   * animation object which contains callback functions for each event that is expected to be
-   * animated.
-   *
-   *   * `eventFn`: `function(element, ... , doneFunction, options)`
-   *   The element to animate, the `doneFunction` and the options fed into the animation. Depending
-   *   on the type of animation additional arguments will be injected into the animation function. The
-   *   list below explains the function signatures for the different animation methods:
-   *
-   *   - setClass: function(element, addedClasses, removedClasses, doneFunction, options)
-   *   - addClass: function(element, addedClasses, doneFunction, options)
-   *   - removeClass: function(element, removedClasses, doneFunction, options)
-   *   - enter, leave, move: function(element, doneFunction, options)
-   *   - animate: function(element, fromStyles, toStyles, doneFunction, options)
-   *
-   *   Make sure to trigger the `doneFunction` once the animation is fully complete.
-   *
-   * ```js
-   *   return {
-   *     //enter, leave, move signature
-   *     eventFn : function(element, done, options) {
-   *       //code to run the animation
-   *       //once complete, then run done()
-   *       return function endFunction(wasCancelled) {
-   *         //code to cancel the animation
-   *       }
-   *     }
-   *   }
-   * ```
-   *
-   * @param {string} name The name of the animation (this is what the class-based CSS value will be compared to).
-   * @param {Function} factory The factory function that will be executed to return the animation
-   *                           object.
-   */
-  this.register = function(name, factory) {
-    if (name && name.charAt(0) !== '.') {
-      throw $animateMinErr('notcsel', 'Expecting class selector starting with \'.\' got \'{0}\'.', name);
-    }
-
-    var key = name + '-animation';
-    provider.$$registeredAnimations[name.substr(1)] = key;
-    $provide.factory(key, factory);
-  };
-
-  /**
-   * @ngdoc method
-   * @name $animateProvider#classNameFilter
-   *
-   * @description
-   * Sets and/or returns the CSS class regular expression that is checked when performing
-   * an animation. Upon bootstrap the classNameFilter value is not set at all and will
-   * therefore enable $animate to attempt to perform an animation on any element that is triggered.
-   * When setting the `classNameFilter` value, animations will only be performed on elements
-   * that successfully match the filter expression. This in turn can boost performance
-   * for low-powered devices as well as applications containing a lot of structural operations.
-   * @param {RegExp=} expression The className expression which will be checked against all animations
-   * @return {RegExp} The current CSS className expression value. If null then there is no expression value
-   */
-  this.classNameFilter = function(expression) {
-    if (arguments.length === 1) {
-      classNameFilter = (expression instanceof RegExp) ? expression : null;
-      if (classNameFilter) {
-        var reservedRegex = new RegExp('[(\\s|\\/)]' + NG_ANIMATE_CLASSNAME + '[(\\s|\\/)]');
-        if (reservedRegex.test(classNameFilter.toString())) {
-          classNameFilter = null;
-          throw $animateMinErr('nongcls', '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);
-        }
-      }
-    }
-    return classNameFilter;
-  };
-
-  this.$get = ['$$animateQueue', function($$animateQueue) {
-    function domInsert(element, parentElement, afterElement) {
-      // if for some reason the previous element was removed
-      // from the dom sometime before this code runs then let's
-      // just stick to using the parent element as the anchor
-      if (afterElement) {
-        var afterNode = extractElementNode(afterElement);
-        if (afterNode && !afterNode.parentNode && !afterNode.previousElementSibling) {
-          afterElement = null;
-        }
-      }
-      if (afterElement) {
-        afterElement.after(element);
-      } else {
-        parentElement.prepend(element);
-      }
-    }
-
-    /**
-     * @ngdoc service
-     * @name $animate
-     * @description The $animate service exposes a series of DOM utility methods that provide support
-     * for animation hooks. The default behavior is the application of DOM operations, however,
-     * when an animation is detected (and animations are enabled), $animate will do the heavy lifting
-     * to ensure that animation runs with the triggered DOM operation.
-     *
-     * By default $animate doesn't trigger any animations. This is because the `ngAnimate` module isn't
-     * included and only when it is active then the animation hooks that `$animate` triggers will be
-     * functional. Once active then all structural `ng-` directives will trigger animations as they perform
-     * their DOM-related operations (enter, leave and move). Other directives such as `ngClass`,
-     * `ngShow`, `ngHide` and `ngMessages` also provide support for animations.
-     *
-     * It is recommended that the`$animate` service is always used when executing DOM-related procedures within directives.
-     *
-     * To learn more about enabling animation support, click here to visit the
-     * {@link ngAnimate ngAnimate module page}.
-     */
-    return {
-      // we don't call it directly since non-existant arguments may
-      // be interpreted as null within the sub enabled function
-
-      /**
-       *
-       * @ngdoc method
-       * @name $animate#on
-       * @kind function
-       * @description Sets up an event listener to fire whenever the animation event (enter, leave, move, etc...)
-       *    has fired on the given element or among any of its children. Once the listener is fired, the provided callback
-       *    is fired with the following params:
-       *
-       * ```js
-       * $animate.on('enter', container,
-       *    function callback(element, phase) {
-       *      // cool we detected an enter animation within the container
-       *    }
-       * );
-       * ```
-       *
-       * @param {string} event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...)
-       * @param {DOMElement} container the container element that will capture each of the animation events that are fired on itself
-       *     as well as among its children
-       * @param {Function} callback the callback function that will be fired when the listener is triggered
-       *
-       * The arguments present in the callback function are:
-       * * `element` - The captured DOM element that the animation was fired on.
-       * * `phase` - The phase of the animation. The two possible phases are **start** (when the animation starts) and **close** (when it ends).
-       */
-      on: $$animateQueue.on,
-
-      /**
-       *
-       * @ngdoc method
-       * @name $animate#off
-       * @kind function
-       * @description Deregisters an event listener based on the event which has been associated with the provided element. This method
-       * can be used in three different ways depending on the arguments:
-       *
-       * ```js
-       * // remove all the animation event listeners listening for `enter`
-       * $animate.off('enter');
-       *
-       * // remove listeners for all animation events from the container element
-       * $animate.off(container);
-       *
-       * // remove all the animation event listeners listening for `enter` on the given element and its children
-       * $animate.off('enter', container);
-       *
-       * // remove the event listener function provided by `callback` that is set
-       * // to listen for `enter` on the given `container` as well as its children
-       * $animate.off('enter', container, callback);
-       * ```
-       *
-       * @param {string|DOMElement} event|container the animation event (e.g. enter, leave, move,
-       * addClass, removeClass, etc...), or the container element. If it is the element, all other
-       * arguments are ignored.
-       * @param {DOMElement=} container the container element the event listener was placed on
-       * @param {Function=} callback the callback function that was registered as the listener
-       */
-      off: $$animateQueue.off,
-
-      /**
-       * @ngdoc method
-       * @name $animate#pin
-       * @kind function
-       * @description Associates the provided element with a host parent element to allow the element to be animated even if it exists
-       *    outside of the DOM structure of the Angular application. By doing so, any animation triggered via `$animate` can be issued on the
-       *    element despite being outside the realm of the application or within another application. Say for example if the application
-       *    was bootstrapped on an element that is somewhere inside of the `<body>` tag, but we wanted to allow for an element to be situated
-       *    as a direct child of `document.body`, then this can be achieved by pinning the element via `$animate.pin(element)`. Keep in mind
-       *    that calling `$animate.pin(element, parentElement)` will not actually insert into the DOM anywhere; it will just create the association.
-       *
-       *    Note that this feature is only active when the `ngAnimate` module is used.
-       *
-       * @param {DOMElement} element the external element that will be pinned
-       * @param {DOMElement} parentElement the host parent element that will be associated with the external element
-       */
-      pin: $$animateQueue.pin,
-
-      /**
-       *
-       * @ngdoc method
-       * @name $animate#enabled
-       * @kind function
-       * @description Used to get and set whether animations are enabled or not on the entire application or on an element and its children. This
-       * function can be called in four ways:
-       *
-       * ```js
-       * // returns true or false
-       * $animate.enabled();
-       *
-       * // changes the enabled state for all animations
-       * $animate.enabled(false);
-       * $animate.enabled(true);
-       *
-       * // returns true or false if animations are enabled for an element
-       * $animate.enabled(element);
-       *
-       * // changes the enabled state for an element and its children
-       * $animate.enabled(element, true);
-       * $animate.enabled(element, false);
-       * ```
-       *
-       * @param {DOMElement=} element the element that will be considered for checking/setting the enabled state
-       * @param {boolean=} enabled whether or not the animations will be enabled for the element
-       *
-       * @return {boolean} whether or not animations are enabled
-       */
-      enabled: $$animateQueue.enabled,
-
-      /**
-       * @ngdoc method
-       * @name $animate#cancel
-       * @kind function
-       * @description Cancels the provided animation.
-       *
-       * @param {Promise} animationPromise The animation promise that is returned when an animation is started.
-       */
-      cancel: function(runner) {
-        if (runner.end) {
-          runner.end();
-        }
-      },
-
-      /**
-       *
-       * @ngdoc method
-       * @name $animate#enter
-       * @kind function
-       * @description Inserts the element into the DOM either after the `after` element (if provided) or
-       *   as the first child within the `parent` element and then triggers an animation.
-       *   A promise is returned that will be resolved during the next digest once the animation
-       *   has completed.
-       *
-       * @param {DOMElement} element the element which will be inserted into the DOM
-       * @param {DOMElement} parent the parent element which will append the element as
-       *   a child (so long as the after element is not present)
-       * @param {DOMElement=} after the sibling element after which the element will be appended
-       * @param {object=} options an optional collection of options/styles that will be applied to the element.
-       *   The object can have the following properties:
-       *
-       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
-       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
-       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
-       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
-       *
-       * @return {Promise} the animation callback promise
-       */
-      enter: function(element, parent, after, options) {
-        parent = parent && jqLite(parent);
-        after = after && jqLite(after);
-        parent = parent || after.parent();
-        domInsert(element, parent, after);
-        return $$animateQueue.push(element, 'enter', prepareAnimateOptions(options));
-      },
-
-      /**
-       *
-       * @ngdoc method
-       * @name $animate#move
-       * @kind function
-       * @description Inserts (moves) the element into its new position in the DOM either after
-       *   the `after` element (if provided) or as the first child within the `parent` element
-       *   and then triggers an animation. A promise is returned that will be resolved
-       *   during the next digest once the animation has completed.
-       *
-       * @param {DOMElement} element the element which will be moved into the new DOM position
-       * @param {DOMElement} parent the parent element which will append the element as
-       *   a child (so long as the after element is not present)
-       * @param {DOMElement=} after the sibling element after which the element will be appended
-       * @param {object=} options an optional collection of options/styles that will be applied to the element.
-       *   The object can have the following properties:
-       *
-       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
-       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
-       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
-       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
-       *
-       * @return {Promise} the animation callback promise
-       */
-      move: function(element, parent, after, options) {
-        parent = parent && jqLite(parent);
-        after = after && jqLite(after);
-        parent = parent || after.parent();
-        domInsert(element, parent, after);
-        return $$animateQueue.push(element, 'move', prepareAnimateOptions(options));
-      },
-
-      /**
-       * @ngdoc method
-       * @name $animate#leave
-       * @kind function
-       * @description Triggers an animation and then removes the element from the DOM.
-       * When the function is called a promise is returned that will be resolved during the next
-       * digest once the animation has completed.
-       *
-       * @param {DOMElement} element the element which will be removed from the DOM
-       * @param {object=} options an optional collection of options/styles that will be applied to the element.
-       *   The object can have the following properties:
-       *
-       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
-       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
-       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
-       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
-       *
-       * @return {Promise} the animation callback promise
-       */
-      leave: function(element, options) {
-        return $$animateQueue.push(element, 'leave', prepareAnimateOptions(options), function() {
-          element.remove();
-        });
-      },
-
-      /**
-       * @ngdoc method
-       * @name $animate#addClass
-       * @kind function
-       *
-       * @description Triggers an addClass animation surrounding the addition of the provided CSS class(es). Upon
-       *   execution, the addClass operation will only be handled after the next digest and it will not trigger an
-       *   animation if element already contains the CSS class or if the class is removed at a later step.
-       *   Note that class-based animations are treated differently compared to structural animations
-       *   (like enter, move and leave) since the CSS classes may be added/removed at different points
-       *   depending if CSS or JavaScript animations are used.
-       *
-       * @param {DOMElement} element the element which the CSS classes will be applied to
-       * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces)
-       * @param {object=} options an optional collection of options/styles that will be applied to the element.
-       *   The object can have the following properties:
-       *
-       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
-       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
-       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
-       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
-       *
-       * @return {Promise} the animation callback promise
-       */
-      addClass: function(element, className, options) {
-        options = prepareAnimateOptions(options);
-        options.addClass = mergeClasses(options.addclass, className);
-        return $$animateQueue.push(element, 'addClass', options);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $animate#removeClass
-       * @kind function
-       *
-       * @description Triggers a removeClass animation surrounding the removal of the provided CSS class(es). Upon
-       *   execution, the removeClass operation will only be handled after the next digest and it will not trigger an
-       *   animation if element does not contain the CSS class or if the class is added at a later step.
-       *   Note that class-based animations are treated differently compared to structural animations
-       *   (like enter, move and leave) since the CSS classes may be added/removed at different points
-       *   depending if CSS or JavaScript animations are used.
-       *
-       * @param {DOMElement} element the element which the CSS classes will be applied to
-       * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces)
-       * @param {object=} options an optional collection of options/styles that will be applied to the element.
-       *   The object can have the following properties:
-       *
-       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
-       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
-       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
-       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
-       *
-       * @return {Promise} the animation callback promise
-       */
-      removeClass: function(element, className, options) {
-        options = prepareAnimateOptions(options);
-        options.removeClass = mergeClasses(options.removeClass, className);
-        return $$animateQueue.push(element, 'removeClass', options);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $animate#setClass
-       * @kind function
-       *
-       * @description Performs both the addition and removal of a CSS classes on an element and (during the process)
-       *    triggers an animation surrounding the class addition/removal. Much like `$animate.addClass` and
-       *    `$animate.removeClass`, `setClass` will only evaluate the classes being added/removed once a digest has
-       *    passed. Note that class-based animations are treated differently compared to structural animations
-       *    (like enter, move and leave) since the CSS classes may be added/removed at different points
-       *    depending if CSS or JavaScript animations are used.
-       *
-       * @param {DOMElement} element the element which the CSS classes will be applied to
-       * @param {string} add the CSS class(es) that will be added (multiple classes are separated via spaces)
-       * @param {string} remove the CSS class(es) that will be removed (multiple classes are separated via spaces)
-       * @param {object=} options an optional collection of options/styles that will be applied to the element.
-       *   The object can have the following properties:
-       *
-       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
-       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
-       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
-       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
-       *
-       * @return {Promise} the animation callback promise
-       */
-      setClass: function(element, add, remove, options) {
-        options = prepareAnimateOptions(options);
-        options.addClass = mergeClasses(options.addClass, add);
-        options.removeClass = mergeClasses(options.removeClass, remove);
-        return $$animateQueue.push(element, 'setClass', options);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $animate#animate
-       * @kind function
-       *
-       * @description Performs an inline animation on the element which applies the provided to and from CSS styles to the element.
-       * If any detected CSS transition, keyframe or JavaScript matches the provided className value, then the animation will take
-       * on the provided styles. For example, if a transition animation is set for the given className, then the provided `from` and
-       * `to` styles will be applied alongside the given transition. If the CSS style provided in `from` does not have a corresponding
-       * style in `to`, the style in `from` is applied immediately, and no animation is run.
-       * If a JavaScript animation is detected then the provided styles will be given in as function parameters into the `animate`
-       * method (or as part of the `options` parameter):
-       *
-       * ```js
-       * ngModule.animation('.my-inline-animation', function() {
-       *   return {
-       *     animate : function(element, from, to, done, options) {
-       *       //animation
-       *       done();
-       *     }
-       *   }
-       * });
-       * ```
-       *
-       * @param {DOMElement} element the element which the CSS styles will be applied to
-       * @param {object} from the from (starting) CSS styles that will be applied to the element and across the animation.
-       * @param {object} to the to (destination) CSS styles that will be applied to the element and across the animation.
-       * @param {string=} className an optional CSS class that will be applied to the element for the duration of the animation. If
-       *    this value is left as empty then a CSS class of `ng-inline-animate` will be applied to the element.
-       *    (Note that if no animation is detected then this value will not be applied to the element.)
-       * @param {object=} options an optional collection of options/styles that will be applied to the element.
-       *   The object can have the following properties:
-       *
-       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
-       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
-       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
-       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
-       *
-       * @return {Promise} the animation callback promise
-       */
-      animate: function(element, from, to, className, options) {
-        options = prepareAnimateOptions(options);
-        options.from = options.from ? extend(options.from, from) : from;
-        options.to   = options.to   ? extend(options.to, to)     : to;
-
-        className = className || 'ng-inline-animate';
-        options.tempClasses = mergeClasses(options.tempClasses, className);
-        return $$animateQueue.push(element, 'animate', options);
-      }
-    };
-  }];
-}];
-
-var $$AnimateAsyncRunFactoryProvider = /** @this */ function() {
-  this.$get = ['$$rAF', function($$rAF) {
-    var waitQueue = [];
-
-    function waitForTick(fn) {
-      waitQueue.push(fn);
-      if (waitQueue.length > 1) return;
-      $$rAF(function() {
-        for (var i = 0; i < waitQueue.length; i++) {
-          waitQueue[i]();
-        }
-        waitQueue = [];
-      });
-    }
-
-    return function() {
-      var passed = false;
-      waitForTick(function() {
-        passed = true;
-      });
-      return function(callback) {
-        if (passed) {
-          callback();
-        } else {
-          waitForTick(callback);
-        }
-      };
-    };
-  }];
-};
-
-var $$AnimateRunnerFactoryProvider = /** @this */ function() {
-  this.$get = ['$q', '$sniffer', '$$animateAsyncRun', '$$isDocumentHidden', '$timeout',
-       function($q,   $sniffer,   $$animateAsyncRun,   $$isDocumentHidden,   $timeout) {
-
-    var INITIAL_STATE = 0;
-    var DONE_PENDING_STATE = 1;
-    var DONE_COMPLETE_STATE = 2;
-
-    AnimateRunner.chain = function(chain, callback) {
-      var index = 0;
-
-      next();
-      function next() {
-        if (index === chain.length) {
-          callback(true);
-          return;
-        }
-
-        chain[index](function(response) {
-          if (response === false) {
-            callback(false);
-            return;
-          }
-          index++;
-          next();
-        });
-      }
-    };
-
-    AnimateRunner.all = function(runners, callback) {
-      var count = 0;
-      var status = true;
-      forEach(runners, function(runner) {
-        runner.done(onProgress);
-      });
-
-      function onProgress(response) {
-        status = status && response;
-        if (++count === runners.length) {
-          callback(status);
-        }
-      }
-    };
-
-    function AnimateRunner(host) {
-      this.setHost(host);
-
-      var rafTick = $$animateAsyncRun();
-      var timeoutTick = function(fn) {
-        $timeout(fn, 0, false);
-      };
-
-      this._doneCallbacks = [];
-      this._tick = function(fn) {
-        if ($$isDocumentHidden()) {
-          timeoutTick(fn);
-        } else {
-          rafTick(fn);
-        }
-      };
-      this._state = 0;
-    }
-
-    AnimateRunner.prototype = {
-      setHost: function(host) {
-        this.host = host || {};
-      },
-
-      done: function(fn) {
-        if (this._state === DONE_COMPLETE_STATE) {
-          fn();
-        } else {
-          this._doneCallbacks.push(fn);
-        }
-      },
-
-      progress: noop,
-
-      getPromise: function() {
-        if (!this.promise) {
-          var self = this;
-          this.promise = $q(function(resolve, reject) {
-            self.done(function(status) {
-              if (status === false) {
-                reject();
-              } else {
-                resolve();
-              }
-            });
-          });
-        }
-        return this.promise;
-      },
-
-      then: function(resolveHandler, rejectHandler) {
-        return this.getPromise().then(resolveHandler, rejectHandler);
-      },
-
-      'catch': function(handler) {
-        return this.getPromise()['catch'](handler);
-      },
-
-      'finally': function(handler) {
-        return this.getPromise()['finally'](handler);
-      },
-
-      pause: function() {
-        if (this.host.pause) {
-          this.host.pause();
-        }
-      },
-
-      resume: function() {
-        if (this.host.resume) {
-          this.host.resume();
-        }
-      },
-
-      end: function() {
-        if (this.host.end) {
-          this.host.end();
-        }
-        this._resolve(true);
-      },
-
-      cancel: function() {
-        if (this.host.cancel) {
-          this.host.cancel();
-        }
-        this._resolve(false);
-      },
-
-      complete: function(response) {
-        var self = this;
-        if (self._state === INITIAL_STATE) {
-          self._state = DONE_PENDING_STATE;
-          self._tick(function() {
-            self._resolve(response);
-          });
-        }
-      },
-
-      _resolve: function(response) {
-        if (this._state !== DONE_COMPLETE_STATE) {
-          forEach(this._doneCallbacks, function(fn) {
-            fn(response);
-          });
-          this._doneCallbacks.length = 0;
-          this._state = DONE_COMPLETE_STATE;
-        }
-      }
-    };
-
-    return AnimateRunner;
-  }];
-};
-
-/* exported $CoreAnimateCssProvider */
-
-/**
- * @ngdoc service
- * @name $animateCss
- * @kind object
- * @this
- *
- * @description
- * This is the core version of `$animateCss`. By default, only when the `ngAnimate` is included,
- * then the `$animateCss` service will actually perform animations.
- *
- * Click here {@link ngAnimate.$animateCss to read the documentation for $animateCss}.
- */
-var $CoreAnimateCssProvider = function() {
-  this.$get = ['$$rAF', '$q', '$$AnimateRunner', function($$rAF, $q, $$AnimateRunner) {
-
-    return function(element, initialOptions) {
-      // all of the animation functions should create
-      // a copy of the options data, however, if a
-      // parent service has already created a copy then
-      // we should stick to using that
-      var options = initialOptions || {};
-      if (!options.$$prepared) {
-        options = copy(options);
-      }
-
-      // there is no point in applying the styles since
-      // there is no animation that goes on at all in
-      // this version of $animateCss.
-      if (options.cleanupStyles) {
-        options.from = options.to = null;
-      }
-
-      if (options.from) {
-        element.css(options.from);
-        options.from = null;
-      }
-
-      var closed, runner = new $$AnimateRunner();
-      return {
-        start: run,
-        end: run
-      };
-
-      function run() {
-        $$rAF(function() {
-          applyAnimationContents();
-          if (!closed) {
-            runner.complete();
-          }
-          closed = true;
-        });
-        return runner;
-      }
-
-      function applyAnimationContents() {
-        if (options.addClass) {
-          element.addClass(options.addClass);
-          options.addClass = null;
-        }
-        if (options.removeClass) {
-          element.removeClass(options.removeClass);
-          options.removeClass = null;
-        }
-        if (options.to) {
-          element.css(options.to);
-          options.to = null;
-        }
-      }
-    };
-  }];
-};
-
-/* global stripHash: true */
-
-/**
- * ! This is a private undocumented service !
- *
- * @name $browser
- * @requires $log
- * @description
- * This object has two goals:
- *
- * - hide all the global state in the browser caused by the window object
- * - abstract away all the browser specific features and inconsistencies
- *
- * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser`
- * service, which can be used for convenient testing of the application without the interaction with
- * the real browser apis.
- */
-/**
- * @param {object} window The global window object.
- * @param {object} document jQuery wrapped document.
- * @param {object} $log window.console or an object with the same interface.
- * @param {object} $sniffer $sniffer service
- */
-function Browser(window, document, $log, $sniffer) {
-  var self = this,
-      location = window.location,
-      history = window.history,
-      setTimeout = window.setTimeout,
-      clearTimeout = window.clearTimeout,
-      pendingDeferIds = {};
-
-  self.isMock = false;
-
-  var outstandingRequestCount = 0;
-  var outstandingRequestCallbacks = [];
-
-  // TODO(vojta): remove this temporary api
-  self.$$completeOutstandingRequest = completeOutstandingRequest;
-  self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; };
-
-  /**
-   * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks`
-   * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed.
-   */
-  function completeOutstandingRequest(fn) {
-    try {
-      fn.apply(null, sliceArgs(arguments, 1));
-    } finally {
-      outstandingRequestCount--;
-      if (outstandingRequestCount === 0) {
-        while (outstandingRequestCallbacks.length) {
-          try {
-            outstandingRequestCallbacks.pop()();
-          } catch (e) {
-            $log.error(e);
-          }
-        }
-      }
-    }
-  }
-
-  function getHash(url) {
-    var index = url.indexOf('#');
-    return index === -1 ? '' : url.substr(index);
-  }
-
-  /**
-   * @private
-   * Note: this method is used only by scenario runner
-   * TODO(vojta): prefix this method with $$ ?
-   * @param {function()} callback Function that will be called when no outstanding request
-   */
-  self.notifyWhenNoOutstandingRequests = function(callback) {
-    if (outstandingRequestCount === 0) {
-      callback();
-    } else {
-      outstandingRequestCallbacks.push(callback);
-    }
-  };
-
-  //////////////////////////////////////////////////////////////
-  // URL API
-  //////////////////////////////////////////////////////////////
-
-  var cachedState, lastHistoryState,
-      lastBrowserUrl = location.href,
-      baseElement = document.find('base'),
-      pendingLocation = null,
-      getCurrentState = !$sniffer.history ? noop : function getCurrentState() {
-        try {
-          return history.state;
-        } catch (e) {
-          // MSIE can reportedly throw when there is no state (UNCONFIRMED).
-        }
-      };
-
-  cacheState();
-
-  /**
-   * @name $browser#url
-   *
-   * @description
-   * GETTER:
-   * Without any argument, this method just returns current value of location.href.
-   *
-   * SETTER:
-   * With at least one argument, this method sets url to new value.
-   * If html5 history api supported, pushState/replaceState is used, otherwise
-   * location.href/location.replace is used.
-   * Returns its own instance to allow chaining
-   *
-   * NOTE: this api is intended for use only by the $location service. Please use the
-   * {@link ng.$location $location service} to change url.
-   *
-   * @param {string} url New url (when used as setter)
-   * @param {boolean=} replace Should new url replace current history record?
-   * @param {object=} state object to use with pushState/replaceState
-   */
-  self.url = function(url, replace, state) {
-    // In modern browsers `history.state` is `null` by default; treating it separately
-    // from `undefined` would cause `$browser.url('/foo')` to change `history.state`
-    // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.
-    if (isUndefined(state)) {
-      state = null;
-    }
-
-    // Android Browser BFCache causes location, history reference to become stale.
-    if (location !== window.location) location = window.location;
-    if (history !== window.history) history = window.history;
-
-    // setter
-    if (url) {
-      var sameState = lastHistoryState === state;
-
-      // Don't change anything if previous and current URLs and states match. This also prevents
-      // IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.
-      // See https://github.com/angular/angular.js/commit/ffb2701
-      if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {
-        return self;
-      }
-      var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
-      lastBrowserUrl = url;
-      lastHistoryState = state;
-      // Don't use history API if only the hash changed
-      // due to a bug in IE10/IE11 which leads
-      // to not firing a `hashchange` nor `popstate` event
-      // in some cases (see #9143).
-      if ($sniffer.history && (!sameBase || !sameState)) {
-        history[replace ? 'replaceState' : 'pushState'](state, '', url);
-        cacheState();
-      } else {
-        if (!sameBase) {
-          pendingLocation = url;
-        }
-        if (replace) {
-          location.replace(url);
-        } else if (!sameBase) {
-          location.href = url;
-        } else {
-          location.hash = getHash(url);
-        }
-        if (location.href !== url) {
-          pendingLocation = url;
-        }
-      }
-      if (pendingLocation) {
-        pendingLocation = url;
-      }
-      return self;
-    // getter
-    } else {
-      // - pendingLocation is needed as browsers don't allow to read out
-      //   the new location.href if a reload happened or if there is a bug like in iOS 9 (see
-      //   https://openradar.appspot.com/22186109).
-      // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
-      return pendingLocation || location.href.replace(/%27/g,'\'');
-    }
-  };
-
-  /**
-   * @name $browser#state
-   *
-   * @description
-   * This method is a getter.
-   *
-   * Return history.state or null if history.state is undefined.
-   *
-   * @returns {object} state
-   */
-  self.state = function() {
-    return cachedState;
-  };
-
-  var urlChangeListeners = [],
-      urlChangeInit = false;
-
-  function cacheStateAndFireUrlChange() {
-    pendingLocation = null;
-    fireStateOrUrlChange();
-  }
-
-  // This variable should be used *only* inside the cacheState function.
-  var lastCachedState = null;
-  function cacheState() {
-    // This should be the only place in $browser where `history.state` is read.
-    cachedState = getCurrentState();
-    cachedState = isUndefined(cachedState) ? null : cachedState;
-
-    // Prevent callbacks fo fire twice if both hashchange & popstate were fired.
-    if (equals(cachedState, lastCachedState)) {
-      cachedState = lastCachedState;
-    }
-
-    lastCachedState = cachedState;
-    lastHistoryState = cachedState;
-  }
-
-  function fireStateOrUrlChange() {
-    var prevLastHistoryState = lastHistoryState;
-    cacheState();
-
-    if (lastBrowserUrl === self.url() && prevLastHistoryState === cachedState) {
-      return;
-    }
-
-    lastBrowserUrl = self.url();
-    lastHistoryState = cachedState;
-    forEach(urlChangeListeners, function(listener) {
-      listener(self.url(), cachedState);
-    });
-  }
-
-  /**
-   * @name $browser#onUrlChange
-   *
-   * @description
-   * Register callback function that will be called, when url changes.
-   *
-   * It's only called when the url is changed from outside of angular:
-   * - user types different url into address bar
-   * - user clicks on history (forward/back) button
-   * - user clicks on a link
-   *
-   * It's not called when url is changed by $browser.url() method
-   *
-   * The listener gets called with new url as parameter.
-   *
-   * NOTE: this api is intended for use only by the $location service. Please use the
-   * {@link ng.$location $location service} to monitor url changes in angular apps.
-   *
-   * @param {function(string)} listener Listener function to be called when url changes.
-   * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous.
-   */
-  self.onUrlChange = function(callback) {
-    // TODO(vojta): refactor to use node's syntax for events
-    if (!urlChangeInit) {
-      // We listen on both (hashchange/popstate) when available, as some browsers don't
-      // fire popstate when user changes the address bar and don't fire hashchange when url
-      // changed by push/replaceState
-
-      // html5 history api - popstate event
-      if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);
-      // hashchange event
-      jqLite(window).on('hashchange', cacheStateAndFireUrlChange);
-
-      urlChangeInit = true;
-    }
-
-    urlChangeListeners.push(callback);
-    return callback;
-  };
-
-  /**
-   * @private
-   * Remove popstate and hashchange handler from window.
-   *
-   * NOTE: this api is intended for use only by $rootScope.
-   */
-  self.$$applicationDestroyed = function() {
-    jqLite(window).off('hashchange popstate', cacheStateAndFireUrlChange);
-  };
-
-  /**
-   * Checks whether the url has changed outside of Angular.
-   * Needs to be exported to be able to check for changes that have been done in sync,
-   * as hashchange/popstate events fire in async.
-   */
-  self.$$checkUrlChange = fireStateOrUrlChange;
-
-  //////////////////////////////////////////////////////////////
-  // Misc API
-  //////////////////////////////////////////////////////////////
-
-  /**
-   * @name $browser#baseHref
-   *
-   * @description
-   * Returns current <base href>
-   * (always relative - without domain)
-   *
-   * @returns {string} The current base href
-   */
-  self.baseHref = function() {
-    var href = baseElement.attr('href');
-    return href ? href.replace(/^(https?:)?\/\/[^/]*/, '') : '';
-  };
-
-  /**
-   * @name $browser#defer
-   * @param {function()} fn A function, who's execution should be deferred.
-   * @param {number=} [delay=0] of milliseconds to defer the function execution.
-   * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`.
-   *
-   * @description
-   * Executes a fn asynchronously via `setTimeout(fn, delay)`.
-   *
-   * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using
-   * `setTimeout` in tests, the fns are queued in an array, which can be programmatically flushed
-   * via `$browser.defer.flush()`.
-   *
-   */
-  self.defer = function(fn, delay) {
-    var timeoutId;
-    outstandingRequestCount++;
-    timeoutId = setTimeout(function() {
-      delete pendingDeferIds[timeoutId];
-      completeOutstandingRequest(fn);
-    }, delay || 0);
-    pendingDeferIds[timeoutId] = true;
-    return timeoutId;
-  };
-
-
-  /**
-   * @name $browser#defer.cancel
-   *
-   * @description
-   * Cancels a deferred task identified with `deferId`.
-   *
-   * @param {*} deferId Token returned by the `$browser.defer` function.
-   * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
-   *                    canceled.
-   */
-  self.defer.cancel = function(deferId) {
-    if (pendingDeferIds[deferId]) {
-      delete pendingDeferIds[deferId];
-      clearTimeout(deferId);
-      completeOutstandingRequest(noop);
-      return true;
-    }
-    return false;
-  };
-
-}
-
-/** @this */
-function $BrowserProvider() {
-  this.$get = ['$window', '$log', '$sniffer', '$document',
-      function($window, $log, $sniffer, $document) {
-        return new Browser($window, $document, $log, $sniffer);
-      }];
-}
-
-/**
- * @ngdoc service
- * @name $cacheFactory
- * @this
- *
- * @description
- * Factory that constructs {@link $cacheFactory.Cache Cache} objects and gives access to
- * them.
- *
- * ```js
- *
- *  var cache = $cacheFactory('cacheId');
- *  expect($cacheFactory.get('cacheId')).toBe(cache);
- *  expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
- *
- *  cache.put("key", "value");
- *  cache.put("another key", "another value");
- *
- *  // We've specified no options on creation
- *  expect(cache.info()).toEqual({id: 'cacheId', size: 2});
- *
- * ```
- *
- *
- * @param {string} cacheId Name or id of the newly created cache.
- * @param {object=} options Options object that specifies the cache behavior. Properties:
- *
- *   - `{number=}` `capacity` — turns the cache into LRU cache.
- *
- * @returns {object} Newly created cache object with the following set of methods:
- *
- * - `{object}` `info()` — Returns id, size, and options of cache.
- * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns
- *   it.
- * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
- * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
- * - `{void}` `removeAll()` — Removes all cached values.
- * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.
- *
- * @example
-   <example module="cacheExampleApp" name="cache-factory">
-     <file name="index.html">
-       <div ng-controller="CacheController">
-         <input ng-model="newCacheKey" placeholder="Key">
-         <input ng-model="newCacheValue" placeholder="Value">
-         <button ng-click="put(newCacheKey, newCacheValue)">Cache</button>
-
-         <p ng-if="keys.length">Cached Values</p>
-         <div ng-repeat="key in keys">
-           <span ng-bind="key"></span>
-           <span>: </span>
-           <b ng-bind="cache.get(key)"></b>
-         </div>
-
-         <p>Cache Info</p>
-         <div ng-repeat="(key, value) in cache.info()">
-           <span ng-bind="key"></span>
-           <span>: </span>
-           <b ng-bind="value"></b>
-         </div>
-       </div>
-     </file>
-     <file name="script.js">
-       angular.module('cacheExampleApp', []).
-         controller('CacheController', ['$scope', '$cacheFactory', function($scope, $cacheFactory) {
-           $scope.keys = [];
-           $scope.cache = $cacheFactory('cacheId');
-           $scope.put = function(key, value) {
-             if (angular.isUndefined($scope.cache.get(key))) {
-               $scope.keys.push(key);
-             }
-             $scope.cache.put(key, angular.isUndefined(value) ? null : value);
-           };
-         }]);
-     </file>
-     <file name="style.css">
-       p {
-         margin: 10px 0 3px;
-       }
-     </file>
-   </example>
- */
-function $CacheFactoryProvider() {
-
-  this.$get = function() {
-    var caches = {};
-
-    function cacheFactory(cacheId, options) {
-      if (cacheId in caches) {
-        throw minErr('$cacheFactory')('iid', 'CacheId \'{0}\' is already taken!', cacheId);
-      }
-
-      var size = 0,
-          stats = extend({}, options, {id: cacheId}),
-          data = createMap(),
-          capacity = (options && options.capacity) || Number.MAX_VALUE,
-          lruHash = createMap(),
-          freshEnd = null,
-          staleEnd = null;
-
-      /**
-       * @ngdoc type
-       * @name $cacheFactory.Cache
-       *
-       * @description
-       * A cache object used to store and retrieve data, primarily used by
-       * {@link $http $http} and the {@link ng.directive:script script} directive to cache
-       * templates and other data.
-       *
-       * ```js
-       *  angular.module('superCache')
-       *    .factory('superCache', ['$cacheFactory', function($cacheFactory) {
-       *      return $cacheFactory('super-cache');
-       *    }]);
-       * ```
-       *
-       * Example test:
-       *
-       * ```js
-       *  it('should behave like a cache', inject(function(superCache) {
-       *    superCache.put('key', 'value');
-       *    superCache.put('another key', 'another value');
-       *
-       *    expect(superCache.info()).toEqual({
-       *      id: 'super-cache',
-       *      size: 2
-       *    });
-       *
-       *    superCache.remove('another key');
-       *    expect(superCache.get('another key')).toBeUndefined();
-       *
-       *    superCache.removeAll();
-       *    expect(superCache.info()).toEqual({
-       *      id: 'super-cache',
-       *      size: 0
-       *    });
-       *  }));
-       * ```
-       */
-      return (caches[cacheId] = {
-
-        /**
-         * @ngdoc method
-         * @name $cacheFactory.Cache#put
-         * @kind function
-         *
-         * @description
-         * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be
-         * retrieved later, and incrementing the size of the cache if the key was not already
-         * present in the cache. If behaving like an LRU cache, it will also remove stale
-         * entries from the set.
-         *
-         * It will not insert undefined values into the cache.
-         *
-         * @param {string} key the key under which the cached data is stored.
-         * @param {*} value the value to store alongside the key. If it is undefined, the key
-         *    will not be stored.
-         * @returns {*} the value stored.
-         */
-        put: function(key, value) {
-          if (isUndefined(value)) return;
-          if (capacity < Number.MAX_VALUE) {
-            var lruEntry = lruHash[key] || (lruHash[key] = {key: key});
-
-            refresh(lruEntry);
-          }
-
-          if (!(key in data)) size++;
-          data[key] = value;
-
-          if (size > capacity) {
-            this.remove(staleEnd.key);
-          }
-
-          return value;
-        },
-
-        /**
-         * @ngdoc method
-         * @name $cacheFactory.Cache#get
-         * @kind function
-         *
-         * @description
-         * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object.
-         *
-         * @param {string} key the key of the data to be retrieved
-         * @returns {*} the value stored.
-         */
-        get: function(key) {
-          if (capacity < Number.MAX_VALUE) {
-            var lruEntry = lruHash[key];
-
-            if (!lruEntry) return;
-
-            refresh(lruEntry);
-          }
-
-          return data[key];
-        },
-
-
-        /**
-         * @ngdoc method
-         * @name $cacheFactory.Cache#remove
-         * @kind function
-         *
-         * @description
-         * Removes an entry from the {@link $cacheFactory.Cache Cache} object.
-         *
-         * @param {string} key the key of the entry to be removed
-         */
-        remove: function(key) {
-          if (capacity < Number.MAX_VALUE) {
-            var lruEntry = lruHash[key];
-
-            if (!lruEntry) return;
-
-            if (lruEntry === freshEnd) freshEnd = lruEntry.p;
-            if (lruEntry === staleEnd) staleEnd = lruEntry.n;
-            link(lruEntry.n,lruEntry.p);
-
-            delete lruHash[key];
-          }
-
-          if (!(key in data)) return;
-
-          delete data[key];
-          size--;
-        },
-
-
-        /**
-         * @ngdoc method
-         * @name $cacheFactory.Cache#removeAll
-         * @kind function
-         *
-         * @description
-         * Clears the cache object of any entries.
-         */
-        removeAll: function() {
-          data = createMap();
-          size = 0;
-          lruHash = createMap();
-          freshEnd = staleEnd = null;
-        },
-
-
-        /**
-         * @ngdoc method
-         * @name $cacheFactory.Cache#destroy
-         * @kind function
-         *
-         * @description
-         * Destroys the {@link $cacheFactory.Cache Cache} object entirely,
-         * removing it from the {@link $cacheFactory $cacheFactory} set.
-         */
-        destroy: function() {
-          data = null;
-          stats = null;
-          lruHash = null;
-          delete caches[cacheId];
-        },
-
-
-        /**
-         * @ngdoc method
-         * @name $cacheFactory.Cache#info
-         * @kind function
-         *
-         * @description
-         * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}.
-         *
-         * @returns {object} an object with the following properties:
-         *   <ul>
-         *     <li>**id**: the id of the cache instance</li>
-         *     <li>**size**: the number of entries kept in the cache instance</li>
-         *     <li>**...**: any additional properties from the options object when creating the
-         *       cache.</li>
-         *   </ul>
-         */
-        info: function() {
-          return extend({}, stats, {size: size});
-        }
-      });
-
-
-      /**
-       * makes the `entry` the freshEnd of the LRU linked list
-       */
-      function refresh(entry) {
-        if (entry !== freshEnd) {
-          if (!staleEnd) {
-            staleEnd = entry;
-          } else if (staleEnd === entry) {
-            staleEnd = entry.n;
-          }
-
-          link(entry.n, entry.p);
-          link(entry, freshEnd);
-          freshEnd = entry;
-          freshEnd.n = null;
-        }
-      }
-
-
-      /**
-       * bidirectionally links two entries of the LRU linked list
-       */
-      function link(nextEntry, prevEntry) {
-        if (nextEntry !== prevEntry) {
-          if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify
-          if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify
-        }
-      }
-    }
-
-
-  /**
-   * @ngdoc method
-   * @name $cacheFactory#info
-   *
-   * @description
-   * Get information about all the caches that have been created
-   *
-   * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
-   */
-    cacheFactory.info = function() {
-      var info = {};
-      forEach(caches, function(cache, cacheId) {
-        info[cacheId] = cache.info();
-      });
-      return info;
-    };
-
-
-  /**
-   * @ngdoc method
-   * @name $cacheFactory#get
-   *
-   * @description
-   * Get access to a cache object by the `cacheId` used when it was created.
-   *
-   * @param {string} cacheId Name or id of a cache to access.
-   * @returns {object} Cache object identified by the cacheId or undefined if no such cache.
-   */
-    cacheFactory.get = function(cacheId) {
-      return caches[cacheId];
-    };
-
-
-    return cacheFactory;
-  };
-}
-
-/**
- * @ngdoc service
- * @name $templateCache
- * @this
- *
- * @description
- * The first time a template is used, it is loaded in the template cache for quick retrieval. You
- * can load templates directly into the cache in a `script` tag, or by consuming the
- * `$templateCache` service directly.
- *
- * Adding via the `script` tag:
- *
- * ```html
- *   <script type="text/ng-template" id="templateId.html">
- *     <p>This is the content of the template</p>
- *   </script>
- * ```
- *
- * **Note:** the `script` tag containing the template does not need to be included in the `head` of
- * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,
- * element with ng-app attribute), otherwise the template will be ignored.
- *
- * Adding via the `$templateCache` service:
- *
- * ```js
- * var myApp = angular.module('myApp', []);
- * myApp.run(function($templateCache) {
- *   $templateCache.put('templateId.html', 'This is the content of the template');
- * });
- * ```
- *
- * To retrieve the template later, simply use it in your component:
- * ```js
- * myApp.component('myComponent', {
- *    templateUrl: 'templateId.html'
- * });
- * ```
- *
- * or get it via the `$templateCache` service:
- * ```js
- * $templateCache.get('templateId.html')
- * ```
- *
- * See {@link ng.$cacheFactory $cacheFactory}.
- *
- */
-function $TemplateCacheProvider() {
-  this.$get = ['$cacheFactory', function($cacheFactory) {
-    return $cacheFactory('templates');
-  }];
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *     Any commits to this file should be reviewed with security in mind.  *
- *   Changes to this file can potentially create security vulnerabilities. *
- *          An approval from 2 Core members with history of modifying      *
- *                         this file is required.                          *
- *                                                                         *
- *  Does the change somehow allow for arbitrary javascript to be executed? *
- *    Or allows for someone to change the prototype of built-in objects?   *
- *     Or gives undesired access to variables like document or window?    *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE!
- *
- * DOM-related variables:
- *
- * - "node" - DOM Node
- * - "element" - DOM Element or Node
- * - "$node" or "$element" - jqLite-wrapped node or element
- *
- *
- * Compiler related stuff:
- *
- * - "linkFn" - linking fn of a single directive
- * - "nodeLinkFn" - function that aggregates all linking fns for a particular node
- * - "childLinkFn" -  function that aggregates all linking fns for child nodes of a particular node
- * - "compositeLinkFn" - function that aggregates all linking fns for a compilation root (nodeList)
- */
-
-
-/**
- * @ngdoc service
- * @name $compile
- * @kind function
- *
- * @description
- * Compiles an HTML string or DOM into a template and produces a template function, which
- * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together.
- *
- * The compilation is a process of walking the DOM tree and matching DOM elements to
- * {@link ng.$compileProvider#directive directives}.
- *
- * <div class="alert alert-warning">
- * **Note:** This document is an in-depth reference of all directive options.
- * For a gentle introduction to directives with examples of common use cases,
- * see the {@link guide/directive directive guide}.
- * </div>
- *
- * ## Comprehensive Directive API
- *
- * There are many different options for a directive.
- *
- * The difference resides in the return value of the factory function.
- * You can either return a {@link $compile#directive-definition-object Directive Definition Object (see below)}
- * that defines the directive properties, or just the `postLink` function (all other properties will have
- * the default values).
- *
- * <div class="alert alert-success">
- * **Best Practice:** It's recommended to use the "directive definition object" form.
- * </div>
- *
- * Here's an example directive declared with a Directive Definition Object:
- *
- * ```js
- *   var myModule = angular.module(...);
- *
- *   myModule.directive('directiveName', function factory(injectables) {
- *     var directiveDefinitionObject = {
- *       {@link $compile#-priority- priority}: 0,
- *       {@link $compile#-template- template}: '<div></div>', // or // function(tElement, tAttrs) { ... },
- *       // or
- *       // {@link $compile#-templateurl- templateUrl}: 'directive.html', // or // function(tElement, tAttrs) { ... },
- *       {@link $compile#-transclude- transclude}: false,
- *       {@link $compile#-restrict- restrict}: 'A',
- *       {@link $compile#-templatenamespace- templateNamespace}: 'html',
- *       {@link $compile#-scope- scope}: false,
- *       {@link $compile#-controller- controller}: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
- *       {@link $compile#-controlleras- controllerAs}: 'stringIdentifier',
- *       {@link $compile#-bindtocontroller- bindToController}: false,
- *       {@link $compile#-require- require}: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
- *       {@link $compile#-multielement- multiElement}: false,
- *       {@link $compile#-compile- compile}: function compile(tElement, tAttrs, transclude) {
- *         return {
- *            {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },
- *            {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }
- *         }
- *         // or
- *         // return function postLink( ... ) { ... }
- *       },
- *       // or
- *       // {@link $compile#-link- link}: {
- *       //  {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },
- *       //  {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }
- *       // }
- *       // or
- *       // {@link $compile#-link- link}: function postLink( ... ) { ... }
- *     };
- *     return directiveDefinitionObject;
- *   });
- * ```
- *
- * <div class="alert alert-warning">
- * **Note:** Any unspecified options will use the default value. You can see the default values below.
- * </div>
- *
- * Therefore the above can be simplified as:
- *
- * ```js
- *   var myModule = angular.module(...);
- *
- *   myModule.directive('directiveName', function factory(injectables) {
- *     var directiveDefinitionObject = {
- *       link: function postLink(scope, iElement, iAttrs) { ... }
- *     };
- *     return directiveDefinitionObject;
- *     // or
- *     // return function postLink(scope, iElement, iAttrs) { ... }
- *   });
- * ```
- *
- * ### Life-cycle hooks
- * Directive controllers can provide the following methods that are called by Angular at points in the life-cycle of the
- * directive:
- * * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
- *   had their bindings initialized (and before the pre &amp; post linking functions for the directives on
- *   this element). This is a good place to put initialization code for your controller.
- * * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The
- *   `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an
- *   object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a
- *   component such as cloning the bound value to prevent accidental mutation of the outer value. Note that this will
- *   also be called when your bindings are initialized.
- * * `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on
- *   changes. Any actions that you wish to take in response to the changes that you detect must be
- *   invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
- *   could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
- *   be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
- *   if detecting changes, you must store the previous value(s) for comparison to the current values.
- * * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
- *   external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in
- *   the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent
- *   components will have their `$onDestroy()` hook called before child components.
- * * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
- *   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
- *   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
- *   they are waiting for their template to load asynchronously and their own compilation and linking has been
- *   suspended until that occurs.
- *
- * #### Comparison with Angular 2 life-cycle hooks
- * Angular 2 also uses life-cycle hooks for its components. While the Angular 1 life-cycle hooks are similar there are
- * some differences that you should be aware of, especially when it comes to moving your code from Angular 1 to Angular 2:
- *
- * * Angular 1 hooks are prefixed with `$`, such as `$onInit`. Angular 2 hooks are prefixed with `ng`, such as `ngOnInit`.
- * * Angular 1 hooks can be defined on the controller prototype or added to the controller inside its constructor.
- *   In Angular 2 you can only define hooks on the prototype of the Component class.
- * * Due to the differences in change-detection, you may get many more calls to `$doCheck` in Angular 1 than you would to
- *   `ngDoCheck` in Angular 2
- * * Changes to the model inside `$doCheck` will trigger new turns of the digest loop, which will cause the changes to be
- *   propagated throughout the application.
- *   Angular 2 does not allow the `ngDoCheck` hook to trigger a change outside of the component. It will either throw an
- *   error or do nothing depending upon the state of `enableProdMode()`.
- *
- * #### Life-cycle hook examples
- *
- * This example shows how you can check for mutations to a Date object even though the identity of the object
- * has not changed.
- *
- * <example name="doCheckDateExample" module="do-check-module">
- *   <file name="app.js">
- *     angular.module('do-check-module', [])
- *       .component('app', {
- *         template:
- *           'Month: <input ng-model="$ctrl.month" ng-change="$ctrl.updateDate()">' +
- *           'Date: {{ $ctrl.date }}' +
- *           '<test date="$ctrl.date"></test>',
- *         controller: function() {
- *           this.date = new Date();
- *           this.month = this.date.getMonth();
- *           this.updateDate = function() {
- *             this.date.setMonth(this.month);
- *           };
- *         }
- *       })
- *       .component('test', {
- *         bindings: { date: '<' },
- *         template:
- *           '<pre>{{ $ctrl.log | json }}</pre>',
- *         controller: function() {
- *           var previousValue;
- *           this.log = [];
- *           this.$doCheck = function() {
- *             var currentValue = this.date && this.date.valueOf();
- *             if (previousValue !== currentValue) {
- *               this.log.push('doCheck: date mutated: ' + this.date);
- *               previousValue = currentValue;
- *             }
- *           };
- *         }
- *       });
- *   </file>
- *   <file name="index.html">
- *     <app></app>
- *   </file>
- * </example>
- *
- * This example show how you might use `$doCheck` to trigger changes in your component's inputs even if the
- * actual identity of the component doesn't change. (Be aware that cloning and deep equality checks on large
- * arrays or objects can have a negative impact on your application performance)
- *
- * <example name="doCheckArrayExample" module="do-check-module">
- *   <file name="index.html">
- *     <div ng-init="items = []">
- *       <button ng-click="items.push(items.length)">Add Item</button>
- *       <button ng-click="items = []">Reset Items</button>
- *       <pre>{{ items }}</pre>
- *       <test items="items"></test>
- *     </div>
- *   </file>
- *   <file name="app.js">
- *      angular.module('do-check-module', [])
- *        .component('test', {
- *          bindings: { items: '<' },
- *          template:
- *            '<pre>{{ $ctrl.log | json }}</pre>',
- *          controller: function() {
- *            this.log = [];
- *
- *            this.$doCheck = function() {
- *              if (this.items_ref !== this.items) {
- *                this.log.push('doCheck: items changed');
- *                this.items_ref = this.items;
- *              }
- *              if (!angular.equals(this.items_clone, this.items)) {
- *                this.log.push('doCheck: items mutated');
- *                this.items_clone = angular.copy(this.items);
- *              }
- *            };
- *          }
- *        });
- *   </file>
- * </example>
- *
- *
- * ### Directive Definition Object
- *
- * The directive definition object provides instructions to the {@link ng.$compile
- * compiler}. The attributes are:
- *
- * #### `multiElement`
- * When this property is set to true (default is `false`), the HTML compiler will collect DOM nodes between
- * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
- * together as the directive elements. It is recommended that this feature be used on directives
- * which are not strictly behavioral (such as {@link ngClick}), and which
- * do not manipulate or replace child nodes (such as {@link ngInclude}).
- *
- * #### `priority`
- * When there are multiple directives defined on a single DOM element, sometimes it
- * is necessary to specify the order in which the directives are applied. The `priority` is used
- * to sort the directives before their `compile` functions get called. Priority is defined as a
- * number. Directives with greater numerical `priority` are compiled first. Pre-link functions
- * are also run in priority order, but post-link functions are run in reverse order. The order
- * of directives with the same priority is undefined. The default priority is `0`.
- *
- * #### `terminal`
- * If set to true then the current `priority` will be the last set of directives
- * which will execute (any directives at the current priority will still execute
- * as the order of execution on same `priority` is undefined). Note that expressions
- * and other directives used in the directive's template will also be excluded from execution.
- *
- * #### `scope`
- * The scope property can be `false`, `true`, or an object:
- *
- * * **`false` (default):** No scope will be created for the directive. The directive will use its
- * parent's scope.
- *
- * * **`true`:** A new child scope that prototypically inherits from its parent will be created for
- * the directive's element. If multiple directives on the same element request a new scope,
- * only one new scope is created.
- *
- * * **`{...}` (an object hash):** A new "isolate" scope is created for the directive's template.
- * The 'isolate' scope differs from normal scope in that it does not prototypically
- * inherit from its parent scope. This is useful when creating reusable components, which should not
- * accidentally read or modify data in the parent scope. Note that an isolate scope
- * directive without a `template` or `templateUrl` will not apply the isolate scope
- * to its children elements.
- *
- * The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the
- * directive's element. These local properties are useful for aliasing values for templates. The keys in
- * the object hash map to the name of the property on the isolate scope; the values define how the property
- * is bound to the parent scope, via matching attributes on the directive's element:
- *
- * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is
- *   always a string since DOM attributes are strings. If no `attr` name is specified then the
- *   attribute name is assumed to be the same as the local name. Given `<my-component
- *   my-attr="hello {{name}}">` and the isolate scope definition `scope: { localName:'@myAttr' }`,
- *   the directive's scope property `localName` will reflect the interpolated value of `hello
- *   {{name}}`. As the `name` attribute changes so will the `localName` property on the directive's
- *   scope. The `name` is read from the parent scope (not the directive's scope).
- *
- * * `=` or `=attr` - set up a bidirectional binding between a local scope property and an expression
- *   passed via the attribute `attr`. The expression is evaluated in the context of the parent scope.
- *   If no `attr` name is specified then the attribute name is assumed to be the same as the local
- *   name. Given `<my-component my-attr="parentModel">` and the isolate scope definition `scope: {
- *   localModel: '=myAttr' }`, the property `localModel` on the directive's scope will reflect the
- *   value of `parentModel` on the parent scope. Changes to `parentModel` will be reflected in
- *   `localModel` and vice versa. Optional attributes should be marked as such with a question mark:
- *   `=?` or `=?attr`. If the binding expression is non-assignable, or if the attribute isn't
- *   optional and doesn't exist, an exception ({@link error/$compile/nonassign `$compile:nonassign`})
- *   will be thrown upon discovering changes to the local value, since it will be impossible to sync
- *   them back to the parent scope. By default, the {@link ng.$rootScope.Scope#$watch `$watch`}
- *   method is used for tracking changes, and the equality check is based on object identity.
- *   However, if an object literal or an array literal is passed as the binding expression, the
- *   equality check is done by value (using the {@link angular.equals} function). It's also possible
- *   to watch the evaluated value shallowly with {@link ng.$rootScope.Scope#$watchCollection
- *   `$watchCollection`}: use `=*` or `=*attr` (`=*?` or `=*?attr` if the attribute is optional).
- *
-  * * `<` or `<attr` - set up a one-way (one-directional) binding between a local scope property and an
- *   expression passed via the attribute `attr`. The expression is evaluated in the context of the
- *   parent scope. If no `attr` name is specified then the attribute name is assumed to be the same as the
- *   local name. You can also make the binding optional by adding `?`: `<?` or `<?attr`.
- *
- *   For example, given `<my-component my-attr="parentModel">` and directive definition of
- *   `scope: { localModel:'<myAttr' }`, then the isolated scope property `localModel` will reflect the
- *   value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
- *   in `localModel`, but changes in `localModel` will not reflect in `parentModel`. There are however
- *   two caveats:
- *     1. one-way binding does not copy the value from the parent to the isolate scope, it simply
- *     sets the same value. That means if your bound value is an object, changes to its properties
- *     in the isolated scope will be reflected in the parent scope (because both reference the same object).
- *     2. one-way binding watches changes to the **identity** of the parent value. That means the
- *     {@link ng.$rootScope.Scope#$watch `$watch`} on the parent value only fires if the reference
- *     to the value has changed. In most cases, this should not be of concern, but can be important
- *     to know if you one-way bind to an object, and then replace that object in the isolated scope.
- *     If you now change a property of the object in your parent scope, the change will not be
- *     propagated to the isolated scope, because the identity of the object on the parent scope
- *     has not changed. Instead you must assign a new object.
- *
- *   One-way binding is useful if you do not plan to propagate changes to your isolated scope bindings
- *   back to the parent. However, it does not make this completely impossible.
- *
- * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. If
- *   no `attr` name is specified then the attribute name is assumed to be the same as the local name.
- *   Given `<my-component my-attr="count = count + value">` and the isolate scope definition `scope: {
- *   localFn:'&myAttr' }`, the isolate scope property `localFn` will point to a function wrapper for
- *   the `count = count + value` expression. Often it's desirable to pass data from the isolated scope
- *   via an expression to the parent scope. This can be done by passing a map of local variable names
- *   and values into the expression wrapper fn. For example, if the expression is `increment(amount)`
- *   then we can specify the amount value by calling the `localFn` as `localFn({amount: 22})`.
- *
- * In general it's possible to apply more than one directive to one element, but there might be limitations
- * depending on the type of scope required by the directives. The following points will help explain these limitations.
- * For simplicity only two directives are taken into account, but it is also applicable for several directives:
- *
- * * **no scope** + **no scope** => Two directives which don't require their own scope will use their parent's scope
- * * **child scope** + **no scope** =>  Both directives will share one single child scope
- * * **child scope** + **child scope** =>  Both directives will share one single child scope
- * * **isolated scope** + **no scope** =>  The isolated directive will use it's own created isolated scope. The other directive will use
- * its parent's scope
- * * **isolated scope** + **child scope** =>  **Won't work!** Only one scope can be related to one element. Therefore these directives cannot
- * be applied to the same element.
- * * **isolated scope** + **isolated scope**  =>  **Won't work!** Only one scope can be related to one element. Therefore these directives
- * cannot be applied to the same element.
- *
- *
- * #### `bindToController`
- * This property is used to bind scope properties directly to the controller. It can be either
- * `true` or an object hash with the same format as the `scope` property.
- *
- * When an isolate scope is used for a directive (see above), `bindToController: true` will
- * allow a component to have its properties bound to the controller, rather than to scope.
- *
- * After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller
- * properties. You can access these bindings once they have been initialized by providing a controller method called
- * `$onInit`, which is called after all the controllers on an element have been constructed and had their bindings
- * initialized.
- *
- * <div class="alert alert-warning">
- * **Deprecation warning:** although bindings for non-ES6 class controllers are currently
- * bound to `this` before the controller constructor is called, this use is now deprecated. Please place initialization
- * code that relies upon bindings inside a `$onInit` method on the controller, instead.
- * </div>
- *
- * It is also possible to set `bindToController` to an object hash with the same format as the `scope` property.
- * This will set up the scope bindings to the controller directly. Note that `scope` can still be used
- * to define which kind of scope is created. By default, no scope is created. Use `scope: {}` to create an isolate
- * scope (useful for component directives).
- *
- * If both `bindToController` and `scope` are defined and have object hashes, `bindToController` overrides `scope`.
- *
- *
- * #### `controller`
- * Controller constructor function. The controller is instantiated before the
- * pre-linking phase and can be accessed by other directives (see
- * `require` attribute). This allows the directives to communicate with each other and augment
- * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:
- *
- * * `$scope` - Current scope associated with the element
- * * `$element` - Current element
- * * `$attrs` - Current attributes object for the element
- * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:
- *   `function([scope], cloneLinkingFn, futureParentElement, slotName)`:
- *    * `scope`: (optional) override the scope.
- *    * `cloneLinkingFn`: (optional) argument to create clones of the original transcluded content.
- *    * `futureParentElement` (optional):
- *        * defines the parent to which the `cloneLinkingFn` will add the cloned elements.
- *        * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.
- *        * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)
- *          and when the `cloneLinkingFn` is passed,
- *          as those elements need to created and cloned in a special way when they are defined outside their
- *          usual containers (e.g. like `<svg>`).
- *        * See also the `directive.templateNamespace` property.
- *    * `slotName`: (optional) the name of the slot to transclude. If falsy (e.g. `null`, `undefined` or `''`)
- *      then the default transclusion is provided.
- *    The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns
- *    `true` if the specified slot contains content (i.e. one or more DOM nodes).
- *
- * #### `require`
- * Require another directive and inject its controller as the fourth argument to the linking function. The
- * `require` property can be a string, an array or an object:
- * * a **string** containing the name of the directive to pass to the linking function
- * * an **array** containing the names of directives to pass to the linking function. The argument passed to the
- * linking function will be an array of controllers in the same order as the names in the `require` property
- * * an **object** whose property values are the names of the directives to pass to the linking function. The argument
- * passed to the linking function will also be an object with matching keys, whose values will hold the corresponding
- * controllers.
- *
- * If the `require` property is an object and `bindToController` is truthy, then the required controllers are
- * bound to the controller using the keys of the `require` property. This binding occurs after all the controllers
- * have been constructed but before `$onInit` is called.
- * If the name of the required controller is the same as the local name (the key), the name can be
- * omitted. For example, `{parentDir: '^^'}` is equivalent to `{parentDir: '^^parentDir'}`.
- * See the {@link $compileProvider#component} helper for an example of how this can be used.
- * If no such required directive(s) can be found, or if the directive does not have a controller, then an error is
- * raised (unless no link function is specified and the required controllers are not being bound to the directive
- * controller, in which case error checking is skipped). The name can be prefixed with:
- *
- * * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
- * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
- * * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found.
- * * `^^` - Locate the required controller by searching the element's parents. Throw an error if not found.
- * * `?^` - Attempt to locate the required controller by searching the element and its parents or pass
- *   `null` to the `link` fn if not found.
- * * `?^^` - Attempt to locate the required controller by searching the element's parents, or pass
- *   `null` to the `link` fn if not found.
- *
- *
- * #### `controllerAs`
- * Identifier name for a reference to the controller in the directive's scope.
- * This allows the controller to be referenced from the directive template. This is especially
- * useful when a directive is used as component, i.e. with an `isolate` scope. It's also possible
- * to use it in a directive without an `isolate` / `new` scope, but you need to be aware that the
- * `controllerAs` reference might overwrite a property that already exists on the parent scope.
- *
- *
- * #### `restrict`
- * String of subset of `EACM` which restricts the directive to a specific directive
- * declaration style. If omitted, the defaults (elements and attributes) are used.
- *
- * * `E` - Element name (default): `<my-directive></my-directive>`
- * * `A` - Attribute (default): `<div my-directive="exp"></div>`
- * * `C` - Class: `<div class="my-directive: exp;"></div>`
- * * `M` - Comment: `<!-- directive: my-directive exp -->`
- *
- *
- * #### `templateNamespace`
- * String representing the document type used by the markup in the template.
- * AngularJS needs this information as those elements need to be created and cloned
- * in a special way when they are defined outside their usual containers like `<svg>` and `<math>`.
- *
- * * `html` - All root nodes in the template are HTML. Root nodes may also be
- *   top-level elements such as `<svg>` or `<math>`.
- * * `svg` - The root nodes in the template are SVG elements (excluding `<math>`).
- * * `math` - The root nodes in the template are MathML elements (excluding `<svg>`).
- *
- * If no `templateNamespace` is specified, then the namespace is considered to be `html`.
- *
- * #### `template`
- * HTML markup that may:
- * * Replace the contents of the directive's element (default).
- * * Replace the directive's element itself (if `replace` is true - DEPRECATED).
- * * Wrap the contents of the directive's element (if `transclude` is true).
- *
- * Value may be:
- *
- * * A string. For example `<div red-on-hover>{{delete_str}}</div>`.
- * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile`
- *   function api below) and returns a string value.
- *
- *
- * #### `templateUrl`
- * This is similar to `template` but the template is loaded from the specified URL, asynchronously.
- *
- * Because template loading is asynchronous the compiler will suspend compilation of directives on that element
- * for later when the template has been resolved.  In the meantime it will continue to compile and link
- * sibling and parent elements as though this element had not contained any directives.
- *
- * The compiler does not suspend the entire compilation to wait for templates to be loaded because this
- * would result in the whole app "stalling" until all templates are loaded asynchronously - even in the
- * case when only one deeply nested directive has `templateUrl`.
- *
- * Template loading is asynchronous even if the template has been preloaded into the {@link $templateCache}
- *
- * You can specify `templateUrl` as a string representing the URL or as a function which takes two
- * arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns
- * a string value representing the url.  In either case, the template URL is passed through {@link
- * $sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}.
- *
- *
- * #### `replace` ([*DEPRECATED*!], will be removed in next major release - i.e. v2.0)
- * specify what the template should replace. Defaults to `false`.
- *
- * * `true` - the template will replace the directive's element.
- * * `false` - the template will replace the contents of the directive's element.
- *
- * The replacement process migrates all of the attributes / classes from the old element to the new
- * one. See the {@link guide/directive#template-expanding-directive
- * Directives Guide} for an example.
- *
- * There are very few scenarios where element replacement is required for the application function,
- * the main one being reusable custom components that are used within SVG contexts
- * (because SVG doesn't work with custom elements in the DOM tree).
- *
- * #### `transclude`
- * Extract the contents of the element where the directive appears and make it available to the directive.
- * The contents are compiled and provided to the directive as a **transclusion function**. See the
- * {@link $compile#transclusion Transclusion} section below.
- *
- *
- * #### `compile`
- *
- * ```js
- *   function compile(tElement, tAttrs, transclude) { ... }
- * ```
- *
- * The compile function deals with transforming the template DOM. Since most directives do not do
- * template transformation, it is not used often. The compile function takes the following arguments:
- *
- *   * `tElement` - template element - The element where the directive has been declared. It is
- *     safe to do template transformation on the element and child elements only.
- *
- *   * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared
- *     between all directive compile functions.
- *
- *   * `transclude` -  [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`
- *
- * <div class="alert alert-warning">
- * **Note:** The template instance and the link instance may be different objects if the template has
- * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that
- * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration
- * should be done in a linking function rather than in a compile function.
- * </div>
-
- * <div class="alert alert-warning">
- * **Note:** The compile function cannot handle directives that recursively use themselves in their
- * own templates or compile functions. Compiling these directives results in an infinite loop and
- * stack overflow errors.
- *
- * This can be avoided by manually using $compile in the postLink function to imperatively compile
- * a directive's template instead of relying on automatic template compilation via `template` or
- * `templateUrl` declaration or manual compilation inside the compile function.
- * </div>
- *
- * <div class="alert alert-danger">
- * **Note:** The `transclude` function that is passed to the compile function is deprecated, as it
- *   e.g. does not know about the right outer scope. Please use the transclude function that is passed
- *   to the link function instead.
- * </div>
-
- * A compile function can have a return value which can be either a function or an object.
- *
- * * returning a (post-link) function - is equivalent to registering the linking function via the
- *   `link` property of the config object when the compile function is empty.
- *
- * * returning an object with function(s) registered via `pre` and `post` properties - allows you to
- *   control when a linking function should be called during the linking phase. See info about
- *   pre-linking and post-linking functions below.
- *
- *
- * #### `link`
- * This property is used only if the `compile` property is not defined.
- *
- * ```js
- *   function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
- * ```
- *
- * The link function is responsible for registering DOM listeners as well as updating the DOM. It is
- * executed after the template has been cloned. This is where most of the directive logic will be
- * put.
- *
- *   * `scope` - {@link ng.$rootScope.Scope Scope} - The scope to be used by the
- *     directive for registering {@link ng.$rootScope.Scope#$watch watches}.
- *
- *   * `iElement` - instance element - The element where the directive is to be used. It is safe to
- *     manipulate the children of the element only in `postLink` function since the children have
- *     already been linked.
- *
- *   * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared
- *     between all directive linking functions.
- *
- *   * `controller` - the directive's required controller instance(s) - Instances are shared
- *     among all directives, which allows the directives to use the controllers as a communication
- *     channel. The exact value depends on the directive's `require` property:
- *       * no controller(s) required: the directive's own controller, or `undefined` if it doesn't have one
- *       * `string`: the controller instance
- *       * `array`: array of controller instances
- *
- *     If a required controller cannot be found, and it is optional, the instance is `null`,
- *     otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.
- *
- *     Note that you can also require the directive's own controller - it will be made available like
- *     any other controller.
- *
- *   * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
- *     This is the same as the `$transclude` parameter of directive controllers,
- *     see {@link ng.$compile#-controller- the controller section for details}.
- *     `function([scope], cloneLinkingFn, futureParentElement)`.
- *
- * #### Pre-linking function
- *
- * Executed before the child elements are linked. Not safe to do DOM transformation since the
- * compiler linking function will fail to locate the correct elements for linking.
- *
- * #### Post-linking function
- *
- * Executed after the child elements are linked.
- *
- * Note that child elements that contain `templateUrl` directives will not have been compiled
- * and linked since they are waiting for their template to load asynchronously and their own
- * compilation and linking has been suspended until that occurs.
- *
- * It is safe to do DOM transformation in the post-linking function on elements that are not waiting
- * for their async templates to be resolved.
- *
- *
- * ### Transclusion
- *
- * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and
- * copying them to another part of the DOM, while maintaining their connection to the original AngularJS
- * scope from where they were taken.
- *
- * Transclusion is used (often with {@link ngTransclude}) to insert the
- * original contents of a directive's element into a specified place in the template of the directive.
- * The benefit of transclusion, over simply moving the DOM elements manually, is that the transcluded
- * content has access to the properties on the scope from which it was taken, even if the directive
- * has isolated scope.
- * See the {@link guide/directive#creating-a-directive-that-wraps-other-elements Directives Guide}.
- *
- * This makes it possible for the widget to have private state for its template, while the transcluded
- * content has access to its originating scope.
- *
- * <div class="alert alert-warning">
- * **Note:** When testing an element transclude directive you must not place the directive at the root of the
- * DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives
- * Testing Transclusion Directives}.
- * </div>
- *
- * There are three kinds of transclusion depending upon whether you want to transclude just the contents of the
- * directive's element, the entire element or multiple parts of the element contents:
- *
- * * `true` - transclude the content (i.e. the child nodes) of the directive's element.
- * * `'element'` - transclude the whole of the directive's element including any directives on this
- *   element that defined at a lower priority than this directive. When used, the `template`
- *   property is ignored.
- * * **`{...}` (an object hash):** - map elements of the content onto transclusion "slots" in the template.
- *
- * **Mult-slot transclusion** is declared by providing an object for the `transclude` property.
- *
- * This object is a map where the keys are the name of the slot to fill and the value is an element selector
- * used to match the HTML to the slot. The element selector should be in normalized form (e.g. `myElement`)
- * and will match the standard element variants (e.g. `my-element`, `my:element`, `data-my-element`, etc).
- *
- * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}
- *
- * If the element selector is prefixed with a `?` then that slot is optional.
- *
- * For example, the transclude object `{ slotA: '?myCustomElement' }` maps `<my-custom-element>` elements to
- * the `slotA` slot, which can be accessed via the `$transclude` function or via the {@link ngTransclude} directive.
- *
- * Slots that are not marked as optional (`?`) will trigger a compile time error if there are no matching elements
- * in the transclude content. If you wish to know if an optional slot was filled with content, then you can call
- * `$transclude.isSlotFilled(slotName)` on the transclude function passed to the directive's link function and
- * injectable into the directive's controller.
- *
- *
- * #### Transclusion Functions
- *
- * When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion
- * function** to the directive's `link` function and `controller`. This transclusion function is a special
- * **linking function** that will return the compiled contents linked to a new transclusion scope.
- *
- * <div class="alert alert-info">
- * If you are just using {@link ngTransclude} then you don't need to worry about this function, since
- * ngTransclude will deal with it for us.
- * </div>
- *
- * If you want to manually control the insertion and removal of the transcluded content in your directive
- * then you must use this transclude function. When you call a transclude function it returns a a jqLite/JQuery
- * object that contains the compiled DOM, which is linked to the correct transclusion scope.
- *
- * When you call a transclusion function you can pass in a **clone attach function**. This function accepts
- * two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded
- * content and the `scope` is the newly created transclusion scope, which the clone will be linked to.
- *
- * <div class="alert alert-info">
- * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a transclude function
- * since you then get a fresh clone of the original DOM and also have access to the new transclusion scope.
- * </div>
- *
- * It is normal practice to attach your transcluded content (`clone`) to the DOM inside your **clone
- * attach function**:
- *
- * ```js
- * var transcludedContent, transclusionScope;
- *
- * $transclude(function(clone, scope) {
- *   element.append(clone);
- *   transcludedContent = clone;
- *   transclusionScope = scope;
- * });
- * ```
- *
- * Later, if you want to remove the transcluded content from your DOM then you should also destroy the
- * associated transclusion scope:
- *
- * ```js
- * transcludedContent.remove();
- * transclusionScope.$destroy();
- * ```
- *
- * <div class="alert alert-info">
- * **Best Practice**: if you intend to add and remove transcluded content manually in your directive
- * (by calling the transclude function to get the DOM and calling `element.remove()` to remove it),
- * then you are also responsible for calling `$destroy` on the transclusion scope.
- * </div>
- *
- * The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat}
- * automatically destroy their transcluded clones as necessary so you do not need to worry about this if
- * you are simply using {@link ngTransclude} to inject the transclusion into your directive.
- *
- *
- * #### Transclusion Scopes
- *
- * When you call a transclude function it returns a DOM fragment that is pre-bound to a **transclusion
- * scope**. This scope is special, in that it is a child of the directive's scope (and so gets destroyed
- * when the directive's scope gets destroyed) but it inherits the properties of the scope from which it
- * was taken.
- *
- * For example consider a directive that uses transclusion and isolated scope. The DOM hierarchy might look
- * like this:
- *
- * ```html
- * <div ng-app>
- *   <div isolate>
- *     <div transclusion>
- *     </div>
- *   </div>
- * </div>
- * ```
- *
- * The `$parent` scope hierarchy will look like this:
- *
-   ```
-   - $rootScope
-     - isolate
-       - transclusion
-   ```
- *
- * but the scopes will inherit prototypically from different scopes to their `$parent`.
- *
-   ```
-   - $rootScope
-     - transclusion
-   - isolate
-   ```
- *
- *
- * ### Attributes
- *
- * The {@link ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the
- * `link()` or `compile()` functions. It has a variety of uses.
- *
- * * *Accessing normalized attribute names:* Directives like 'ngBind' can be expressed in many ways:
- *   'ng:bind', `data-ng-bind`, or 'x-ng-bind'. The attributes object allows for normalized access
- *   to the attributes.
- *
- * * *Directive inter-communication:* All directives share the same instance of the attributes
- *   object which allows the directives to use the attributes object as inter directive
- *   communication.
- *
- * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object
- *   allowing other directives to read the interpolated value.
- *
- * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes
- *   that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also
- *   the only way to easily get the actual value because during the linking phase the interpolation
- *   hasn't been evaluated yet and so the value is at this time set to `undefined`.
- *
- * ```js
- * function linkingFn(scope, elm, attrs, ctrl) {
- *   // get the attribute value
- *   console.log(attrs.ngModel);
- *
- *   // change the attribute
- *   attrs.$set('ngModel', 'new value');
- *
- *   // observe changes to interpolated attribute
- *   attrs.$observe('ngModel', function(value) {
- *     console.log('ngModel has changed value to ' + value);
- *   });
- * }
- * ```
- *
- * ## Example
- *
- * <div class="alert alert-warning">
- * **Note**: Typically directives are registered with `module.directive`. The example below is
- * to illustrate how `$compile` works.
- * </div>
- *
- <example module="compileExample" name="compile">
-   <file name="index.html">
-    <script>
-      angular.module('compileExample', [], function($compileProvider) {
-        // configure new 'compile' directive by passing a directive
-        // factory function. The factory function injects the '$compile'
-        $compileProvider.directive('compile', function($compile) {
-          // directive factory creates a link function
-          return function(scope, element, attrs) {
-            scope.$watch(
-              function(scope) {
-                 // watch the 'compile' expression for changes
-                return scope.$eval(attrs.compile);
-              },
-              function(value) {
-                // when the 'compile' expression changes
-                // assign it into the current DOM
-                element.html(value);
-
-                // compile the new DOM and link it to the current
-                // scope.
-                // NOTE: we only compile .childNodes so that
-                // we don't get into infinite loop compiling ourselves
-                $compile(element.contents())(scope);
-              }
-            );
-          };
-        });
-      })
-      .controller('GreeterController', ['$scope', function($scope) {
-        $scope.name = 'Angular';
-        $scope.html = 'Hello {{name}}';
-      }]);
-    </script>
-    <div ng-controller="GreeterController">
-      <input ng-model="name"> <br/>
-      <textarea ng-model="html"></textarea> <br/>
-      <div compile="html"></div>
-    </div>
-   </file>
-   <file name="protractor.js" type="protractor">
-     it('should auto compile', function() {
-       var textarea = $('textarea');
-       var output = $('div[compile]');
-       // The initial state reads 'Hello Angular'.
-       expect(output.getText()).toBe('Hello Angular');
-       textarea.clear();
-       textarea.sendKeys('{{name}}!');
-       expect(output.getText()).toBe('Angular!');
-     });
-   </file>
- </example>
-
- *
- *
- * @param {string|DOMElement} element Element or HTML string to compile into a template function.
- * @param {function(angular.Scope, cloneAttachFn=)} transclude function available to directives - DEPRECATED.
- *
- * <div class="alert alert-danger">
- * **Note:** Passing a `transclude` function to the $compile function is deprecated, as it
- *   e.g. will not use the right outer scope. Please pass the transclude function as a
- *   `parentBoundTranscludeFn` to the link function instead.
- * </div>
- *
- * @param {number} maxPriority only apply directives lower than given priority (Only effects the
- *                 root element(s), not their children)
- * @returns {function(scope, cloneAttachFn=, options=)} a link function which is used to bind template
- * (a DOM element/tree) to a scope. Where:
- *
- *  * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to.
- *  * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the
- *  `template` and call the `cloneAttachFn` function allowing the caller to attach the
- *  cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is
- *  called as: <br/> `cloneAttachFn(clonedElement, scope)` where:
- *
- *      * `clonedElement` - is a clone of the original `element` passed into the compiler.
- *      * `scope` - is the current scope with which the linking function is working with.
- *
- *  * `options` - An optional object hash with linking options. If `options` is provided, then the following
- *  keys may be used to control linking behavior:
- *
- *      * `parentBoundTranscludeFn` - the transclude function made available to
- *        directives; if given, it will be passed through to the link functions of
- *        directives found in `element` during compilation.
- *      * `transcludeControllers` - an object hash with keys that map controller names
- *        to a hash with the key `instance`, which maps to the controller instance;
- *        if given, it will make the controllers available to directives on the compileNode:
- *        ```
- *        {
- *          parent: {
- *            instance: parentControllerInstance
- *          }
- *        }
- *        ```
- *      * `futureParentElement` - defines the parent to which the `cloneAttachFn` will add
- *        the cloned elements; only needed for transcludes that are allowed to contain non html
- *        elements (e.g. SVG elements). See also the directive.controller property.
- *
- * Calling the linking function returns the element of the template. It is either the original
- * element passed in, or the clone of the element if the `cloneAttachFn` is provided.
- *
- * After linking the view is not updated until after a call to $digest which typically is done by
- * Angular automatically.
- *
- * If you need access to the bound view, there are two ways to do it:
- *
- * - If you are not asking the linking function to clone the template, create the DOM element(s)
- *   before you send them to the compiler and keep this reference around.
- *   ```js
- *     var element = $compile('<p>{{total}}</p>')(scope);
- *   ```
- *
- * - if on the other hand, you need the element to be cloned, the view reference from the original
- *   example would not point to the clone, but rather to the original template that was cloned. In
- *   this case, you can access the clone via the cloneAttachFn:
- *   ```js
- *     var templateElement = angular.element('<p>{{total}}</p>'),
- *         scope = ....;
- *
- *     var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
- *       //attach the clone to DOM document at the right place
- *     });
- *
- *     //now we have reference to the cloned DOM via `clonedElement`
- *   ```
- *
- *
- * For information on how the compiler works, see the
- * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide.
- *
- * @knownIssue
- *
- * ### Double Compilation
- *
-   Double compilation occurs when an already compiled part of the DOM gets
-   compiled again. This is an undesired effect and can lead to misbehaving directives, performance issues,
-   and memory leaks. Refer to the Compiler Guide {@link guide/compiler#double-compilation-and-how-to-avoid-it
-   section on double compilation} for an in-depth explanation and ways to avoid it.
- *
- */
-
-var $compileMinErr = minErr('$compile');
-
-function UNINITIALIZED_VALUE() {}
-var _UNINITIALIZED_VALUE = new UNINITIALIZED_VALUE();
-
-/**
- * @ngdoc provider
- * @name $compileProvider
- *
- * @description
- */
-$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
-/** @this */
-function $CompileProvider($provide, $$sanitizeUriProvider) {
-  var hasDirectives = {},
-      Suffix = 'Directive',
-      COMMENT_DIRECTIVE_REGEXP = /^\s*directive:\s*([\w-]+)\s+(.*)$/,
-      CLASS_DIRECTIVE_REGEXP = /(([\w-]+)(?::([^;]+))?;?)/,
-      ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),
-      REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/;
-
-  // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
-  // The assumption is that future DOM event attribute names will begin with
-  // 'on' and be composed of only English letters.
-  var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
-  var bindingCache = createMap();
-
-  function parseIsolateBindings(scope, directiveName, isController) {
-    var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*([\w$]*)\s*$/;
-
-    var bindings = createMap();
-
-    forEach(scope, function(definition, scopeName) {
-      if (definition in bindingCache) {
-        bindings[scopeName] = bindingCache[definition];
-        return;
-      }
-      var match = definition.match(LOCAL_REGEXP);
-
-      if (!match) {
-        throw $compileMinErr('iscp',
-            'Invalid {3} for directive \'{0}\'.' +
-            ' Definition: {... {1}: \'{2}\' ...}',
-            directiveName, scopeName, definition,
-            (isController ? 'controller bindings definition' :
-            'isolate scope definition'));
-      }
-
-      bindings[scopeName] = {
-        mode: match[1][0],
-        collection: match[2] === '*',
-        optional: match[3] === '?',
-        attrName: match[4] || scopeName
-      };
-      if (match[4]) {
-        bindingCache[definition] = bindings[scopeName];
-      }
-    });
-
-    return bindings;
-  }
-
-  function parseDirectiveBindings(directive, directiveName) {
-    var bindings = {
-      isolateScope: null,
-      bindToController: null
-    };
-    if (isObject(directive.scope)) {
-      if (directive.bindToController === true) {
-        bindings.bindToController = parseIsolateBindings(directive.scope,
-                                                         directiveName, true);
-        bindings.isolateScope = {};
-      } else {
-        bindings.isolateScope = parseIsolateBindings(directive.scope,
-                                                     directiveName, false);
-      }
-    }
-    if (isObject(directive.bindToController)) {
-      bindings.bindToController =
-          parseIsolateBindings(directive.bindToController, directiveName, true);
-    }
-    if (bindings.bindToController && !directive.controller) {
-      // There is no controller
-      throw $compileMinErr('noctrl',
-            'Cannot bind to controller without directive \'{0}\'s controller.',
-            directiveName);
-    }
-    return bindings;
-  }
-
-  function assertValidDirectiveName(name) {
-    var letter = name.charAt(0);
-    if (!letter || letter !== lowercase(letter)) {
-      throw $compileMinErr('baddir', 'Directive/Component name \'{0}\' is invalid. The first character must be a lowercase letter', name);
-    }
-    if (name !== name.trim()) {
-      throw $compileMinErr('baddir',
-            'Directive/Component name \'{0}\' is invalid. The name should not contain leading or trailing whitespaces',
-            name);
-    }
-  }
-
-  function getDirectiveRequire(directive) {
-    var require = directive.require || (directive.controller && directive.name);
-
-    if (!isArray(require) && isObject(require)) {
-      forEach(require, function(value, key) {
-        var match = value.match(REQUIRE_PREFIX_REGEXP);
-        var name = value.substring(match[0].length);
-        if (!name) require[key] = match[0] + key;
-      });
-    }
-
-    return require;
-  }
-
-  function getDirectiveRestrict(restrict, name) {
-    if (restrict && !(isString(restrict) && /[EACM]/.test(restrict))) {
-      throw $compileMinErr('badrestrict',
-          'Restrict property \'{0}\' of directive \'{1}\' is invalid',
-          restrict,
-          name);
-    }
-
-    return restrict || 'EA';
-  }
-
-  /**
-   * @ngdoc method
-   * @name $compileProvider#directive
-   * @kind function
-   *
-   * @description
-   * Register a new directive with the compiler.
-   *
-   * @param {string|Object} name Name of the directive in camel-case (i.e. <code>ngBind</code> which
-   *    will match as <code>ng-bind</code>), or an object map of directives where the keys are the
-   *    names and the values are the factories.
-   * @param {Function|Array} directiveFactory An injectable directive factory function. See the
-   *    {@link guide/directive directive guide} and the {@link $compile compile API} for more info.
-   * @returns {ng.$compileProvider} Self for chaining.
-   */
-  this.directive = function registerDirective(name, directiveFactory) {
-    assertArg(name, 'name');
-    assertNotHasOwnProperty(name, 'directive');
-    if (isString(name)) {
-      assertValidDirectiveName(name);
-      assertArg(directiveFactory, 'directiveFactory');
-      if (!hasDirectives.hasOwnProperty(name)) {
-        hasDirectives[name] = [];
-        $provide.factory(name + Suffix, ['$injector', '$exceptionHandler',
-          function($injector, $exceptionHandler) {
-            var directives = [];
-            forEach(hasDirectives[name], function(directiveFactory, index) {
-              try {
-                var directive = $injector.invoke(directiveFactory);
-                if (isFunction(directive)) {
-                  directive = { compile: valueFn(directive) };
-                } else if (!directive.compile && directive.link) {
-                  directive.compile = valueFn(directive.link);
-                }
-                directive.priority = directive.priority || 0;
-                directive.index = index;
-                directive.name = directive.name || name;
-                directive.require = getDirectiveRequire(directive);
-                directive.restrict = getDirectiveRestrict(directive.restrict, name);
-                directive.$$moduleName = directiveFactory.$$moduleName;
-                directives.push(directive);
-              } catch (e) {
-                $exceptionHandler(e);
-              }
-            });
-            return directives;
-          }]);
-      }
-      hasDirectives[name].push(directiveFactory);
-    } else {
-      forEach(name, reverseParams(registerDirective));
-    }
-    return this;
-  };
-
-  /**
-   * @ngdoc method
-   * @name $compileProvider#component
-   * @module ng
-   * @param {string} name Name of the component in camelCase (i.e. `myComp` which will match `<my-comp>`)
-   * @param {Object} options Component definition object (a simplified
-   *    {@link ng.$compile#directive-definition-object directive definition object}),
-   *    with the following properties (all optional):
-   *
-   *    - `controller` – `{(string|function()=}` – controller constructor function that should be
-   *      associated with newly created scope or the name of a {@link ng.$compile#-controller-
-   *      registered controller} if passed as a string. An empty `noop` function by default.
-   *    - `controllerAs` – `{string=}` – identifier name for to reference the controller in the component's scope.
-   *      If present, the controller will be published to scope under the `controllerAs` name.
-   *      If not present, this will default to be `$ctrl`.
-   *    - `template` – `{string=|function()=}` – html template as a string or a function that
-   *      returns an html template as a string which should be used as the contents of this component.
-   *      Empty string by default.
-   *
-   *      If `template` is a function, then it is {@link auto.$injector#invoke injected} with
-   *      the following locals:
-   *
-   *      - `$element` - Current element
-   *      - `$attrs` - Current attributes object for the element
-   *
-   *    - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
-   *      template that should be used  as the contents of this component.
-   *
-   *      If `templateUrl` is a function, then it is {@link auto.$injector#invoke injected} with
-   *      the following locals:
-   *
-   *      - `$element` - Current element
-   *      - `$attrs` - Current attributes object for the element
-   *
-   *    - `bindings` – `{object=}` – defines bindings between DOM attributes and component properties.
-   *      Component properties are always bound to the component controller and not to the scope.
-   *      See {@link ng.$compile#-bindtocontroller- `bindToController`}.
-   *    - `transclude` – `{boolean=}` – whether {@link $compile#transclusion content transclusion} is enabled.
-   *      Disabled by default.
-   *    - `require` - `{Object<string, string>=}` - requires the controllers of other directives and binds them to
-   *      this component's controller. The object keys specify the property names under which the required
-   *      controllers (object values) will be bound. See {@link ng.$compile#-require- `require`}.
-   *    - `$...` – additional properties to attach to the directive factory function and the controller
-   *      constructor function. (This is used by the component router to annotate)
-   *
-   * @returns {ng.$compileProvider} the compile provider itself, for chaining of function calls.
-   * @description
-   * Register a **component definition** with the compiler. This is a shorthand for registering a special
-   * type of directive, which represents a self-contained UI component in your application. Such components
-   * are always isolated (i.e. `scope: {}`) and are always restricted to elements (i.e. `restrict: 'E'`).
-   *
-   * Component definitions are very simple and do not require as much configuration as defining general
-   * directives. Component definitions usually consist only of a template and a controller backing it.
-   *
-   * In order to make the definition easier, components enforce best practices like use of `controllerAs`,
-   * `bindToController`. They always have **isolate scope** and are restricted to elements.
-   *
-   * Here are a few examples of how you would usually define components:
-   *
-   * ```js
-   *   var myMod = angular.module(...);
-   *   myMod.component('myComp', {
-   *     template: '<div>My name is {{$ctrl.name}}</div>',
-   *     controller: function() {
-   *       this.name = 'shahar';
-   *     }
-   *   });
-   *
-   *   myMod.component('myComp', {
-   *     template: '<div>My name is {{$ctrl.name}}</div>',
-   *     bindings: {name: '@'}
-   *   });
-   *
-   *   myMod.component('myComp', {
-   *     templateUrl: 'views/my-comp.html',
-   *     controller: 'MyCtrl',
-   *     controllerAs: 'ctrl',
-   *     bindings: {name: '@'}
-   *   });
-   *
-   * ```
-   * For more examples, and an in-depth guide, see the {@link guide/component component guide}.
-   *
-   * <br />
-   * See also {@link ng.$compileProvider#directive $compileProvider.directive()}.
-   */
-  this.component = function registerComponent(name, options) {
-    var controller = options.controller || function() {};
-
-    function factory($injector) {
-      function makeInjectable(fn) {
-        if (isFunction(fn) || isArray(fn)) {
-          return /** @this */ function(tElement, tAttrs) {
-            return $injector.invoke(fn, this, {$element: tElement, $attrs: tAttrs});
-          };
-        } else {
-          return fn;
-        }
-      }
-
-      var template = (!options.template && !options.templateUrl ? '' : options.template);
-      var ddo = {
-        controller: controller,
-        controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
-        template: makeInjectable(template),
-        templateUrl: makeInjectable(options.templateUrl),
-        transclude: options.transclude,
-        scope: {},
-        bindToController: options.bindings || {},
-        restrict: 'E',
-        require: options.require
-      };
-
-      // Copy annotations (starting with $) over to the DDO
-      forEach(options, function(val, key) {
-        if (key.charAt(0) === '$') ddo[key] = val;
-      });
-
-      return ddo;
-    }
-
-    // TODO(pete) remove the following `forEach` before we release 1.6.0
-    // The component-router@0.2.0 looks for the annotations on the controller constructor
-    // Nothing in Angular looks for annotations on the factory function but we can't remove
-    // it from 1.5.x yet.
-
-    // Copy any annotation properties (starting with $) over to the factory and controller constructor functions
-    // These could be used by libraries such as the new component router
-    forEach(options, function(val, key) {
-      if (key.charAt(0) === '$') {
-        factory[key] = val;
-        // Don't try to copy over annotations to named controller
-        if (isFunction(controller)) controller[key] = val;
-      }
-    });
-
-    factory.$inject = ['$injector'];
-
-    return this.directive(name, factory);
-  };
-
-
-  /**
-   * @ngdoc method
-   * @name $compileProvider#aHrefSanitizationWhitelist
-   * @kind function
-   *
-   * @description
-   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
-   * urls during a[href] sanitization.
-   *
-   * The sanitization is a security measure aimed at preventing XSS attacks via html links.
-   *
-   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
-   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
-   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
-   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
-   *
-   * @param {RegExp=} regexp New regexp to whitelist urls with.
-   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
-   *    chaining otherwise.
-   */
-  this.aHrefSanitizationWhitelist = function(regexp) {
-    if (isDefined(regexp)) {
-      $$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);
-      return this;
-    } else {
-      return $$sanitizeUriProvider.aHrefSanitizationWhitelist();
-    }
-  };
-
-
-  /**
-   * @ngdoc method
-   * @name $compileProvider#imgSrcSanitizationWhitelist
-   * @kind function
-   *
-   * @description
-   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
-   * urls during img[src] sanitization.
-   *
-   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
-   *
-   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into
-   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
-   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
-   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
-   *
-   * @param {RegExp=} regexp New regexp to whitelist urls with.
-   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
-   *    chaining otherwise.
-   */
-  this.imgSrcSanitizationWhitelist = function(regexp) {
-    if (isDefined(regexp)) {
-      $$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);
-      return this;
-    } else {
-      return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();
-    }
-  };
-
-  /**
-   * @ngdoc method
-   * @name  $compileProvider#debugInfoEnabled
-   *
-   * @param {boolean=} enabled update the debugInfoEnabled state if provided, otherwise just return the
-   * current debugInfoEnabled state
-   * @returns {*} current value if used as getter or itself (chaining) if used as setter
-   *
-   * @kind function
-   *
-   * @description
-   * Call this method to enable/disable various debug runtime information in the compiler such as adding
-   * binding information and a reference to the current scope on to DOM elements.
-   * If enabled, the compiler will add the following to DOM elements that have been bound to the scope
-   * * `ng-binding` CSS class
-   * * `$binding` data property containing an array of the binding expressions
-   *
-   * You may want to disable this in production for a significant performance boost. See
-   * {@link guide/production#disabling-debug-data Disabling Debug Data} for more.
-   *
-   * The default value is true.
-   */
-  var debugInfoEnabled = true;
-  this.debugInfoEnabled = function(enabled) {
-    if (isDefined(enabled)) {
-      debugInfoEnabled = enabled;
-      return this;
-    }
-    return debugInfoEnabled;
-  };
-
-  /**
-   * @ngdoc method
-   * @name  $compileProvider#preAssignBindingsEnabled
-   *
-   * @param {boolean=} enabled update the preAssignBindingsEnabled state if provided, otherwise just return the
-   * current preAssignBindingsEnabled state
-   * @returns {*} current value if used as getter or itself (chaining) if used as setter
-   *
-   * @kind function
-   *
-   * @description
-   * Call this method to enable/disable whether directive controllers are assigned bindings before
-   * calling the controller's constructor.
-   * If enabled (true), the compiler assigns the value of each of the bindings to the
-   * properties of the controller object before the constructor of this object is called.
-   *
-   * If disabled (false), the compiler calls the constructor first before assigning bindings.
-   *
-   * The default value is true in Angular 1.5.x but will switch to false in Angular 1.6.x.
-   */
-  var preAssignBindingsEnabled = false;
-  this.preAssignBindingsEnabled = function(enabled) {
-    if (isDefined(enabled)) {
-      preAssignBindingsEnabled = enabled;
-      return this;
-    }
-    return preAssignBindingsEnabled;
-  };
-
-
-  var TTL = 10;
-  /**
-   * @ngdoc method
-   * @name $compileProvider#onChangesTtl
-   * @description
-   *
-   * Sets the number of times `$onChanges` hooks can trigger new changes before giving up and
-   * assuming that the model is unstable.
-   *
-   * The current default is 10 iterations.
-   *
-   * In complex applications it's possible that dependencies between `$onChanges` hooks and bindings will result
-   * in several iterations of calls to these hooks. However if an application needs more than the default 10
-   * iterations to stabilize then you should investigate what is causing the model to continuously change during
-   * the `$onChanges` hook execution.
-   *
-   * Increasing the TTL could have performance implications, so you should not change it without proper justification.
-   *
-   * @param {number} limit The number of `$onChanges` hook iterations.
-   * @returns {number|object} the current limit (or `this` if called as a setter for chaining)
-   */
-  this.onChangesTtl = function(value) {
-    if (arguments.length) {
-      TTL = value;
-      return this;
-    }
-    return TTL;
-  };
-
-  var commentDirectivesEnabledConfig = true;
-  /**
-   * @ngdoc method
-   * @name $compileProvider#commentDirectivesEnabled
-   * @description
-   *
-   * It indicates to the compiler
-   * whether or not directives on comments should be compiled.
-   * Defaults to `true`.
-   *
-   * Calling this function with false disables the compilation of directives
-   * on comments for the whole application.
-   * This results in a compilation performance gain,
-   * as the compiler doesn't have to check comments when looking for directives.
-   * This should however only be used if you are sure that no comment directives are used in
-   * the application (including any 3rd party directives).
-   *
-   * @param {boolean} enabled `false` if the compiler may ignore directives on comments
-   * @returns {boolean|object} the current value (or `this` if called as a setter for chaining)
-   */
-  this.commentDirectivesEnabled = function(value) {
-    if (arguments.length) {
-      commentDirectivesEnabledConfig = value;
-      return this;
-    }
-    return commentDirectivesEnabledConfig;
-  };
-
-
-  var cssClassDirectivesEnabledConfig = true;
-  /**
-   * @ngdoc method
-   * @name $compileProvider#cssClassDirectivesEnabled
-   * @description
-   *
-   * It indicates to the compiler
-   * whether or not directives on element classes should be compiled.
-   * Defaults to `true`.
-   *
-   * Calling this function with false disables the compilation of directives
-   * on element classes for the whole application.
-   * This results in a compilation performance gain,
-   * as the compiler doesn't have to check element classes when looking for directives.
-   * This should however only be used if you are sure that no class directives are used in
-   * the application (including any 3rd party directives).
-   *
-   * @param {boolean} enabled `false` if the compiler may ignore directives on element classes
-   * @returns {boolean|object} the current value (or `this` if called as a setter for chaining)
-   */
-  this.cssClassDirectivesEnabled = function(value) {
-    if (arguments.length) {
-      cssClassDirectivesEnabledConfig = value;
-      return this;
-    }
-    return cssClassDirectivesEnabledConfig;
-  };
-
-  this.$get = [
-            '$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',
-            '$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri',
-    function($injector,   $interpolate,   $exceptionHandler,   $templateRequest,   $parse,
-             $controller,   $rootScope,   $sce,   $animate,   $$sanitizeUri) {
-
-    var SIMPLE_ATTR_NAME = /^\w/;
-    var specialAttrHolder = window.document.createElement('div');
-
-
-    var commentDirectivesEnabled = commentDirectivesEnabledConfig;
-    var cssClassDirectivesEnabled = cssClassDirectivesEnabledConfig;
-
-
-    var onChangesTtl = TTL;
-    // The onChanges hooks should all be run together in a single digest
-    // When changes occur, the call to trigger their hooks will be added to this queue
-    var onChangesQueue;
-
-    // This function is called in a $$postDigest to trigger all the onChanges hooks in a single digest
-    function flushOnChangesQueue() {
-      try {
-        if (!(--onChangesTtl)) {
-          // We have hit the TTL limit so reset everything
-          onChangesQueue = undefined;
-          throw $compileMinErr('infchng', '{0} $onChanges() iterations reached. Aborting!\n', TTL);
-        }
-        // We must run this hook in an apply since the $$postDigest runs outside apply
-        $rootScope.$apply(function() {
-          var errors = [];
-          for (var i = 0, ii = onChangesQueue.length; i < ii; ++i) {
-            try {
-              onChangesQueue[i]();
-            } catch (e) {
-              errors.push(e);
-            }
-          }
-          // Reset the queue to trigger a new schedule next time there is a change
-          onChangesQueue = undefined;
-          if (errors.length) {
-            throw errors;
-          }
-        });
-      } finally {
-        onChangesTtl++;
-      }
-    }
-
-
-    function Attributes(element, attributesToCopy) {
-      if (attributesToCopy) {
-        var keys = Object.keys(attributesToCopy);
-        var i, l, key;
-
-        for (i = 0, l = keys.length; i < l; i++) {
-          key = keys[i];
-          this[key] = attributesToCopy[key];
-        }
-      } else {
-        this.$attr = {};
-      }
-
-      this.$$element = element;
-    }
-
-    Attributes.prototype = {
-      /**
-       * @ngdoc method
-       * @name $compile.directive.Attributes#$normalize
-       * @kind function
-       *
-       * @description
-       * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or
-       * `data-`) to its normalized, camelCase form.
-       *
-       * Also there is special case for Moz prefix starting with upper case letter.
-       *
-       * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}
-       *
-       * @param {string} name Name to normalize
-       */
-      $normalize: directiveNormalize,
-
-
-      /**
-       * @ngdoc method
-       * @name $compile.directive.Attributes#$addClass
-       * @kind function
-       *
-       * @description
-       * Adds the CSS class value specified by the classVal parameter to the element. If animations
-       * are enabled then an animation will be triggered for the class addition.
-       *
-       * @param {string} classVal The className value that will be added to the element
-       */
-      $addClass: function(classVal) {
-        if (classVal && classVal.length > 0) {
-          $animate.addClass(this.$$element, classVal);
-        }
-      },
-
-      /**
-       * @ngdoc method
-       * @name $compile.directive.Attributes#$removeClass
-       * @kind function
-       *
-       * @description
-       * Removes the CSS class value specified by the classVal parameter from the element. If
-       * animations are enabled then an animation will be triggered for the class removal.
-       *
-       * @param {string} classVal The className value that will be removed from the element
-       */
-      $removeClass: function(classVal) {
-        if (classVal && classVal.length > 0) {
-          $animate.removeClass(this.$$element, classVal);
-        }
-      },
-
-      /**
-       * @ngdoc method
-       * @name $compile.directive.Attributes#$updateClass
-       * @kind function
-       *
-       * @description
-       * Adds and removes the appropriate CSS class values to the element based on the difference
-       * between the new and old CSS class values (specified as newClasses and oldClasses).
-       *
-       * @param {string} newClasses The current CSS className value
-       * @param {string} oldClasses The former CSS className value
-       */
-      $updateClass: function(newClasses, oldClasses) {
-        var toAdd = tokenDifference(newClasses, oldClasses);
-        if (toAdd && toAdd.length) {
-          $animate.addClass(this.$$element, toAdd);
-        }
-
-        var toRemove = tokenDifference(oldClasses, newClasses);
-        if (toRemove && toRemove.length) {
-          $animate.removeClass(this.$$element, toRemove);
-        }
-      },
-
-      /**
-       * Set a normalized attribute on the element in a way such that all directives
-       * can share the attribute. This function properly handles boolean attributes.
-       * @param {string} key Normalized key. (ie ngAttribute)
-       * @param {string|boolean} value The value to set. If `null` attribute will be deleted.
-       * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.
-       *     Defaults to true.
-       * @param {string=} attrName Optional none normalized name. Defaults to key.
-       */
-      $set: function(key, value, writeAttr, attrName) {
-        // TODO: decide whether or not to throw an error if "class"
-        //is set through this function since it may cause $updateClass to
-        //become unstable.
-
-        var node = this.$$element[0],
-            booleanKey = getBooleanAttrName(node, key),
-            aliasedKey = getAliasedAttrName(key),
-            observer = key,
-            nodeName;
-
-        if (booleanKey) {
-          this.$$element.prop(key, value);
-          attrName = booleanKey;
-        } else if (aliasedKey) {
-          this[aliasedKey] = value;
-          observer = aliasedKey;
-        }
-
-        this[key] = value;
-
-        // translate normalized key to actual key
-        if (attrName) {
-          this.$attr[key] = attrName;
-        } else {
-          attrName = this.$attr[key];
-          if (!attrName) {
-            this.$attr[key] = attrName = snake_case(key, '-');
-          }
-        }
-
-        nodeName = nodeName_(this.$$element);
-
-        if ((nodeName === 'a' && (key === 'href' || key === 'xlinkHref')) ||
-            (nodeName === 'img' && key === 'src')) {
-          // sanitize a[href] and img[src] values
-          this[key] = value = $$sanitizeUri(value, key === 'src');
-        } else if (nodeName === 'img' && key === 'srcset' && isDefined(value)) {
-          // sanitize img[srcset] values
-          var result = '';
-
-          // first check if there are spaces because it's not the same pattern
-          var trimmedSrcset = trim(value);
-          //                (   999x   ,|   999w   ,|   ,|,   )
-          var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
-          var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;
-
-          // split srcset into tuple of uri and descriptor except for the last item
-          var rawUris = trimmedSrcset.split(pattern);
-
-          // for each tuples
-          var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
-          for (var i = 0; i < nbrUrisWith2parts; i++) {
-            var innerIdx = i * 2;
-            // sanitize the uri
-            result += $$sanitizeUri(trim(rawUris[innerIdx]), true);
-            // add the descriptor
-            result += (' ' + trim(rawUris[innerIdx + 1]));
-          }
-
-          // split the last item into uri and descriptor
-          var lastTuple = trim(rawUris[i * 2]).split(/\s/);
-
-          // sanitize the last uri
-          result += $$sanitizeUri(trim(lastTuple[0]), true);
-
-          // and add the last descriptor if any
-          if (lastTuple.length === 2) {
-            result += (' ' + trim(lastTuple[1]));
-          }
-          this[key] = value = result;
-        }
-
-        if (writeAttr !== false) {
-          if (value === null || isUndefined(value)) {
-            this.$$element.removeAttr(attrName);
-          } else {
-            if (SIMPLE_ATTR_NAME.test(attrName)) {
-              this.$$element.attr(attrName, value);
-            } else {
-              setSpecialAttr(this.$$element[0], attrName, value);
-            }
-          }
-        }
-
-        // fire observers
-        var $$observers = this.$$observers;
-        if ($$observers) {
-          forEach($$observers[observer], function(fn) {
-            try {
-              fn(value);
-            } catch (e) {
-              $exceptionHandler(e);
-            }
-          });
-        }
-      },
-
-
-      /**
-       * @ngdoc method
-       * @name $compile.directive.Attributes#$observe
-       * @kind function
-       *
-       * @description
-       * Observes an interpolated attribute.
-       *
-       * The observer function will be invoked once during the next `$digest` following
-       * compilation. The observer is then invoked whenever the interpolated value
-       * changes.
-       *
-       * @param {string} key Normalized key. (ie ngAttribute) .
-       * @param {function(interpolatedValue)} fn Function that will be called whenever
-                the interpolated value of the attribute changes.
-       *        See the {@link guide/interpolation#how-text-and-attribute-bindings-work Interpolation
-       *        guide} for more info.
-       * @returns {function()} Returns a deregistration function for this observer.
-       */
-      $observe: function(key, fn) {
-        var attrs = this,
-            $$observers = (attrs.$$observers || (attrs.$$observers = createMap())),
-            listeners = ($$observers[key] || ($$observers[key] = []));
-
-        listeners.push(fn);
-        $rootScope.$evalAsync(function() {
-          if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) {
-            // no one registered attribute interpolation function, so lets call it manually
-            fn(attrs[key]);
-          }
-        });
-
-        return function() {
-          arrayRemove(listeners, fn);
-        };
-      }
-    };
-
-    function setSpecialAttr(element, attrName, value) {
-      // Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute`
-      // so we have to jump through some hoops to get such an attribute
-      // https://github.com/angular/angular.js/pull/13318
-      specialAttrHolder.innerHTML = '<span ' + attrName + '>';
-      var attributes = specialAttrHolder.firstChild.attributes;
-      var attribute = attributes[0];
-      // We have to remove the attribute from its container element before we can add it to the destination element
-      attributes.removeNamedItem(attribute.name);
-      attribute.value = value;
-      element.attributes.setNamedItem(attribute);
-    }
-
-    function safeAddClass($element, className) {
-      try {
-        $element.addClass(className);
-      } catch (e) {
-        // ignore, since it means that we are trying to set class on
-        // SVG element, where class name is read-only.
-      }
-    }
-
-
-    var startSymbol = $interpolate.startSymbol(),
-        endSymbol = $interpolate.endSymbol(),
-        denormalizeTemplate = (startSymbol === '{{' && endSymbol  === '}}')
-            ? identity
-            : function denormalizeTemplate(template) {
-              return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
-        },
-        NG_ATTR_BINDING = /^ngAttr[A-Z]/;
-    var MULTI_ELEMENT_DIR_RE = /^(.+)Start$/;
-
-    compile.$$addBindingInfo = debugInfoEnabled ? function $$addBindingInfo($element, binding) {
-      var bindings = $element.data('$binding') || [];
-
-      if (isArray(binding)) {
-        bindings = bindings.concat(binding);
-      } else {
-        bindings.push(binding);
-      }
-
-      $element.data('$binding', bindings);
-    } : noop;
-
-    compile.$$addBindingClass = debugInfoEnabled ? function $$addBindingClass($element) {
-      safeAddClass($element, 'ng-binding');
-    } : noop;
-
-    compile.$$addScopeInfo = debugInfoEnabled ? function $$addScopeInfo($element, scope, isolated, noTemplate) {
-      var dataName = isolated ? (noTemplate ? '$isolateScopeNoTemplate' : '$isolateScope') : '$scope';
-      $element.data(dataName, scope);
-    } : noop;
-
-    compile.$$addScopeClass = debugInfoEnabled ? function $$addScopeClass($element, isolated) {
-      safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope');
-    } : noop;
-
-    compile.$$createComment = function(directiveName, comment) {
-      var content = '';
-      if (debugInfoEnabled) {
-        content = ' ' + (directiveName || '') + ': ';
-        if (comment) content += comment + ' ';
-      }
-      return window.document.createComment(content);
-    };
-
-    return compile;
-
-    //================================
-
-    function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective,
-                        previousCompileContext) {
-      if (!($compileNodes instanceof jqLite)) {
-        // jquery always rewraps, whereas we need to preserve the original selector so that we can
-        // modify it.
-        $compileNodes = jqLite($compileNodes);
-      }
-      var compositeLinkFn =
-              compileNodes($compileNodes, transcludeFn, $compileNodes,
-                           maxPriority, ignoreDirective, previousCompileContext);
-      compile.$$addScopeClass($compileNodes);
-      var namespace = null;
-      return function publicLinkFn(scope, cloneConnectFn, options) {
-        if (!$compileNodes) {
-          throw $compileMinErr('multilink', 'This element has already been linked.');
-        }
-        assertArg(scope, 'scope');
-
-        if (previousCompileContext && previousCompileContext.needsNewScope) {
-          // A parent directive did a replace and a directive on this element asked
-          // for transclusion, which caused us to lose a layer of element on which
-          // we could hold the new transclusion scope, so we will create it manually
-          // here.
-          scope = scope.$parent.$new();
-        }
-
-        options = options || {};
-        var parentBoundTranscludeFn = options.parentBoundTranscludeFn,
-          transcludeControllers = options.transcludeControllers,
-          futureParentElement = options.futureParentElement;
-
-        // When `parentBoundTranscludeFn` is passed, it is a
-        // `controllersBoundTransclude` function (it was previously passed
-        // as `transclude` to directive.link) so we must unwrap it to get
-        // its `boundTranscludeFn`
-        if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) {
-          parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude;
-        }
-
-        if (!namespace) {
-          namespace = detectNamespaceForChildElements(futureParentElement);
-        }
-        var $linkNode;
-        if (namespace !== 'html') {
-          // When using a directive with replace:true and templateUrl the $compileNodes
-          // (or a child element inside of them)
-          // might change, so we need to recreate the namespace adapted compileNodes
-          // for call to the link function.
-          // Note: This will already clone the nodes...
-          $linkNode = jqLite(
-            wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())
-          );
-        } else if (cloneConnectFn) {
-          // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
-          // and sometimes changes the structure of the DOM.
-          $linkNode = JQLitePrototype.clone.call($compileNodes);
-        } else {
-          $linkNode = $compileNodes;
-        }
-
-        if (transcludeControllers) {
-          for (var controllerName in transcludeControllers) {
-            $linkNode.data('$' + controllerName + 'Controller', transcludeControllers[controllerName].instance);
-          }
-        }
-
-        compile.$$addScopeInfo($linkNode, scope);
-
-        if (cloneConnectFn) cloneConnectFn($linkNode, scope);
-        if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);
-
-        if (!cloneConnectFn) {
-          $compileNodes = compositeLinkFn = null;
-        }
-        return $linkNode;
-      };
-    }
-
-    function detectNamespaceForChildElements(parentElement) {
-      // TODO: Make this detect MathML as well...
-      var node = parentElement && parentElement[0];
-      if (!node) {
-        return 'html';
-      } else {
-        return nodeName_(node) !== 'foreignobject' && toString.call(node).match(/SVG/) ? 'svg' : 'html';
-      }
-    }
-
-    /**
-     * Compile function matches each node in nodeList against the directives. Once all directives
-     * for a particular node are collected their compile functions are executed. The compile
-     * functions return values - the linking functions - are combined into a composite linking
-     * function, which is the a linking function for the node.
-     *
-     * @param {NodeList} nodeList an array of nodes or NodeList to compile
-     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the
-     *        scope argument is auto-generated to the new child of the transcluded parent scope.
-     * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then
-     *        the rootElement must be set the jqLite collection of the compile root. This is
-     *        needed so that the jqLite collection items can be replaced with widgets.
-     * @param {number=} maxPriority Max directive priority.
-     * @returns {Function} A composite linking function of all of the matched directives or null.
-     */
-    function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,
-                            previousCompileContext) {
-      var linkFns = [],
-          // `nodeList` can be either an element's `.childNodes` (live NodeList)
-          // or a jqLite/jQuery collection or an array
-          notLiveList = isArray(nodeList) || (nodeList instanceof jqLite),
-          attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound;
-
-
-      for (var i = 0; i < nodeList.length; i++) {
-        attrs = new Attributes();
-
-        // Support: IE 11 only
-        // Workaround for #11781 and #14924
-        if (msie === 11) {
-          mergeConsecutiveTextNodes(nodeList, i, notLiveList);
-        }
-
-        // We must always refer to `nodeList[i]` hereafter,
-        // since the nodes can be replaced underneath us.
-        directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,
-                                        ignoreDirective);
-
-        nodeLinkFn = (directives.length)
-            ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement,
-                                      null, [], [], previousCompileContext)
-            : null;
-
-        if (nodeLinkFn && nodeLinkFn.scope) {
-          compile.$$addScopeClass(attrs.$$element);
-        }
-
-        childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||
-                      !(childNodes = nodeList[i].childNodes) ||
-                      !childNodes.length)
-            ? null
-            : compileNodes(childNodes,
-                 nodeLinkFn ? (
-                  (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement)
-                     && nodeLinkFn.transclude) : transcludeFn);
-
-        if (nodeLinkFn || childLinkFn) {
-          linkFns.push(i, nodeLinkFn, childLinkFn);
-          linkFnFound = true;
-          nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;
-        }
-
-        //use the previous context only for the first element in the virtual group
-        previousCompileContext = null;
-      }
-
-      // return a linking function if we have found anything, null otherwise
-      return linkFnFound ? compositeLinkFn : null;
-
-      function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {
-        var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;
-        var stableNodeList;
-
-
-        if (nodeLinkFnFound) {
-          // copy nodeList so that if a nodeLinkFn removes or adds an element at this DOM level our
-          // offsets don't get screwed up
-          var nodeListLength = nodeList.length;
-          stableNodeList = new Array(nodeListLength);
-
-          // create a sparse array by only copying the elements which have a linkFn
-          for (i = 0; i < linkFns.length; i += 3) {
-            idx = linkFns[i];
-            stableNodeList[idx] = nodeList[idx];
-          }
-        } else {
-          stableNodeList = nodeList;
-        }
-
-        for (i = 0, ii = linkFns.length; i < ii;) {
-          node = stableNodeList[linkFns[i++]];
-          nodeLinkFn = linkFns[i++];
-          childLinkFn = linkFns[i++];
-
-          if (nodeLinkFn) {
-            if (nodeLinkFn.scope) {
-              childScope = scope.$new();
-              compile.$$addScopeInfo(jqLite(node), childScope);
-            } else {
-              childScope = scope;
-            }
-
-            if (nodeLinkFn.transcludeOnThisElement) {
-              childBoundTranscludeFn = createBoundTranscludeFn(
-                  scope, nodeLinkFn.transclude, parentBoundTranscludeFn);
-
-            } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {
-              childBoundTranscludeFn = parentBoundTranscludeFn;
-
-            } else if (!parentBoundTranscludeFn && transcludeFn) {
-              childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);
-
-            } else {
-              childBoundTranscludeFn = null;
-            }
-
-            nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);
-
-          } else if (childLinkFn) {
-            childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);
-          }
-        }
-      }
-    }
-
-    function mergeConsecutiveTextNodes(nodeList, idx, notLiveList) {
-      var node = nodeList[idx];
-      var parent = node.parentNode;
-      var sibling;
-
-      if (node.nodeType !== NODE_TYPE_TEXT) {
-        return;
-      }
-
-      while (true) {
-        sibling = parent ? node.nextSibling : nodeList[idx + 1];
-        if (!sibling || sibling.nodeType !== NODE_TYPE_TEXT) {
-          break;
-        }
-
-        node.nodeValue = node.nodeValue + sibling.nodeValue;
-
-        if (sibling.parentNode) {
-          sibling.parentNode.removeChild(sibling);
-        }
-        if (notLiveList && sibling === nodeList[idx + 1]) {
-          nodeList.splice(idx + 1, 1);
-        }
-      }
-    }
-
-    function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
-      function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
-
-        if (!transcludedScope) {
-          transcludedScope = scope.$new(false, containingScope);
-          transcludedScope.$$transcluded = true;
-        }
-
-        return transcludeFn(transcludedScope, cloneFn, {
-          parentBoundTranscludeFn: previousBoundTranscludeFn,
-          transcludeControllers: controllers,
-          futureParentElement: futureParentElement
-        });
-      }
-
-      // We need  to attach the transclusion slots onto the `boundTranscludeFn`
-      // so that they are available inside the `controllersBoundTransclude` function
-      var boundSlots = boundTranscludeFn.$$slots = createMap();
-      for (var slotName in transcludeFn.$$slots) {
-        if (transcludeFn.$$slots[slotName]) {
-          boundSlots[slotName] = createBoundTranscludeFn(scope, transcludeFn.$$slots[slotName], previousBoundTranscludeFn);
-        } else {
-          boundSlots[slotName] = null;
-        }
-      }
-
-      return boundTranscludeFn;
-    }
-
-    /**
-     * Looks for directives on the given node and adds them to the directive collection which is
-     * sorted.
-     *
-     * @param node Node to search.
-     * @param directives An array to which the directives are added to. This array is sorted before
-     *        the function returns.
-     * @param attrs The shared attrs object which is used to populate the normalized attributes.
-     * @param {number=} maxPriority Max directive priority.
-     */
-    function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
-      var nodeType = node.nodeType,
-          attrsMap = attrs.$attr,
-          match,
-          nodeName,
-          className;
-
-      switch (nodeType) {
-        case NODE_TYPE_ELEMENT: /* Element */
-
-          nodeName = nodeName_(node);
-
-          // use the node name: <directive>
-          addDirective(directives,
-              directiveNormalize(nodeName), 'E', maxPriority, ignoreDirective);
-
-          // iterate over the attributes
-          for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,
-                   j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
-            var attrStartName = false;
-            var attrEndName = false;
-
-            attr = nAttrs[j];
-            name = attr.name;
-            value = attr.value;
-
-            // support ngAttr attribute binding
-            ngAttrName = directiveNormalize(name);
-            isNgAttr = NG_ATTR_BINDING.test(ngAttrName);
-            if (isNgAttr) {
-              name = name.replace(PREFIX_REGEXP, '')
-                .substr(8).replace(/_(.)/g, function(match, letter) {
-                  return letter.toUpperCase();
-                });
-            }
-
-            var multiElementMatch = ngAttrName.match(MULTI_ELEMENT_DIR_RE);
-            if (multiElementMatch && directiveIsMultiElement(multiElementMatch[1])) {
-              attrStartName = name;
-              attrEndName = name.substr(0, name.length - 5) + 'end';
-              name = name.substr(0, name.length - 6);
-            }
-
-            nName = directiveNormalize(name.toLowerCase());
-            attrsMap[nName] = name;
-            if (isNgAttr || !attrs.hasOwnProperty(nName)) {
-                attrs[nName] = value;
-                if (getBooleanAttrName(node, nName)) {
-                  attrs[nName] = true; // presence means true
-                }
-            }
-            addAttrInterpolateDirective(node, directives, value, nName, isNgAttr);
-            addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,
-                          attrEndName);
-          }
-
-          if (nodeName === 'input' && node.getAttribute('type') === 'hidden') {
-            // Hidden input elements can have strange behaviour when navigating back to the page
-            // This tells the browser not to try to cache and reinstate previous values
-            node.setAttribute('autocomplete', 'off');
-          }
-
-          // use class as directive
-          if (!cssClassDirectivesEnabled) break;
-          className = node.className;
-          if (isObject(className)) {
-              // Maybe SVGAnimatedString
-              className = className.animVal;
-          }
-          if (isString(className) && className !== '') {
-            while ((match = CLASS_DIRECTIVE_REGEXP.exec(className))) {
-              nName = directiveNormalize(match[2]);
-              if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) {
-                attrs[nName] = trim(match[3]);
-              }
-              className = className.substr(match.index + match[0].length);
-            }
-          }
-          break;
-        case NODE_TYPE_TEXT: /* Text Node */
-          addTextInterpolateDirective(directives, node.nodeValue);
-          break;
-        case NODE_TYPE_COMMENT: /* Comment */
-          if (!commentDirectivesEnabled) break;
-          collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective);
-          break;
-      }
-
-      directives.sort(byPriority);
-      return directives;
-    }
-
-    function collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
-      // function created because of performance, try/catch disables
-      // the optimization of the whole function #14848
-      try {
-        var match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);
-        if (match) {
-          var nName = directiveNormalize(match[1]);
-          if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) {
-            attrs[nName] = trim(match[2]);
-          }
-        }
-      } catch (e) {
-        // turns out that under some circumstances IE9 throws errors when one attempts to read
-        // comment's node value.
-        // Just ignore it and continue. (Can't seem to reproduce in test case.)
-      }
-    }
-
-    /**
-     * Given a node with a directive-start it collects all of the siblings until it finds
-     * directive-end.
-     * @param node
-     * @param attrStart
-     * @param attrEnd
-     * @returns {*}
-     */
-    function groupScan(node, attrStart, attrEnd) {
-      var nodes = [];
-      var depth = 0;
-      if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {
-        do {
-          if (!node) {
-            throw $compileMinErr('uterdir',
-                      'Unterminated attribute, found \'{0}\' but no matching \'{1}\' found.',
-                      attrStart, attrEnd);
-          }
-          if (node.nodeType === NODE_TYPE_ELEMENT) {
-            if (node.hasAttribute(attrStart)) depth++;
-            if (node.hasAttribute(attrEnd)) depth--;
-          }
-          nodes.push(node);
-          node = node.nextSibling;
-        } while (depth > 0);
-      } else {
-        nodes.push(node);
-      }
-
-      return jqLite(nodes);
-    }
-
-    /**
-     * Wrapper for linking function which converts normal linking function into a grouped
-     * linking function.
-     * @param linkFn
-     * @param attrStart
-     * @param attrEnd
-     * @returns {Function}
-     */
-    function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
-      return function groupedElementsLink(scope, element, attrs, controllers, transcludeFn) {
-        element = groupScan(element[0], attrStart, attrEnd);
-        return linkFn(scope, element, attrs, controllers, transcludeFn);
-      };
-    }
-
-    /**
-     * A function generator that is used to support both eager and lazy compilation
-     * linking function.
-     * @param eager
-     * @param $compileNodes
-     * @param transcludeFn
-     * @param maxPriority
-     * @param ignoreDirective
-     * @param previousCompileContext
-     * @returns {Function}
-     */
-    function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {
-      var compiled;
-
-      if (eager) {
-        return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
-      }
-      return /** @this */ function lazyCompilation() {
-        if (!compiled) {
-          compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
-
-          // Null out all of these references in order to make them eligible for garbage collection
-          // since this is a potentially long lived closure
-          $compileNodes = transcludeFn = previousCompileContext = null;
-        }
-        return compiled.apply(this, arguments);
-      };
-    }
-
-    /**
-     * Once the directives have been collected, their compile functions are executed. This method
-     * is responsible for inlining directive templates as well as terminating the application
-     * of the directives if the terminal directive has been reached.
-     *
-     * @param {Array} directives Array of collected directives to execute their compile function.
-     *        this needs to be pre-sorted by priority order.
-     * @param {Node} compileNode The raw DOM node to apply the compile functions to
-     * @param {Object} templateAttrs The shared attribute function
-     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the
-     *                                                  scope argument is auto-generated to the new
-     *                                                  child of the transcluded parent scope.
-     * @param {JQLite} jqCollection If we are working on the root of the compile tree then this
-     *                              argument has the root jqLite array so that we can replace nodes
-     *                              on it.
-     * @param {Object=} originalReplaceDirective An optional directive that will be ignored when
-     *                                           compiling the transclusion.
-     * @param {Array.<Function>} preLinkFns
-     * @param {Array.<Function>} postLinkFns
-     * @param {Object} previousCompileContext Context used for previous compilation of the current
-     *                                        node
-     * @returns {Function} linkFn
-     */
-    function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,
-                                   jqCollection, originalReplaceDirective, preLinkFns, postLinkFns,
-                                   previousCompileContext) {
-      previousCompileContext = previousCompileContext || {};
-
-      var terminalPriority = -Number.MAX_VALUE,
-          newScopeDirective = previousCompileContext.newScopeDirective,
-          controllerDirectives = previousCompileContext.controllerDirectives,
-          newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
-          templateDirective = previousCompileContext.templateDirective,
-          nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
-          hasTranscludeDirective = false,
-          hasTemplate = false,
-          hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,
-          $compileNode = templateAttrs.$$element = jqLite(compileNode),
-          directive,
-          directiveName,
-          $template,
-          replaceDirective = originalReplaceDirective,
-          childTranscludeFn = transcludeFn,
-          linkFn,
-          didScanForMultipleTransclusion = false,
-          mightHaveMultipleTransclusionError = false,
-          directiveValue;
-
-      // executes all directives on the current element
-      for (var i = 0, ii = directives.length; i < ii; i++) {
-        directive = directives[i];
-        var attrStart = directive.$$start;
-        var attrEnd = directive.$$end;
-
-        // collect multiblock sections
-        if (attrStart) {
-          $compileNode = groupScan(compileNode, attrStart, attrEnd);
-        }
-        $template = undefined;
-
-        if (terminalPriority > directive.priority) {
-          break; // prevent further processing of directives
-        }
-
-        directiveValue = directive.scope;
-
-        if (directiveValue) {
-
-          // skip the check for directives with async templates, we'll check the derived sync
-          // directive when the template arrives
-          if (!directive.templateUrl) {
-            if (isObject(directiveValue)) {
-              // This directive is trying to add an isolated scope.
-              // Check that there is no scope of any kind already
-              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective,
-                                directive, $compileNode);
-              newIsolateScopeDirective = directive;
-            } else {
-              // This directive is trying to add a child scope.
-              // Check that there is no isolated scope already
-              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive,
-                                $compileNode);
-            }
-          }
-
-          newScopeDirective = newScopeDirective || directive;
-        }
-
-        directiveName = directive.name;
-
-        // If we encounter a condition that can result in transclusion on the directive,
-        // then scan ahead in the remaining directives for others that may cause a multiple
-        // transclusion error to be thrown during the compilation process.  If a matching directive
-        // is found, then we know that when we encounter a transcluded directive, we need to eagerly
-        // compile the `transclude` function rather than doing it lazily in order to throw
-        // exceptions at the correct time
-        if (!didScanForMultipleTransclusion && ((directive.replace && (directive.templateUrl || directive.template))
-            || (directive.transclude && !directive.$$tlb))) {
-                var candidateDirective;
-
-                for (var scanningIndex = i + 1; (candidateDirective = directives[scanningIndex++]);) {
-                    if ((candidateDirective.transclude && !candidateDirective.$$tlb)
-                        || (candidateDirective.replace && (candidateDirective.templateUrl || candidateDirective.template))) {
-                        mightHaveMultipleTransclusionError = true;
-                        break;
-                    }
-                }
-
-                didScanForMultipleTransclusion = true;
-        }
-
-        if (!directive.templateUrl && directive.controller) {
-          controllerDirectives = controllerDirectives || createMap();
-          assertNoDuplicate('\'' + directiveName + '\' controller',
-              controllerDirectives[directiveName], directive, $compileNode);
-          controllerDirectives[directiveName] = directive;
-        }
-
-        directiveValue = directive.transclude;
-
-        if (directiveValue) {
-          hasTranscludeDirective = true;
-
-          // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
-          // This option should only be used by directives that know how to safely handle element transclusion,
-          // where the transcluded nodes are added or replaced after linking.
-          if (!directive.$$tlb) {
-            assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
-            nonTlbTranscludeDirective = directive;
-          }
-
-          if (directiveValue === 'element') {
-            hasElementTranscludeDirective = true;
-            terminalPriority = directive.priority;
-            $template = $compileNode;
-            $compileNode = templateAttrs.$$element =
-                jqLite(compile.$$createComment(directiveName, templateAttrs[directiveName]));
-            compileNode = $compileNode[0];
-            replaceWith(jqCollection, sliceArgs($template), compileNode);
-
-            // Support: Chrome < 50
-            // https://github.com/angular/angular.js/issues/14041
-
-            // In the versions of V8 prior to Chrome 50, the document fragment that is created
-            // in the `replaceWith` function is improperly garbage collected despite still
-            // being referenced by the `parentNode` property of all of the child nodes.  By adding
-            // a reference to the fragment via a different property, we can avoid that incorrect
-            // behavior.
-            // TODO: remove this line after Chrome 50 has been released
-            $template[0].$$parentNode = $template[0].parentNode;
-
-            childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority,
-                                        replaceDirective && replaceDirective.name, {
-                                          // Don't pass in:
-                                          // - controllerDirectives - otherwise we'll create duplicates controllers
-                                          // - newIsolateScopeDirective or templateDirective - combining templates with
-                                          //   element transclusion doesn't make sense.
-                                          //
-                                          // We need only nonTlbTranscludeDirective so that we prevent putting transclusion
-                                          // on the same element more than once.
-                                          nonTlbTranscludeDirective: nonTlbTranscludeDirective
-                                        });
-          } else {
-
-            var slots = createMap();
-
-            if (!isObject(directiveValue)) {
-              $template = jqLite(jqLiteClone(compileNode)).contents();
-            } else {
-
-              // We have transclusion slots,
-              // collect them up, compile them and store their transclusion functions
-              $template = [];
-
-              var slotMap = createMap();
-              var filledSlots = createMap();
-
-              // Parse the element selectors
-              forEach(directiveValue, function(elementSelector, slotName) {
-                // If an element selector starts with a ? then it is optional
-                var optional = (elementSelector.charAt(0) === '?');
-                elementSelector = optional ? elementSelector.substring(1) : elementSelector;
-
-                slotMap[elementSelector] = slotName;
-
-                // We explicitly assign `null` since this implies that a slot was defined but not filled.
-                // Later when calling boundTransclusion functions with a slot name we only error if the
-                // slot is `undefined`
-                slots[slotName] = null;
-
-                // filledSlots contains `true` for all slots that are either optional or have been
-                // filled. This is used to check that we have not missed any required slots
-                filledSlots[slotName] = optional;
-              });
-
-              // Add the matching elements into their slot
-              forEach($compileNode.contents(), function(node) {
-                var slotName = slotMap[directiveNormalize(nodeName_(node))];
-                if (slotName) {
-                  filledSlots[slotName] = true;
-                  slots[slotName] = slots[slotName] || [];
-                  slots[slotName].push(node);
-                } else {
-                  $template.push(node);
-                }
-              });
-
-              // Check for required slots that were not filled
-              forEach(filledSlots, function(filled, slotName) {
-                if (!filled) {
-                  throw $compileMinErr('reqslot', 'Required transclusion slot `{0}` was not filled.', slotName);
-                }
-              });
-
-              for (var slotName in slots) {
-                if (slots[slotName]) {
-                  // Only define a transclusion function if the slot was filled
-                  slots[slotName] = compilationGenerator(mightHaveMultipleTransclusionError, slots[slotName], transcludeFn);
-                }
-              }
-            }
-
-            $compileNode.empty(); // clear contents
-            childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, undefined,
-                undefined, { needsNewScope: directive.$$isolateScope || directive.$$newScope});
-            childTranscludeFn.$$slots = slots;
-          }
-        }
-
-        if (directive.template) {
-          hasTemplate = true;
-          assertNoDuplicate('template', templateDirective, directive, $compileNode);
-          templateDirective = directive;
-
-          directiveValue = (isFunction(directive.template))
-              ? directive.template($compileNode, templateAttrs)
-              : directive.template;
-
-          directiveValue = denormalizeTemplate(directiveValue);
-
-          if (directive.replace) {
-            replaceDirective = directive;
-            if (jqLiteIsTextNode(directiveValue)) {
-              $template = [];
-            } else {
-              $template = removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue)));
-            }
-            compileNode = $template[0];
-
-            if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
-              throw $compileMinErr('tplrt',
-                  'Template for directive \'{0}\' must have exactly one root element. {1}',
-                  directiveName, '');
-            }
-
-            replaceWith(jqCollection, $compileNode, compileNode);
-
-            var newTemplateAttrs = {$attr: {}};
-
-            // combine directives from the original node and from the template:
-            // - take the array of directives for this element
-            // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)
-            // - collect directives from the template and sort them by priority
-            // - combine directives as: processed + template + unprocessed
-            var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs);
-            var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));
-
-            if (newIsolateScopeDirective || newScopeDirective) {
-              // The original directive caused the current element to be replaced but this element
-              // also needs to have a new scope, so we need to tell the template directives
-              // that they would need to get their scope from further up, if they require transclusion
-              markDirectiveScope(templateDirectives, newIsolateScopeDirective, newScopeDirective);
-            }
-            directives = directives.concat(templateDirectives).concat(unprocessedDirectives);
-            mergeTemplateAttributes(templateAttrs, newTemplateAttrs);
-
-            ii = directives.length;
-          } else {
-            $compileNode.html(directiveValue);
-          }
-        }
-
-        if (directive.templateUrl) {
-          hasTemplate = true;
-          assertNoDuplicate('template', templateDirective, directive, $compileNode);
-          templateDirective = directive;
-
-          if (directive.replace) {
-            replaceDirective = directive;
-          }
-
-          // eslint-disable-next-line no-func-assign
-          nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
-              templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {
-                controllerDirectives: controllerDirectives,
-                newScopeDirective: (newScopeDirective !== directive) && newScopeDirective,
-                newIsolateScopeDirective: newIsolateScopeDirective,
-                templateDirective: templateDirective,
-                nonTlbTranscludeDirective: nonTlbTranscludeDirective
-              });
-          ii = directives.length;
-        } else if (directive.compile) {
-          try {
-            linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);
-            var context = directive.$$originalDirective || directive;
-            if (isFunction(linkFn)) {
-              addLinkFns(null, bind(context, linkFn), attrStart, attrEnd);
-            } else if (linkFn) {
-              addLinkFns(bind(context, linkFn.pre), bind(context, linkFn.post), attrStart, attrEnd);
-            }
-          } catch (e) {
-            $exceptionHandler(e, startingTag($compileNode));
-          }
-        }
-
-        if (directive.terminal) {
-          nodeLinkFn.terminal = true;
-          terminalPriority = Math.max(terminalPriority, directive.priority);
-        }
-
-      }
-
-      nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
-      nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
-      nodeLinkFn.templateOnThisElement = hasTemplate;
-      nodeLinkFn.transclude = childTranscludeFn;
-
-      previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;
-
-      // might be normal or delayed nodeLinkFn depending on if templateUrl is present
-      return nodeLinkFn;
-
-      ////////////////////
-
-      function addLinkFns(pre, post, attrStart, attrEnd) {
-        if (pre) {
-          if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
-          pre.require = directive.require;
-          pre.directiveName = directiveName;
-          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
-            pre = cloneAndAnnotateFn(pre, {isolateScope: true});
-          }
-          preLinkFns.push(pre);
-        }
-        if (post) {
-          if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
-          post.require = directive.require;
-          post.directiveName = directiveName;
-          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
-            post = cloneAndAnnotateFn(post, {isolateScope: true});
-          }
-          postLinkFns.push(post);
-        }
-      }
-
-      function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
-        var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,
-            attrs, scopeBindingInfo;
-
-        if (compileNode === linkNode) {
-          attrs = templateAttrs;
-          $element = templateAttrs.$$element;
-        } else {
-          $element = jqLite(linkNode);
-          attrs = new Attributes($element, templateAttrs);
-        }
-
-        controllerScope = scope;
-        if (newIsolateScopeDirective) {
-          isolateScope = scope.$new(true);
-        } else if (newScopeDirective) {
-          controllerScope = scope.$parent;
-        }
-
-        if (boundTranscludeFn) {
-          // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`
-          // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
-          transcludeFn = controllersBoundTransclude;
-          transcludeFn.$$boundTransclude = boundTranscludeFn;
-          // expose the slots on the `$transclude` function
-          transcludeFn.isSlotFilled = function(slotName) {
-            return !!boundTranscludeFn.$$slots[slotName];
-          };
-        }
-
-        if (controllerDirectives) {
-          elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective);
-        }
-
-        if (newIsolateScopeDirective) {
-          // Initialize isolate scope bindings for new isolate scope directive.
-          compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||
-              templateDirective === newIsolateScopeDirective.$$originalDirective)));
-          compile.$$addScopeClass($element, true);
-          isolateScope.$$isolateBindings =
-              newIsolateScopeDirective.$$isolateBindings;
-          scopeBindingInfo = initializeDirectiveBindings(scope, attrs, isolateScope,
-                                        isolateScope.$$isolateBindings,
-                                        newIsolateScopeDirective);
-          if (scopeBindingInfo.removeWatches) {
-            isolateScope.$on('$destroy', scopeBindingInfo.removeWatches);
-          }
-        }
-
-        // Initialize bindToController bindings
-        for (var name in elementControllers) {
-          var controllerDirective = controllerDirectives[name];
-          var controller = elementControllers[name];
-          var bindings = controllerDirective.$$bindings.bindToController;
-
-          if (preAssignBindingsEnabled) {
-            if (bindings) {
-              controller.bindingInfo =
-                initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
-            } else {
-              controller.bindingInfo = {};
-            }
-
-            var controllerResult = controller();
-            if (controllerResult !== controller.instance) {
-              // If the controller constructor has a return value, overwrite the instance
-              // from setupControllers
-              controller.instance = controllerResult;
-              $element.data('$' + controllerDirective.name + 'Controller', controllerResult);
-              if (controller.bindingInfo.removeWatches) {
-                controller.bindingInfo.removeWatches();
-              }
-              controller.bindingInfo =
-                initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
-            }
-          } else {
-            controller.instance = controller();
-            $element.data('$' + controllerDirective.name + 'Controller', controller.instance);
-            controller.bindingInfo =
-              initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
-          }
-        }
-
-        // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
-        forEach(controllerDirectives, function(controllerDirective, name) {
-          var require = controllerDirective.require;
-          if (controllerDirective.bindToController && !isArray(require) && isObject(require)) {
-            extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers));
-          }
-        });
-
-        // Handle the init and destroy lifecycle hooks on all controllers that have them
-        forEach(elementControllers, function(controller) {
-          var controllerInstance = controller.instance;
-          if (isFunction(controllerInstance.$onChanges)) {
-            try {
-              controllerInstance.$onChanges(controller.bindingInfo.initialChanges);
-            } catch (e) {
-              $exceptionHandler(e);
-            }
-          }
-          if (isFunction(controllerInstance.$onInit)) {
-            try {
-              controllerInstance.$onInit();
-            } catch (e) {
-              $exceptionHandler(e);
-            }
-          }
-          if (isFunction(controllerInstance.$doCheck)) {
-            controllerScope.$watch(function() { controllerInstance.$doCheck(); });
-            controllerInstance.$doCheck();
-          }
-          if (isFunction(controllerInstance.$onDestroy)) {
-            controllerScope.$on('$destroy', function callOnDestroyHook() {
-              controllerInstance.$onDestroy();
-            });
-          }
-        });
-
-        // PRELINKING
-        for (i = 0, ii = preLinkFns.length; i < ii; i++) {
-          linkFn = preLinkFns[i];
-          invokeLinkFn(linkFn,
-              linkFn.isolateScope ? isolateScope : scope,
-              $element,
-              attrs,
-              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),
-              transcludeFn
-          );
-        }
-
-        // RECURSION
-        // We only pass the isolate scope, if the isolate directive has a template,
-        // otherwise the child elements do not belong to the isolate directive.
-        var scopeToChild = scope;
-        if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {
-          scopeToChild = isolateScope;
-        }
-        if (childLinkFn) {
-          childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);
-        }
-
-        // POSTLINKING
-        for (i = postLinkFns.length - 1; i >= 0; i--) {
-          linkFn = postLinkFns[i];
-          invokeLinkFn(linkFn,
-              linkFn.isolateScope ? isolateScope : scope,
-              $element,
-              attrs,
-              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),
-              transcludeFn
-          );
-        }
-
-        // Trigger $postLink lifecycle hooks
-        forEach(elementControllers, function(controller) {
-          var controllerInstance = controller.instance;
-          if (isFunction(controllerInstance.$postLink)) {
-            controllerInstance.$postLink();
-          }
-        });
-
-        // This is the function that is injected as `$transclude`.
-        // Note: all arguments are optional!
-        function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {
-          var transcludeControllers;
-          // No scope passed in:
-          if (!isScope(scope)) {
-            slotName = futureParentElement;
-            futureParentElement = cloneAttachFn;
-            cloneAttachFn = scope;
-            scope = undefined;
-          }
-
-          if (hasElementTranscludeDirective) {
-            transcludeControllers = elementControllers;
-          }
-          if (!futureParentElement) {
-            futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;
-          }
-          if (slotName) {
-            // slotTranscludeFn can be one of three things:
-            //  * a transclude function - a filled slot
-            //  * `null` - an optional slot that was not filled
-            //  * `undefined` - a slot that was not declared (i.e. invalid)
-            var slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
-            if (slotTranscludeFn) {
-              return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
-            } else if (isUndefined(slotTranscludeFn)) {
-              throw $compileMinErr('noslot',
-               'No parent directive that requires a transclusion with slot name "{0}". ' +
-               'Element: {1}',
-               slotName, startingTag($element));
-            }
-          } else {
-            return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
-          }
-        }
-      }
-    }
-
-    function getControllers(directiveName, require, $element, elementControllers) {
-      var value;
-
-      if (isString(require)) {
-        var match = require.match(REQUIRE_PREFIX_REGEXP);
-        var name = require.substring(match[0].length);
-        var inheritType = match[1] || match[3];
-        var optional = match[2] === '?';
-
-        //If only parents then start at the parent element
-        if (inheritType === '^^') {
-          $element = $element.parent();
-        //Otherwise attempt getting the controller from elementControllers in case
-        //the element is transcluded (and has no data) and to avoid .data if possible
-        } else {
-          value = elementControllers && elementControllers[name];
-          value = value && value.instance;
-        }
-
-        if (!value) {
-          var dataName = '$' + name + 'Controller';
-          value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
-        }
-
-        if (!value && !optional) {
-          throw $compileMinErr('ctreq',
-              'Controller \'{0}\', required by directive \'{1}\', can\'t be found!',
-              name, directiveName);
-        }
-      } else if (isArray(require)) {
-        value = [];
-        for (var i = 0, ii = require.length; i < ii; i++) {
-          value[i] = getControllers(directiveName, require[i], $element, elementControllers);
-        }
-      } else if (isObject(require)) {
-        value = {};
-        forEach(require, function(controller, property) {
-          value[property] = getControllers(directiveName, controller, $element, elementControllers);
-        });
-      }
-
-      return value || null;
-    }
-
-    function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective) {
-      var elementControllers = createMap();
-      for (var controllerKey in controllerDirectives) {
-        var directive = controllerDirectives[controllerKey];
-        var locals = {
-          $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
-          $element: $element,
-          $attrs: attrs,
-          $transclude: transcludeFn
-        };
-
-        var controller = directive.controller;
-        if (controller === '@') {
-          controller = attrs[directive.name];
-        }
-
-        var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
-
-        // For directives with element transclusion the element is a comment.
-        // In this case .data will not attach any data.
-        // Instead, we save the controllers for the element in a local hash and attach to .data
-        // later, once we have the actual element.
-        elementControllers[directive.name] = controllerInstance;
-        $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
-      }
-      return elementControllers;
-    }
-
-    // Depending upon the context in which a directive finds itself it might need to have a new isolated
-    // or child scope created. For instance:
-    // * if the directive has been pulled into a template because another directive with a higher priority
-    // asked for element transclusion
-    // * if the directive itself asks for transclusion but it is at the root of a template and the original
-    // element was replaced. See https://github.com/angular/angular.js/issues/12936
-    function markDirectiveScope(directives, isolateScope, newScope) {
-      for (var j = 0, jj = directives.length; j < jj; j++) {
-        directives[j] = inherit(directives[j], {$$isolateScope: isolateScope, $$newScope: newScope});
-      }
-    }
-
-    /**
-     * looks up the directive and decorates it with exception handling and proper parameters. We
-     * call this the boundDirective.
-     *
-     * @param {string} name name of the directive to look up.
-     * @param {string} location The directive must be found in specific format.
-     *   String containing any of theses characters:
-     *
-     *   * `E`: element name
-     *   * `A': attribute
-     *   * `C`: class
-     *   * `M`: comment
-     * @returns {boolean} true if directive was added.
-     */
-    function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName,
-                          endAttrName) {
-      if (name === ignoreDirective) return null;
-      var match = null;
-      if (hasDirectives.hasOwnProperty(name)) {
-        for (var directive, directives = $injector.get(name + Suffix),
-            i = 0, ii = directives.length; i < ii; i++) {
-          directive = directives[i];
-          if ((isUndefined(maxPriority) || maxPriority > directive.priority) &&
-               directive.restrict.indexOf(location) !== -1) {
-            if (startAttrName) {
-              directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
-            }
-            if (!directive.$$bindings) {
-              var bindings = directive.$$bindings =
-                  parseDirectiveBindings(directive, directive.name);
-              if (isObject(bindings.isolateScope)) {
-                directive.$$isolateBindings = bindings.isolateScope;
-              }
-            }
-            tDirectives.push(directive);
-            match = directive;
-          }
-        }
-      }
-      return match;
-    }
-
-
-    /**
-     * looks up the directive and returns true if it is a multi-element directive,
-     * and therefore requires DOM nodes between -start and -end markers to be grouped
-     * together.
-     *
-     * @param {string} name name of the directive to look up.
-     * @returns true if directive was registered as multi-element.
-     */
-    function directiveIsMultiElement(name) {
-      if (hasDirectives.hasOwnProperty(name)) {
-        for (var directive, directives = $injector.get(name + Suffix),
-            i = 0, ii = directives.length; i < ii; i++) {
-          directive = directives[i];
-          if (directive.multiElement) {
-            return true;
-          }
-        }
-      }
-      return false;
-    }
-
-    /**
-     * When the element is replaced with HTML template then the new attributes
-     * on the template need to be merged with the existing attributes in the DOM.
-     * The desired effect is to have both of the attributes present.
-     *
-     * @param {object} dst destination attributes (original DOM)
-     * @param {object} src source attributes (from the directive template)
-     */
-    function mergeTemplateAttributes(dst, src) {
-      var srcAttr = src.$attr,
-          dstAttr = dst.$attr;
-
-      // reapply the old attributes to the new element
-      forEach(dst, function(value, key) {
-        if (key.charAt(0) !== '$') {
-          if (src[key] && src[key] !== value) {
-            if (value.length) {
-              value += (key === 'style' ? ';' : ' ') + src[key];
-            } else {
-              value = src[key];
-            }
-          }
-          dst.$set(key, value, true, srcAttr[key]);
-        }
-      });
-
-      // copy the new attributes on the old attrs object
-      forEach(src, function(value, key) {
-        // Check if we already set this attribute in the loop above.
-        // `dst` will never contain hasOwnProperty as DOM parser won't let it.
-        // You will get an "InvalidCharacterError: DOM Exception 5" error if you
-        // have an attribute like "has-own-property" or "data-has-own-property", etc.
-        if (!dst.hasOwnProperty(key) && key.charAt(0) !== '$') {
-          dst[key] = value;
-
-          if (key !== 'class' && key !== 'style') {
-            dstAttr[key] = srcAttr[key];
-          }
-        }
-      });
-    }
-
-
-    function compileTemplateUrl(directives, $compileNode, tAttrs,
-        $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {
-      var linkQueue = [],
-          afterTemplateNodeLinkFn,
-          afterTemplateChildLinkFn,
-          beforeTemplateCompileNode = $compileNode[0],
-          origAsyncDirective = directives.shift(),
-          derivedSyncDirective = inherit(origAsyncDirective, {
-            templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective
-          }),
-          templateUrl = (isFunction(origAsyncDirective.templateUrl))
-              ? origAsyncDirective.templateUrl($compileNode, tAttrs)
-              : origAsyncDirective.templateUrl,
-          templateNamespace = origAsyncDirective.templateNamespace;
-
-      $compileNode.empty();
-
-      $templateRequest(templateUrl)
-        .then(function(content) {
-          var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;
-
-          content = denormalizeTemplate(content);
-
-          if (origAsyncDirective.replace) {
-            if (jqLiteIsTextNode(content)) {
-              $template = [];
-            } else {
-              $template = removeComments(wrapTemplate(templateNamespace, trim(content)));
-            }
-            compileNode = $template[0];
-
-            if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
-              throw $compileMinErr('tplrt',
-                  'Template for directive \'{0}\' must have exactly one root element. {1}',
-                  origAsyncDirective.name, templateUrl);
-            }
-
-            tempTemplateAttrs = {$attr: {}};
-            replaceWith($rootElement, $compileNode, compileNode);
-            var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs);
-
-            if (isObject(origAsyncDirective.scope)) {
-              // the original directive that caused the template to be loaded async required
-              // an isolate scope
-              markDirectiveScope(templateDirectives, true);
-            }
-            directives = templateDirectives.concat(directives);
-            mergeTemplateAttributes(tAttrs, tempTemplateAttrs);
-          } else {
-            compileNode = beforeTemplateCompileNode;
-            $compileNode.html(content);
-          }
-
-          directives.unshift(derivedSyncDirective);
-
-          afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs,
-              childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns,
-              previousCompileContext);
-          forEach($rootElement, function(node, i) {
-            if (node === compileNode) {
-              $rootElement[i] = $compileNode[0];
-            }
-          });
-          afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
-
-          while (linkQueue.length) {
-            var scope = linkQueue.shift(),
-                beforeTemplateLinkNode = linkQueue.shift(),
-                linkRootElement = linkQueue.shift(),
-                boundTranscludeFn = linkQueue.shift(),
-                linkNode = $compileNode[0];
-
-            if (scope.$$destroyed) continue;
-
-            if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
-              var oldClasses = beforeTemplateLinkNode.className;
-
-              if (!(previousCompileContext.hasElementTranscludeDirective &&
-                  origAsyncDirective.replace)) {
-                // it was cloned therefore we have to clone as well.
-                linkNode = jqLiteClone(compileNode);
-              }
-              replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
-
-              // Copy in CSS classes from original node
-              safeAddClass(jqLite(linkNode), oldClasses);
-            }
-            if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
-              childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
-            } else {
-              childBoundTranscludeFn = boundTranscludeFn;
-            }
-            afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,
-              childBoundTranscludeFn);
-          }
-          linkQueue = null;
-        }).catch(function(error) {
-          if (error instanceof Error) {
-            $exceptionHandler(error);
-          }
-        });
-
-      return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {
-        var childBoundTranscludeFn = boundTranscludeFn;
-        if (scope.$$destroyed) return;
-        if (linkQueue) {
-          linkQueue.push(scope,
-                         node,
-                         rootElement,
-                         childBoundTranscludeFn);
-        } else {
-          if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
-            childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
-          }
-          afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn);
-        }
-      };
-    }
-
-
-    /**
-     * Sorting function for bound directives.
-     */
-    function byPriority(a, b) {
-      var diff = b.priority - a.priority;
-      if (diff !== 0) return diff;
-      if (a.name !== b.name) return (a.name < b.name) ? -1 : 1;
-      return a.index - b.index;
-    }
-
-    function assertNoDuplicate(what, previousDirective, directive, element) {
-
-      function wrapModuleNameIfDefined(moduleName) {
-        return moduleName ?
-          (' (module: ' + moduleName + ')') :
-          '';
-      }
-
-      if (previousDirective) {
-        throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}',
-            previousDirective.name, wrapModuleNameIfDefined(previousDirective.$$moduleName),
-            directive.name, wrapModuleNameIfDefined(directive.$$moduleName), what, startingTag(element));
-      }
-    }
-
-
-    function addTextInterpolateDirective(directives, text) {
-      var interpolateFn = $interpolate(text, true);
-      if (interpolateFn) {
-        directives.push({
-          priority: 0,
-          compile: function textInterpolateCompileFn(templateNode) {
-            var templateNodeParent = templateNode.parent(),
-                hasCompileParent = !!templateNodeParent.length;
-
-            // When transcluding a template that has bindings in the root
-            // we don't have a parent and thus need to add the class during linking fn.
-            if (hasCompileParent) compile.$$addBindingClass(templateNodeParent);
-
-            return function textInterpolateLinkFn(scope, node) {
-              var parent = node.parent();
-              if (!hasCompileParent) compile.$$addBindingClass(parent);
-              compile.$$addBindingInfo(parent, interpolateFn.expressions);
-              scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {
-                node[0].nodeValue = value;
-              });
-            };
-          }
-        });
-      }
-    }
-
-
-    function wrapTemplate(type, template) {
-      type = lowercase(type || 'html');
-      switch (type) {
-      case 'svg':
-      case 'math':
-        var wrapper = window.document.createElement('div');
-        wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';
-        return wrapper.childNodes[0].childNodes;
-      default:
-        return template;
-      }
-    }
-
-
-    function getTrustedContext(node, attrNormalizedName) {
-      if (attrNormalizedName === 'srcdoc') {
-        return $sce.HTML;
-      }
-      var tag = nodeName_(node);
-      // All tags with src attributes require a RESOURCE_URL value, except for
-      // img and various html5 media tags.
-      if (attrNormalizedName === 'src' || attrNormalizedName === 'ngSrc') {
-        if (['img', 'video', 'audio', 'source', 'track'].indexOf(tag) === -1) {
-          return $sce.RESOURCE_URL;
-        }
-      // maction[xlink:href] can source SVG.  It's not limited to <maction>.
-      } else if (attrNormalizedName === 'xlinkHref' ||
-          (tag === 'form' && attrNormalizedName === 'action') ||
-          // links can be stylesheets or imports, which can run script in the current origin
-          (tag === 'link' && attrNormalizedName === 'href')
-      ) {
-        return $sce.RESOURCE_URL;
-      }
-    }
-
-
-    function addAttrInterpolateDirective(node, directives, value, name, isNgAttr) {
-      var trustedContext = getTrustedContext(node, name);
-      var mustHaveExpression = !isNgAttr;
-      var allOrNothing = ALL_OR_NOTHING_ATTRS[name] || isNgAttr;
-
-      var interpolateFn = $interpolate(value, mustHaveExpression, trustedContext, allOrNothing);
-
-      // no interpolation found -> ignore
-      if (!interpolateFn) return;
-
-      if (name === 'multiple' && nodeName_(node) === 'select') {
-        throw $compileMinErr('selmulti',
-            'Binding to the \'multiple\' attribute is not supported. Element: {0}',
-            startingTag(node));
-      }
-
-      if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {
-        throw $compileMinErr('nodomevents',
-            'Interpolations for HTML DOM event attributes are disallowed.  Please use the ' +
-                'ng- versions (such as ng-click instead of onclick) instead.');
-      }
-
-      directives.push({
-        priority: 100,
-        compile: function() {
-            return {
-              pre: function attrInterpolatePreLinkFn(scope, element, attr) {
-                var $$observers = (attr.$$observers || (attr.$$observers = createMap()));
-
-                // If the attribute has changed since last $interpolate()ed
-                var newValue = attr[name];
-                if (newValue !== value) {
-                  // we need to interpolate again since the attribute value has been updated
-                  // (e.g. by another directive's compile function)
-                  // ensure unset/empty values make interpolateFn falsy
-                  interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing);
-                  value = newValue;
-                }
-
-                // if attribute was updated so that there is no interpolation going on we don't want to
-                // register any observers
-                if (!interpolateFn) return;
-
-                // initialize attr object so that it's ready in case we need the value for isolate
-                // scope initialization, otherwise the value would not be available from isolate
-                // directive's linking fn during linking phase
-                attr[name] = interpolateFn(scope);
-
-                ($$observers[name] || ($$observers[name] = [])).$$inter = true;
-                (attr.$$observers && attr.$$observers[name].$$scope || scope).
-                  $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {
-                    //special case for class attribute addition + removal
-                    //so that class changes can tap into the animation
-                    //hooks provided by the $animate service. Be sure to
-                    //skip animations when the first digest occurs (when
-                    //both the new and the old values are the same) since
-                    //the CSS classes are the non-interpolated values
-                    if (name === 'class' && newValue !== oldValue) {
-                      attr.$updateClass(newValue, oldValue);
-                    } else {
-                      attr.$set(name, newValue);
-                    }
-                  });
-              }
-            };
-          }
-      });
-    }
-
-
-    /**
-     * This is a special jqLite.replaceWith, which can replace items which
-     * have no parents, provided that the containing jqLite collection is provided.
-     *
-     * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes
-     *                               in the root of the tree.
-     * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep
-     *                                  the shell, but replace its DOM node reference.
-     * @param {Node} newNode The new DOM node.
-     */
-    function replaceWith($rootElement, elementsToRemove, newNode) {
-      var firstElementToRemove = elementsToRemove[0],
-          removeCount = elementsToRemove.length,
-          parent = firstElementToRemove.parentNode,
-          i, ii;
-
-      if ($rootElement) {
-        for (i = 0, ii = $rootElement.length; i < ii; i++) {
-          if ($rootElement[i] === firstElementToRemove) {
-            $rootElement[i++] = newNode;
-            for (var j = i, j2 = j + removeCount - 1,
-                     jj = $rootElement.length;
-                 j < jj; j++, j2++) {
-              if (j2 < jj) {
-                $rootElement[j] = $rootElement[j2];
-              } else {
-                delete $rootElement[j];
-              }
-            }
-            $rootElement.length -= removeCount - 1;
-
-            // If the replaced element is also the jQuery .context then replace it
-            // .context is a deprecated jQuery api, so we should set it only when jQuery set it
-            // http://api.jquery.com/context/
-            if ($rootElement.context === firstElementToRemove) {
-              $rootElement.context = newNode;
-            }
-            break;
-          }
-        }
-      }
-
-      if (parent) {
-        parent.replaceChild(newNode, firstElementToRemove);
-      }
-
-      // Append all the `elementsToRemove` to a fragment. This will...
-      // - remove them from the DOM
-      // - allow them to still be traversed with .nextSibling
-      // - allow a single fragment.qSA to fetch all elements being removed
-      var fragment = window.document.createDocumentFragment();
-      for (i = 0; i < removeCount; i++) {
-        fragment.appendChild(elementsToRemove[i]);
-      }
-
-      if (jqLite.hasData(firstElementToRemove)) {
-        // Copy over user data (that includes Angular's $scope etc.). Don't copy private
-        // data here because there's no public interface in jQuery to do that and copying over
-        // event listeners (which is the main use of private data) wouldn't work anyway.
-        jqLite.data(newNode, jqLite.data(firstElementToRemove));
-
-        // Remove $destroy event listeners from `firstElementToRemove`
-        jqLite(firstElementToRemove).off('$destroy');
-      }
-
-      // Cleanup any data/listeners on the elements and children.
-      // This includes invoking the $destroy event on any elements with listeners.
-      jqLite.cleanData(fragment.querySelectorAll('*'));
-
-      // Update the jqLite collection to only contain the `newNode`
-      for (i = 1; i < removeCount; i++) {
-        delete elementsToRemove[i];
-      }
-      elementsToRemove[0] = newNode;
-      elementsToRemove.length = 1;
-    }
-
-
-    function cloneAndAnnotateFn(fn, annotation) {
-      return extend(function() { return fn.apply(null, arguments); }, fn, annotation);
-    }
-
-
-    function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {
-      try {
-        linkFn(scope, $element, attrs, controllers, transcludeFn);
-      } catch (e) {
-        $exceptionHandler(e, startingTag($element));
-      }
-    }
-
-
-    // Set up $watches for isolate scope and controller bindings.
-    function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {
-      var removeWatchCollection = [];
-      var initialChanges = {};
-      var changes;
-      forEach(bindings, function initializeBinding(definition, scopeName) {
-        var attrName = definition.attrName,
-        optional = definition.optional,
-        mode = definition.mode, // @, =, <, or &
-        lastValue,
-        parentGet, parentSet, compare, removeWatch;
-
-        switch (mode) {
-
-          case '@':
-            if (!optional && !hasOwnProperty.call(attrs, attrName)) {
-              destination[scopeName] = attrs[attrName] = undefined;
-            }
-            removeWatch = attrs.$observe(attrName, function(value) {
-              if (isString(value) || isBoolean(value)) {
-                var oldValue = destination[scopeName];
-                recordChanges(scopeName, value, oldValue);
-                destination[scopeName] = value;
-              }
-            });
-            attrs.$$observers[attrName].$$scope = scope;
-            lastValue = attrs[attrName];
-            if (isString(lastValue)) {
-              // If the attribute has been provided then we trigger an interpolation to ensure
-              // the value is there for use in the link fn
-              destination[scopeName] = $interpolate(lastValue)(scope);
-            } else if (isBoolean(lastValue)) {
-              // If the attributes is one of the BOOLEAN_ATTR then Angular will have converted
-              // the value to boolean rather than a string, so we special case this situation
-              destination[scopeName] = lastValue;
-            }
-            initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);
-            removeWatchCollection.push(removeWatch);
-            break;
-
-          case '=':
-            if (!hasOwnProperty.call(attrs, attrName)) {
-              if (optional) break;
-              attrs[attrName] = undefined;
-            }
-            if (optional && !attrs[attrName]) break;
-
-            parentGet = $parse(attrs[attrName]);
-            if (parentGet.literal) {
-              compare = equals;
-            } else {
-              // eslint-disable-next-line no-self-compare
-              compare = function simpleCompare(a, b) { return a === b || (a !== a && b !== b); };
-            }
-            parentSet = parentGet.assign || function() {
-              // reset the change, or we will throw this exception on every $digest
-              lastValue = destination[scopeName] = parentGet(scope);
-              throw $compileMinErr('nonassign',
-                  'Expression \'{0}\' in attribute \'{1}\' used with directive \'{2}\' is non-assignable!',
-                  attrs[attrName], attrName, directive.name);
-            };
-            lastValue = destination[scopeName] = parentGet(scope);
-            var parentValueWatch = function parentValueWatch(parentValue) {
-              if (!compare(parentValue, destination[scopeName])) {
-                // we are out of sync and need to copy
-                if (!compare(parentValue, lastValue)) {
-                  // parent changed and it has precedence
-                  destination[scopeName] = parentValue;
-                } else {
-                  // if the parent can be assigned then do so
-                  parentSet(scope, parentValue = destination[scopeName]);
-                }
-              }
-              lastValue = parentValue;
-              return lastValue;
-            };
-            parentValueWatch.$stateful = true;
-            if (definition.collection) {
-              removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
-            } else {
-              removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
-            }
-            removeWatchCollection.push(removeWatch);
-            break;
-
-          case '<':
-            if (!hasOwnProperty.call(attrs, attrName)) {
-              if (optional) break;
-              attrs[attrName] = undefined;
-            }
-            if (optional && !attrs[attrName]) break;
-
-            parentGet = $parse(attrs[attrName]);
-            var deepWatch = parentGet.literal;
-
-            var initialValue = destination[scopeName] = parentGet(scope);
-            initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);
-
-            removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newValue, oldValue) {
-              if (oldValue === newValue) {
-                if (oldValue === initialValue || (deepWatch && equals(oldValue, initialValue))) {
-                  return;
-                }
-                oldValue = initialValue;
-              }
-              recordChanges(scopeName, newValue, oldValue);
-              destination[scopeName] = newValue;
-            }, deepWatch);
-
-            removeWatchCollection.push(removeWatch);
-            break;
-
-          case '&':
-            // Don't assign Object.prototype method to scope
-            parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;
-
-            // Don't assign noop to destination if expression is not valid
-            if (parentGet === noop && optional) break;
-
-            destination[scopeName] = function(locals) {
-              return parentGet(scope, locals);
-            };
-            break;
-        }
-      });
-
-      function recordChanges(key, currentValue, previousValue) {
-        if (isFunction(destination.$onChanges) && currentValue !== previousValue &&
-            // eslint-disable-next-line no-self-compare
-            (currentValue === currentValue || previousValue === previousValue)) {
-          // If we have not already scheduled the top level onChangesQueue handler then do so now
-          if (!onChangesQueue) {
-            scope.$$postDigest(flushOnChangesQueue);
-            onChangesQueue = [];
-          }
-          // If we have not already queued a trigger of onChanges for this controller then do so now
-          if (!changes) {
-            changes = {};
-            onChangesQueue.push(triggerOnChangesHook);
-          }
-          // If the has been a change on this property already then we need to reuse the previous value
-          if (changes[key]) {
-            previousValue = changes[key].previousValue;
-          }
-          // Store this change
-          changes[key] = new SimpleChange(previousValue, currentValue);
-        }
-      }
-
-      function triggerOnChangesHook() {
-        destination.$onChanges(changes);
-        // Now clear the changes so that we schedule onChanges when more changes arrive
-        changes = undefined;
-      }
-
-      return {
-        initialChanges: initialChanges,
-        removeWatches: removeWatchCollection.length && function removeWatches() {
-          for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) {
-            removeWatchCollection[i]();
-          }
-        }
-      };
-    }
-  }];
-}
-
-function SimpleChange(previous, current) {
-  this.previousValue = previous;
-  this.currentValue = current;
-}
-SimpleChange.prototype.isFirstChange = function() { return this.previousValue === _UNINITIALIZED_VALUE; };
-
-
-var PREFIX_REGEXP = /^((?:x|data)[:\-_])/i;
-var SPECIAL_CHARS_REGEXP = /[:\-_]+(.)/g;
-
-/**
- * Converts all accepted directives format into proper directive name.
- * @param name Name to normalize
- */
-function directiveNormalize(name) {
-  return name
-    .replace(PREFIX_REGEXP, '')
-    .replace(SPECIAL_CHARS_REGEXP, fnCamelCaseReplace);
-}
-
-/**
- * @ngdoc type
- * @name $compile.directive.Attributes
- *
- * @description
- * A shared object between directive compile / linking functions which contains normalized DOM
- * element attributes. The values reflect current binding state `{{ }}`. The normalization is
- * needed since all of these are treated as equivalent in Angular:
- *
- * ```
- *    <span ng:bind="a" ng-bind="a" data-ng-bind="a" x-ng-bind="a">
- * ```
- */
-
-/**
- * @ngdoc property
- * @name $compile.directive.Attributes#$attr
- *
- * @description
- * A map of DOM element attribute names to the normalized name. This is
- * needed to do reverse lookup from normalized name back to actual name.
- */
-
-
-/**
- * @ngdoc method
- * @name $compile.directive.Attributes#$set
- * @kind function
- *
- * @description
- * Set DOM element attribute value.
- *
- *
- * @param {string} name Normalized element attribute name of the property to modify. The name is
- *          reverse-translated using the {@link ng.$compile.directive.Attributes#$attr $attr}
- *          property to the original name.
- * @param {string} value Value to set the attribute to. The value can be an interpolated string.
- */
-
-
-
-/**
- * Closure compiler type information
- */
-
-function nodesetLinkingFn(
-  /* angular.Scope */ scope,
-  /* NodeList */ nodeList,
-  /* Element */ rootElement,
-  /* function(Function) */ boundTranscludeFn
-) {}
-
-function directiveLinkingFn(
-  /* nodesetLinkingFn */ nodesetLinkingFn,
-  /* angular.Scope */ scope,
-  /* Node */ node,
-  /* Element */ rootElement,
-  /* function(Function) */ boundTranscludeFn
-) {}
-
-function tokenDifference(str1, str2) {
-  var values = '',
-      tokens1 = str1.split(/\s+/),
-      tokens2 = str2.split(/\s+/);
-
-  outer:
-  for (var i = 0; i < tokens1.length; i++) {
-    var token = tokens1[i];
-    for (var j = 0; j < tokens2.length; j++) {
-      if (token === tokens2[j]) continue outer;
-    }
-    values += (values.length > 0 ? ' ' : '') + token;
-  }
-  return values;
-}
-
-function removeComments(jqNodes) {
-  jqNodes = jqLite(jqNodes);
-  var i = jqNodes.length;
-
-  if (i <= 1) {
-    return jqNodes;
-  }
-
-  while (i--) {
-    var node = jqNodes[i];
-    if (node.nodeType === NODE_TYPE_COMMENT ||
-       (node.nodeType === NODE_TYPE_TEXT && node.nodeValue.trim() === '')) {
-         splice.call(jqNodes, i, 1);
-    }
-  }
-  return jqNodes;
-}
-
-var $controllerMinErr = minErr('$controller');
-
-
-var CNTRL_REG = /^(\S+)(\s+as\s+([\w$]+))?$/;
-function identifierForController(controller, ident) {
-  if (ident && isString(ident)) return ident;
-  if (isString(controller)) {
-    var match = CNTRL_REG.exec(controller);
-    if (match) return match[3];
-  }
-}
-
-
-/**
- * @ngdoc provider
- * @name $controllerProvider
- * @this
- *
- * @description
- * The {@link ng.$controller $controller service} is used by Angular to create new
- * controllers.
- *
- * This provider allows controller registration via the
- * {@link ng.$controllerProvider#register register} method.
- */
-function $ControllerProvider() {
-  var controllers = {},
-      globals = false;
-
-  /**
-   * @ngdoc method
-   * @name $controllerProvider#has
-   * @param {string} name Controller name to check.
-   */
-  this.has = function(name) {
-    return controllers.hasOwnProperty(name);
-  };
-
-  /**
-   * @ngdoc method
-   * @name $controllerProvider#register
-   * @param {string|Object} name Controller name, or an object map of controllers where the keys are
-   *    the names and the values are the constructors.
-   * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI
-   *    annotations in the array notation).
-   */
-  this.register = function(name, constructor) {
-    assertNotHasOwnProperty(name, 'controller');
-    if (isObject(name)) {
-      extend(controllers, name);
-    } else {
-      controllers[name] = constructor;
-    }
-  };
-
-  /**
-   * @ngdoc method
-   * @name $controllerProvider#allowGlobals
-   * @description If called, allows `$controller` to find controller constructors on `window`
-   *
-   * @deprecated
-   * sinceVersion="v1.3.0"
-   * removeVersion="v1.7.0"
-   * This method of finding controllers has been deprecated.
-   */
-  this.allowGlobals = function() {
-    globals = true;
-  };
-
-
-  this.$get = ['$injector', '$window', function($injector, $window) {
-
-    /**
-     * @ngdoc service
-     * @name $controller
-     * @requires $injector
-     *
-     * @param {Function|string} constructor If called with a function then it's considered to be the
-     *    controller constructor function. Otherwise it's considered to be a string which is used
-     *    to retrieve the controller constructor using the following steps:
-     *
-     *    * check if a controller with given name is registered via `$controllerProvider`
-     *    * check if evaluating the string on the current scope returns a constructor
-     *    * if $controllerProvider#allowGlobals, check `window[constructor]` on the global
-     *      `window` object (deprecated, not recommended)
-     *
-     *    The string can use the `controller as property` syntax, where the controller instance is published
-     *    as the specified property on the `scope`; the `scope` must be injected into `locals` param for this
-     *    to work correctly.
-     *
-     * @param {Object} locals Injection locals for Controller.
-     * @return {Object} Instance of given controller.
-     *
-     * @description
-     * `$controller` service is responsible for instantiating controllers.
-     *
-     * It's just a simple call to {@link auto.$injector $injector}, but extracted into
-     * a service, so that one can override this service with [BC version](https://gist.github.com/1649788).
-     */
-    return function $controller(expression, locals, later, ident) {
-      // PRIVATE API:
-      //   param `later` --- indicates that the controller's constructor is invoked at a later time.
-      //                     If true, $controller will allocate the object with the correct
-      //                     prototype chain, but will not invoke the controller until a returned
-      //                     callback is invoked.
-      //   param `ident` --- An optional label which overrides the label parsed from the controller
-      //                     expression, if any.
-      var instance, match, constructor, identifier;
-      later = later === true;
-      if (ident && isString(ident)) {
-        identifier = ident;
-      }
-
-      if (isString(expression)) {
-        match = expression.match(CNTRL_REG);
-        if (!match) {
-          throw $controllerMinErr('ctrlfmt',
-            'Badly formed controller string \'{0}\'. ' +
-            'Must match `__name__ as __id__` or `__name__`.', expression);
-        }
-        constructor = match[1];
-        identifier = identifier || match[3];
-        expression = controllers.hasOwnProperty(constructor)
-            ? controllers[constructor]
-            : getter(locals.$scope, constructor, true) ||
-                (globals ? getter($window, constructor, true) : undefined);
-
-        if (!expression) {
-          throw $controllerMinErr('ctrlreg',
-            'The controller with the name \'{0}\' is not registered.', constructor);
-        }
-
-        assertArgFn(expression, constructor, true);
-      }
-
-      if (later) {
-        // Instantiate controller later:
-        // This machinery is used to create an instance of the object before calling the
-        // controller's constructor itself.
-        //
-        // This allows properties to be added to the controller before the constructor is
-        // invoked. Primarily, this is used for isolate scope bindings in $compile.
-        //
-        // This feature is not intended for use by applications, and is thus not documented
-        // publicly.
-        // Object creation: http://jsperf.com/create-constructor/2
-        var controllerPrototype = (isArray(expression) ?
-          expression[expression.length - 1] : expression).prototype;
-        instance = Object.create(controllerPrototype || null);
-
-        if (identifier) {
-          addIdentifier(locals, identifier, instance, constructor || expression.name);
-        }
-
-        return extend(function $controllerInit() {
-          var result = $injector.invoke(expression, instance, locals, constructor);
-          if (result !== instance && (isObject(result) || isFunction(result))) {
-            instance = result;
-            if (identifier) {
-              // If result changed, re-assign controllerAs value to scope.
-              addIdentifier(locals, identifier, instance, constructor || expression.name);
-            }
-          }
-          return instance;
-        }, {
-          instance: instance,
-          identifier: identifier
-        });
-      }
-
-      instance = $injector.instantiate(expression, locals, constructor);
-
-      if (identifier) {
-        addIdentifier(locals, identifier, instance, constructor || expression.name);
-      }
-
-      return instance;
-    };
-
-    function addIdentifier(locals, identifier, instance, name) {
-      if (!(locals && isObject(locals.$scope))) {
-        throw minErr('$controller')('noscp',
-          'Cannot export controller \'{0}\' as \'{1}\'! No $scope object provided via `locals`.',
-          name, identifier);
-      }
-
-      locals.$scope[identifier] = instance;
-    }
-  }];
-}
-
-/**
- * @ngdoc service
- * @name $document
- * @requires $window
- * @this
- *
- * @description
- * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object.
- *
- * @example
-   <example module="documentExample" name="document">
-     <file name="index.html">
-       <div ng-controller="ExampleController">
-         <p>$document title: <b ng-bind="title"></b></p>
-         <p>window.document title: <b ng-bind="windowTitle"></b></p>
-       </div>
-     </file>
-     <file name="script.js">
-       angular.module('documentExample', [])
-         .controller('ExampleController', ['$scope', '$document', function($scope, $document) {
-           $scope.title = $document[0].title;
-           $scope.windowTitle = angular.element(window.document)[0].title;
-         }]);
-     </file>
-   </example>
- */
-function $DocumentProvider() {
-  this.$get = ['$window', function(window) {
-    return jqLite(window.document);
-  }];
-}
-
-
-/**
- * @private
- * @this
- * Listens for document visibility change and makes the current status accessible.
- */
-function $$IsDocumentHiddenProvider() {
-  this.$get = ['$document', '$rootScope', function($document, $rootScope) {
-    var doc = $document[0];
-    var hidden = doc && doc.hidden;
-
-    $document.on('visibilitychange', changeListener);
-
-    $rootScope.$on('$destroy', function() {
-      $document.off('visibilitychange', changeListener);
-    });
-
-    function changeListener() {
-      hidden = doc.hidden;
-    }
-
-    return function() {
-      return hidden;
-    };
-  }];
-}
-
-/**
- * @ngdoc service
- * @name $exceptionHandler
- * @requires ng.$log
- * @this
- *
- * @description
- * Any uncaught exception in angular expressions is delegated to this service.
- * The default implementation simply delegates to `$log.error` which logs it into
- * the browser console.
- *
- * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by
- * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing.
- *
- * ## Example:
- *
- * The example below will overwrite the default `$exceptionHandler` in order to (a) log uncaught
- * errors to the backend for later inspection by the developers and (b) to use `$log.warn()` instead
- * of `$log.error()`.
- *
- * ```js
- *   angular.
- *     module('exceptionOverwrite', []).
- *     factory('$exceptionHandler', ['$log', 'logErrorsToBackend', function($log, logErrorsToBackend) {
- *       return function myExceptionHandler(exception, cause) {
- *         logErrorsToBackend(exception, cause);
- *         $log.warn(exception, cause);
- *       };
- *     }]);
- * ```
- *
- * <hr />
- * Note, that code executed in event-listeners (even those registered using jqLite's `on`/`bind`
- * methods) does not delegate exceptions to the {@link ng.$exceptionHandler $exceptionHandler}
- * (unless executed during a digest).
- *
- * If you wish, you can manually delegate exceptions, e.g.
- * `try { ... } catch(e) { $exceptionHandler(e); }`
- *
- * @param {Error} exception Exception associated with the error.
- * @param {string=} cause Optional information about the context in which
- *       the error was thrown.
- *
- */
-function $ExceptionHandlerProvider() {
-  this.$get = ['$log', function($log) {
-    return function(exception, cause) {
-      $log.error.apply($log, arguments);
-    };
-  }];
-}
-
-var $$ForceReflowProvider = /** @this */ function() {
-  this.$get = ['$document', function($document) {
-    return function(domNode) {
-      //the line below will force the browser to perform a repaint so
-      //that all the animated elements within the animation frame will
-      //be properly updated and drawn on screen. This is required to
-      //ensure that the preparation animation is properly flushed so that
-      //the active state picks up from there. DO NOT REMOVE THIS LINE.
-      //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
-      //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
-      //WILL TAKE YEARS AWAY FROM YOUR LIFE.
-      if (domNode) {
-        if (!domNode.nodeType && domNode instanceof jqLite) {
-          domNode = domNode[0];
-        }
-      } else {
-        domNode = $document[0].body;
-      }
-      return domNode.offsetWidth + 1;
-    };
-  }];
-};
-
-var APPLICATION_JSON = 'application/json';
-var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
-var JSON_START = /^\[|^\{(?!\{)/;
-var JSON_ENDS = {
-  '[': /]$/,
-  '{': /}$/
-};
-var JSON_PROTECTION_PREFIX = /^\)]\}',?\n/;
-var $httpMinErr = minErr('$http');
-
-function serializeValue(v) {
-  if (isObject(v)) {
-    return isDate(v) ? v.toISOString() : toJson(v);
-  }
-  return v;
-}
-
-
-/** @this */
-function $HttpParamSerializerProvider() {
-  /**
-   * @ngdoc service
-   * @name $httpParamSerializer
-   * @description
-   *
-   * Default {@link $http `$http`} params serializer that converts objects to strings
-   * according to the following rules:
-   *
-   * * `{'foo': 'bar'}` results in `foo=bar`
-   * * `{'foo': Date.now()}` results in `foo=2015-04-01T09%3A50%3A49.262Z` (`toISOString()` and encoded representation of a Date object)
-   * * `{'foo': ['bar', 'baz']}` results in `foo=bar&foo=baz` (repeated key for each array element)
-   * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D` (stringified and encoded representation of an object)
-   *
-   * Note that serializer will sort the request parameters alphabetically.
-   * */
-
-  this.$get = function() {
-    return function ngParamSerializer(params) {
-      if (!params) return '';
-      var parts = [];
-      forEachSorted(params, function(value, key) {
-        if (value === null || isUndefined(value)) return;
-        if (isArray(value)) {
-          forEach(value, function(v) {
-            parts.push(encodeUriQuery(key)  + '=' + encodeUriQuery(serializeValue(v)));
-          });
-        } else {
-          parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value)));
-        }
-      });
-
-      return parts.join('&');
-    };
-  };
-}
-
-/** @this */
-function $HttpParamSerializerJQLikeProvider() {
-  /**
-   * @ngdoc service
-   * @name $httpParamSerializerJQLike
-   *
-   * @description
-   *
-   * Alternative {@link $http `$http`} params serializer that follows
-   * jQuery's [`param()`](http://api.jquery.com/jquery.param/) method logic.
-   * The serializer will also sort the params alphabetically.
-   *
-   * To use it for serializing `$http` request parameters, set it as the `paramSerializer` property:
-   *
-   * ```js
-   * $http({
-   *   url: myUrl,
-   *   method: 'GET',
-   *   params: myParams,
-   *   paramSerializer: '$httpParamSerializerJQLike'
-   * });
-   * ```
-   *
-   * It is also possible to set it as the default `paramSerializer` in the
-   * {@link $httpProvider#defaults `$httpProvider`}.
-   *
-   * Additionally, you can inject the serializer and use it explicitly, for example to serialize
-   * form data for submission:
-   *
-   * ```js
-   * .controller(function($http, $httpParamSerializerJQLike) {
-   *   //...
-   *
-   *   $http({
-   *     url: myUrl,
-   *     method: 'POST',
-   *     data: $httpParamSerializerJQLike(myData),
-   *     headers: {
-   *       'Content-Type': 'application/x-www-form-urlencoded'
-   *     }
-   *   });
-   *
-   * });
-   * ```
-   *
-   * */
-  this.$get = function() {
-    return function jQueryLikeParamSerializer(params) {
-      if (!params) return '';
-      var parts = [];
-      serialize(params, '', true);
-      return parts.join('&');
-
-      function serialize(toSerialize, prefix, topLevel) {
-        if (toSerialize === null || isUndefined(toSerialize)) return;
-        if (isArray(toSerialize)) {
-          forEach(toSerialize, function(value, index) {
-            serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');
-          });
-        } else if (isObject(toSerialize) && !isDate(toSerialize)) {
-          forEachSorted(toSerialize, function(value, key) {
-            serialize(value, prefix +
-                (topLevel ? '' : '[') +
-                key +
-                (topLevel ? '' : ']'));
-          });
-        } else {
-          parts.push(encodeUriQuery(prefix) + '=' + encodeUriQuery(serializeValue(toSerialize)));
-        }
-      }
-    };
-  };
-}
-
-function defaultHttpResponseTransform(data, headers) {
-  if (isString(data)) {
-    // Strip json vulnerability protection prefix and trim whitespace
-    var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();
-
-    if (tempData) {
-      var contentType = headers('Content-Type');
-      if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {
-        data = fromJson(tempData);
-      }
-    }
-  }
-
-  return data;
-}
-
-function isJsonLike(str) {
-    var jsonStart = str.match(JSON_START);
-    return jsonStart && JSON_ENDS[jsonStart[0]].test(str);
-}
-
-/**
- * Parse headers into key value object
- *
- * @param {string} headers Raw headers as a string
- * @returns {Object} Parsed headers as key value object
- */
-function parseHeaders(headers) {
-  var parsed = createMap(), i;
-
-  function fillInParsed(key, val) {
-    if (key) {
-      parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
-    }
-  }
-
-  if (isString(headers)) {
-    forEach(headers.split('\n'), function(line) {
-      i = line.indexOf(':');
-      fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1)));
-    });
-  } else if (isObject(headers)) {
-    forEach(headers, function(headerVal, headerKey) {
-      fillInParsed(lowercase(headerKey), trim(headerVal));
-    });
-  }
-
-  return parsed;
-}
-
-
-/**
- * Returns a function that provides access to parsed headers.
- *
- * Headers are lazy parsed when first requested.
- * @see parseHeaders
- *
- * @param {(string|Object)} headers Headers to provide access to.
- * @returns {function(string=)} Returns a getter function which if called with:
- *
- *   - if called with an argument returns a single header value or null
- *   - if called with no arguments returns an object containing all headers.
- */
-function headersGetter(headers) {
-  var headersObj;
-
-  return function(name) {
-    if (!headersObj) headersObj =  parseHeaders(headers);
-
-    if (name) {
-      var value = headersObj[lowercase(name)];
-      if (value === undefined) {
-        value = null;
-      }
-      return value;
-    }
-
-    return headersObj;
-  };
-}
-
-
-/**
- * Chain all given functions
- *
- * This function is used for both request and response transforming
- *
- * @param {*} data Data to transform.
- * @param {function(string=)} headers HTTP headers getter fn.
- * @param {number} status HTTP status code of the response.
- * @param {(Function|Array.<Function>)} fns Function or an array of functions.
- * @returns {*} Transformed data.
- */
-function transformData(data, headers, status, fns) {
-  if (isFunction(fns)) {
-    return fns(data, headers, status);
-  }
-
-  forEach(fns, function(fn) {
-    data = fn(data, headers, status);
-  });
-
-  return data;
-}
-
-
-function isSuccess(status) {
-  return 200 <= status && status < 300;
-}
-
-
-/**
- * @ngdoc provider
- * @name $httpProvider
- * @this
- *
- * @description
- * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.
- * */
-function $HttpProvider() {
-  /**
-   * @ngdoc property
-   * @name $httpProvider#defaults
-   * @description
-   *
-   * Object containing default values for all {@link ng.$http $http} requests.
-   *
-   * - **`defaults.cache`** - {boolean|Object} - A boolean value or object created with
-   * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of HTTP responses
-   * by default. See {@link $http#caching $http Caching} for more information.
-   *
-   * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
-   * Defaults value is `'XSRF-TOKEN'`.
-   *
-   * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the
-   * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.
-   *
-   * - **`defaults.headers`** - {Object} - Default headers for all $http requests.
-   * Refer to {@link ng.$http#setting-http-headers $http} for documentation on
-   * setting default headers.
-   *     - **`defaults.headers.common`**
-   *     - **`defaults.headers.post`**
-   *     - **`defaults.headers.put`**
-   *     - **`defaults.headers.patch`**
-   *
-   *
-   * - **`defaults.paramSerializer`** - `{string|function(Object<string,string>):string}` - A function
-   *  used to the prepare string representation of request parameters (specified as an object).
-   *  If specified as string, it is interpreted as a function registered with the {@link auto.$injector $injector}.
-   *  Defaults to {@link ng.$httpParamSerializer $httpParamSerializer}.
-   *
-   * - **`defaults.jsonpCallbackParam`** - `{string}` - the name of the query parameter that passes the name of the
-   * callback in a JSONP request. The value of this parameter will be replaced with the expression generated by the
-   * {@link $jsonpCallbacks} service. Defaults to `'callback'`.
-   *
-   **/
-  var defaults = this.defaults = {
-    // transform incoming response data
-    transformResponse: [defaultHttpResponseTransform],
-
-    // transform outgoing request data
-    transformRequest: [function(d) {
-      return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;
-    }],
-
-    // default headers
-    headers: {
-      common: {
-        'Accept': 'application/json, text/plain, */*'
-      },
-      post:   shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
-      put:    shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
-      patch:  shallowCopy(CONTENT_TYPE_APPLICATION_JSON)
-    },
-
-    xsrfCookieName: 'XSRF-TOKEN',
-    xsrfHeaderName: 'X-XSRF-TOKEN',
-
-    paramSerializer: '$httpParamSerializer',
-
-    jsonpCallbackParam: 'callback'
-  };
-
-  var useApplyAsync = false;
-  /**
-   * @ngdoc method
-   * @name $httpProvider#useApplyAsync
-   * @description
-   *
-   * Configure $http service to combine processing of multiple http responses received at around
-   * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in
-   * significant performance improvement for bigger applications that make many HTTP requests
-   * concurrently (common during application bootstrap).
-   *
-   * Defaults to false. If no value is specified, returns the current configured value.
-   *
-   * @param {boolean=} value If true, when requests are loaded, they will schedule a deferred
-   *    "apply" on the next tick, giving time for subsequent requests in a roughly ~10ms window
-   *    to load and share the same digest cycle.
-   *
-   * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.
-   *    otherwise, returns the current configured value.
-   **/
-  this.useApplyAsync = function(value) {
-    if (isDefined(value)) {
-      useApplyAsync = !!value;
-      return this;
-    }
-    return useApplyAsync;
-  };
-
-  /**
-   * @ngdoc property
-   * @name $httpProvider#interceptors
-   * @description
-   *
-   * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}
-   * pre-processing of request or postprocessing of responses.
-   *
-   * These service factories are ordered by request, i.e. they are applied in the same order as the
-   * array, on request, but reverse order, on response.
-   *
-   * {@link ng.$http#interceptors Interceptors detailed info}
-   **/
-  var interceptorFactories = this.interceptors = [];
-
-  this.$get = ['$browser', '$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector', '$sce',
-      function($browser, $httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector, $sce) {
-
-    var defaultCache = $cacheFactory('$http');
-
-    /**
-     * Make sure that default param serializer is exposed as a function
-     */
-    defaults.paramSerializer = isString(defaults.paramSerializer) ?
-      $injector.get(defaults.paramSerializer) : defaults.paramSerializer;
-
-    /**
-     * Interceptors stored in reverse order. Inner interceptors before outer interceptors.
-     * The reversal is needed so that we can build up the interception chain around the
-     * server request.
-     */
-    var reversedInterceptors = [];
-
-    forEach(interceptorFactories, function(interceptorFactory) {
-      reversedInterceptors.unshift(isString(interceptorFactory)
-          ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
-    });
-
-    /**
-     * @ngdoc service
-     * @kind function
-     * @name $http
-     * @requires ng.$httpBackend
-     * @requires $cacheFactory
-     * @requires $rootScope
-     * @requires $q
-     * @requires $injector
-     *
-     * @description
-     * The `$http` service is a core Angular service that facilitates communication with the remote
-     * HTTP servers via the browser's [XMLHttpRequest](https://developer.mozilla.org/en/xmlhttprequest)
-     * object or via [JSONP](http://en.wikipedia.org/wiki/JSONP).
-     *
-     * For unit testing applications that use `$http` service, see
-     * {@link ngMock.$httpBackend $httpBackend mock}.
-     *
-     * For a higher level of abstraction, please check out the {@link ngResource.$resource
-     * $resource} service.
-     *
-     * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
-     * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
-     * it is important to familiarize yourself with these APIs and the guarantees they provide.
-     *
-     *
-     * ## General usage
-     * The `$http` service is a function which takes a single argument — a {@link $http#usage configuration object} —
-     * that is used to generate an HTTP request and returns  a {@link ng.$q promise}.
-     *
-     * ```js
-     *   // Simple GET request example:
-     *   $http({
-     *     method: 'GET',
-     *     url: '/someUrl'
-     *   }).then(function successCallback(response) {
-     *       // this callback will be called asynchronously
-     *       // when the response is available
-     *     }, function errorCallback(response) {
-     *       // called asynchronously if an error occurs
-     *       // or server returns response with an error status.
-     *     });
-     * ```
-     *
-     * The response object has these properties:
-     *
-     *   - **data** – `{string|Object}` – The response body transformed with the transform
-     *     functions.
-     *   - **status** – `{number}` – HTTP status code of the response.
-     *   - **headers** – `{function([headerName])}` – Header getter function.
-     *   - **config** – `{Object}` – The configuration object that was used to generate the request.
-     *   - **statusText** – `{string}` – HTTP status text of the response.
-     *
-     * A response status code between 200 and 299 is considered a success status and will result in
-     * the success callback being called. Any response status code outside of that range is
-     * considered an error status and will result in the error callback being called.
-     * Also, status codes less than -1 are normalized to zero. -1 usually means the request was
-     * aborted, e.g. using a `config.timeout`.
-     * Note that if the response is a redirect, XMLHttpRequest will transparently follow it, meaning
-     * that the outcome (success or error) will be determined by the final response status code.
-     *
-     *
-     * ## Shortcut methods
-     *
-     * Shortcut methods are also available. All shortcut methods require passing in the URL, and
-     * request data must be passed in for POST/PUT requests. An optional config can be passed as the
-     * last argument.
-     *
-     * ```js
-     *   $http.get('/someUrl', config).then(successCallback, errorCallback);
-     *   $http.post('/someUrl', data, config).then(successCallback, errorCallback);
-     * ```
-     *
-     * Complete list of shortcut methods:
-     *
-     * - {@link ng.$http#get $http.get}
-     * - {@link ng.$http#head $http.head}
-     * - {@link ng.$http#post $http.post}
-     * - {@link ng.$http#put $http.put}
-     * - {@link ng.$http#delete $http.delete}
-     * - {@link ng.$http#jsonp $http.jsonp}
-     * - {@link ng.$http#patch $http.patch}
-     *
-     *
-     * ## Writing Unit Tests that use $http
-     * When unit testing (using {@link ngMock ngMock}), it is necessary to call
-     * {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending
-     * request using trained responses.
-     *
-     * ```
-     * $httpBackend.expectGET(...);
-     * $http.get(...);
-     * $httpBackend.flush();
-     * ```
-     *
-     * ## Setting HTTP Headers
-     *
-     * The $http service will automatically add certain HTTP headers to all requests. These defaults
-     * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
-     * object, which currently contains this default configuration:
-     *
-     * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
-     *   - <code>Accept: application/json, text/plain, \*&#65279;/&#65279;\*</code>
-     * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
-     *   - `Content-Type: application/json`
-     * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
-     *   - `Content-Type: application/json`
-     *
-     * To add or overwrite these defaults, simply add or remove a property from these configuration
-     * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
-     * with the lowercased HTTP method name as the key, e.g.
-     * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }`.
-     *
-     * The defaults can also be set at runtime via the `$http.defaults` object in the same
-     * fashion. For example:
-     *
-     * ```
-     * module.run(function($http) {
-     *   $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';
-     * });
-     * ```
-     *
-     * In addition, you can supply a `headers` property in the config object passed when
-     * calling `$http(config)`, which overrides the defaults without changing them globally.
-     *
-     * To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis,
-     * Use the `headers` property, setting the desired header to `undefined`. For example:
-     *
-     * ```js
-     * var req = {
-     *  method: 'POST',
-     *  url: 'http://example.com',
-     *  headers: {
-     *    'Content-Type': undefined
-     *  },
-     *  data: { test: 'test' }
-     * }
-     *
-     * $http(req).then(function(){...}, function(){...});
-     * ```
-     *
-     * ## Transforming Requests and Responses
-     *
-     * Both requests and responses can be transformed using transformation functions: `transformRequest`
-     * and `transformResponse`. These properties can be a single function that returns
-     * the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions,
-     * which allows you to `push` or `unshift` a new transformation function into the transformation chain.
-     *
-     * <div class="alert alert-warning">
-     * **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline.
-     * That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference).
-     * For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest
-     * function will be reflected on the scope and in any templates where the object is data-bound.
-     * To prevent this, transform functions should have no side-effects.
-     * If you need to modify properties, it is recommended to make a copy of the data, or create new object to return.
-     * </div>
-     *
-     * ### Default Transformations
-     *
-     * The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and
-     * `defaults.transformResponse` properties. If a request does not provide its own transformations
-     * then these will be applied.
-     *
-     * You can augment or replace the default transformations by modifying these properties by adding to or
-     * replacing the array.
-     *
-     * Angular provides the following default transformations:
-     *
-     * Request transformations (`$httpProvider.defaults.transformRequest` and `$http.defaults.transformRequest`):
-     *
-     * - If the `data` property of the request configuration object contains an object, serialize it
-     *   into JSON format.
-     *
-     * Response transformations (`$httpProvider.defaults.transformResponse` and `$http.defaults.transformResponse`):
-     *
-     *  - If XSRF prefix is detected, strip it (see Security Considerations section below).
-     *  - If JSON response is detected, deserialize it using a JSON parser.
-     *
-     *
-     * ### Overriding the Default Transformations Per Request
-     *
-     * If you wish to override the request/response transformations only for a single request then provide
-     * `transformRequest` and/or `transformResponse` properties on the configuration object passed
-     * into `$http`.
-     *
-     * Note that if you provide these properties on the config object the default transformations will be
-     * overwritten. If you wish to augment the default transformations then you must include them in your
-     * local transformation array.
-     *
-     * The following code demonstrates adding a new response transformation to be run after the default response
-     * transformations have been run.
-     *
-     * ```js
-     * function appendTransform(defaults, transform) {
-     *
-     *   // We can't guarantee that the default transformation is an array
-     *   defaults = angular.isArray(defaults) ? defaults : [defaults];
-     *
-     *   // Append the new transformation to the defaults
-     *   return defaults.concat(transform);
-     * }
-     *
-     * $http({
-     *   url: '...',
-     *   method: 'GET',
-     *   transformResponse: appendTransform($http.defaults.transformResponse, function(value) {
-     *     return doTransform(value);
-     *   })
-     * });
-     * ```
-     *
-     *
-     * ## Caching
-     *
-     * {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must
-     * set the config.cache value or the default cache value to TRUE or to a cache object (created
-     * with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes
-     * precedence over the default cache value.
-     *
-     * In order to:
-     *   * cache all responses - set the default cache value to TRUE or to a cache object
-     *   * cache a specific response - set config.cache value to TRUE or to a cache object
-     *
-     * If caching is enabled, but neither the default cache nor config.cache are set to a cache object,
-     * then the default `$cacheFactory("$http")` object is used.
-     *
-     * The default cache value can be set by updating the
-     * {@link ng.$http#defaults `$http.defaults.cache`} property or the
-     * {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property.
-     *
-     * When caching is enabled, {@link ng.$http `$http`} stores the response from the server using
-     * the relevant cache object. The next time the same request is made, the response is returned
-     * from the cache without sending a request to the server.
-     *
-     * Take note that:
-     *
-     *   * Only GET and JSONP requests are cached.
-     *   * The cache key is the request URL including search parameters; headers are not considered.
-     *   * Cached responses are returned asynchronously, in the same way as responses from the server.
-     *   * If multiple identical requests are made using the same cache, which is not yet populated,
-     *     one request will be made to the server and remaining requests will return the same response.
-     *   * A cache-control header on the response does not affect if or how responses are cached.
-     *
-     *
-     * ## Interceptors
-     *
-     * Before you start creating interceptors, be sure to understand the
-     * {@link ng.$q $q and deferred/promise APIs}.
-     *
-     * For purposes of global error handling, authentication, or any kind of synchronous or
-     * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be
-     * able to intercept requests before they are handed to the server and
-     * responses before they are handed over to the application code that
-     * initiated these requests. The interceptors leverage the {@link ng.$q
-     * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.
-     *
-     * The interceptors are service factories that are registered with the `$httpProvider` by
-     * adding them to the `$httpProvider.interceptors` array. The factory is called and
-     * injected with dependencies (if specified) and returns the interceptor.
-     *
-     * There are two kinds of interceptors (and two kinds of rejection interceptors):
-     *
-     *   * `request`: interceptors get called with a http {@link $http#usage config} object. The function is free to
-     *     modify the `config` object or create a new one. The function needs to return the `config`
-     *     object directly, or a promise containing the `config` or a new `config` object.
-     *   * `requestError`: interceptor gets called when a previous interceptor threw an error or
-     *     resolved with a rejection.
-     *   * `response`: interceptors get called with http `response` object. The function is free to
-     *     modify the `response` object or create a new one. The function needs to return the `response`
-     *     object directly, or as a promise containing the `response` or a new `response` object.
-     *   * `responseError`: interceptor gets called when a previous interceptor threw an error or
-     *     resolved with a rejection.
-     *
-     *
-     * ```js
-     *   // register the interceptor as a service
-     *   $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
-     *     return {
-     *       // optional method
-     *       'request': function(config) {
-     *         // do something on success
-     *         return config;
-     *       },
-     *
-     *       // optional method
-     *      'requestError': function(rejection) {
-     *         // do something on error
-     *         if (canRecover(rejection)) {
-     *           return responseOrNewPromise
-     *         }
-     *         return $q.reject(rejection);
-     *       },
-     *
-     *
-     *
-     *       // optional method
-     *       'response': function(response) {
-     *         // do something on success
-     *         return response;
-     *       },
-     *
-     *       // optional method
-     *      'responseError': function(rejection) {
-     *         // do something on error
-     *         if (canRecover(rejection)) {
-     *           return responseOrNewPromise
-     *         }
-     *         return $q.reject(rejection);
-     *       }
-     *     };
-     *   });
-     *
-     *   $httpProvider.interceptors.push('myHttpInterceptor');
-     *
-     *
-     *   // alternatively, register the interceptor via an anonymous factory
-     *   $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
-     *     return {
-     *      'request': function(config) {
-     *          // same as above
-     *       },
-     *
-     *       'response': function(response) {
-     *          // same as above
-     *       }
-     *     };
-     *   });
-     * ```
-     *
-     * ## Security Considerations
-     *
-     * When designing web applications, consider security threats from:
-     *
-     * - [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)
-     * - [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery)
-     *
-     * Both server and the client must cooperate in order to eliminate these threats. Angular comes
-     * pre-configured with strategies that address these issues, but for this to work backend server
-     * cooperation is required.
-     *
-     * ### JSON Vulnerability Protection
-     *
-     * A [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)
-     * allows third party website to turn your JSON resource URL into
-     * [JSONP](http://en.wikipedia.org/wiki/JSONP) request under some conditions. To
-     * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
-     * Angular will automatically strip the prefix before processing it as JSON.
-     *
-     * For example if your server needs to return:
-     * ```js
-     * ['one','two']
-     * ```
-     *
-     * which is vulnerable to attack, your server can return:
-     * ```js
-     * )]}',
-     * ['one','two']
-     * ```
-     *
-     * Angular will strip the prefix, before processing the JSON.
-     *
-     *
-     * ### Cross Site Request Forgery (XSRF) Protection
-     *
-     * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by
-     * which the attacker can trick an authenticated user into unknowingly executing actions on your
-     * website. Angular provides a mechanism to counter XSRF. When performing XHR requests, the
-     * $http service reads a token from a cookie (by default, `XSRF-TOKEN`) and sets it as an HTTP
-     * header (`X-XSRF-TOKEN`). Since only JavaScript that runs on your domain could read the
-     * cookie, your server can be assured that the XHR came from JavaScript running on your domain.
-     * The header will not be set for cross-domain requests.
-     *
-     * To take advantage of this, your server needs to set a token in a JavaScript readable session
-     * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
-     * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
-     * that only JavaScript running on your domain could have sent the request. The token must be
-     * unique for each user and must be verifiable by the server (to prevent the JavaScript from
-     * making up its own tokens). We recommend that the token is a digest of your site's
-     * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography&#41;)
-     * for added security.
-     *
-     * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
-     * properties of either $httpProvider.defaults at config-time, $http.defaults at run-time,
-     * or the per-request config object.
-     *
-     * In order to prevent collisions in environments where multiple Angular apps share the
-     * same domain or subdomain, we recommend that each application uses unique cookie name.
-     *
-     * @param {object} config Object describing the request to be made and how it should be
-     *    processed. The object has following properties:
-     *
-     *    - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)
-     *    - **url** – `{string|TrustedObject}` – Absolute or relative URL of the resource that is being requested;
-     *      or an object created by a call to `$sce.trustAsResourceUrl(url)`.
-     *    - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be serialized
-     *      with the `paramSerializer` and appended as GET parameters.
-     *    - **data** – `{string|Object}` – Data to be sent as the request message data.
-     *    - **headers** – `{Object}` – Map of strings or functions which return strings representing
-     *      HTTP headers to send to the server. If the return value of a function is null, the
-     *      header will not be sent. Functions accept a config object as an argument.
-     *    - **eventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest object.
-     *      To bind events to the XMLHttpRequest upload object, use `uploadEventHandlers`.
-     *      The handler will be called in the context of a `$apply` block.
-     *    - **uploadEventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest upload
-     *      object. To bind events to the XMLHttpRequest object, use `eventHandlers`.
-     *      The handler will be called in the context of a `$apply` block.
-     *    - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
-     *    - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
-     *    - **transformRequest** –
-     *      `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
-     *      transform function or an array of such functions. The transform function takes the http
-     *      request body and headers and returns its transformed (typically serialized) version.
-     *      See {@link ng.$http#overriding-the-default-transformations-per-request
-     *      Overriding the Default Transformations}
-     *    - **transformResponse** –
-     *      `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –
-     *      transform function or an array of such functions. The transform function takes the http
-     *      response body, headers and status and returns its transformed (typically deserialized) version.
-     *      See {@link ng.$http#overriding-the-default-transformations-per-request
-     *      Overriding the Default Transformations}
-     *    - **paramSerializer** - `{string|function(Object<string,string>):string}` - A function used to
-     *      prepare the string representation of request parameters (specified as an object).
-     *      If specified as string, it is interpreted as function registered with the
-     *      {@link $injector $injector}, which means you can create your own serializer
-     *      by registering it as a {@link auto.$provide#service service}.
-     *      The default serializer is the {@link $httpParamSerializer $httpParamSerializer};
-     *      alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike}
-     *    - **cache** – `{boolean|Object}` – A boolean value or object created with
-     *      {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.
-     *      See {@link $http#caching $http Caching} for more information.
-     *    - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
-     *      that should abort the request when resolved.
-     *    - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the
-     *      XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials)
-     *      for more information.
-     *    - **responseType** - `{string}` - see
-     *      [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype).
-     *
-     * @returns {HttpPromise} Returns a {@link ng.$q `Promise}` that will be resolved to a response object
-     *                        when the request succeeds or fails.
-     *
-     *
-     * @property {Array.<Object>} pendingRequests Array of config objects for currently pending
-     *   requests. This is primarily meant to be used for debugging purposes.
-     *
-     *
-     * @example
-<example module="httpExample" name="http-service">
-<file name="index.html">
-  <div ng-controller="FetchController">
-    <select ng-model="method" aria-label="Request method">
-      <option>GET</option>
-      <option>JSONP</option>
-    </select>
-    <input type="text" ng-model="url" size="80" aria-label="URL" />
-    <button id="fetchbtn" ng-click="fetch()">fetch</button><br>
-    <button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
-    <button id="samplejsonpbtn"
-      ng-click="updateModel('JSONP',
-                    'https://angularjs.org/greet.php?name=Super%20Hero')">
-      Sample JSONP
-    </button>
-    <button id="invalidjsonpbtn"
-      ng-click="updateModel('JSONP', 'https://angularjs.org/doesntexist')">
-        Invalid JSONP
-      </button>
-    <pre>http status code: {{status}}</pre>
-    <pre>http response data: {{data}}</pre>
-  </div>
-</file>
-<file name="script.js">
-  angular.module('httpExample', [])
-    .config(['$sceDelegateProvider', function($sceDelegateProvider) {
-      // We must whitelist the JSONP endpoint that we are using to show that we trust it
-      $sceDelegateProvider.resourceUrlWhitelist([
-        'self',
-        'https://angularjs.org/**'
-      ]);
-    }])
-    .controller('FetchController', ['$scope', '$http', '$templateCache',
-      function($scope, $http, $templateCache) {
-        $scope.method = 'GET';
-        $scope.url = 'http-hello.html';
-
-        $scope.fetch = function() {
-          $scope.code = null;
-          $scope.response = null;
-
-          $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
-            then(function(response) {
-              $scope.status = response.status;
-              $scope.data = response.data;
-            }, function(response) {
-              $scope.data = response.data || 'Request failed';
-              $scope.status = response.status;
-          });
-        };
-
-        $scope.updateModel = function(method, url) {
-          $scope.method = method;
-          $scope.url = url;
-        };
-      }]);
-</file>
-<file name="http-hello.html">
-  Hello, $http!
-</file>
-<file name="protractor.js" type="protractor">
-  var status = element(by.binding('status'));
-  var data = element(by.binding('data'));
-  var fetchBtn = element(by.id('fetchbtn'));
-  var sampleGetBtn = element(by.id('samplegetbtn'));
-  var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));
-
-  it('should make an xhr GET request', function() {
-    sampleGetBtn.click();
-    fetchBtn.click();
-    expect(status.getText()).toMatch('200');
-    expect(data.getText()).toMatch(/Hello, \$http!/);
-  });
-
-// Commented out due to flakes. See https://github.com/angular/angular.js/issues/9185
-// it('should make a JSONP request to angularjs.org', function() {
-//   var sampleJsonpBtn = element(by.id('samplejsonpbtn'));
-//   sampleJsonpBtn.click();
-//   fetchBtn.click();
-//   expect(status.getText()).toMatch('200');
-//   expect(data.getText()).toMatch(/Super Hero!/);
-// });
-
-  it('should make JSONP request to invalid URL and invoke the error handler',
-      function() {
-    invalidJsonpBtn.click();
-    fetchBtn.click();
-    expect(status.getText()).toMatch('0');
-    expect(data.getText()).toMatch('Request failed');
-  });
-</file>
-</example>
-     */
-    function $http(requestConfig) {
-
-      if (!isObject(requestConfig)) {
-        throw minErr('$http')('badreq', 'Http request configuration must be an object.  Received: {0}', requestConfig);
-      }
-
-      if (!isString($sce.valueOf(requestConfig.url))) {
-        throw minErr('$http')('badreq', 'Http request configuration url must be a string or a $sce trusted object.  Received: {0}', requestConfig.url);
-      }
-
-      var config = extend({
-        method: 'get',
-        transformRequest: defaults.transformRequest,
-        transformResponse: defaults.transformResponse,
-        paramSerializer: defaults.paramSerializer,
-        jsonpCallbackParam: defaults.jsonpCallbackParam
-      }, requestConfig);
-
-      config.headers = mergeHeaders(requestConfig);
-      config.method = uppercase(config.method);
-      config.paramSerializer = isString(config.paramSerializer) ?
-          $injector.get(config.paramSerializer) : config.paramSerializer;
-
-      $browser.$$incOutstandingRequestCount();
-
-      var requestInterceptors = [];
-      var responseInterceptors = [];
-      var promise = $q.resolve(config);
-
-      // apply interceptors
-      forEach(reversedInterceptors, function(interceptor) {
-        if (interceptor.request || interceptor.requestError) {
-          requestInterceptors.unshift(interceptor.request, interceptor.requestError);
-        }
-        if (interceptor.response || interceptor.responseError) {
-          responseInterceptors.push(interceptor.response, interceptor.responseError);
-        }
-      });
-
-      promise = chainInterceptors(promise, requestInterceptors);
-      promise = promise.then(serverRequest);
-      promise = chainInterceptors(promise, responseInterceptors);
-      promise = promise.finally(completeOutstandingRequest);
-
-      return promise;
-
-
-      function chainInterceptors(promise, interceptors) {
-        for (var i = 0, ii = interceptors.length; i < ii;) {
-          var thenFn = interceptors[i++];
-          var rejectFn = interceptors[i++];
-
-          promise = promise.then(thenFn, rejectFn);
-        }
-
-        interceptors.length = 0;
-
-        return promise;
-      }
-
-      function completeOutstandingRequest() {
-        $browser.$$completeOutstandingRequest(noop);
-      }
-
-      function executeHeaderFns(headers, config) {
-        var headerContent, processedHeaders = {};
-
-        forEach(headers, function(headerFn, header) {
-          if (isFunction(headerFn)) {
-            headerContent = headerFn(config);
-            if (headerContent != null) {
-              processedHeaders[header] = headerContent;
-            }
-          } else {
-            processedHeaders[header] = headerFn;
-          }
-        });
-
-        return processedHeaders;
-      }
-
-      function mergeHeaders(config) {
-        var defHeaders = defaults.headers,
-            reqHeaders = extend({}, config.headers),
-            defHeaderName, lowercaseDefHeaderName, reqHeaderName;
-
-        defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);
-
-        // using for-in instead of forEach to avoid unnecessary iteration after header has been found
-        defaultHeadersIteration:
-        for (defHeaderName in defHeaders) {
-          lowercaseDefHeaderName = lowercase(defHeaderName);
-
-          for (reqHeaderName in reqHeaders) {
-            if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {
-              continue defaultHeadersIteration;
-            }
-          }
-
-          reqHeaders[defHeaderName] = defHeaders[defHeaderName];
-        }
-
-        // execute if header value is a function for merged headers
-        return executeHeaderFns(reqHeaders, shallowCopy(config));
-      }
-
-      function serverRequest(config) {
-        var headers = config.headers;
-        var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest);
-
-        // strip content-type if data is undefined
-        if (isUndefined(reqData)) {
-          forEach(headers, function(value, header) {
-            if (lowercase(header) === 'content-type') {
-              delete headers[header];
-            }
-          });
-        }
-
-        if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
-          config.withCredentials = defaults.withCredentials;
-        }
-
-        // send request
-        return sendReq(config, reqData).then(transformResponse, transformResponse);
-      }
-
-      function transformResponse(response) {
-        // make a copy since the response must be cacheable
-        var resp = extend({}, response);
-        resp.data = transformData(response.data, response.headers, response.status,
-                                  config.transformResponse);
-        return (isSuccess(response.status))
-          ? resp
-          : $q.reject(resp);
-      }
-    }
-
-    $http.pendingRequests = [];
-
-    /**
-     * @ngdoc method
-     * @name $http#get
-     *
-     * @description
-     * Shortcut method to perform `GET` request.
-     *
-     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;
-     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.
-     * @param {Object=} config Optional configuration object
-     * @returns {HttpPromise} Future object
-     */
-
-    /**
-     * @ngdoc method
-     * @name $http#delete
-     *
-     * @description
-     * Shortcut method to perform `DELETE` request.
-     *
-     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;
-     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.
-     * @param {Object=} config Optional configuration object
-     * @returns {HttpPromise} Future object
-     */
-
-    /**
-     * @ngdoc method
-     * @name $http#head
-     *
-     * @description
-     * Shortcut method to perform `HEAD` request.
-     *
-     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;
-     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.
-     * @param {Object=} config Optional configuration object
-     * @returns {HttpPromise} Future object
-     */
-
-    /**
-     * @ngdoc method
-     * @name $http#jsonp
-     *
-     * @description
-     * Shortcut method to perform `JSONP` request.
-     *
-     * Note that, since JSONP requests are sensitive because the response is given full access to the browser,
-     * the url must be declared, via {@link $sce} as a trusted resource URL.
-     * You can trust a URL by adding it to the whitelist via
-     * {@link $sceDelegateProvider#resourceUrlWhitelist  `$sceDelegateProvider.resourceUrlWhitelist`} or
-     * by explicitly trusting the URL via {@link $sce#trustAsResourceUrl `$sce.trustAsResourceUrl(url)`}.
-     *
-     * JSONP requests must specify a callback to be used in the response from the server. This callback
-     * is passed as a query parameter in the request. You must specify the name of this parameter by
-     * setting the `jsonpCallbackParam` property on the request config object.
-     *
-     * ```
-     * $http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})
-     * ```
-     *
-     * You can also specify a default callback parameter name in `$http.defaults.jsonpCallbackParam`.
-     * Initially this is set to `'callback'`.
-     *
-     * <div class="alert alert-danger">
-     * You can no longer use the `JSON_CALLBACK` string as a placeholder for specifying where the callback
-     * parameter value should go.
-     * </div>
-     *
-     * If you would like to customise where and how the callbacks are stored then try overriding
-     * or decorating the {@link $jsonpCallbacks} service.
-     *
-     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;
-     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.
-     * @param {Object=} config Optional configuration object
-     * @returns {HttpPromise} Future object
-     */
-    createShortMethods('get', 'delete', 'head', 'jsonp');
-
-    /**
-     * @ngdoc method
-     * @name $http#post
-     *
-     * @description
-     * Shortcut method to perform `POST` request.
-     *
-     * @param {string} url Relative or absolute URL specifying the destination of the request
-     * @param {*} data Request content
-     * @param {Object=} config Optional configuration object
-     * @returns {HttpPromise} Future object
-     */
-
-    /**
-     * @ngdoc method
-     * @name $http#put
-     *
-     * @description
-     * Shortcut method to perform `PUT` request.
-     *
-     * @param {string} url Relative or absolute URL specifying the destination of the request
-     * @param {*} data Request content
-     * @param {Object=} config Optional configuration object
-     * @returns {HttpPromise} Future object
-     */
-
-     /**
-      * @ngdoc method
-      * @name $http#patch
-      *
-      * @description
-      * Shortcut method to perform `PATCH` request.
-      *
-      * @param {string} url Relative or absolute URL specifying the destination of the request
-      * @param {*} data Request content
-      * @param {Object=} config Optional configuration object
-      * @returns {HttpPromise} Future object
-      */
-    createShortMethodsWithData('post', 'put', 'patch');
-
-        /**
-         * @ngdoc property
-         * @name $http#defaults
-         *
-         * @description
-         * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of
-         * default headers, withCredentials as well as request and response transformations.
-         *
-         * See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above.
-         */
-    $http.defaults = defaults;
-
-
-    return $http;
-
-
-    function createShortMethods(names) {
-      forEach(arguments, function(name) {
-        $http[name] = function(url, config) {
-          return $http(extend({}, config || {}, {
-            method: name,
-            url: url
-          }));
-        };
-      });
-    }
-
-
-    function createShortMethodsWithData(name) {
-      forEach(arguments, function(name) {
-        $http[name] = function(url, data, config) {
-          return $http(extend({}, config || {}, {
-            method: name,
-            url: url,
-            data: data
-          }));
-        };
-      });
-    }
-
-
-    /**
-     * Makes the request.
-     *
-     * !!! ACCESSES CLOSURE VARS:
-     * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests
-     */
-    function sendReq(config, reqData) {
-      var deferred = $q.defer(),
-          promise = deferred.promise,
-          cache,
-          cachedResp,
-          reqHeaders = config.headers,
-          isJsonp = lowercase(config.method) === 'jsonp',
-          url = config.url;
-
-      if (isJsonp) {
-        // JSONP is a pretty sensitive operation where we're allowing a script to have full access to
-        // our DOM and JS space.  So we require that the URL satisfies SCE.RESOURCE_URL.
-        url = $sce.getTrustedResourceUrl(url);
-      } else if (!isString(url)) {
-        // If it is not a string then the URL must be a $sce trusted object
-        url = $sce.valueOf(url);
-      }
-
-      url = buildUrl(url, config.paramSerializer(config.params));
-
-      if (isJsonp) {
-        // Check the url and add the JSONP callback placeholder
-        url = sanitizeJsonpCallbackParam(url, config.jsonpCallbackParam);
-      }
-
-      $http.pendingRequests.push(config);
-      promise.then(removePendingReq, removePendingReq);
-
-      if ((config.cache || defaults.cache) && config.cache !== false &&
-          (config.method === 'GET' || config.method === 'JSONP')) {
-        cache = isObject(config.cache) ? config.cache
-            : isObject(/** @type {?} */ (defaults).cache)
-              ? /** @type {?} */ (defaults).cache
-              : defaultCache;
-      }
-
-      if (cache) {
-        cachedResp = cache.get(url);
-        if (isDefined(cachedResp)) {
-          if (isPromiseLike(cachedResp)) {
-            // cached request has already been sent, but there is no response yet
-            cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult);
-          } else {
-            // serving from cache
-            if (isArray(cachedResp)) {
-              resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]);
-            } else {
-              resolvePromise(cachedResp, 200, {}, 'OK');
-            }
-          }
-        } else {
-          // put the promise for the non-transformed response into cache as a placeholder
-          cache.put(url, promise);
-        }
-      }
-
-
-      // if we won't have the response in cache, set the xsrf headers and
-      // send the request to the backend
-      if (isUndefined(cachedResp)) {
-        var xsrfValue = urlIsSameOrigin(config.url)
-            ? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName]
-            : undefined;
-        if (xsrfValue) {
-          reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
-        }
-
-        $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
-            config.withCredentials, config.responseType,
-            createApplyHandlers(config.eventHandlers),
-            createApplyHandlers(config.uploadEventHandlers));
-      }
-
-      return promise;
-
-      function createApplyHandlers(eventHandlers) {
-        if (eventHandlers) {
-          var applyHandlers = {};
-          forEach(eventHandlers, function(eventHandler, key) {
-            applyHandlers[key] = function(event) {
-              if (useApplyAsync) {
-                $rootScope.$applyAsync(callEventHandler);
-              } else if ($rootScope.$$phase) {
-                callEventHandler();
-              } else {
-                $rootScope.$apply(callEventHandler);
-              }
-
-              function callEventHandler() {
-                eventHandler(event);
-              }
-            };
-          });
-          return applyHandlers;
-        }
-      }
-
-
-      /**
-       * Callback registered to $httpBackend():
-       *  - caches the response if desired
-       *  - resolves the raw $http promise
-       *  - calls $apply
-       */
-      function done(status, response, headersString, statusText) {
-        if (cache) {
-          if (isSuccess(status)) {
-            cache.put(url, [status, response, parseHeaders(headersString), statusText]);
-          } else {
-            // remove promise from the cache
-            cache.remove(url);
-          }
-        }
-
-        function resolveHttpPromise() {
-          resolvePromise(response, status, headersString, statusText);
-        }
-
-        if (useApplyAsync) {
-          $rootScope.$applyAsync(resolveHttpPromise);
-        } else {
-          resolveHttpPromise();
-          if (!$rootScope.$$phase) $rootScope.$apply();
-        }
-      }
-
-
-      /**
-       * Resolves the raw $http promise.
-       */
-      function resolvePromise(response, status, headers, statusText) {
-        //status: HTTP response status code, 0, -1 (aborted by timeout / promise)
-        status = status >= -1 ? status : 0;
-
-        (isSuccess(status) ? deferred.resolve : deferred.reject)({
-          data: response,
-          status: status,
-          headers: headersGetter(headers),
-          config: config,
-          statusText: statusText
-        });
-      }
-
-      function resolvePromiseWithResult(result) {
-        resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText);
-      }
-
-      function removePendingReq() {
-        var idx = $http.pendingRequests.indexOf(config);
-        if (idx !== -1) $http.pendingRequests.splice(idx, 1);
-      }
-    }
-
-
-    function buildUrl(url, serializedParams) {
-      if (serializedParams.length > 0) {
-        url += ((url.indexOf('?') === -1) ? '?' : '&') + serializedParams;
-      }
-      return url;
-    }
-
-    function sanitizeJsonpCallbackParam(url, key) {
-      if (/[&?][^=]+=JSON_CALLBACK/.test(url)) {
-        // Throw if the url already contains a reference to JSON_CALLBACK
-        throw $httpMinErr('badjsonp', 'Illegal use of JSON_CALLBACK in url, "{0}"', url);
-      }
-
-      var callbackParamRegex = new RegExp('[&?]' + key + '=');
-      if (callbackParamRegex.test(url)) {
-        // Throw if the callback param was already provided
-        throw $httpMinErr('badjsonp', 'Illegal use of callback param, "{0}", in url, "{1}"', key, url);
-      }
-
-      // Add in the JSON_CALLBACK callback param value
-      url += ((url.indexOf('?') === -1) ? '?' : '&') + key + '=JSON_CALLBACK';
-
-      return url;
-    }
-  }];
-}
-
-/**
- * @ngdoc service
- * @name $xhrFactory
- * @this
- *
- * @description
- * Factory function used to create XMLHttpRequest objects.
- *
- * Replace or decorate this service to create your own custom XMLHttpRequest objects.
- *
- * ```
- * angular.module('myApp', [])
- * .factory('$xhrFactory', function() {
- *   return function createXhr(method, url) {
- *     return new window.XMLHttpRequest({mozSystem: true});
- *   };
- * });
- * ```
- *
- * @param {string} method HTTP method of the request (GET, POST, PUT, ..)
- * @param {string} url URL of the request.
- */
-function $xhrFactoryProvider() {
-  this.$get = function() {
-    return function createXhr() {
-      return new window.XMLHttpRequest();
-    };
-  };
-}
-
-/**
- * @ngdoc service
- * @name $httpBackend
- * @requires $jsonpCallbacks
- * @requires $document
- * @requires $xhrFactory
- * @this
- *
- * @description
- * HTTP backend used by the {@link ng.$http service} that delegates to
- * XMLHttpRequest object or JSONP and deals with browser incompatibilities.
- *
- * You should never need to use this service directly, instead use the higher-level abstractions:
- * {@link ng.$http $http} or {@link ngResource.$resource $resource}.
- *
- * During testing this implementation is swapped with {@link ngMock.$httpBackend mock
- * $httpBackend} which can be trained with responses.
- */
-function $HttpBackendProvider() {
-  this.$get = ['$browser', '$jsonpCallbacks', '$document', '$xhrFactory', function($browser, $jsonpCallbacks, $document, $xhrFactory) {
-    return createHttpBackend($browser, $xhrFactory, $browser.defer, $jsonpCallbacks, $document[0]);
-  }];
-}
-
-function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
-  // TODO(vojta): fix the signature
-  return function(method, url, post, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers) {
-    url = url || $browser.url();
-
-    if (lowercase(method) === 'jsonp') {
-      var callbackPath = callbacks.createCallback(url);
-      var jsonpDone = jsonpReq(url, callbackPath, function(status, text) {
-        // jsonpReq only ever sets status to 200 (OK), 404 (ERROR) or -1 (WAITING)
-        var response = (status === 200) && callbacks.getResponse(callbackPath);
-        completeRequest(callback, status, response, '', text);
-        callbacks.removeCallback(callbackPath);
-      });
-    } else {
-
-      var xhr = createXhr(method, url);
-
-      xhr.open(method, url, true);
-      forEach(headers, function(value, key) {
-        if (isDefined(value)) {
-            xhr.setRequestHeader(key, value);
-        }
-      });
-
-      xhr.onload = function requestLoaded() {
-        var statusText = xhr.statusText || '';
-
-        // responseText is the old-school way of retrieving response (supported by IE9)
-        // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
-        var response = ('response' in xhr) ? xhr.response : xhr.responseText;
-
-        // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
-        var status = xhr.status === 1223 ? 204 : xhr.status;
-
-        // fix status code when it is 0 (0 status is undocumented).
-        // Occurs when accessing file resources or on Android 4.1 stock browser
-        // while retrieving files from application cache.
-        if (status === 0) {
-          status = response ? 200 : urlResolve(url).protocol === 'file' ? 404 : 0;
-        }
-
-        completeRequest(callback,
-            status,
-            response,
-            xhr.getAllResponseHeaders(),
-            statusText);
-      };
-
-      var requestError = function() {
-        // The response is always empty
-        // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
-        completeRequest(callback, -1, null, null, '');
-      };
-
-      xhr.onerror = requestError;
-      xhr.onabort = requestError;
-      xhr.ontimeout = requestError;
-
-      forEach(eventHandlers, function(value, key) {
-          xhr.addEventListener(key, value);
-      });
-
-      forEach(uploadEventHandlers, function(value, key) {
-        xhr.upload.addEventListener(key, value);
-      });
-
-      if (withCredentials) {
-        xhr.withCredentials = true;
-      }
-
-      if (responseType) {
-        try {
-          xhr.responseType = responseType;
-        } catch (e) {
-          // WebKit added support for the json responseType value on 09/03/2013
-          // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
-          // known to throw when setting the value "json" as the response type. Other older
-          // browsers implementing the responseType
-          //
-          // The json response type can be ignored if not supported, because JSON payloads are
-          // parsed on the client-side regardless.
-          if (responseType !== 'json') {
-            throw e;
-          }
-        }
-      }
-
-      xhr.send(isUndefined(post) ? null : post);
-    }
-
-    if (timeout > 0) {
-      var timeoutId = $browserDefer(timeoutRequest, timeout);
-    } else if (isPromiseLike(timeout)) {
-      timeout.then(timeoutRequest);
-    }
-
-
-    function timeoutRequest() {
-      if (jsonpDone) {
-        jsonpDone();
-      }
-      if (xhr) {
-        xhr.abort();
-      }
-    }
-
-    function completeRequest(callback, status, response, headersString, statusText) {
-      // cancel timeout and subsequent timeout promise resolution
-      if (isDefined(timeoutId)) {
-        $browserDefer.cancel(timeoutId);
-      }
-      jsonpDone = xhr = null;
-
-      callback(status, response, headersString, statusText);
-    }
-  };
-
-  function jsonpReq(url, callbackPath, done) {
-    url = url.replace('JSON_CALLBACK', callbackPath);
-    // we can't use jQuery/jqLite here because jQuery does crazy stuff with script elements, e.g.:
-    // - fetches local scripts via XHR and evals them
-    // - adds and immediately removes script elements from the document
-    var script = rawDocument.createElement('script'), callback = null;
-    script.type = 'text/javascript';
-    script.src = url;
-    script.async = true;
-
-    callback = function(event) {
-      script.removeEventListener('load', callback);
-      script.removeEventListener('error', callback);
-      rawDocument.body.removeChild(script);
-      script = null;
-      var status = -1;
-      var text = 'unknown';
-
-      if (event) {
-        if (event.type === 'load' && !callbacks.wasCalled(callbackPath)) {
-          event = { type: 'error' };
-        }
-        text = event.type;
-        status = event.type === 'error' ? 404 : 200;
-      }
-
-      if (done) {
-        done(status, text);
-      }
-    };
-
-    script.addEventListener('load', callback);
-    script.addEventListener('error', callback);
-    rawDocument.body.appendChild(script);
-    return callback;
-  }
-}
-
-var $interpolateMinErr = angular.$interpolateMinErr = minErr('$interpolate');
-$interpolateMinErr.throwNoconcat = function(text) {
-  throw $interpolateMinErr('noconcat',
-      'Error while interpolating: {0}\nStrict Contextual Escaping disallows ' +
-      'interpolations that concatenate multiple expressions when a trusted value is ' +
-      'required.  See http://docs.angularjs.org/api/ng.$sce', text);
-};
-
-$interpolateMinErr.interr = function(text, err) {
-  return $interpolateMinErr('interr', 'Can\'t interpolate: {0}\n{1}', text, err.toString());
-};
-
-/**
- * @ngdoc provider
- * @name $interpolateProvider
- * @this
- *
- * @description
- *
- * Used for configuring the interpolation markup. Defaults to `{{` and `}}`.
- *
- * <div class="alert alert-danger">
- * This feature is sometimes used to mix different markup languages, e.g. to wrap an Angular
- * template within a Python Jinja template (or any other template language). Mixing templating
- * languages is **very dangerous**. The embedding template language will not safely escape Angular
- * expressions, so any user-controlled values in the template will cause Cross Site Scripting (XSS)
- * security bugs!
- * </div>
- *
- * @example
-<example name="custom-interpolation-markup" module="customInterpolationApp">
-<file name="index.html">
-<script>
-  var customInterpolationApp = angular.module('customInterpolationApp', []);
-
-  customInterpolationApp.config(function($interpolateProvider) {
-    $interpolateProvider.startSymbol('//');
-    $interpolateProvider.endSymbol('//');
-  });
-
-
-  customInterpolationApp.controller('DemoController', function() {
-      this.label = "This binding is brought you by // interpolation symbols.";
-  });
-</script>
-<div ng-controller="DemoController as demo">
-    //demo.label//
-</div>
-</file>
-<file name="protractor.js" type="protractor">
-  it('should interpolate binding with custom symbols', function() {
-    expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');
-  });
-</file>
-</example>
- */
-function $InterpolateProvider() {
-  var startSymbol = '{{';
-  var endSymbol = '}}';
-
-  /**
-   * @ngdoc method
-   * @name $interpolateProvider#startSymbol
-   * @description
-   * Symbol to denote start of expression in the interpolated string. Defaults to `{{`.
-   *
-   * @param {string=} value new value to set the starting symbol to.
-   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
-   */
-  this.startSymbol = function(value) {
-    if (value) {
-      startSymbol = value;
-      return this;
-    } else {
-      return startSymbol;
-    }
-  };
-
-  /**
-   * @ngdoc method
-   * @name $interpolateProvider#endSymbol
-   * @description
-   * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
-   *
-   * @param {string=} value new value to set the ending symbol to.
-   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
-   */
-  this.endSymbol = function(value) {
-    if (value) {
-      endSymbol = value;
-      return this;
-    } else {
-      return endSymbol;
-    }
-  };
-
-
-  this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) {
-    var startSymbolLength = startSymbol.length,
-        endSymbolLength = endSymbol.length,
-        escapedStartRegexp = new RegExp(startSymbol.replace(/./g, escape), 'g'),
-        escapedEndRegexp = new RegExp(endSymbol.replace(/./g, escape), 'g');
-
-    function escape(ch) {
-      return '\\\\\\' + ch;
-    }
-
-    function unescapeText(text) {
-      return text.replace(escapedStartRegexp, startSymbol).
-        replace(escapedEndRegexp, endSymbol);
-    }
-
-    // TODO: this is the same as the constantWatchDelegate in parse.js
-    function constantWatchDelegate(scope, listener, objectEquality, constantInterp) {
-      var unwatch = scope.$watch(function constantInterpolateWatch(scope) {
-        unwatch();
-        return constantInterp(scope);
-      }, listener, objectEquality);
-      return unwatch;
-    }
-
-    /**
-     * @ngdoc service
-     * @name $interpolate
-     * @kind function
-     *
-     * @requires $parse
-     * @requires $sce
-     *
-     * @description
-     *
-     * Compiles a string with markup into an interpolation function. This service is used by the
-     * HTML {@link ng.$compile $compile} service for data binding. See
-     * {@link ng.$interpolateProvider $interpolateProvider} for configuring the
-     * interpolation markup.
-     *
-     *
-     * ```js
-     *   var $interpolate = ...; // injected
-     *   var exp = $interpolate('Hello {{name | uppercase}}!');
-     *   expect(exp({name:'Angular'})).toEqual('Hello ANGULAR!');
-     * ```
-     *
-     * `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is
-     * `true`, the interpolation function will return `undefined` unless all embedded expressions
-     * evaluate to a value other than `undefined`.
-     *
-     * ```js
-     *   var $interpolate = ...; // injected
-     *   var context = {greeting: 'Hello', name: undefined };
-     *
-     *   // default "forgiving" mode
-     *   var exp = $interpolate('{{greeting}} {{name}}!');
-     *   expect(exp(context)).toEqual('Hello !');
-     *
-     *   // "allOrNothing" mode
-     *   exp = $interpolate('{{greeting}} {{name}}!', false, null, true);
-     *   expect(exp(context)).toBeUndefined();
-     *   context.name = 'Angular';
-     *   expect(exp(context)).toEqual('Hello Angular!');
-     * ```
-     *
-     * `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior.
-     *
-     * #### Escaped Interpolation
-     * $interpolate provides a mechanism for escaping interpolation markers. Start and end markers
-     * can be escaped by preceding each of their characters with a REVERSE SOLIDUS U+005C (backslash).
-     * It will be rendered as a regular start/end marker, and will not be interpreted as an expression
-     * or binding.
-     *
-     * This enables web-servers to prevent script injection attacks and defacing attacks, to some
-     * degree, while also enabling code examples to work without relying on the
-     * {@link ng.directive:ngNonBindable ngNonBindable} directive.
-     *
-     * **For security purposes, it is strongly encouraged that web servers escape user-supplied data,
-     * replacing angle brackets (&lt;, &gt;) with &amp;lt; and &amp;gt; respectively, and replacing all
-     * interpolation start/end markers with their escaped counterparts.**
-     *
-     * Escaped interpolation markers are only replaced with the actual interpolation markers in rendered
-     * output when the $interpolate service processes the text. So, for HTML elements interpolated
-     * by {@link ng.$compile $compile}, or otherwise interpolated with the `mustHaveExpression` parameter
-     * set to `true`, the interpolated text must contain an unescaped interpolation expression. As such,
-     * this is typically useful only when user-data is used in rendering a template from the server, or
-     * when otherwise untrusted data is used by a directive.
-     *
-     * <example name="interpolation">
-     *  <file name="index.html">
-     *    <div ng-init="username='A user'">
-     *      <p ng-init="apptitle='Escaping demo'">{{apptitle}}: \{\{ username = "defaced value"; \}\}
-     *        </p>
-     *      <p><strong>{{username}}</strong> attempts to inject code which will deface the
-     *        application, but fails to accomplish their task, because the server has correctly
-     *        escaped the interpolation start/end markers with REVERSE SOLIDUS U+005C (backslash)
-     *        characters.</p>
-     *      <p>Instead, the result of the attempted script injection is visible, and can be removed
-     *        from the database by an administrator.</p>
-     *    </div>
-     *  </file>
-     * </example>
-     *
-     * @knownIssue
-     * It is currently not possible for an interpolated expression to contain the interpolation end
-     * symbol. For example, `{{ '}}' }}` will be incorrectly interpreted as `{{ ' }}` + `' }}`, i.e.
-     * an interpolated expression consisting of a single-quote (`'`) and the `' }}` string.
-     *
-     * @knownIssue
-     * All directives and components must use the standard `{{` `}}` interpolation symbols
-     * in their templates. If you change the application interpolation symbols the {@link $compile}
-     * service will attempt to denormalize the standard symbols to the custom symbols.
-     * The denormalization process is not clever enough to know not to replace instances of the standard
-     * symbols where they would not normally be treated as interpolation symbols. For example in the following
-     * code snippet the closing braces of the literal object will get incorrectly denormalized:
-     *
-     * ```
-     * <div data-context='{"context":{"id":3,"type":"page"}}">
-     * ```
-     *
-     * The workaround is to ensure that such instances are separated by whitespace:
-     * ```
-     * <div data-context='{"context":{"id":3,"type":"page"} }">
-     * ```
-     *
-     * See https://github.com/angular/angular.js/pull/14610#issuecomment-219401099 for more information.
-     *
-     * @param {string} text The text with markup to interpolate.
-     * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have
-     *    embedded expression in order to return an interpolation function. Strings with no
-     *    embedded expression will return null for the interpolation function.
-     * @param {string=} trustedContext when provided, the returned function passes the interpolated
-     *    result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,
-     *    trustedContext)} before returning it.  Refer to the {@link ng.$sce $sce} service that
-     *    provides Strict Contextual Escaping for details.
-     * @param {boolean=} allOrNothing if `true`, then the returned function returns undefined
-     *    unless all embedded expressions evaluate to a value other than `undefined`.
-     * @returns {function(context)} an interpolation function which is used to compute the
-     *    interpolated string. The function has these parameters:
-     *
-     * - `context`: evaluation context for all expressions embedded in the interpolated text
-     */
-    function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
-      // Provide a quick exit and simplified result function for text with no interpolation
-      if (!text.length || text.indexOf(startSymbol) === -1) {
-        var constantInterp;
-        if (!mustHaveExpression) {
-          var unescapedText = unescapeText(text);
-          constantInterp = valueFn(unescapedText);
-          constantInterp.exp = text;
-          constantInterp.expressions = [];
-          constantInterp.$$watchDelegate = constantWatchDelegate;
-        }
-        return constantInterp;
-      }
-
-      allOrNothing = !!allOrNothing;
-      var startIndex,
-          endIndex,
-          index = 0,
-          expressions = [],
-          parseFns = [],
-          textLength = text.length,
-          exp,
-          concat = [],
-          expressionPositions = [];
-
-      while (index < textLength) {
-        if (((startIndex = text.indexOf(startSymbol, index)) !== -1) &&
-             ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) !== -1)) {
-          if (index !== startIndex) {
-            concat.push(unescapeText(text.substring(index, startIndex)));
-          }
-          exp = text.substring(startIndex + startSymbolLength, endIndex);
-          expressions.push(exp);
-          parseFns.push($parse(exp, parseStringifyInterceptor));
-          index = endIndex + endSymbolLength;
-          expressionPositions.push(concat.length);
-          concat.push('');
-        } else {
-          // we did not find an interpolation, so we have to add the remainder to the separators array
-          if (index !== textLength) {
-            concat.push(unescapeText(text.substring(index)));
-          }
-          break;
-        }
-      }
-
-      // Concatenating expressions makes it hard to reason about whether some combination of
-      // concatenated values are unsafe to use and could easily lead to XSS.  By requiring that a
-      // single expression be used for iframe[src], object[src], etc., we ensure that the value
-      // that's used is assigned or constructed by some JS code somewhere that is more testable or
-      // make it obvious that you bound the value to some user controlled value.  This helps reduce
-      // the load when auditing for XSS issues.
-      if (trustedContext && concat.length > 1) {
-          $interpolateMinErr.throwNoconcat(text);
-      }
-
-      if (!mustHaveExpression || expressions.length) {
-        var compute = function(values) {
-          for (var i = 0, ii = expressions.length; i < ii; i++) {
-            if (allOrNothing && isUndefined(values[i])) return;
-            concat[expressionPositions[i]] = values[i];
-          }
-          return concat.join('');
-        };
-
-        var getValue = function(value) {
-          return trustedContext ?
-            $sce.getTrusted(trustedContext, value) :
-            $sce.valueOf(value);
-        };
-
-        return extend(function interpolationFn(context) {
-            var i = 0;
-            var ii = expressions.length;
-            var values = new Array(ii);
-
-            try {
-              for (; i < ii; i++) {
-                values[i] = parseFns[i](context);
-              }
-
-              return compute(values);
-            } catch (err) {
-              $exceptionHandler($interpolateMinErr.interr(text, err));
-            }
-
-          }, {
-          // all of these properties are undocumented for now
-          exp: text, //just for compatibility with regular watchers created via $watch
-          expressions: expressions,
-          $$watchDelegate: function(scope, listener) {
-            var lastValue;
-            return scope.$watchGroup(parseFns, /** @this */ function interpolateFnWatcher(values, oldValues) {
-              var currValue = compute(values);
-              if (isFunction(listener)) {
-                listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);
-              }
-              lastValue = currValue;
-            });
-          }
-        });
-      }
-
-      function parseStringifyInterceptor(value) {
-        try {
-          value = getValue(value);
-          return allOrNothing && !isDefined(value) ? value : stringify(value);
-        } catch (err) {
-          $exceptionHandler($interpolateMinErr.interr(text, err));
-        }
-      }
-    }
-
-
-    /**
-     * @ngdoc method
-     * @name $interpolate#startSymbol
-     * @description
-     * Symbol to denote the start of expression in the interpolated string. Defaults to `{{`.
-     *
-     * Use {@link ng.$interpolateProvider#startSymbol `$interpolateProvider.startSymbol`} to change
-     * the symbol.
-     *
-     * @returns {string} start symbol.
-     */
-    $interpolate.startSymbol = function() {
-      return startSymbol;
-    };
-
-
-    /**
-     * @ngdoc method
-     * @name $interpolate#endSymbol
-     * @description
-     * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
-     *
-     * Use {@link ng.$interpolateProvider#endSymbol `$interpolateProvider.endSymbol`} to change
-     * the symbol.
-     *
-     * @returns {string} end symbol.
-     */
-    $interpolate.endSymbol = function() {
-      return endSymbol;
-    };
-
-    return $interpolate;
-  }];
-}
-
-/** @this */
-function $IntervalProvider() {
-  this.$get = ['$rootScope', '$window', '$q', '$$q', '$browser',
-       function($rootScope,   $window,   $q,   $$q,   $browser) {
-    var intervals = {};
-
-
-     /**
-      * @ngdoc service
-      * @name $interval
-      *
-      * @description
-      * Angular's wrapper for `window.setInterval`. The `fn` function is executed every `delay`
-      * milliseconds.
-      *
-      * The return value of registering an interval function is a promise. This promise will be
-      * notified upon each tick of the interval, and will be resolved after `count` iterations, or
-      * run indefinitely if `count` is not defined. The value of the notification will be the
-      * number of iterations that have run.
-      * To cancel an interval, call `$interval.cancel(promise)`.
-      *
-      * In tests you can use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
-      * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
-      * time.
-      *
-      * <div class="alert alert-warning">
-      * **Note**: Intervals created by this service must be explicitly destroyed when you are finished
-      * with them.  In particular they are not automatically destroyed when a controller's scope or a
-      * directive's element are destroyed.
-      * You should take this into consideration and make sure to always cancel the interval at the
-      * appropriate moment.  See the example below for more details on how and when to do this.
-      * </div>
-      *
-      * @param {function()} fn A function that should be called repeatedly. If no additional arguments
-      *   are passed (see below), the function is called with the current iteration count.
-      * @param {number} delay Number of milliseconds between each function call.
-      * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
-      *   indefinitely.
-      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
-      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
-      * @param {...*=} Pass additional parameters to the executed function.
-      * @returns {promise} A promise which will be notified on each iteration.
-      *
-      * @example
-      * <example module="intervalExample" name="interval-service">
-      * <file name="index.html">
-      *   <script>
-      *     angular.module('intervalExample', [])
-      *       .controller('ExampleController', ['$scope', '$interval',
-      *         function($scope, $interval) {
-      *           $scope.format = 'M/d/yy h:mm:ss a';
-      *           $scope.blood_1 = 100;
-      *           $scope.blood_2 = 120;
-      *
-      *           var stop;
-      *           $scope.fight = function() {
-      *             // Don't start a new fight if we are already fighting
-      *             if ( angular.isDefined(stop) ) return;
-      *
-      *             stop = $interval(function() {
-      *               if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
-      *                 $scope.blood_1 = $scope.blood_1 - 3;
-      *                 $scope.blood_2 = $scope.blood_2 - 4;
-      *               } else {
-      *                 $scope.stopFight();
-      *               }
-      *             }, 100);
-      *           };
-      *
-      *           $scope.stopFight = function() {
-      *             if (angular.isDefined(stop)) {
-      *               $interval.cancel(stop);
-      *               stop = undefined;
-      *             }
-      *           };
-      *
-      *           $scope.resetFight = function() {
-      *             $scope.blood_1 = 100;
-      *             $scope.blood_2 = 120;
-      *           };
-      *
-      *           $scope.$on('$destroy', function() {
-      *             // Make sure that the interval is destroyed too
-      *             $scope.stopFight();
-      *           });
-      *         }])
-      *       // Register the 'myCurrentTime' directive factory method.
-      *       // We inject $interval and dateFilter service since the factory method is DI.
-      *       .directive('myCurrentTime', ['$interval', 'dateFilter',
-      *         function($interval, dateFilter) {
-      *           // return the directive link function. (compile function not needed)
-      *           return function(scope, element, attrs) {
-      *             var format,  // date format
-      *                 stopTime; // so that we can cancel the time updates
-      *
-      *             // used to update the UI
-      *             function updateTime() {
-      *               element.text(dateFilter(new Date(), format));
-      *             }
-      *
-      *             // watch the expression, and update the UI on change.
-      *             scope.$watch(attrs.myCurrentTime, function(value) {
-      *               format = value;
-      *               updateTime();
-      *             });
-      *
-      *             stopTime = $interval(updateTime, 1000);
-      *
-      *             // listen on DOM destroy (removal) event, and cancel the next UI update
-      *             // to prevent updating time after the DOM element was removed.
-      *             element.on('$destroy', function() {
-      *               $interval.cancel(stopTime);
-      *             });
-      *           }
-      *         }]);
-      *   </script>
-      *
-      *   <div>
-      *     <div ng-controller="ExampleController">
-      *       <label>Date format: <input ng-model="format"></label> <hr/>
-      *       Current time is: <span my-current-time="format"></span>
-      *       <hr/>
-      *       Blood 1 : <font color='red'>{{blood_1}}</font>
-      *       Blood 2 : <font color='red'>{{blood_2}}</font>
-      *       <button type="button" data-ng-click="fight()">Fight</button>
-      *       <button type="button" data-ng-click="stopFight()">StopFight</button>
-      *       <button type="button" data-ng-click="resetFight()">resetFight</button>
-      *     </div>
-      *   </div>
-      *
-      * </file>
-      * </example>
-      */
-    function interval(fn, delay, count, invokeApply) {
-      var hasParams = arguments.length > 4,
-          args = hasParams ? sliceArgs(arguments, 4) : [],
-          setInterval = $window.setInterval,
-          clearInterval = $window.clearInterval,
-          iteration = 0,
-          skipApply = (isDefined(invokeApply) && !invokeApply),
-          deferred = (skipApply ? $$q : $q).defer(),
-          promise = deferred.promise;
-
-      count = isDefined(count) ? count : 0;
-
-      promise.$$intervalId = setInterval(function tick() {
-        if (skipApply) {
-          $browser.defer(callback);
-        } else {
-          $rootScope.$evalAsync(callback);
-        }
-        deferred.notify(iteration++);
-
-        if (count > 0 && iteration >= count) {
-          deferred.resolve(iteration);
-          clearInterval(promise.$$intervalId);
-          delete intervals[promise.$$intervalId];
-        }
-
-        if (!skipApply) $rootScope.$apply();
-
-      }, delay);
-
-      intervals[promise.$$intervalId] = deferred;
-
-      return promise;
-
-      function callback() {
-        if (!hasParams) {
-          fn(iteration);
-        } else {
-          fn.apply(null, args);
-        }
-      }
-    }
-
-
-     /**
-      * @ngdoc method
-      * @name $interval#cancel
-      *
-      * @description
-      * Cancels a task associated with the `promise`.
-      *
-      * @param {Promise=} promise returned by the `$interval` function.
-      * @returns {boolean} Returns `true` if the task was successfully canceled.
-      */
-    interval.cancel = function(promise) {
-      if (promise && promise.$$intervalId in intervals) {
-        // Interval cancels should not report as unhandled promise.
-        intervals[promise.$$intervalId].promise.catch(noop);
-        intervals[promise.$$intervalId].reject('canceled');
-        $window.clearInterval(promise.$$intervalId);
-        delete intervals[promise.$$intervalId];
-        return true;
-      }
-      return false;
-    };
-
-    return interval;
-  }];
-}
-
-/**
- * @ngdoc service
- * @name $jsonpCallbacks
- * @requires $window
- * @description
- * This service handles the lifecycle of callbacks to handle JSONP requests.
- * Override this service if you wish to customise where the callbacks are stored and
- * how they vary compared to the requested url.
- */
-var $jsonpCallbacksProvider = /** @this */ function() {
-  this.$get = function() {
-    var callbacks = angular.callbacks;
-    var callbackMap = {};
-
-    function createCallback(callbackId) {
-      var callback = function(data) {
-        callback.data = data;
-        callback.called = true;
-      };
-      callback.id = callbackId;
-      return callback;
-    }
-
-    return {
-      /**
-       * @ngdoc method
-       * @name $jsonpCallbacks#createCallback
-       * @param {string} url the url of the JSONP request
-       * @returns {string} the callback path to send to the server as part of the JSONP request
-       * @description
-       * {@link $httpBackend} calls this method to create a callback and get hold of the path to the callback
-       * to pass to the server, which will be used to call the callback with its payload in the JSONP response.
-       */
-      createCallback: function(url) {
-        var callbackId = '_' + (callbacks.$$counter++).toString(36);
-        var callbackPath = 'angular.callbacks.' + callbackId;
-        var callback = createCallback(callbackId);
-        callbackMap[callbackPath] = callbacks[callbackId] = callback;
-        return callbackPath;
-      },
-      /**
-       * @ngdoc method
-       * @name $jsonpCallbacks#wasCalled
-       * @param {string} callbackPath the path to the callback that was sent in the JSONP request
-       * @returns {boolean} whether the callback has been called, as a result of the JSONP response
-       * @description
-       * {@link $httpBackend} calls this method to find out whether the JSONP response actually called the
-       * callback that was passed in the request.
-       */
-      wasCalled: function(callbackPath) {
-        return callbackMap[callbackPath].called;
-      },
-      /**
-       * @ngdoc method
-       * @name $jsonpCallbacks#getResponse
-       * @param {string} callbackPath the path to the callback that was sent in the JSONP request
-       * @returns {*} the data received from the response via the registered callback
-       * @description
-       * {@link $httpBackend} calls this method to get hold of the data that was provided to the callback
-       * in the JSONP response.
-       */
-      getResponse: function(callbackPath) {
-        return callbackMap[callbackPath].data;
-      },
-      /**
-       * @ngdoc method
-       * @name $jsonpCallbacks#removeCallback
-       * @param {string} callbackPath the path to the callback that was sent in the JSONP request
-       * @description
-       * {@link $httpBackend} calls this method to remove the callback after the JSONP request has
-       * completed or timed-out.
-       */
-      removeCallback: function(callbackPath) {
-        var callback = callbackMap[callbackPath];
-        delete callbacks[callback.id];
-        delete callbackMap[callbackPath];
-      }
-    };
-  };
-};
-
-/**
- * @ngdoc service
- * @name $locale
- *
- * @description
- * $locale service provides localization rules for various Angular components. As of right now the
- * only public api is:
- *
- * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
- */
-
-var PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/,
-    DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};
-var $locationMinErr = minErr('$location');
-
-
-/**
- * Encode path using encodeUriSegment, ignoring forward slashes
- *
- * @param {string} path Path to encode
- * @returns {string}
- */
-function encodePath(path) {
-  var segments = path.split('/'),
-      i = segments.length;
-
-  while (i--) {
-    segments[i] = encodeUriSegment(segments[i]);
-  }
-
-  return segments.join('/');
-}
-
-function parseAbsoluteUrl(absoluteUrl, locationObj) {
-  var parsedUrl = urlResolve(absoluteUrl);
-
-  locationObj.$$protocol = parsedUrl.protocol;
-  locationObj.$$host = parsedUrl.hostname;
-  locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
-}
-
-var DOUBLE_SLASH_REGEX = /^\s*[\\/]{2,}/;
-function parseAppUrl(url, locationObj) {
-
-  if (DOUBLE_SLASH_REGEX.test(url)) {
-    throw $locationMinErr('badpath', 'Invalid url "{0}".', url);
-  }
-
-  var prefixed = (url.charAt(0) !== '/');
-  if (prefixed) {
-    url = '/' + url;
-  }
-  var match = urlResolve(url);
-  locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
-      match.pathname.substring(1) : match.pathname);
-  locationObj.$$search = parseKeyValue(match.search);
-  locationObj.$$hash = decodeURIComponent(match.hash);
-
-  // make sure path starts with '/';
-  if (locationObj.$$path && locationObj.$$path.charAt(0) !== '/') {
-    locationObj.$$path = '/' + locationObj.$$path;
-  }
-}
-
-function startsWith(str, search) {
-  return str.slice(0, search.length) === search;
-}
-
-/**
- *
- * @param {string} base
- * @param {string} url
- * @returns {string} returns text from `url` after `base` or `undefined` if it does not begin with
- *                   the expected string.
- */
-function stripBaseUrl(base, url) {
-  if (startsWith(url, base)) {
-    return url.substr(base.length);
-  }
-}
-
-
-function stripHash(url) {
-  var index = url.indexOf('#');
-  return index === -1 ? url : url.substr(0, index);
-}
-
-function trimEmptyHash(url) {
-  return url.replace(/(#.+)|#$/, '$1');
-}
-
-
-function stripFile(url) {
-  return url.substr(0, stripHash(url).lastIndexOf('/') + 1);
-}
-
-/* return the server only (scheme://host:port) */
-function serverBase(url) {
-  return url.substring(0, url.indexOf('/', url.indexOf('//') + 2));
-}
-
-
-/**
- * LocationHtml5Url represents a URL
- * This object is exposed as $location service when HTML5 mode is enabled and supported
- *
- * @constructor
- * @param {string} appBase application base URL
- * @param {string} appBaseNoFile application base URL stripped of any filename
- * @param {string} basePrefix URL path prefix
- */
-function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {
-  this.$$html5 = true;
-  basePrefix = basePrefix || '';
-  parseAbsoluteUrl(appBase, this);
-
-
-  /**
-   * Parse given HTML5 (regular) URL string into properties
-   * @param {string} url HTML5 URL
-   * @private
-   */
-  this.$$parse = function(url) {
-    var pathUrl = stripBaseUrl(appBaseNoFile, url);
-    if (!isString(pathUrl)) {
-      throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url,
-          appBaseNoFile);
-    }
-
-    parseAppUrl(pathUrl, this);
-
-    if (!this.$$path) {
-      this.$$path = '/';
-    }
-
-    this.$$compose();
-  };
-
-  /**
-   * Compose url and update `absUrl` property
-   * @private
-   */
-  this.$$compose = function() {
-    var search = toKeyValue(this.$$search),
-        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
-
-    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
-    this.$$absUrl = appBaseNoFile + this.$$url.substr(1); // first char is always '/'
-
-    this.$$urlUpdatedByLocation = true;
-  };
-
-  this.$$parseLinkUrl = function(url, relHref) {
-    if (relHref && relHref[0] === '#') {
-      // special case for links to hash fragments:
-      // keep the old url and only replace the hash fragment
-      this.hash(relHref.slice(1));
-      return true;
-    }
-    var appUrl, prevAppUrl;
-    var rewrittenUrl;
-
-
-    if (isDefined(appUrl = stripBaseUrl(appBase, url))) {
-      prevAppUrl = appUrl;
-      if (basePrefix && isDefined(appUrl = stripBaseUrl(basePrefix, appUrl))) {
-        rewrittenUrl = appBaseNoFile + (stripBaseUrl('/', appUrl) || appUrl);
-      } else {
-        rewrittenUrl = appBase + prevAppUrl;
-      }
-    } else if (isDefined(appUrl = stripBaseUrl(appBaseNoFile, url))) {
-      rewrittenUrl = appBaseNoFile + appUrl;
-    } else if (appBaseNoFile === url + '/') {
-      rewrittenUrl = appBaseNoFile;
-    }
-    if (rewrittenUrl) {
-      this.$$parse(rewrittenUrl);
-    }
-    return !!rewrittenUrl;
-  };
-}
-
-
-/**
- * LocationHashbangUrl represents URL
- * This object is exposed as $location service when developer doesn't opt into html5 mode.
- * It also serves as the base class for html5 mode fallback on legacy browsers.
- *
- * @constructor
- * @param {string} appBase application base URL
- * @param {string} appBaseNoFile application base URL stripped of any filename
- * @param {string} hashPrefix hashbang prefix
- */
-function LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) {
-
-  parseAbsoluteUrl(appBase, this);
-
-
-  /**
-   * Parse given hashbang URL into properties
-   * @param {string} url Hashbang URL
-   * @private
-   */
-  this.$$parse = function(url) {
-    var withoutBaseUrl = stripBaseUrl(appBase, url) || stripBaseUrl(appBaseNoFile, url);
-    var withoutHashUrl;
-
-    if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === '#') {
-
-      // The rest of the URL starts with a hash so we have
-      // got either a hashbang path or a plain hash fragment
-      withoutHashUrl = stripBaseUrl(hashPrefix, withoutBaseUrl);
-      if (isUndefined(withoutHashUrl)) {
-        // There was no hashbang prefix so we just have a hash fragment
-        withoutHashUrl = withoutBaseUrl;
-      }
-
-    } else {
-      // There was no hashbang path nor hash fragment:
-      // If we are in HTML5 mode we use what is left as the path;
-      // Otherwise we ignore what is left
-      if (this.$$html5) {
-        withoutHashUrl = withoutBaseUrl;
-      } else {
-        withoutHashUrl = '';
-        if (isUndefined(withoutBaseUrl)) {
-          appBase = url;
-          /** @type {?} */ (this).replace();
-        }
-      }
-    }
-
-    parseAppUrl(withoutHashUrl, this);
-
-    this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
-
-    this.$$compose();
-
-    /*
-     * In Windows, on an anchor node on documents loaded from
-     * the filesystem, the browser will return a pathname
-     * prefixed with the drive name ('/C:/path') when a
-     * pathname without a drive is set:
-     *  * a.setAttribute('href', '/foo')
-     *   * a.pathname === '/C:/foo' //true
-     *
-     * Inside of Angular, we're always using pathnames that
-     * do not include drive names for routing.
-     */
-    function removeWindowsDriveName(path, url, base) {
-      /*
-      Matches paths for file protocol on windows,
-      such as /C:/foo/bar, and captures only /foo/bar.
-      */
-      var windowsFilePathExp = /^\/[A-Z]:(\/.*)/;
-
-      var firstPathSegmentMatch;
-
-      //Get the relative path from the input URL.
-      if (startsWith(url, base)) {
-        url = url.replace(base, '');
-      }
-
-      // The input URL intentionally contains a first path segment that ends with a colon.
-      if (windowsFilePathExp.exec(url)) {
-        return path;
-      }
-
-      firstPathSegmentMatch = windowsFilePathExp.exec(path);
-      return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
-    }
-  };
-
-  /**
-   * Compose hashbang URL and update `absUrl` property
-   * @private
-   */
-  this.$$compose = function() {
-    var search = toKeyValue(this.$$search),
-        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
-
-    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
-    this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : '');
-
-    this.$$urlUpdatedByLocation = true;
-  };
-
-  this.$$parseLinkUrl = function(url, relHref) {
-    if (stripHash(appBase) === stripHash(url)) {
-      this.$$parse(url);
-      return true;
-    }
-    return false;
-  };
-}
-
-
-/**
- * LocationHashbangUrl represents URL
- * This object is exposed as $location service when html5 history api is enabled but the browser
- * does not support it.
- *
- * @constructor
- * @param {string} appBase application base URL
- * @param {string} appBaseNoFile application base URL stripped of any filename
- * @param {string} hashPrefix hashbang prefix
- */
-function LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) {
-  this.$$html5 = true;
-  LocationHashbangUrl.apply(this, arguments);
-
-  this.$$parseLinkUrl = function(url, relHref) {
-    if (relHref && relHref[0] === '#') {
-      // special case for links to hash fragments:
-      // keep the old url and only replace the hash fragment
-      this.hash(relHref.slice(1));
-      return true;
-    }
-
-    var rewrittenUrl;
-    var appUrl;
-
-    if (appBase === stripHash(url)) {
-      rewrittenUrl = url;
-    } else if ((appUrl = stripBaseUrl(appBaseNoFile, url))) {
-      rewrittenUrl = appBase + hashPrefix + appUrl;
-    } else if (appBaseNoFile === url + '/') {
-      rewrittenUrl = appBaseNoFile;
-    }
-    if (rewrittenUrl) {
-      this.$$parse(rewrittenUrl);
-    }
-    return !!rewrittenUrl;
-  };
-
-  this.$$compose = function() {
-    var search = toKeyValue(this.$$search),
-        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
-
-    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
-    // include hashPrefix in $$absUrl when $$url is empty so IE9 does not reload page because of removal of '#'
-    this.$$absUrl = appBase + hashPrefix + this.$$url;
-
-    this.$$urlUpdatedByLocation = true;
-  };
-
-}
-
-
-var locationPrototype = {
-
-  /**
-   * Ensure absolute URL is initialized.
-   * @private
-   */
-  $$absUrl:'',
-
-  /**
-   * Are we in html5 mode?
-   * @private
-   */
-  $$html5: false,
-
-  /**
-   * Has any change been replacing?
-   * @private
-   */
-  $$replace: false,
-
-  /**
-   * @ngdoc method
-   * @name $location#absUrl
-   *
-   * @description
-   * This method is getter only.
-   *
-   * Return full URL representation with all segments encoded according to rules specified in
-   * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
-   *
-   *
-   * ```js
-   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
-   * var absUrl = $location.absUrl();
-   * // => "http://example.com/#/some/path?foo=bar&baz=xoxo"
-   * ```
-   *
-   * @return {string} full URL
-   */
-  absUrl: locationGetter('$$absUrl'),
-
-  /**
-   * @ngdoc method
-   * @name $location#url
-   *
-   * @description
-   * This method is getter / setter.
-   *
-   * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.
-   *
-   * Change path, search and hash, when called with parameter and return `$location`.
-   *
-   *
-   * ```js
-   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
-   * var url = $location.url();
-   * // => "/some/path?foo=bar&baz=xoxo"
-   * ```
-   *
-   * @param {string=} url New URL without base prefix (e.g. `/path?a=b#hash`)
-   * @return {string} url
-   */
-  url: function(url) {
-    if (isUndefined(url)) {
-      return this.$$url;
-    }
-
-    var match = PATH_MATCH.exec(url);
-    if (match[1] || url === '') this.path(decodeURIComponent(match[1]));
-    if (match[2] || match[1] || url === '') this.search(match[3] || '');
-    this.hash(match[5] || '');
-
-    return this;
-  },
-
-  /**
-   * @ngdoc method
-   * @name $location#protocol
-   *
-   * @description
-   * This method is getter only.
-   *
-   * Return protocol of current URL.
-   *
-   *
-   * ```js
-   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
-   * var protocol = $location.protocol();
-   * // => "http"
-   * ```
-   *
-   * @return {string} protocol of current URL
-   */
-  protocol: locationGetter('$$protocol'),
-
-  /**
-   * @ngdoc method
-   * @name $location#host
-   *
-   * @description
-   * This method is getter only.
-   *
-   * Return host of current URL.
-   *
-   * Note: compared to the non-angular version `location.host` which returns `hostname:port`, this returns the `hostname` portion only.
-   *
-   *
-   * ```js
-   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
-   * var host = $location.host();
-   * // => "example.com"
-   *
-   * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo
-   * host = $location.host();
-   * // => "example.com"
-   * host = location.host;
-   * // => "example.com:8080"
-   * ```
-   *
-   * @return {string} host of current URL.
-   */
-  host: locationGetter('$$host'),
-
-  /**
-   * @ngdoc method
-   * @name $location#port
-   *
-   * @description
-   * This method is getter only.
-   *
-   * Return port of current URL.
-   *
-   *
-   * ```js
-   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
-   * var port = $location.port();
-   * // => 80
-   * ```
-   *
-   * @return {Number} port
-   */
-  port: locationGetter('$$port'),
-
-  /**
-   * @ngdoc method
-   * @name $location#path
-   *
-   * @description
-   * This method is getter / setter.
-   *
-   * Return path of current URL when called without any parameter.
-   *
-   * Change path when called with parameter and return `$location`.
-   *
-   * Note: Path should always begin with forward slash (/), this method will add the forward slash
-   * if it is missing.
-   *
-   *
-   * ```js
-   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
-   * var path = $location.path();
-   * // => "/some/path"
-   * ```
-   *
-   * @param {(string|number)=} path New path
-   * @return {(string|object)} path if called with no parameters, or `$location` if called with a parameter
-   */
-  path: locationGetterSetter('$$path', function(path) {
-    path = path !== null ? path.toString() : '';
-    return path.charAt(0) === '/' ? path : '/' + path;
-  }),
-
-  /**
-   * @ngdoc method
-   * @name $location#search
-   *
-   * @description
-   * This method is getter / setter.
-   *
-   * Return search part (as object) of current URL when called without any parameter.
-   *
-   * Change search part when called with parameter and return `$location`.
-   *
-   *
-   * ```js
-   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
-   * var searchObject = $location.search();
-   * // => {foo: 'bar', baz: 'xoxo'}
-   *
-   * // set foo to 'yipee'
-   * $location.search('foo', 'yipee');
-   * // $location.search() => {foo: 'yipee', baz: 'xoxo'}
-   * ```
-   *
-   * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or
-   * hash object.
-   *
-   * When called with a single argument the method acts as a setter, setting the `search` component
-   * of `$location` to the specified value.
-   *
-   * If the argument is a hash object containing an array of values, these values will be encoded
-   * as duplicate search parameters in the URL.
-   *
-   * @param {(string|Number|Array<string>|boolean)=} paramValue If `search` is a string or number, then `paramValue`
-   * will override only a single search property.
-   *
-   * If `paramValue` is an array, it will override the property of the `search` component of
-   * `$location` specified via the first argument.
-   *
-   * If `paramValue` is `null`, the property specified via the first argument will be deleted.
-   *
-   * If `paramValue` is `true`, the property specified via the first argument will be added with no
-   * value nor trailing equal sign.
-   *
-   * @return {Object} If called with no arguments returns the parsed `search` object. If called with
-   * one or more arguments returns `$location` object itself.
-   */
-  search: function(search, paramValue) {
-    switch (arguments.length) {
-      case 0:
-        return this.$$search;
-      case 1:
-        if (isString(search) || isNumber(search)) {
-          search = search.toString();
-          this.$$search = parseKeyValue(search);
-        } else if (isObject(search)) {
-          search = copy(search, {});
-          // remove object undefined or null properties
-          forEach(search, function(value, key) {
-            if (value == null) delete search[key];
-          });
-
-          this.$$search = search;
-        } else {
-          throw $locationMinErr('isrcharg',
-              'The first argument of the `$location#search()` call must be a string or an object.');
-        }
-        break;
-      default:
-        if (isUndefined(paramValue) || paramValue === null) {
-          delete this.$$search[search];
-        } else {
-          this.$$search[search] = paramValue;
-        }
-    }
-
-    this.$$compose();
-    return this;
-  },
-
-  /**
-   * @ngdoc method
-   * @name $location#hash
-   *
-   * @description
-   * This method is getter / setter.
-   *
-   * Returns the hash fragment when called without any parameters.
-   *
-   * Changes the hash fragment when called with a parameter and returns `$location`.
-   *
-   *
-   * ```js
-   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue
-   * var hash = $location.hash();
-   * // => "hashValue"
-   * ```
-   *
-   * @param {(string|number)=} hash New hash fragment
-   * @return {string} hash
-   */
-  hash: locationGetterSetter('$$hash', function(hash) {
-    return hash !== null ? hash.toString() : '';
-  }),
-
-  /**
-   * @ngdoc method
-   * @name $location#replace
-   *
-   * @description
-   * If called, all changes to $location during the current `$digest` will replace the current history
-   * record, instead of adding a new one.
-   */
-  replace: function() {
-    this.$$replace = true;
-    return this;
-  }
-};
-
-forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) {
-  Location.prototype = Object.create(locationPrototype);
-
-  /**
-   * @ngdoc method
-   * @name $location#state
-   *
-   * @description
-   * This method is getter / setter.
-   *
-   * Return the history state object when called without any parameter.
-   *
-   * Change the history state object when called with one parameter and return `$location`.
-   * The state object is later passed to `pushState` or `replaceState`.
-   *
-   * NOTE: This method is supported only in HTML5 mode and only in browsers supporting
-   * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support
-   * older browsers (like IE9 or Android < 4.0), don't use this method.
-   *
-   * @param {object=} state State object for pushState or replaceState
-   * @return {object} state
-   */
-  Location.prototype.state = function(state) {
-    if (!arguments.length) {
-      return this.$$state;
-    }
-
-    if (Location !== LocationHtml5Url || !this.$$html5) {
-      throw $locationMinErr('nostate', 'History API state support is available only ' +
-        'in HTML5 mode and only in browsers supporting HTML5 History API');
-    }
-    // The user might modify `stateObject` after invoking `$location.state(stateObject)`
-    // but we're changing the $$state reference to $browser.state() during the $digest
-    // so the modification window is narrow.
-    this.$$state = isUndefined(state) ? null : state;
-    this.$$urlUpdatedByLocation = true;
-
-    return this;
-  };
-});
-
-
-function locationGetter(property) {
-  return /** @this */ function() {
-    return this[property];
-  };
-}
-
-
-function locationGetterSetter(property, preprocess) {
-  return /** @this */ function(value) {
-    if (isUndefined(value)) {
-      return this[property];
-    }
-
-    this[property] = preprocess(value);
-    this.$$compose();
-
-    return this;
-  };
-}
-
-
-/**
- * @ngdoc service
- * @name $location
- *
- * @requires $rootElement
- *
- * @description
- * The $location service parses the URL in the browser address bar (based on the
- * [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL
- * available to your application. Changes to the URL in the address bar are reflected into
- * $location service and changes to $location are reflected into the browser address bar.
- *
- * **The $location service:**
- *
- * - Exposes the current URL in the browser address bar, so you can
- *   - Watch and observe the URL.
- *   - Change the URL.
- * - Synchronizes the URL with the browser when the user
- *   - Changes the address bar.
- *   - Clicks the back or forward button (or clicks a History link).
- *   - Clicks on a link.
- * - Represents the URL object as a set of methods (protocol, host, port, path, search, hash).
- *
- * For more information see {@link guide/$location Developer Guide: Using $location}
- */
-
-/**
- * @ngdoc provider
- * @name $locationProvider
- * @this
- *
- * @description
- * Use the `$locationProvider` to configure how the application deep linking paths are stored.
- */
-function $LocationProvider() {
-  var hashPrefix = '!',
-      html5Mode = {
-        enabled: false,
-        requireBase: true,
-        rewriteLinks: true
-      };
-
-  /**
-   * @ngdoc method
-   * @name $locationProvider#hashPrefix
-   * @description
-   * The default value for the prefix is `'!'`.
-   * @param {string=} prefix Prefix for hash part (containing path and search)
-   * @returns {*} current value if used as getter or itself (chaining) if used as setter
-   */
-  this.hashPrefix = function(prefix) {
-    if (isDefined(prefix)) {
-      hashPrefix = prefix;
-      return this;
-    } else {
-      return hashPrefix;
-    }
-  };
-
-  /**
-   * @ngdoc method
-   * @name $locationProvider#html5Mode
-   * @description
-   * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value.
-   *   If object, sets `enabled`, `requireBase` and `rewriteLinks` to respective values. Supported
-   *   properties:
-   *   - **enabled** – `{boolean}` – (default: false) If true, will rely on `history.pushState` to
-   *     change urls where supported. Will fall back to hash-prefixed paths in browsers that do not
-   *     support `pushState`.
-   *   - **requireBase** - `{boolean}` - (default: `true`) When html5Mode is enabled, specifies
-   *     whether or not a <base> tag is required to be present. If `enabled` and `requireBase` are
-   *     true, and a base tag is not present, an error will be thrown when `$location` is injected.
-   *     See the {@link guide/$location $location guide for more information}
-   *   - **rewriteLinks** - `{boolean|string}` - (default: `true`) When html5Mode is enabled,
-   *     enables/disables URL rewriting for relative links. If set to a string, URL rewriting will
-   *     only happen on links with an attribute that matches the given string. For example, if set
-   *     to `'internal-link'`, then the URL will only be rewritten for `<a internal-link>` links.
-   *     Note that [attribute name normalization](guide/directive#normalization) does not apply
-   *     here, so `'internalLink'` will **not** match `'internal-link'`.
-   *
-   * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter
-   */
-  this.html5Mode = function(mode) {
-    if (isBoolean(mode)) {
-      html5Mode.enabled = mode;
-      return this;
-    } else if (isObject(mode)) {
-
-      if (isBoolean(mode.enabled)) {
-        html5Mode.enabled = mode.enabled;
-      }
-
-      if (isBoolean(mode.requireBase)) {
-        html5Mode.requireBase = mode.requireBase;
-      }
-
-      if (isBoolean(mode.rewriteLinks) || isString(mode.rewriteLinks)) {
-        html5Mode.rewriteLinks = mode.rewriteLinks;
-      }
-
-      return this;
-    } else {
-      return html5Mode;
-    }
-  };
-
-  /**
-   * @ngdoc event
-   * @name $location#$locationChangeStart
-   * @eventType broadcast on root scope
-   * @description
-   * Broadcasted before a URL will change.
-   *
-   * This change can be prevented by calling
-   * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more
-   * details about event object. Upon successful change
-   * {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired.
-   *
-   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
-   * the browser supports the HTML5 History API.
-   *
-   * @param {Object} angularEvent Synthetic event object.
-   * @param {string} newUrl New URL
-   * @param {string=} oldUrl URL that was before it was changed.
-   * @param {string=} newState New history state object
-   * @param {string=} oldState History state object that was before it was changed.
-   */
-
-  /**
-   * @ngdoc event
-   * @name $location#$locationChangeSuccess
-   * @eventType broadcast on root scope
-   * @description
-   * Broadcasted after a URL was changed.
-   *
-   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
-   * the browser supports the HTML5 History API.
-   *
-   * @param {Object} angularEvent Synthetic event object.
-   * @param {string} newUrl New URL
-   * @param {string=} oldUrl URL that was before it was changed.
-   * @param {string=} newState New history state object
-   * @param {string=} oldState History state object that was before it was changed.
-   */
-
-  this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', '$window',
-      function($rootScope, $browser, $sniffer, $rootElement, $window) {
-    var $location,
-        LocationMode,
-        baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
-        initialUrl = $browser.url(),
-        appBase;
-
-    if (html5Mode.enabled) {
-      if (!baseHref && html5Mode.requireBase) {
-        throw $locationMinErr('nobase',
-          '$location in HTML5 mode requires a <base> tag to be present!');
-      }
-      appBase = serverBase(initialUrl) + (baseHref || '/');
-      LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url;
-    } else {
-      appBase = stripHash(initialUrl);
-      LocationMode = LocationHashbangUrl;
-    }
-    var appBaseNoFile = stripFile(appBase);
-
-    $location = new LocationMode(appBase, appBaseNoFile, '#' + hashPrefix);
-    $location.$$parseLinkUrl(initialUrl, initialUrl);
-
-    $location.$$state = $browser.state();
-
-    var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
-
-    function setBrowserUrlWithFallback(url, replace, state) {
-      var oldUrl = $location.url();
-      var oldState = $location.$$state;
-      try {
-        $browser.url(url, replace, state);
-
-        // Make sure $location.state() returns referentially identical (not just deeply equal)
-        // state object; this makes possible quick checking if the state changed in the digest
-        // loop. Checking deep equality would be too expensive.
-        $location.$$state = $browser.state();
-      } catch (e) {
-        // Restore old values if pushState fails
-        $location.url(oldUrl);
-        $location.$$state = oldState;
-
-        throw e;
-      }
-    }
-
-    $rootElement.on('click', function(event) {
-      var rewriteLinks = html5Mode.rewriteLinks;
-      // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
-      // currently we open nice url link and redirect then
-
-      if (!rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 || event.button === 2) return;
-
-      var elm = jqLite(event.target);
-
-      // traverse the DOM up to find first A tag
-      while (nodeName_(elm[0]) !== 'a') {
-        // ignore rewriting if no A tag (reached root element, or no parent - removed from document)
-        if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return;
-      }
-
-      if (isString(rewriteLinks) && isUndefined(elm.attr(rewriteLinks))) return;
-
-      var absHref = elm.prop('href');
-      // get the actual href attribute - see
-      // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx
-      var relHref = elm.attr('href') || elm.attr('xlink:href');
-
-      if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {
-        // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during
-        // an animation.
-        absHref = urlResolve(absHref.animVal).href;
-      }
-
-      // Ignore when url is started with javascript: or mailto:
-      if (IGNORE_URI_REGEXP.test(absHref)) return;
-
-      if (absHref && !elm.attr('target') && !event.isDefaultPrevented()) {
-        if ($location.$$parseLinkUrl(absHref, relHref)) {
-          // We do a preventDefault for all urls that are part of the angular application,
-          // in html5mode and also without, so that we are able to abort navigation without
-          // getting double entries in the location history.
-          event.preventDefault();
-          // update location manually
-          if ($location.absUrl() !== $browser.url()) {
-            $rootScope.$apply();
-            // hack to work around FF6 bug 684208 when scenario runner clicks on links
-            $window.angular['ff-684208-preventDefault'] = true;
-          }
-        }
-      }
-    });
-
-
-    // rewrite hashbang url <> html5 url
-    if (trimEmptyHash($location.absUrl()) !== trimEmptyHash(initialUrl)) {
-      $browser.url($location.absUrl(), true);
-    }
-
-    var initializing = true;
-
-    // update $location when $browser url changes
-    $browser.onUrlChange(function(newUrl, newState) {
-
-      if (!startsWith(newUrl, appBaseNoFile)) {
-        // If we are navigating outside of the app then force a reload
-        $window.location.href = newUrl;
-        return;
-      }
-
-      $rootScope.$evalAsync(function() {
-        var oldUrl = $location.absUrl();
-        var oldState = $location.$$state;
-        var defaultPrevented;
-        newUrl = trimEmptyHash(newUrl);
-        $location.$$parse(newUrl);
-        $location.$$state = newState;
-
-        defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
-            newState, oldState).defaultPrevented;
-
-        // if the location was changed by a `$locationChangeStart` handler then stop
-        // processing this location change
-        if ($location.absUrl() !== newUrl) return;
-
-        if (defaultPrevented) {
-          $location.$$parse(oldUrl);
-          $location.$$state = oldState;
-          setBrowserUrlWithFallback(oldUrl, false, oldState);
-        } else {
-          initializing = false;
-          afterLocationChange(oldUrl, oldState);
-        }
-      });
-      if (!$rootScope.$$phase) $rootScope.$digest();
-    });
-
-    // update browser
-    $rootScope.$watch(function $locationWatch() {
-      if (initializing || $location.$$urlUpdatedByLocation) {
-        $location.$$urlUpdatedByLocation = false;
-
-        var oldUrl = trimEmptyHash($browser.url());
-        var newUrl = trimEmptyHash($location.absUrl());
-        var oldState = $browser.state();
-        var currentReplace = $location.$$replace;
-        var urlOrStateChanged = oldUrl !== newUrl ||
-          ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);
-
-        if (initializing || urlOrStateChanged) {
-          initializing = false;
-
-          $rootScope.$evalAsync(function() {
-            var newUrl = $location.absUrl();
-            var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
-                $location.$$state, oldState).defaultPrevented;
-
-            // if the location was changed by a `$locationChangeStart` handler then stop
-            // processing this location change
-            if ($location.absUrl() !== newUrl) return;
-
-            if (defaultPrevented) {
-              $location.$$parse(oldUrl);
-              $location.$$state = oldState;
-            } else {
-              if (urlOrStateChanged) {
-                setBrowserUrlWithFallback(newUrl, currentReplace,
-                                          oldState === $location.$$state ? null : $location.$$state);
-              }
-              afterLocationChange(oldUrl, oldState);
-            }
-          });
-        }
-      }
-
-      $location.$$replace = false;
-
-      // we don't need to return anything because $evalAsync will make the digest loop dirty when
-      // there is a change
-    });
-
-    return $location;
-
-    function afterLocationChange(oldUrl, oldState) {
-      $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl,
-        $location.$$state, oldState);
-    }
-}];
-}
-
-/**
- * @ngdoc service
- * @name $log
- * @requires $window
- *
- * @description
- * Simple service for logging. Default implementation safely writes the message
- * into the browser's console (if present).
- *
- * The main purpose of this service is to simplify debugging and troubleshooting.
- *
- * The default is to log `debug` messages. You can use
- * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
- *
- * @example
-   <example module="logExample" name="log-service">
-     <file name="script.js">
-       angular.module('logExample', [])
-         .controller('LogController', ['$scope', '$log', function($scope, $log) {
-           $scope.$log = $log;
-           $scope.message = 'Hello World!';
-         }]);
-     </file>
-     <file name="index.html">
-       <div ng-controller="LogController">
-         <p>Reload this page with open console, enter text and hit the log button...</p>
-         <label>Message:
-         <input type="text" ng-model="message" /></label>
-         <button ng-click="$log.log(message)">log</button>
-         <button ng-click="$log.warn(message)">warn</button>
-         <button ng-click="$log.info(message)">info</button>
-         <button ng-click="$log.error(message)">error</button>
-         <button ng-click="$log.debug(message)">debug</button>
-       </div>
-     </file>
-   </example>
- */
-
-/**
- * @ngdoc provider
- * @name $logProvider
- * @this
- *
- * @description
- * Use the `$logProvider` to configure how the application logs messages
- */
-function $LogProvider() {
-  var debug = true,
-      self = this;
-
-  /**
-   * @ngdoc method
-   * @name $logProvider#debugEnabled
-   * @description
-   * @param {boolean=} flag enable or disable debug level messages
-   * @returns {*} current value if used as getter or itself (chaining) if used as setter
-   */
-  this.debugEnabled = function(flag) {
-    if (isDefined(flag)) {
-      debug = flag;
-      return this;
-    } else {
-      return debug;
-    }
-  };
-
-  this.$get = ['$window', function($window) {
-    // Support: IE 9-11, Edge 12-14+
-    // IE/Edge display errors in such a way that it requires the user to click in 4 places
-    // to see the stack trace. There is no way to feature-detect it so there's a chance
-    // of the user agent sniffing to go wrong but since it's only about logging, this shouldn't
-    // break apps. Other browsers display errors in a sensible way and some of them map stack
-    // traces along source maps if available so it makes sense to let browsers display it
-    // as they want.
-    var formatStackTrace = msie || /\bEdge\//.test($window.navigator && $window.navigator.userAgent);
-
-    return {
-      /**
-       * @ngdoc method
-       * @name $log#log
-       *
-       * @description
-       * Write a log message
-       */
-      log: consoleLog('log'),
-
-      /**
-       * @ngdoc method
-       * @name $log#info
-       *
-       * @description
-       * Write an information message
-       */
-      info: consoleLog('info'),
-
-      /**
-       * @ngdoc method
-       * @name $log#warn
-       *
-       * @description
-       * Write a warning message
-       */
-      warn: consoleLog('warn'),
-
-      /**
-       * @ngdoc method
-       * @name $log#error
-       *
-       * @description
-       * Write an error message
-       */
-      error: consoleLog('error'),
-
-      /**
-       * @ngdoc method
-       * @name $log#debug
-       *
-       * @description
-       * Write a debug message
-       */
-      debug: (function() {
-        var fn = consoleLog('debug');
-
-        return function() {
-          if (debug) {
-            fn.apply(self, arguments);
-          }
-        };
-      })()
-    };
-
-    function formatError(arg) {
-      if (arg instanceof Error) {
-        if (arg.stack && formatStackTrace) {
-          arg = (arg.message && arg.stack.indexOf(arg.message) === -1)
-              ? 'Error: ' + arg.message + '\n' + arg.stack
-              : arg.stack;
-        } else if (arg.sourceURL) {
-          arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line;
-        }
-      }
-      return arg;
-    }
-
-    function consoleLog(type) {
-      var console = $window.console || {},
-          logFn = console[type] || console.log || noop,
-          hasApply = false;
-
-      // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
-      // The reason behind this is that console.log has type "object" in IE8...
-      try {
-        hasApply = !!logFn.apply;
-      } catch (e) { /* empty */ }
-
-      if (hasApply) {
-        return function() {
-          var args = [];
-          forEach(arguments, function(arg) {
-            args.push(formatError(arg));
-          });
-          return logFn.apply(console, args);
-        };
-      }
-
-      // we are IE which either doesn't have window.console => this is noop and we do nothing,
-      // or we are IE where console.log doesn't have apply so we log at least first 2 args
-      return function(arg1, arg2) {
-        logFn(arg1, arg2 == null ? '' : arg2);
-      };
-    }
-  }];
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *     Any commits to this file should be reviewed with security in mind.  *
- *   Changes to this file can potentially create security vulnerabilities. *
- *          An approval from 2 Core members with history of modifying      *
- *                         this file is required.                          *
- *                                                                         *
- *  Does the change somehow allow for arbitrary javascript to be executed? *
- *    Or allows for someone to change the prototype of built-in objects?   *
- *     Or gives undesired access to variables likes document or window?    *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-var $parseMinErr = minErr('$parse');
-
-var objectValueOf = {}.constructor.prototype.valueOf;
-
-// Sandboxing Angular Expressions
-// ------------------------------
-// Angular expressions are no longer sandboxed. So it is now even easier to access arbitrary JS code by
-// various means such as obtaining a reference to native JS functions like the Function constructor.
-//
-// As an example, consider the following Angular expression:
-//
-//   {}.toString.constructor('alert("evil JS code")')
-//
-// It is important to realize that if you create an expression from a string that contains user provided
-// content then it is possible that your application contains a security vulnerability to an XSS style attack.
-//
-// See https://docs.angularjs.org/guide/security
-
-
-function getStringValue(name) {
-  // Property names must be strings. This means that non-string objects cannot be used
-  // as keys in an object. Any non-string object, including a number, is typecasted
-  // into a string via the toString method.
-  // -- MDN, https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names
-  //
-  // So, to ensure that we are checking the same `name` that JavaScript would use, we cast it
-  // to a string. It's not always possible. If `name` is an object and its `toString` method is
-  // 'broken' (doesn't return a string, isn't a function, etc.), an error will be thrown:
-  //
-  // TypeError: Cannot convert object to primitive value
-  //
-  // For performance reasons, we don't catch this error here and allow it to propagate up the call
-  // stack. Note that you'll get the same error in JavaScript if you try to access a property using
-  // such a 'broken' object as a key.
-  return name + '';
-}
-
-
-var OPERATORS = createMap();
-forEach('+ - * / % === !== == != < > <= >= && || ! = |'.split(' '), function(operator) { OPERATORS[operator] = true; });
-var ESCAPE = {'n':'\n', 'f':'\f', 'r':'\r', 't':'\t', 'v':'\v', '\'':'\'', '"':'"'};
-
-
-/////////////////////////////////////////
-
-
-/**
- * @constructor
- */
-var Lexer = function Lexer(options) {
-  this.options = options;
-};
-
-Lexer.prototype = {
-  constructor: Lexer,
-
-  lex: function(text) {
-    this.text = text;
-    this.index = 0;
-    this.tokens = [];
-
-    while (this.index < this.text.length) {
-      var ch = this.text.charAt(this.index);
-      if (ch === '"' || ch === '\'') {
-        this.readString(ch);
-      } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {
-        this.readNumber();
-      } else if (this.isIdentifierStart(this.peekMultichar())) {
-        this.readIdent();
-      } else if (this.is(ch, '(){}[].,;:?')) {
-        this.tokens.push({index: this.index, text: ch});
-        this.index++;
-      } else if (this.isWhitespace(ch)) {
-        this.index++;
-      } else {
-        var ch2 = ch + this.peek();
-        var ch3 = ch2 + this.peek(2);
-        var op1 = OPERATORS[ch];
-        var op2 = OPERATORS[ch2];
-        var op3 = OPERATORS[ch3];
-        if (op1 || op2 || op3) {
-          var token = op3 ? ch3 : (op2 ? ch2 : ch);
-          this.tokens.push({index: this.index, text: token, operator: true});
-          this.index += token.length;
-        } else {
-          this.throwError('Unexpected next character ', this.index, this.index + 1);
-        }
-      }
-    }
-    return this.tokens;
-  },
-
-  is: function(ch, chars) {
-    return chars.indexOf(ch) !== -1;
-  },
-
-  peek: function(i) {
-    var num = i || 1;
-    return (this.index + num < this.text.length) ? this.text.charAt(this.index + num) : false;
-  },
-
-  isNumber: function(ch) {
-    return ('0' <= ch && ch <= '9') && typeof ch === 'string';
-  },
-
-  isWhitespace: function(ch) {
-    // IE treats non-breaking space as \u00A0
-    return (ch === ' ' || ch === '\r' || ch === '\t' ||
-            ch === '\n' || ch === '\v' || ch === '\u00A0');
-  },
-
-  isIdentifierStart: function(ch) {
-    return this.options.isIdentifierStart ?
-        this.options.isIdentifierStart(ch, this.codePointAt(ch)) :
-        this.isValidIdentifierStart(ch);
-  },
-
-  isValidIdentifierStart: function(ch) {
-    return ('a' <= ch && ch <= 'z' ||
-            'A' <= ch && ch <= 'Z' ||
-            '_' === ch || ch === '$');
-  },
-
-  isIdentifierContinue: function(ch) {
-    return this.options.isIdentifierContinue ?
-        this.options.isIdentifierContinue(ch, this.codePointAt(ch)) :
-        this.isValidIdentifierContinue(ch);
-  },
-
-  isValidIdentifierContinue: function(ch, cp) {
-    return this.isValidIdentifierStart(ch, cp) || this.isNumber(ch);
-  },
-
-  codePointAt: function(ch) {
-    if (ch.length === 1) return ch.charCodeAt(0);
-    // eslint-disable-next-line no-bitwise
-    return (ch.charCodeAt(0) << 10) + ch.charCodeAt(1) - 0x35FDC00;
-  },
-
-  peekMultichar: function() {
-    var ch = this.text.charAt(this.index);
-    var peek = this.peek();
-    if (!peek) {
-      return ch;
-    }
-    var cp1 = ch.charCodeAt(0);
-    var cp2 = peek.charCodeAt(0);
-    if (cp1 >= 0xD800 && cp1 <= 0xDBFF && cp2 >= 0xDC00 && cp2 <= 0xDFFF) {
-      return ch + peek;
-    }
-    return ch;
-  },
-
-  isExpOperator: function(ch) {
-    return (ch === '-' || ch === '+' || this.isNumber(ch));
-  },
-
-  throwError: function(error, start, end) {
-    end = end || this.index;
-    var colStr = (isDefined(start)
-            ? 's ' + start +  '-' + this.index + ' [' + this.text.substring(start, end) + ']'
-            : ' ' + end);
-    throw $parseMinErr('lexerr', 'Lexer Error: {0} at column{1} in expression [{2}].',
-        error, colStr, this.text);
-  },
-
-  readNumber: function() {
-    var number = '';
-    var start = this.index;
-    while (this.index < this.text.length) {
-      var ch = lowercase(this.text.charAt(this.index));
-      if (ch === '.' || this.isNumber(ch)) {
-        number += ch;
-      } else {
-        var peekCh = this.peek();
-        if (ch === 'e' && this.isExpOperator(peekCh)) {
-          number += ch;
-        } else if (this.isExpOperator(ch) &&
-            peekCh && this.isNumber(peekCh) &&
-            number.charAt(number.length - 1) === 'e') {
-          number += ch;
-        } else if (this.isExpOperator(ch) &&
-            (!peekCh || !this.isNumber(peekCh)) &&
-            number.charAt(number.length - 1) === 'e') {
-          this.throwError('Invalid exponent');
-        } else {
-          break;
-        }
-      }
-      this.index++;
-    }
-    this.tokens.push({
-      index: start,
-      text: number,
-      constant: true,
-      value: Number(number)
-    });
-  },
-
-  readIdent: function() {
-    var start = this.index;
-    this.index += this.peekMultichar().length;
-    while (this.index < this.text.length) {
-      var ch = this.peekMultichar();
-      if (!this.isIdentifierContinue(ch)) {
-        break;
-      }
-      this.index += ch.length;
-    }
-    this.tokens.push({
-      index: start,
-      text: this.text.slice(start, this.index),
-      identifier: true
-    });
-  },
-
-  readString: function(quote) {
-    var start = this.index;
-    this.index++;
-    var string = '';
-    var rawString = quote;
-    var escape = false;
-    while (this.index < this.text.length) {
-      var ch = this.text.charAt(this.index);
-      rawString += ch;
-      if (escape) {
-        if (ch === 'u') {
-          var hex = this.text.substring(this.index + 1, this.index + 5);
-          if (!hex.match(/[\da-f]{4}/i)) {
-            this.throwError('Invalid unicode escape [\\u' + hex + ']');
-          }
-          this.index += 4;
-          string += String.fromCharCode(parseInt(hex, 16));
-        } else {
-          var rep = ESCAPE[ch];
-          string = string + (rep || ch);
-        }
-        escape = false;
-      } else if (ch === '\\') {
-        escape = true;
-      } else if (ch === quote) {
-        this.index++;
-        this.tokens.push({
-          index: start,
-          text: rawString,
-          constant: true,
-          value: string
-        });
-        return;
-      } else {
-        string += ch;
-      }
-      this.index++;
-    }
-    this.throwError('Unterminated quote', start);
-  }
-};
-
-var AST = function AST(lexer, options) {
-  this.lexer = lexer;
-  this.options = options;
-};
-
-AST.Program = 'Program';
-AST.ExpressionStatement = 'ExpressionStatement';
-AST.AssignmentExpression = 'AssignmentExpression';
-AST.ConditionalExpression = 'ConditionalExpression';
-AST.LogicalExpression = 'LogicalExpression';
-AST.BinaryExpression = 'BinaryExpression';
-AST.UnaryExpression = 'UnaryExpression';
-AST.CallExpression = 'CallExpression';
-AST.MemberExpression = 'MemberExpression';
-AST.Identifier = 'Identifier';
-AST.Literal = 'Literal';
-AST.ArrayExpression = 'ArrayExpression';
-AST.Property = 'Property';
-AST.ObjectExpression = 'ObjectExpression';
-AST.ThisExpression = 'ThisExpression';
-AST.LocalsExpression = 'LocalsExpression';
-
-// Internal use only
-AST.NGValueParameter = 'NGValueParameter';
-
-AST.prototype = {
-  ast: function(text) {
-    this.text = text;
-    this.tokens = this.lexer.lex(text);
-
-    var value = this.program();
-
-    if (this.tokens.length !== 0) {
-      this.throwError('is an unexpected token', this.tokens[0]);
-    }
-
-    return value;
-  },
-
-  program: function() {
-    var body = [];
-    while (true) {
-      if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))
-        body.push(this.expressionStatement());
-      if (!this.expect(';')) {
-        return { type: AST.Program, body: body};
-      }
-    }
-  },
-
-  expressionStatement: function() {
-    return { type: AST.ExpressionStatement, expression: this.filterChain() };
-  },
-
-  filterChain: function() {
-    var left = this.expression();
-    while (this.expect('|')) {
-      left = this.filter(left);
-    }
-    return left;
-  },
-
-  expression: function() {
-    return this.assignment();
-  },
-
-  assignment: function() {
-    var result = this.ternary();
-    if (this.expect('=')) {
-      if (!isAssignable(result)) {
-        throw $parseMinErr('lval', 'Trying to assign a value to a non l-value');
-      }
-
-      result = { type: AST.AssignmentExpression, left: result, right: this.assignment(), operator: '='};
-    }
-    return result;
-  },
-
-  ternary: function() {
-    var test = this.logicalOR();
-    var alternate;
-    var consequent;
-    if (this.expect('?')) {
-      alternate = this.expression();
-      if (this.consume(':')) {
-        consequent = this.expression();
-        return { type: AST.ConditionalExpression, test: test, alternate: alternate, consequent: consequent};
-      }
-    }
-    return test;
-  },
-
-  logicalOR: function() {
-    var left = this.logicalAND();
-    while (this.expect('||')) {
-      left = { type: AST.LogicalExpression, operator: '||', left: left, right: this.logicalAND() };
-    }
-    return left;
-  },
-
-  logicalAND: function() {
-    var left = this.equality();
-    while (this.expect('&&')) {
-      left = { type: AST.LogicalExpression, operator: '&&', left: left, right: this.equality()};
-    }
-    return left;
-  },
-
-  equality: function() {
-    var left = this.relational();
-    var token;
-    while ((token = this.expect('==','!=','===','!=='))) {
-      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.relational() };
-    }
-    return left;
-  },
-
-  relational: function() {
-    var left = this.additive();
-    var token;
-    while ((token = this.expect('<', '>', '<=', '>='))) {
-      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.additive() };
-    }
-    return left;
-  },
-
-  additive: function() {
-    var left = this.multiplicative();
-    var token;
-    while ((token = this.expect('+','-'))) {
-      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.multiplicative() };
-    }
-    return left;
-  },
-
-  multiplicative: function() {
-    var left = this.unary();
-    var token;
-    while ((token = this.expect('*','/','%'))) {
-      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.unary() };
-    }
-    return left;
-  },
-
-  unary: function() {
-    var token;
-    if ((token = this.expect('+', '-', '!'))) {
-      return { type: AST.UnaryExpression, operator: token.text, prefix: true, argument: this.unary() };
-    } else {
-      return this.primary();
-    }
-  },
-
-  primary: function() {
-    var primary;
-    if (this.expect('(')) {
-      primary = this.filterChain();
-      this.consume(')');
-    } else if (this.expect('[')) {
-      primary = this.arrayDeclaration();
-    } else if (this.expect('{')) {
-      primary = this.object();
-    } else if (this.selfReferential.hasOwnProperty(this.peek().text)) {
-      primary = copy(this.selfReferential[this.consume().text]);
-    } else if (this.options.literals.hasOwnProperty(this.peek().text)) {
-      primary = { type: AST.Literal, value: this.options.literals[this.consume().text]};
-    } else if (this.peek().identifier) {
-      primary = this.identifier();
-    } else if (this.peek().constant) {
-      primary = this.constant();
-    } else {
-      this.throwError('not a primary expression', this.peek());
-    }
-
-    var next;
-    while ((next = this.expect('(', '[', '.'))) {
-      if (next.text === '(') {
-        primary = {type: AST.CallExpression, callee: primary, arguments: this.parseArguments() };
-        this.consume(')');
-      } else if (next.text === '[') {
-        primary = { type: AST.MemberExpression, object: primary, property: this.expression(), computed: true };
-        this.consume(']');
-      } else if (next.text === '.') {
-        primary = { type: AST.MemberExpression, object: primary, property: this.identifier(), computed: false };
-      } else {
-        this.throwError('IMPOSSIBLE');
-      }
-    }
-    return primary;
-  },
-
-  filter: function(baseExpression) {
-    var args = [baseExpression];
-    var result = {type: AST.CallExpression, callee: this.identifier(), arguments: args, filter: true};
-
-    while (this.expect(':')) {
-      args.push(this.expression());
-    }
-
-    return result;
-  },
-
-  parseArguments: function() {
-    var args = [];
-    if (this.peekToken().text !== ')') {
-      do {
-        args.push(this.filterChain());
-      } while (this.expect(','));
-    }
-    return args;
-  },
-
-  identifier: function() {
-    var token = this.consume();
-    if (!token.identifier) {
-      this.throwError('is not a valid identifier', token);
-    }
-    return { type: AST.Identifier, name: token.text };
-  },
-
-  constant: function() {
-    // TODO check that it is a constant
-    return { type: AST.Literal, value: this.consume().value };
-  },
-
-  arrayDeclaration: function() {
-    var elements = [];
-    if (this.peekToken().text !== ']') {
-      do {
-        if (this.peek(']')) {
-          // Support trailing commas per ES5.1.
-          break;
-        }
-        elements.push(this.expression());
-      } while (this.expect(','));
-    }
-    this.consume(']');
-
-    return { type: AST.ArrayExpression, elements: elements };
-  },
-
-  object: function() {
-    var properties = [], property;
-    if (this.peekToken().text !== '}') {
-      do {
-        if (this.peek('}')) {
-          // Support trailing commas per ES5.1.
-          break;
-        }
-        property = {type: AST.Property, kind: 'init'};
-        if (this.peek().constant) {
-          property.key = this.constant();
-          property.computed = false;
-          this.consume(':');
-          property.value = this.expression();
-        } else if (this.peek().identifier) {
-          property.key = this.identifier();
-          property.computed = false;
-          if (this.peek(':')) {
-            this.consume(':');
-            property.value = this.expression();
-          } else {
-            property.value = property.key;
-          }
-        } else if (this.peek('[')) {
-          this.consume('[');
-          property.key = this.expression();
-          this.consume(']');
-          property.computed = true;
-          this.consume(':');
-          property.value = this.expression();
-        } else {
-          this.throwError('invalid key', this.peek());
-        }
-        properties.push(property);
-      } while (this.expect(','));
-    }
-    this.consume('}');
-
-    return {type: AST.ObjectExpression, properties: properties };
-  },
-
-  throwError: function(msg, token) {
-    throw $parseMinErr('syntax',
-        'Syntax Error: Token \'{0}\' {1} at column {2} of the expression [{3}] starting at [{4}].',
-          token.text, msg, (token.index + 1), this.text, this.text.substring(token.index));
-  },
-
-  consume: function(e1) {
-    if (this.tokens.length === 0) {
-      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
-    }
-
-    var token = this.expect(e1);
-    if (!token) {
-      this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());
-    }
-    return token;
-  },
-
-  peekToken: function() {
-    if (this.tokens.length === 0) {
-      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
-    }
-    return this.tokens[0];
-  },
-
-  peek: function(e1, e2, e3, e4) {
-    return this.peekAhead(0, e1, e2, e3, e4);
-  },
-
-  peekAhead: function(i, e1, e2, e3, e4) {
-    if (this.tokens.length > i) {
-      var token = this.tokens[i];
-      var t = token.text;
-      if (t === e1 || t === e2 || t === e3 || t === e4 ||
-          (!e1 && !e2 && !e3 && !e4)) {
-        return token;
-      }
-    }
-    return false;
-  },
-
-  expect: function(e1, e2, e3, e4) {
-    var token = this.peek(e1, e2, e3, e4);
-    if (token) {
-      this.tokens.shift();
-      return token;
-    }
-    return false;
-  },
-
-  selfReferential: {
-    'this': {type: AST.ThisExpression },
-    '$locals': {type: AST.LocalsExpression }
-  }
-};
-
-function ifDefined(v, d) {
-  return typeof v !== 'undefined' ? v : d;
-}
-
-function plusFn(l, r) {
-  if (typeof l === 'undefined') return r;
-  if (typeof r === 'undefined') return l;
-  return l + r;
-}
-
-function isStateless($filter, filterName) {
-  var fn = $filter(filterName);
-  return !fn.$stateful;
-}
-
-function findConstantAndWatchExpressions(ast, $filter) {
-  var allConstants;
-  var argsToWatch;
-  var isStatelessFilter;
-  switch (ast.type) {
-  case AST.Program:
-    allConstants = true;
-    forEach(ast.body, function(expr) {
-      findConstantAndWatchExpressions(expr.expression, $filter);
-      allConstants = allConstants && expr.expression.constant;
-    });
-    ast.constant = allConstants;
-    break;
-  case AST.Literal:
-    ast.constant = true;
-    ast.toWatch = [];
-    break;
-  case AST.UnaryExpression:
-    findConstantAndWatchExpressions(ast.argument, $filter);
-    ast.constant = ast.argument.constant;
-    ast.toWatch = ast.argument.toWatch;
-    break;
-  case AST.BinaryExpression:
-    findConstantAndWatchExpressions(ast.left, $filter);
-    findConstantAndWatchExpressions(ast.right, $filter);
-    ast.constant = ast.left.constant && ast.right.constant;
-    ast.toWatch = ast.left.toWatch.concat(ast.right.toWatch);
-    break;
-  case AST.LogicalExpression:
-    findConstantAndWatchExpressions(ast.left, $filter);
-    findConstantAndWatchExpressions(ast.right, $filter);
-    ast.constant = ast.left.constant && ast.right.constant;
-    ast.toWatch = ast.constant ? [] : [ast];
-    break;
-  case AST.ConditionalExpression:
-    findConstantAndWatchExpressions(ast.test, $filter);
-    findConstantAndWatchExpressions(ast.alternate, $filter);
-    findConstantAndWatchExpressions(ast.consequent, $filter);
-    ast.constant = ast.test.constant && ast.alternate.constant && ast.consequent.constant;
-    ast.toWatch = ast.constant ? [] : [ast];
-    break;
-  case AST.Identifier:
-    ast.constant = false;
-    ast.toWatch = [ast];
-    break;
-  case AST.MemberExpression:
-    findConstantAndWatchExpressions(ast.object, $filter);
-    if (ast.computed) {
-      findConstantAndWatchExpressions(ast.property, $filter);
-    }
-    ast.constant = ast.object.constant && (!ast.computed || ast.property.constant);
-    ast.toWatch = [ast];
-    break;
-  case AST.CallExpression:
-    isStatelessFilter = ast.filter ? isStateless($filter, ast.callee.name) : false;
-    allConstants = isStatelessFilter;
-    argsToWatch = [];
-    forEach(ast.arguments, function(expr) {
-      findConstantAndWatchExpressions(expr, $filter);
-      allConstants = allConstants && expr.constant;
-      if (!expr.constant) {
-        argsToWatch.push.apply(argsToWatch, expr.toWatch);
-      }
-    });
-    ast.constant = allConstants;
-    ast.toWatch = isStatelessFilter ? argsToWatch : [ast];
-    break;
-  case AST.AssignmentExpression:
-    findConstantAndWatchExpressions(ast.left, $filter);
-    findConstantAndWatchExpressions(ast.right, $filter);
-    ast.constant = ast.left.constant && ast.right.constant;
-    ast.toWatch = [ast];
-    break;
-  case AST.ArrayExpression:
-    allConstants = true;
-    argsToWatch = [];
-    forEach(ast.elements, function(expr) {
-      findConstantAndWatchExpressions(expr, $filter);
-      allConstants = allConstants && expr.constant;
-      if (!expr.constant) {
-        argsToWatch.push.apply(argsToWatch, expr.toWatch);
-      }
-    });
-    ast.constant = allConstants;
-    ast.toWatch = argsToWatch;
-    break;
-  case AST.ObjectExpression:
-    allConstants = true;
-    argsToWatch = [];
-    forEach(ast.properties, function(property) {
-      findConstantAndWatchExpressions(property.value, $filter);
-      allConstants = allConstants && property.value.constant && !property.computed;
-      if (!property.value.constant) {
-        argsToWatch.push.apply(argsToWatch, property.value.toWatch);
-      }
-      if (property.computed) {
-        findConstantAndWatchExpressions(property.key, $filter);
-        if (!property.key.constant) {
-          argsToWatch.push.apply(argsToWatch, property.key.toWatch);
-        }
-      }
-
-    });
-    ast.constant = allConstants;
-    ast.toWatch = argsToWatch;
-    break;
-  case AST.ThisExpression:
-    ast.constant = false;
-    ast.toWatch = [];
-    break;
-  case AST.LocalsExpression:
-    ast.constant = false;
-    ast.toWatch = [];
-    break;
-  }
-}
-
-function getInputs(body) {
-  if (body.length !== 1) return;
-  var lastExpression = body[0].expression;
-  var candidate = lastExpression.toWatch;
-  if (candidate.length !== 1) return candidate;
-  return candidate[0] !== lastExpression ? candidate : undefined;
-}
-
-function isAssignable(ast) {
-  return ast.type === AST.Identifier || ast.type === AST.MemberExpression;
-}
-
-function assignableAST(ast) {
-  if (ast.body.length === 1 && isAssignable(ast.body[0].expression)) {
-    return {type: AST.AssignmentExpression, left: ast.body[0].expression, right: {type: AST.NGValueParameter}, operator: '='};
-  }
-}
-
-function isLiteral(ast) {
-  return ast.body.length === 0 ||
-      ast.body.length === 1 && (
-      ast.body[0].expression.type === AST.Literal ||
-      ast.body[0].expression.type === AST.ArrayExpression ||
-      ast.body[0].expression.type === AST.ObjectExpression);
-}
-
-function isConstant(ast) {
-  return ast.constant;
-}
-
-function ASTCompiler(astBuilder, $filter) {
-  this.astBuilder = astBuilder;
-  this.$filter = $filter;
-}
-
-ASTCompiler.prototype = {
-  compile: function(expression) {
-    var self = this;
-    var ast = this.astBuilder.ast(expression);
-    this.state = {
-      nextId: 0,
-      filters: {},
-      fn: {vars: [], body: [], own: {}},
-      assign: {vars: [], body: [], own: {}},
-      inputs: []
-    };
-    findConstantAndWatchExpressions(ast, self.$filter);
-    var extra = '';
-    var assignable;
-    this.stage = 'assign';
-    if ((assignable = assignableAST(ast))) {
-      this.state.computing = 'assign';
-      var result = this.nextId();
-      this.recurse(assignable, result);
-      this.return_(result);
-      extra = 'fn.assign=' + this.generateFunction('assign', 's,v,l');
-    }
-    var toWatch = getInputs(ast.body);
-    self.stage = 'inputs';
-    forEach(toWatch, function(watch, key) {
-      var fnKey = 'fn' + key;
-      self.state[fnKey] = {vars: [], body: [], own: {}};
-      self.state.computing = fnKey;
-      var intoId = self.nextId();
-      self.recurse(watch, intoId);
-      self.return_(intoId);
-      self.state.inputs.push(fnKey);
-      watch.watchId = key;
-    });
-    this.state.computing = 'fn';
-    this.stage = 'main';
-    this.recurse(ast);
-    var fnString =
-      // The build and minification steps remove the string "use strict" from the code, but this is done using a regex.
-      // This is a workaround for this until we do a better job at only removing the prefix only when we should.
-      '"' + this.USE + ' ' + this.STRICT + '";\n' +
-      this.filterPrefix() +
-      'var fn=' + this.generateFunction('fn', 's,l,a,i') +
-      extra +
-      this.watchFns() +
-      'return fn;';
-
-    // eslint-disable-next-line no-new-func
-    var fn = (new Function('$filter',
-        'getStringValue',
-        'ifDefined',
-        'plus',
-        fnString))(
-          this.$filter,
-          getStringValue,
-          ifDefined,
-          plusFn);
-    this.state = this.stage = undefined;
-    fn.literal = isLiteral(ast);
-    fn.constant = isConstant(ast);
-    return fn;
-  },
-
-  USE: 'use',
-
-  STRICT: 'strict',
-
-  watchFns: function() {
-    var result = [];
-    var fns = this.state.inputs;
-    var self = this;
-    forEach(fns, function(name) {
-      result.push('var ' + name + '=' + self.generateFunction(name, 's'));
-    });
-    if (fns.length) {
-      result.push('fn.inputs=[' + fns.join(',') + '];');
-    }
-    return result.join('');
-  },
-
-  generateFunction: function(name, params) {
-    return 'function(' + params + '){' +
-        this.varsPrefix(name) +
-        this.body(name) +
-        '};';
-  },
-
-  filterPrefix: function() {
-    var parts = [];
-    var self = this;
-    forEach(this.state.filters, function(id, filter) {
-      parts.push(id + '=$filter(' + self.escape(filter) + ')');
-    });
-    if (parts.length) return 'var ' + parts.join(',') + ';';
-    return '';
-  },
-
-  varsPrefix: function(section) {
-    return this.state[section].vars.length ? 'var ' + this.state[section].vars.join(',') + ';' : '';
-  },
-
-  body: function(section) {
-    return this.state[section].body.join('');
-  },
-
-  recurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {
-    var left, right, self = this, args, expression, computed;
-    recursionFn = recursionFn || noop;
-    if (!skipWatchIdCheck && isDefined(ast.watchId)) {
-      intoId = intoId || this.nextId();
-      this.if_('i',
-        this.lazyAssign(intoId, this.computedMember('i', ast.watchId)),
-        this.lazyRecurse(ast, intoId, nameId, recursionFn, create, true)
-      );
-      return;
-    }
-    switch (ast.type) {
-    case AST.Program:
-      forEach(ast.body, function(expression, pos) {
-        self.recurse(expression.expression, undefined, undefined, function(expr) { right = expr; });
-        if (pos !== ast.body.length - 1) {
-          self.current().body.push(right, ';');
-        } else {
-          self.return_(right);
-        }
-      });
-      break;
-    case AST.Literal:
-      expression = this.escape(ast.value);
-      this.assign(intoId, expression);
-      recursionFn(intoId || expression);
-      break;
-    case AST.UnaryExpression:
-      this.recurse(ast.argument, undefined, undefined, function(expr) { right = expr; });
-      expression = ast.operator + '(' + this.ifDefined(right, 0) + ')';
-      this.assign(intoId, expression);
-      recursionFn(expression);
-      break;
-    case AST.BinaryExpression:
-      this.recurse(ast.left, undefined, undefined, function(expr) { left = expr; });
-      this.recurse(ast.right, undefined, undefined, function(expr) { right = expr; });
-      if (ast.operator === '+') {
-        expression = this.plus(left, right);
-      } else if (ast.operator === '-') {
-        expression = this.ifDefined(left, 0) + ast.operator + this.ifDefined(right, 0);
-      } else {
-        expression = '(' + left + ')' + ast.operator + '(' + right + ')';
-      }
-      this.assign(intoId, expression);
-      recursionFn(expression);
-      break;
-    case AST.LogicalExpression:
-      intoId = intoId || this.nextId();
-      self.recurse(ast.left, intoId);
-      self.if_(ast.operator === '&&' ? intoId : self.not(intoId), self.lazyRecurse(ast.right, intoId));
-      recursionFn(intoId);
-      break;
-    case AST.ConditionalExpression:
-      intoId = intoId || this.nextId();
-      self.recurse(ast.test, intoId);
-      self.if_(intoId, self.lazyRecurse(ast.alternate, intoId), self.lazyRecurse(ast.consequent, intoId));
-      recursionFn(intoId);
-      break;
-    case AST.Identifier:
-      intoId = intoId || this.nextId();
-      if (nameId) {
-        nameId.context = self.stage === 'inputs' ? 's' : this.assign(this.nextId(), this.getHasOwnProperty('l', ast.name) + '?l:s');
-        nameId.computed = false;
-        nameId.name = ast.name;
-      }
-      self.if_(self.stage === 'inputs' || self.not(self.getHasOwnProperty('l', ast.name)),
-        function() {
-          self.if_(self.stage === 'inputs' || 's', function() {
-            if (create && create !== 1) {
-              self.if_(
-                self.isNull(self.nonComputedMember('s', ast.name)),
-                self.lazyAssign(self.nonComputedMember('s', ast.name), '{}'));
-            }
-            self.assign(intoId, self.nonComputedMember('s', ast.name));
-          });
-        }, intoId && self.lazyAssign(intoId, self.nonComputedMember('l', ast.name))
-        );
-      recursionFn(intoId);
-      break;
-    case AST.MemberExpression:
-      left = nameId && (nameId.context = this.nextId()) || this.nextId();
-      intoId = intoId || this.nextId();
-      self.recurse(ast.object, left, undefined, function() {
-        self.if_(self.notNull(left), function() {
-          if (ast.computed) {
-            right = self.nextId();
-            self.recurse(ast.property, right);
-            self.getStringValue(right);
-            if (create && create !== 1) {
-              self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), '{}'));
-            }
-            expression = self.computedMember(left, right);
-            self.assign(intoId, expression);
-            if (nameId) {
-              nameId.computed = true;
-              nameId.name = right;
-            }
-          } else {
-            if (create && create !== 1) {
-              self.if_(self.isNull(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}'));
-            }
-            expression = self.nonComputedMember(left, ast.property.name);
-            self.assign(intoId, expression);
-            if (nameId) {
-              nameId.computed = false;
-              nameId.name = ast.property.name;
-            }
-          }
-        }, function() {
-          self.assign(intoId, 'undefined');
-        });
-        recursionFn(intoId);
-      }, !!create);
-      break;
-    case AST.CallExpression:
-      intoId = intoId || this.nextId();
-      if (ast.filter) {
-        right = self.filter(ast.callee.name);
-        args = [];
-        forEach(ast.arguments, function(expr) {
-          var argument = self.nextId();
-          self.recurse(expr, argument);
-          args.push(argument);
-        });
-        expression = right + '(' + args.join(',') + ')';
-        self.assign(intoId, expression);
-        recursionFn(intoId);
-      } else {
-        right = self.nextId();
-        left = {};
-        args = [];
-        self.recurse(ast.callee, right, left, function() {
-          self.if_(self.notNull(right), function() {
-            forEach(ast.arguments, function(expr) {
-              self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) {
-                args.push(argument);
-              });
-            });
-            if (left.name) {
-              expression = self.member(left.context, left.name, left.computed) + '(' + args.join(',') + ')';
-            } else {
-              expression = right + '(' + args.join(',') + ')';
-            }
-            self.assign(intoId, expression);
-          }, function() {
-            self.assign(intoId, 'undefined');
-          });
-          recursionFn(intoId);
-        });
-      }
-      break;
-    case AST.AssignmentExpression:
-      right = this.nextId();
-      left = {};
-      this.recurse(ast.left, undefined, left, function() {
-        self.if_(self.notNull(left.context), function() {
-          self.recurse(ast.right, right);
-          expression = self.member(left.context, left.name, left.computed) + ast.operator + right;
-          self.assign(intoId, expression);
-          recursionFn(intoId || expression);
-        });
-      }, 1);
-      break;
-    case AST.ArrayExpression:
-      args = [];
-      forEach(ast.elements, function(expr) {
-        self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) {
-          args.push(argument);
-        });
-      });
-      expression = '[' + args.join(',') + ']';
-      this.assign(intoId, expression);
-      recursionFn(intoId || expression);
-      break;
-    case AST.ObjectExpression:
-      args = [];
-      computed = false;
-      forEach(ast.properties, function(property) {
-        if (property.computed) {
-          computed = true;
-        }
-      });
-      if (computed) {
-        intoId = intoId || this.nextId();
-        this.assign(intoId, '{}');
-        forEach(ast.properties, function(property) {
-          if (property.computed) {
-            left = self.nextId();
-            self.recurse(property.key, left);
-          } else {
-            left = property.key.type === AST.Identifier ?
-                       property.key.name :
-                       ('' + property.key.value);
-          }
-          right = self.nextId();
-          self.recurse(property.value, right);
-          self.assign(self.member(intoId, left, property.computed), right);
-        });
-      } else {
-        forEach(ast.properties, function(property) {
-          self.recurse(property.value, ast.constant ? undefined : self.nextId(), undefined, function(expr) {
-            args.push(self.escape(
-                property.key.type === AST.Identifier ? property.key.name :
-                  ('' + property.key.value)) +
-                ':' + expr);
-          });
-        });
-        expression = '{' + args.join(',') + '}';
-        this.assign(intoId, expression);
-      }
-      recursionFn(intoId || expression);
-      break;
-    case AST.ThisExpression:
-      this.assign(intoId, 's');
-      recursionFn(intoId || 's');
-      break;
-    case AST.LocalsExpression:
-      this.assign(intoId, 'l');
-      recursionFn(intoId || 'l');
-      break;
-    case AST.NGValueParameter:
-      this.assign(intoId, 'v');
-      recursionFn(intoId || 'v');
-      break;
-    }
-  },
-
-  getHasOwnProperty: function(element, property) {
-    var key = element + '.' + property;
-    var own = this.current().own;
-    if (!own.hasOwnProperty(key)) {
-      own[key] = this.nextId(false, element + '&&(' + this.escape(property) + ' in ' + element + ')');
-    }
-    return own[key];
-  },
-
-  assign: function(id, value) {
-    if (!id) return;
-    this.current().body.push(id, '=', value, ';');
-    return id;
-  },
-
-  filter: function(filterName) {
-    if (!this.state.filters.hasOwnProperty(filterName)) {
-      this.state.filters[filterName] = this.nextId(true);
-    }
-    return this.state.filters[filterName];
-  },
-
-  ifDefined: function(id, defaultValue) {
-    return 'ifDefined(' + id + ',' + this.escape(defaultValue) + ')';
-  },
-
-  plus: function(left, right) {
-    return 'plus(' + left + ',' + right + ')';
-  },
-
-  return_: function(id) {
-    this.current().body.push('return ', id, ';');
-  },
-
-  if_: function(test, alternate, consequent) {
-    if (test === true) {
-      alternate();
-    } else {
-      var body = this.current().body;
-      body.push('if(', test, '){');
-      alternate();
-      body.push('}');
-      if (consequent) {
-        body.push('else{');
-        consequent();
-        body.push('}');
-      }
-    }
-  },
-
-  not: function(expression) {
-    return '!(' + expression + ')';
-  },
-
-  isNull: function(expression) {
-    return expression + '==null';
-  },
-
-  notNull: function(expression) {
-    return expression + '!=null';
-  },
-
-  nonComputedMember: function(left, right) {
-    var SAFE_IDENTIFIER = /^[$_a-zA-Z][$_a-zA-Z0-9]*$/;
-    var UNSAFE_CHARACTERS = /[^$_a-zA-Z0-9]/g;
-    if (SAFE_IDENTIFIER.test(right)) {
-      return left + '.' + right;
-    } else {
-      return left  + '["' + right.replace(UNSAFE_CHARACTERS, this.stringEscapeFn) + '"]';
-    }
-  },
-
-  computedMember: function(left, right) {
-    return left + '[' + right + ']';
-  },
-
-  member: function(left, right, computed) {
-    if (computed) return this.computedMember(left, right);
-    return this.nonComputedMember(left, right);
-  },
-
-  getStringValue: function(item) {
-    this.assign(item, 'getStringValue(' + item + ')');
-  },
-
-  lazyRecurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {
-    var self = this;
-    return function() {
-      self.recurse(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck);
-    };
-  },
-
-  lazyAssign: function(id, value) {
-    var self = this;
-    return function() {
-      self.assign(id, value);
-    };
-  },
-
-  stringEscapeRegex: /[^ a-zA-Z0-9]/g,
-
-  stringEscapeFn: function(c) {
-    return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4);
-  },
-
-  escape: function(value) {
-    if (isString(value)) return '\'' + value.replace(this.stringEscapeRegex, this.stringEscapeFn) + '\'';
-    if (isNumber(value)) return value.toString();
-    if (value === true) return 'true';
-    if (value === false) return 'false';
-    if (value === null) return 'null';
-    if (typeof value === 'undefined') return 'undefined';
-
-    throw $parseMinErr('esc', 'IMPOSSIBLE');
-  },
-
-  nextId: function(skip, init) {
-    var id = 'v' + (this.state.nextId++);
-    if (!skip) {
-      this.current().vars.push(id + (init ? '=' + init : ''));
-    }
-    return id;
-  },
-
-  current: function() {
-    return this.state[this.state.computing];
-  }
-};
-
-
-function ASTInterpreter(astBuilder, $filter) {
-  this.astBuilder = astBuilder;
-  this.$filter = $filter;
-}
-
-ASTInterpreter.prototype = {
-  compile: function(expression) {
-    var self = this;
-    var ast = this.astBuilder.ast(expression);
-    findConstantAndWatchExpressions(ast, self.$filter);
-    var assignable;
-    var assign;
-    if ((assignable = assignableAST(ast))) {
-      assign = this.recurse(assignable);
-    }
-    var toWatch = getInputs(ast.body);
-    var inputs;
-    if (toWatch) {
-      inputs = [];
-      forEach(toWatch, function(watch, key) {
-        var input = self.recurse(watch);
-        watch.input = input;
-        inputs.push(input);
-        watch.watchId = key;
-      });
-    }
-    var expressions = [];
-    forEach(ast.body, function(expression) {
-      expressions.push(self.recurse(expression.expression));
-    });
-    var fn = ast.body.length === 0 ? noop :
-             ast.body.length === 1 ? expressions[0] :
-             function(scope, locals) {
-               var lastValue;
-               forEach(expressions, function(exp) {
-                 lastValue = exp(scope, locals);
-               });
-               return lastValue;
-             };
-    if (assign) {
-      fn.assign = function(scope, value, locals) {
-        return assign(scope, locals, value);
-      };
-    }
-    if (inputs) {
-      fn.inputs = inputs;
-    }
-    fn.literal = isLiteral(ast);
-    fn.constant = isConstant(ast);
-    return fn;
-  },
-
-  recurse: function(ast, context, create) {
-    var left, right, self = this, args;
-    if (ast.input) {
-      return this.inputs(ast.input, ast.watchId);
-    }
-    switch (ast.type) {
-    case AST.Literal:
-      return this.value(ast.value, context);
-    case AST.UnaryExpression:
-      right = this.recurse(ast.argument);
-      return this['unary' + ast.operator](right, context);
-    case AST.BinaryExpression:
-      left = this.recurse(ast.left);
-      right = this.recurse(ast.right);
-      return this['binary' + ast.operator](left, right, context);
-    case AST.LogicalExpression:
-      left = this.recurse(ast.left);
-      right = this.recurse(ast.right);
-      return this['binary' + ast.operator](left, right, context);
-    case AST.ConditionalExpression:
-      return this['ternary?:'](
-        this.recurse(ast.test),
-        this.recurse(ast.alternate),
-        this.recurse(ast.consequent),
-        context
-      );
-    case AST.Identifier:
-      return self.identifier(ast.name, context, create);
-    case AST.MemberExpression:
-      left = this.recurse(ast.object, false, !!create);
-      if (!ast.computed) {
-        right = ast.property.name;
-      }
-      if (ast.computed) right = this.recurse(ast.property);
-      return ast.computed ?
-        this.computedMember(left, right, context, create) :
-        this.nonComputedMember(left, right, context, create);
-    case AST.CallExpression:
-      args = [];
-      forEach(ast.arguments, function(expr) {
-        args.push(self.recurse(expr));
-      });
-      if (ast.filter) right = this.$filter(ast.callee.name);
-      if (!ast.filter) right = this.recurse(ast.callee, true);
-      return ast.filter ?
-        function(scope, locals, assign, inputs) {
-          var values = [];
-          for (var i = 0; i < args.length; ++i) {
-            values.push(args[i](scope, locals, assign, inputs));
-          }
-          var value = right.apply(undefined, values, inputs);
-          return context ? {context: undefined, name: undefined, value: value} : value;
-        } :
-        function(scope, locals, assign, inputs) {
-          var rhs = right(scope, locals, assign, inputs);
-          var value;
-          if (rhs.value != null) {
-            var values = [];
-            for (var i = 0; i < args.length; ++i) {
-              values.push(args[i](scope, locals, assign, inputs));
-            }
-            value = rhs.value.apply(rhs.context, values);
-          }
-          return context ? {value: value} : value;
-        };
-    case AST.AssignmentExpression:
-      left = this.recurse(ast.left, true, 1);
-      right = this.recurse(ast.right);
-      return function(scope, locals, assign, inputs) {
-        var lhs = left(scope, locals, assign, inputs);
-        var rhs = right(scope, locals, assign, inputs);
-        lhs.context[lhs.name] = rhs;
-        return context ? {value: rhs} : rhs;
-      };
-    case AST.ArrayExpression:
-      args = [];
-      forEach(ast.elements, function(expr) {
-        args.push(self.recurse(expr));
-      });
-      return function(scope, locals, assign, inputs) {
-        var value = [];
-        for (var i = 0; i < args.length; ++i) {
-          value.push(args[i](scope, locals, assign, inputs));
-        }
-        return context ? {value: value} : value;
-      };
-    case AST.ObjectExpression:
-      args = [];
-      forEach(ast.properties, function(property) {
-        if (property.computed) {
-          args.push({key: self.recurse(property.key),
-                     computed: true,
-                     value: self.recurse(property.value)
-          });
-        } else {
-          args.push({key: property.key.type === AST.Identifier ?
-                          property.key.name :
-                          ('' + property.key.value),
-                     computed: false,
-                     value: self.recurse(property.value)
-          });
-        }
-      });
-      return function(scope, locals, assign, inputs) {
-        var value = {};
-        for (var i = 0; i < args.length; ++i) {
-          if (args[i].computed) {
-            value[args[i].key(scope, locals, assign, inputs)] = args[i].value(scope, locals, assign, inputs);
-          } else {
-            value[args[i].key] = args[i].value(scope, locals, assign, inputs);
-          }
-        }
-        return context ? {value: value} : value;
-      };
-    case AST.ThisExpression:
-      return function(scope) {
-        return context ? {value: scope} : scope;
-      };
-    case AST.LocalsExpression:
-      return function(scope, locals) {
-        return context ? {value: locals} : locals;
-      };
-    case AST.NGValueParameter:
-      return function(scope, locals, assign) {
-        return context ? {value: assign} : assign;
-      };
-    }
-  },
-
-  'unary+': function(argument, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = argument(scope, locals, assign, inputs);
-      if (isDefined(arg)) {
-        arg = +arg;
-      } else {
-        arg = 0;
-      }
-      return context ? {value: arg} : arg;
-    };
-  },
-  'unary-': function(argument, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = argument(scope, locals, assign, inputs);
-      if (isDefined(arg)) {
-        arg = -arg;
-      } else {
-        arg = -0;
-      }
-      return context ? {value: arg} : arg;
-    };
-  },
-  'unary!': function(argument, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = !argument(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary+': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var lhs = left(scope, locals, assign, inputs);
-      var rhs = right(scope, locals, assign, inputs);
-      var arg = plusFn(lhs, rhs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary-': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var lhs = left(scope, locals, assign, inputs);
-      var rhs = right(scope, locals, assign, inputs);
-      var arg = (isDefined(lhs) ? lhs : 0) - (isDefined(rhs) ? rhs : 0);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary*': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) * right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary/': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) / right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary%': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) % right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary===': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) === right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary!==': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) !== right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary==': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      // eslint-disable-next-line eqeqeq
-      var arg = left(scope, locals, assign, inputs) == right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary!=': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      // eslint-disable-next-line eqeqeq
-      var arg = left(scope, locals, assign, inputs) != right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary<': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) < right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary>': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) > right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary<=': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) <= right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary>=': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) >= right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary&&': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) && right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'binary||': function(left, right, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = left(scope, locals, assign, inputs) || right(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  'ternary?:': function(test, alternate, consequent, context) {
-    return function(scope, locals, assign, inputs) {
-      var arg = test(scope, locals, assign, inputs) ? alternate(scope, locals, assign, inputs) : consequent(scope, locals, assign, inputs);
-      return context ? {value: arg} : arg;
-    };
-  },
-  value: function(value, context) {
-    return function() { return context ? {context: undefined, name: undefined, value: value} : value; };
-  },
-  identifier: function(name, context, create) {
-    return function(scope, locals, assign, inputs) {
-      var base = locals && (name in locals) ? locals : scope;
-      if (create && create !== 1 && base && base[name] == null) {
-        base[name] = {};
-      }
-      var value = base ? base[name] : undefined;
-      if (context) {
-        return {context: base, name: name, value: value};
-      } else {
-        return value;
-      }
-    };
-  },
-  computedMember: function(left, right, context, create) {
-    return function(scope, locals, assign, inputs) {
-      var lhs = left(scope, locals, assign, inputs);
-      var rhs;
-      var value;
-      if (lhs != null) {
-        rhs = right(scope, locals, assign, inputs);
-        rhs = getStringValue(rhs);
-        if (create && create !== 1) {
-          if (lhs && !(lhs[rhs])) {
-            lhs[rhs] = {};
-          }
-        }
-        value = lhs[rhs];
-      }
-      if (context) {
-        return {context: lhs, name: rhs, value: value};
-      } else {
-        return value;
-      }
-    };
-  },
-  nonComputedMember: function(left, right, context, create) {
-    return function(scope, locals, assign, inputs) {
-      var lhs = left(scope, locals, assign, inputs);
-      if (create && create !== 1) {
-        if (lhs && lhs[right] == null) {
-          lhs[right] = {};
-        }
-      }
-      var value = lhs != null ? lhs[right] : undefined;
-      if (context) {
-        return {context: lhs, name: right, value: value};
-      } else {
-        return value;
-      }
-    };
-  },
-  inputs: function(input, watchId) {
-    return function(scope, value, locals, inputs) {
-      if (inputs) return inputs[watchId];
-      return input(scope, value, locals);
-    };
-  }
-};
-
-/**
- * @constructor
- */
-var Parser = function Parser(lexer, $filter, options) {
-  this.lexer = lexer;
-  this.$filter = $filter;
-  this.options = options;
-  this.ast = new AST(lexer, options);
-  this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) :
-                                   new ASTCompiler(this.ast, $filter);
-};
-
-Parser.prototype = {
-  constructor: Parser,
-
-  parse: function(text) {
-    return this.astCompiler.compile(text);
-  }
-};
-
-function getValueOf(value) {
-  return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);
-}
-
-///////////////////////////////////
-
-/**
- * @ngdoc service
- * @name $parse
- * @kind function
- *
- * @description
- *
- * Converts Angular {@link guide/expression expression} into a function.
- *
- * ```js
- *   var getter = $parse('user.name');
- *   var setter = getter.assign;
- *   var context = {user:{name:'angular'}};
- *   var locals = {user:{name:'local'}};
- *
- *   expect(getter(context)).toEqual('angular');
- *   setter(context, 'newValue');
- *   expect(context.user.name).toEqual('newValue');
- *   expect(getter(context, locals)).toEqual('local');
- * ```
- *
- *
- * @param {string} expression String expression to compile.
- * @returns {function(context, locals)} a function which represents the compiled expression:
- *
- *    * `context` – `{object}` – an object against which any expressions embedded in the strings
- *      are evaluated against (typically a scope object).
- *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
- *      `context`.
- *
- *    The returned function also has the following properties:
- *      * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript
- *        literal.
- *      * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript
- *        constant literals.
- *      * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be
- *        set to a function to change its value on the given context.
- *
- */
-
-
-/**
- * @ngdoc provider
- * @name $parseProvider
- * @this
- *
- * @description
- * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse}
- *  service.
- */
-function $ParseProvider() {
-  var cache = createMap();
-  var literals = {
-    'true': true,
-    'false': false,
-    'null': null,
-    'undefined': undefined
-  };
-  var identStart, identContinue;
-
-  /**
-   * @ngdoc method
-   * @name $parseProvider#addLiteral
-   * @description
-   *
-   * Configure $parse service to add literal values that will be present as literal at expressions.
-   *
-   * @param {string} literalName Token for the literal value. The literal name value must be a valid literal name.
-   * @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`.
-   *
-   **/
-  this.addLiteral = function(literalName, literalValue) {
-    literals[literalName] = literalValue;
-  };
-
- /**
-  * @ngdoc method
-  * @name $parseProvider#setIdentifierFns
-  *
-  * @description
-  *
-  * Allows defining the set of characters that are allowed in Angular expressions. The function
-  * `identifierStart` will get called to know if a given character is a valid character to be the
-  * first character for an identifier. The function `identifierContinue` will get called to know if
-  * a given character is a valid character to be a follow-up identifier character. The functions
-  * `identifierStart` and `identifierContinue` will receive as arguments the single character to be
-  * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in
-  * mind that the `string` parameter can be two characters long depending on the character
-  * representation. It is expected for the function to return `true` or `false`, whether that
-  * character is allowed or not.
-  *
-  * Since this function will be called extensively, keep the implementation of these functions fast,
-  * as the performance of these functions have a direct impact on the expressions parsing speed.
-  *
-  * @param {function=} identifierStart The function that will decide whether the given character is
-  *   a valid identifier start character.
-  * @param {function=} identifierContinue The function that will decide whether the given character is
-  *   a valid identifier continue character.
-  */
-  this.setIdentifierFns = function(identifierStart, identifierContinue) {
-    identStart = identifierStart;
-    identContinue = identifierContinue;
-    return this;
-  };
-
-  this.$get = ['$filter', function($filter) {
-    var noUnsafeEval = csp().noUnsafeEval;
-    var $parseOptions = {
-          csp: noUnsafeEval,
-          literals: copy(literals),
-          isIdentifierStart: isFunction(identStart) && identStart,
-          isIdentifierContinue: isFunction(identContinue) && identContinue
-        };
-    return $parse;
-
-    function $parse(exp, interceptorFn) {
-      var parsedExpression, oneTime, cacheKey;
-
-      switch (typeof exp) {
-        case 'string':
-          exp = exp.trim();
-          cacheKey = exp;
-
-          parsedExpression = cache[cacheKey];
-
-          if (!parsedExpression) {
-            if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
-              oneTime = true;
-              exp = exp.substring(2);
-            }
-            var lexer = new Lexer($parseOptions);
-            var parser = new Parser(lexer, $filter, $parseOptions);
-            parsedExpression = parser.parse(exp);
-            if (parsedExpression.constant) {
-              parsedExpression.$$watchDelegate = constantWatchDelegate;
-            } else if (oneTime) {
-              parsedExpression.$$watchDelegate = parsedExpression.literal ?
-                  oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
-            } else if (parsedExpression.inputs) {
-              parsedExpression.$$watchDelegate = inputsWatchDelegate;
-            }
-            cache[cacheKey] = parsedExpression;
-          }
-          return addInterceptor(parsedExpression, interceptorFn);
-
-        case 'function':
-          return addInterceptor(exp, interceptorFn);
-
-        default:
-          return addInterceptor(noop, interceptorFn);
-      }
-    }
-
-    function expressionInputDirtyCheck(newValue, oldValueOfValue, compareObjectIdentity) {
-
-      if (newValue == null || oldValueOfValue == null) { // null/undefined
-        return newValue === oldValueOfValue;
-      }
-
-      if (typeof newValue === 'object' && !compareObjectIdentity) {
-
-        // attempt to convert the value to a primitive type
-        // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can
-        //             be cheaply dirty-checked
-        newValue = getValueOf(newValue);
-
-        if (typeof newValue === 'object') {
-          // objects/arrays are not supported - deep-watching them would be too expensive
-          return false;
-        }
-
-        // fall-through to the primitive equality check
-      }
-
-      //Primitive or NaN
-      // eslint-disable-next-line no-self-compare
-      return newValue === oldValueOfValue || (newValue !== newValue && oldValueOfValue !== oldValueOfValue);
-    }
-
-    function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {
-      var inputExpressions = parsedExpression.inputs;
-      var lastResult;
-
-      if (inputExpressions.length === 1) {
-        var oldInputValueOf = expressionInputDirtyCheck; // init to something unique so that equals check fails
-        inputExpressions = inputExpressions[0];
-        return scope.$watch(function expressionInputWatch(scope) {
-          var newInputValue = inputExpressions(scope);
-          if (!expressionInputDirtyCheck(newInputValue, oldInputValueOf, parsedExpression.literal)) {
-            lastResult = parsedExpression(scope, undefined, undefined, [newInputValue]);
-            oldInputValueOf = newInputValue && getValueOf(newInputValue);
-          }
-          return lastResult;
-        }, listener, objectEquality, prettyPrintExpression);
-      }
-
-      var oldInputValueOfValues = [];
-      var oldInputValues = [];
-      for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
-        oldInputValueOfValues[i] = expressionInputDirtyCheck; // init to something unique so that equals check fails
-        oldInputValues[i] = null;
-      }
-
-      return scope.$watch(function expressionInputsWatch(scope) {
-        var changed = false;
-
-        for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
-          var newInputValue = inputExpressions[i](scope);
-          if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i], parsedExpression.literal))) {
-            oldInputValues[i] = newInputValue;
-            oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);
-          }
-        }
-
-        if (changed) {
-          lastResult = parsedExpression(scope, undefined, undefined, oldInputValues);
-        }
-
-        return lastResult;
-      }, listener, objectEquality, prettyPrintExpression);
-    }
-
-    function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {
-      var unwatch, lastValue;
-      if (parsedExpression.inputs) {
-        unwatch = inputsWatchDelegate(scope, oneTimeListener, objectEquality, parsedExpression, prettyPrintExpression);
-      } else {
-        unwatch = scope.$watch(oneTimeWatch, oneTimeListener, objectEquality);
-      }
-      return unwatch;
-
-      function oneTimeWatch(scope) {
-        return parsedExpression(scope);
-      }
-      function oneTimeListener(value, old, scope) {
-        lastValue = value;
-        if (isFunction(listener)) {
-          listener(value, old, scope);
-        }
-        if (isDefined(value)) {
-          scope.$$postDigest(function() {
-            if (isDefined(lastValue)) {
-              unwatch();
-            }
-          });
-        }
-      }
-    }
-
-    function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) {
-      var unwatch, lastValue;
-      unwatch = scope.$watch(function oneTimeWatch(scope) {
-        return parsedExpression(scope);
-      }, function oneTimeListener(value, old, scope) {
-        lastValue = value;
-        if (isFunction(listener)) {
-          listener(value, old, scope);
-        }
-        if (isAllDefined(value)) {
-          scope.$$postDigest(function() {
-            if (isAllDefined(lastValue)) unwatch();
-          });
-        }
-      }, objectEquality);
-
-      return unwatch;
-
-      function isAllDefined(value) {
-        var allDefined = true;
-        forEach(value, function(val) {
-          if (!isDefined(val)) allDefined = false;
-        });
-        return allDefined;
-      }
-    }
-
-    function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) {
-      var unwatch = scope.$watch(function constantWatch(scope) {
-        unwatch();
-        return parsedExpression(scope);
-      }, listener, objectEquality);
-      return unwatch;
-    }
-
-    function addInterceptor(parsedExpression, interceptorFn) {
-      if (!interceptorFn) return parsedExpression;
-      var watchDelegate = parsedExpression.$$watchDelegate;
-      var useInputs = false;
-
-      var regularWatch =
-          watchDelegate !== oneTimeLiteralWatchDelegate &&
-          watchDelegate !== oneTimeWatchDelegate;
-
-      var fn = regularWatch ? function regularInterceptedExpression(scope, locals, assign, inputs) {
-        var value = useInputs && inputs ? inputs[0] : parsedExpression(scope, locals, assign, inputs);
-        return interceptorFn(value, scope, locals);
-      } : function oneTimeInterceptedExpression(scope, locals, assign, inputs) {
-        var value = parsedExpression(scope, locals, assign, inputs);
-        var result = interceptorFn(value, scope, locals);
-        // we only return the interceptor's result if the
-        // initial value is defined (for bind-once)
-        return isDefined(value) ? result : value;
-      };
-
-      // Propagate $$watchDelegates other then inputsWatchDelegate
-      useInputs = !parsedExpression.inputs;
-      if (parsedExpression.$$watchDelegate &&
-          parsedExpression.$$watchDelegate !== inputsWatchDelegate) {
-        fn.$$watchDelegate = parsedExpression.$$watchDelegate;
-        fn.inputs = parsedExpression.inputs;
-      } else if (!interceptorFn.$stateful) {
-        // If there is an interceptor, but no watchDelegate then treat the interceptor like
-        // we treat filters - it is assumed to be a pure function unless flagged with $stateful
-        fn.$$watchDelegate = inputsWatchDelegate;
-        fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression];
-      }
-
-      return fn;
-    }
-  }];
-}
-
-/**
- * @ngdoc service
- * @name $q
- * @requires $rootScope
- *
- * @description
- * A service that helps you run functions asynchronously, and use their return values (or exceptions)
- * when they are done processing.
- *
- * This is a [Promises/A+](https://promisesaplus.com/)-compliant implementation of promises/deferred
- * objects inspired by [Kris Kowal's Q](https://github.com/kriskowal/q).
- *
- * $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred
- * implementations, and the other which resembles ES6 (ES2015) promises to some degree.
- *
- * # $q constructor
- *
- * The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`
- * function as the first argument. This is similar to the native Promise implementation from ES6,
- * see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
- *
- * While the constructor-style use is supported, not all of the supporting methods from ES6 promises are
- * available yet.
- *
- * It can be used like so:
- *
- * ```js
- *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`
- *   // are available in the current lexical scope (they could have been injected or passed in).
- *
- *   function asyncGreet(name) {
- *     // perform some asynchronous operation, resolve or reject the promise when appropriate.
- *     return $q(function(resolve, reject) {
- *       setTimeout(function() {
- *         if (okToGreet(name)) {
- *           resolve('Hello, ' + name + '!');
- *         } else {
- *           reject('Greeting ' + name + ' is not allowed.');
- *         }
- *       }, 1000);
- *     });
- *   }
- *
- *   var promise = asyncGreet('Robin Hood');
- *   promise.then(function(greeting) {
- *     alert('Success: ' + greeting);
- *   }, function(reason) {
- *     alert('Failed: ' + reason);
- *   });
- * ```
- *
- * Note: progress/notify callbacks are not currently supported via the ES6-style interface.
- *
- * Note: unlike ES6 behavior, an exception thrown in the constructor function will NOT implicitly reject the promise.
- *
- * However, the more traditional CommonJS-style usage is still available, and documented below.
- *
- * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an
- * interface for interacting with an object that represents the result of an action that is
- * performed asynchronously, and may or may not be finished at any given point in time.
- *
- * From the perspective of dealing with error handling, deferred and promise APIs are to
- * asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
- *
- * ```js
- *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`
- *   // are available in the current lexical scope (they could have been injected or passed in).
- *
- *   function asyncGreet(name) {
- *     var deferred = $q.defer();
- *
- *     setTimeout(function() {
- *       deferred.notify('About to greet ' + name + '.');
- *
- *       if (okToGreet(name)) {
- *         deferred.resolve('Hello, ' + name + '!');
- *       } else {
- *         deferred.reject('Greeting ' + name + ' is not allowed.');
- *       }
- *     }, 1000);
- *
- *     return deferred.promise;
- *   }
- *
- *   var promise = asyncGreet('Robin Hood');
- *   promise.then(function(greeting) {
- *     alert('Success: ' + greeting);
- *   }, function(reason) {
- *     alert('Failed: ' + reason);
- *   }, function(update) {
- *     alert('Got notification: ' + update);
- *   });
- * ```
- *
- * At first it might not be obvious why this extra complexity is worth the trouble. The payoff
- * comes in the way of guarantees that promise and deferred APIs make, see
- * https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md.
- *
- * Additionally the promise api allows for composition that is very hard to do with the
- * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.
- * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the
- * section on serial or parallel joining of promises.
- *
- * # The Deferred API
- *
- * A new instance of deferred is constructed by calling `$q.defer()`.
- *
- * The purpose of the deferred object is to expose the associated Promise instance as well as APIs
- * that can be used for signaling the successful or unsuccessful completion, as well as the status
- * of the task.
- *
- * **Methods**
- *
- * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection
- *   constructed via `$q.reject`, the promise will be rejected instead.
- * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
- *   resolving it with a rejection constructed via `$q.reject`.
- * - `notify(value)` - provides updates on the status of the promise's execution. This may be called
- *   multiple times before the promise is either resolved or rejected.
- *
- * **Properties**
- *
- * - promise – `{Promise}` – promise object associated with this deferred.
- *
- *
- * # The Promise API
- *
- * A new promise instance is created when a deferred instance is created and can be retrieved by
- * calling `deferred.promise`.
- *
- * The purpose of the promise object is to allow for interested parties to get access to the result
- * of the deferred task when it completes.
- *
- * **Methods**
- *
- * - `then(successCallback, [errorCallback], [notifyCallback])` – regardless of when the promise was or
- *   will be resolved or rejected, `then` calls one of the success or error callbacks asynchronously
- *   as soon as the result is available. The callbacks are called with a single argument: the result
- *   or rejection reason. Additionally, the notify callback may be called zero or more times to
- *   provide a progress indication, before the promise is resolved or rejected.
- *
- *   This method *returns a new promise* which is resolved or rejected via the return value of the
- *   `successCallback`, `errorCallback` (unless that value is a promise, in which case it is resolved
- *   with the value which is resolved in that promise using
- *   [promise chaining](http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promises-queues)).
- *   It also notifies via the return value of the `notifyCallback` method. The promise cannot be
- *   resolved or rejected from the notifyCallback method. The errorCallback and notifyCallback
- *   arguments are optional.
- *
- * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`
- *
- * - `finally(callback, notifyCallback)` – allows you to observe either the fulfillment or rejection of a promise,
- *   but to do so without modifying the final value. This is useful to release resources or do some
- *   clean-up that needs to be done whether the promise was rejected or resolved. See the [full
- *   specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for
- *   more information.
- *
- * # Chaining promises
- *
- * Because calling the `then` method of a promise returns a new derived promise, it is easily
- * possible to create a chain of promises:
- *
- * ```js
- *   promiseB = promiseA.then(function(result) {
- *     return result + 1;
- *   });
- *
- *   // promiseB will be resolved immediately after promiseA is resolved and its value
- *   // will be the result of promiseA incremented by 1
- * ```
- *
- * It is possible to create chains of any length and since a promise can be resolved with another
- * promise (which will defer its resolution further), it is possible to pause/defer resolution of
- * the promises at any point in the chain. This makes it possible to implement powerful APIs like
- * $http's response interceptors.
- *
- *
- * # Differences between Kris Kowal's Q and $q
- *
- *  There are two main differences:
- *
- * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation
- *   mechanism in angular, which means faster propagation of resolution or rejection into your
- *   models and avoiding unnecessary browser repaints, which would result in flickering UI.
- * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
- *   all the important functionality needed for common async tasks.
- *
- * # Testing
- *
- *  ```js
- *    it('should simulate promise', inject(function($q, $rootScope) {
- *      var deferred = $q.defer();
- *      var promise = deferred.promise;
- *      var resolvedValue;
- *
- *      promise.then(function(value) { resolvedValue = value; });
- *      expect(resolvedValue).toBeUndefined();
- *
- *      // Simulate resolving of promise
- *      deferred.resolve(123);
- *      // Note that the 'then' function does not get called synchronously.
- *      // This is because we want the promise API to always be async, whether or not
- *      // it got called synchronously or asynchronously.
- *      expect(resolvedValue).toBeUndefined();
- *
- *      // Propagate promise resolution to 'then' functions using $apply().
- *      $rootScope.$apply();
- *      expect(resolvedValue).toEqual(123);
- *    }));
- *  ```
- *
- * @param {function(function, function)} resolver Function which is responsible for resolving or
- *   rejecting the newly created promise. The first parameter is a function which resolves the
- *   promise, the second parameter is a function which rejects the promise.
- *
- * @returns {Promise} The newly created promise.
- */
-/**
- * @ngdoc provider
- * @name $qProvider
- * @this
- *
- * @description
- */
-function $QProvider() {
-  var errorOnUnhandledRejections = true;
-  this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {
-    return qFactory(function(callback) {
-      $rootScope.$evalAsync(callback);
-    }, $exceptionHandler, errorOnUnhandledRejections);
-  }];
-
-  /**
-   * @ngdoc method
-   * @name $qProvider#errorOnUnhandledRejections
-   * @kind function
-   *
-   * @description
-   * Retrieves or overrides whether to generate an error when a rejected promise is not handled.
-   * This feature is enabled by default.
-   *
-   * @param {boolean=} value Whether to generate an error when a rejected promise is not handled.
-   * @returns {boolean|ng.$qProvider} Current value when called without a new value or self for
-   *    chaining otherwise.
-   */
-  this.errorOnUnhandledRejections = function(value) {
-    if (isDefined(value)) {
-      errorOnUnhandledRejections = value;
-      return this;
-    } else {
-      return errorOnUnhandledRejections;
-    }
-  };
-}
-
-/** @this */
-function $$QProvider() {
-  var errorOnUnhandledRejections = true;
-  this.$get = ['$browser', '$exceptionHandler', function($browser, $exceptionHandler) {
-    return qFactory(function(callback) {
-      $browser.defer(callback);
-    }, $exceptionHandler, errorOnUnhandledRejections);
-  }];
-
-  this.errorOnUnhandledRejections = function(value) {
-    if (isDefined(value)) {
-      errorOnUnhandledRejections = value;
-      return this;
-    } else {
-      return errorOnUnhandledRejections;
-    }
-  };
-}
-
-/**
- * Constructs a promise manager.
- *
- * @param {function(function)} nextTick Function for executing functions in the next turn.
- * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for
- *     debugging purposes.
- @ param {=boolean} errorOnUnhandledRejections Whether an error should be generated on unhandled
- *     promises rejections.
- * @returns {object} Promise manager.
- */
-function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
-  var $qMinErr = minErr('$q', TypeError);
-  var queueSize = 0;
-  var checkQueue = [];
-
-  /**
-   * @ngdoc method
-   * @name ng.$q#defer
-   * @kind function
-   *
-   * @description
-   * Creates a `Deferred` object which represents a task which will finish in the future.
-   *
-   * @returns {Deferred} Returns a new instance of deferred.
-   */
-  function defer() {
-    return new Deferred();
-  }
-
-  function Deferred() {
-    var promise = this.promise = new Promise();
-    //Non prototype methods necessary to support unbound execution :/
-    this.resolve = function(val) { resolvePromise(promise, val); };
-    this.reject = function(reason) { rejectPromise(promise, reason); };
-    this.notify = function(progress) { notifyPromise(promise, progress); };
-  }
-
-
-  function Promise() {
-    this.$$state = { status: 0 };
-  }
-
-  extend(Promise.prototype, {
-    then: function(onFulfilled, onRejected, progressBack) {
-      if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) {
-        return this;
-      }
-      var result = new Promise();
-
-      this.$$state.pending = this.$$state.pending || [];
-      this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
-      if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);
-
-      return result;
-    },
-
-    'catch': function(callback) {
-      return this.then(null, callback);
-    },
-
-    'finally': function(callback, progressBack) {
-      return this.then(function(value) {
-        return handleCallback(value, resolve, callback);
-      }, function(error) {
-        return handleCallback(error, reject, callback);
-      }, progressBack);
-    }
-  });
-
-  function processQueue(state) {
-    var fn, promise, pending;
-
-    pending = state.pending;
-    state.processScheduled = false;
-    state.pending = undefined;
-    try {
-      for (var i = 0, ii = pending.length; i < ii; ++i) {
-        state.pur = true;
-        promise = pending[i][0];
-        fn = pending[i][state.status];
-        try {
-          if (isFunction(fn)) {
-            resolvePromise(promise, fn(state.value));
-          } else if (state.status === 1) {
-            resolvePromise(promise, state.value);
-          } else {
-            rejectPromise(promise, state.value);
-          }
-        } catch (e) {
-          rejectPromise(promise, e);
-        }
-      }
-    } finally {
-      --queueSize;
-      if (errorOnUnhandledRejections && queueSize === 0) {
-        nextTick(processChecks);
-      }
-    }
-  }
-
-  function processChecks() {
-    // eslint-disable-next-line no-unmodified-loop-condition
-    while (!queueSize && checkQueue.length) {
-      var toCheck = checkQueue.shift();
-      if (!toCheck.pur) {
-        toCheck.pur = true;
-        var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value);
-        if (toCheck.value instanceof Error) {
-          exceptionHandler(toCheck.value, errorMessage);
-        } else {
-          exceptionHandler(errorMessage);
-        }
-      }
-    }
-  }
-
-  function scheduleProcessQueue(state) {
-    if (errorOnUnhandledRejections && !state.pending && state.status === 2 && !state.pur) {
-      if (queueSize === 0 && checkQueue.length === 0) {
-        nextTick(processChecks);
-      }
-      checkQueue.push(state);
-    }
-    if (state.processScheduled || !state.pending) return;
-    state.processScheduled = true;
-    ++queueSize;
-    nextTick(function() { processQueue(state); });
-  }
-
-  function resolvePromise(promise, val) {
-    if (promise.$$state.status) return;
-    if (val === promise) {
-      $$reject(promise, $qMinErr(
-        'qcycle',
-        'Expected promise to be resolved with value other than itself \'{0}\'',
-        val));
-    } else {
-      $$resolve(promise, val);
-    }
-
-  }
-
-  function $$resolve(promise, val) {
-    var then;
-    var done = false;
-    try {
-      if (isObject(val) || isFunction(val)) then = val.then;
-      if (isFunction(then)) {
-        promise.$$state.status = -1;
-        then.call(val, doResolve, doReject, doNotify);
-      } else {
-        promise.$$state.value = val;
-        promise.$$state.status = 1;
-        scheduleProcessQueue(promise.$$state);
-      }
-    } catch (e) {
-      doReject(e);
-    }
-
-    function doResolve(val) {
-      if (done) return;
-      done = true;
-      $$resolve(promise, val);
-    }
-    function doReject(val) {
-      if (done) return;
-      done = true;
-      $$reject(promise, val);
-    }
-    function doNotify(progress) {
-      notifyPromise(promise, progress);
-    }
-  }
-
-  function rejectPromise(promise, reason) {
-    if (promise.$$state.status) return;
-    $$reject(promise, reason);
-  }
-
-  function $$reject(promise, reason) {
-    promise.$$state.value = reason;
-    promise.$$state.status = 2;
-    scheduleProcessQueue(promise.$$state);
-  }
-
-  function notifyPromise(promise, progress) {
-    var callbacks = promise.$$state.pending;
-
-    if ((promise.$$state.status <= 0) && callbacks && callbacks.length) {
-      nextTick(function() {
-        var callback, result;
-        for (var i = 0, ii = callbacks.length; i < ii; i++) {
-          result = callbacks[i][0];
-          callback = callbacks[i][3];
-          try {
-            notifyPromise(result, isFunction(callback) ? callback(progress) : progress);
-          } catch (e) {
-            exceptionHandler(e);
-          }
-        }
-      });
-    }
-  }
-
-  /**
-   * @ngdoc method
-   * @name $q#reject
-   * @kind function
-   *
-   * @description
-   * Creates a promise that is resolved as rejected with the specified `reason`. This api should be
-   * used to forward rejection in a chain of promises. If you are dealing with the last promise in
-   * a promise chain, you don't need to worry about it.
-   *
-   * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of
-   * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via
-   * a promise error callback and you want to forward the error to the promise derived from the
-   * current promise, you have to "rethrow" the error by returning a rejection constructed via
-   * `reject`.
-   *
-   * ```js
-   *   promiseB = promiseA.then(function(result) {
-   *     // success: do something and resolve promiseB
-   *     //          with the old or a new result
-   *     return result;
-   *   }, function(reason) {
-   *     // error: handle the error if possible and
-   *     //        resolve promiseB with newPromiseOrValue,
-   *     //        otherwise forward the rejection to promiseB
-   *     if (canHandle(reason)) {
-   *      // handle the error and recover
-   *      return newPromiseOrValue;
-   *     }
-   *     return $q.reject(reason);
-   *   });
-   * ```
-   *
-   * @param {*} reason Constant, message, exception or an object representing the rejection reason.
-   * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
-   */
-  function reject(reason) {
-    var result = new Promise();
-    rejectPromise(result, reason);
-    return result;
-  }
-
-  function handleCallback(value, resolver, callback) {
-    var callbackOutput = null;
-    try {
-      if (isFunction(callback)) callbackOutput = callback();
-    } catch (e) {
-      return reject(e);
-    }
-    if (isPromiseLike(callbackOutput)) {
-      return callbackOutput.then(function() {
-        return resolver(value);
-      }, reject);
-    } else {
-      return resolver(value);
-    }
-  }
-
-  /**
-   * @ngdoc method
-   * @name $q#when
-   * @kind function
-   *
-   * @description
-   * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
-   * This is useful when you are dealing with an object that might or might not be a promise, or if
-   * the promise comes from a source that can't be trusted.
-   *
-   * @param {*} value Value or a promise
-   * @param {Function=} successCallback
-   * @param {Function=} errorCallback
-   * @param {Function=} progressCallback
-   * @returns {Promise} Returns a promise of the passed value or promise
-   */
-
-
-  function when(value, callback, errback, progressBack) {
-    var result = new Promise();
-    resolvePromise(result, value);
-    return result.then(callback, errback, progressBack);
-  }
-
-  /**
-   * @ngdoc method
-   * @name $q#resolve
-   * @kind function
-   *
-   * @description
-   * Alias of {@link ng.$q#when when} to maintain naming consistency with ES6.
-   *
-   * @param {*} value Value or a promise
-   * @param {Function=} successCallback
-   * @param {Function=} errorCallback
-   * @param {Function=} progressCallback
-   * @returns {Promise} Returns a promise of the passed value or promise
-   */
-  var resolve = when;
-
-  /**
-   * @ngdoc method
-   * @name $q#all
-   * @kind function
-   *
-   * @description
-   * Combines multiple promises into a single promise that is resolved when all of the input
-   * promises are resolved.
-   *
-   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
-   * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values,
-   *   each value corresponding to the promise at the same index/key in the `promises` array/hash.
-   *   If any of the promises is resolved with a rejection, this resulting promise will be rejected
-   *   with the same rejection value.
-   */
-
-  function all(promises) {
-    var result = new Promise(),
-        counter = 0,
-        results = isArray(promises) ? [] : {};
-
-    forEach(promises, function(promise, key) {
-      counter++;
-      when(promise).then(function(value) {
-        results[key] = value;
-        if (!(--counter)) resolvePromise(result, results);
-      }, function(reason) {
-        rejectPromise(result, reason);
-      });
-    });
-
-    if (counter === 0) {
-      resolvePromise(result, results);
-    }
-
-    return result;
-  }
-
-  /**
-   * @ngdoc method
-   * @name $q#race
-   * @kind function
-   *
-   * @description
-   * Returns a promise that resolves or rejects as soon as one of those promises
-   * resolves or rejects, with the value or reason from that promise.
-   *
-   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
-   * @returns {Promise} a promise that resolves or rejects as soon as one of the `promises`
-   * resolves or rejects, with the value or reason from that promise.
-   */
-
-  function race(promises) {
-    var deferred = defer();
-
-    forEach(promises, function(promise) {
-      when(promise).then(deferred.resolve, deferred.reject);
-    });
-
-    return deferred.promise;
-  }
-
-  function $Q(resolver) {
-    if (!isFunction(resolver)) {
-      throw $qMinErr('norslvr', 'Expected resolverFn, got \'{0}\'', resolver);
-    }
-
-    var promise = new Promise();
-
-    function resolveFn(value) {
-      resolvePromise(promise, value);
-    }
-
-    function rejectFn(reason) {
-      rejectPromise(promise, reason);
-    }
-
-    resolver(resolveFn, rejectFn);
-
-    return promise;
-  }
-
-  // Let's make the instanceof operator work for promises, so that
-  // `new $q(fn) instanceof $q` would evaluate to true.
-  $Q.prototype = Promise.prototype;
-
-  $Q.defer = defer;
-  $Q.reject = reject;
-  $Q.when = when;
-  $Q.resolve = resolve;
-  $Q.all = all;
-  $Q.race = race;
-
-  return $Q;
-}
-
-/** @this */
-function $$RAFProvider() { //rAF
-  this.$get = ['$window', '$timeout', function($window, $timeout) {
-    var requestAnimationFrame = $window.requestAnimationFrame ||
-                                $window.webkitRequestAnimationFrame;
-
-    var cancelAnimationFrame = $window.cancelAnimationFrame ||
-                               $window.webkitCancelAnimationFrame ||
-                               $window.webkitCancelRequestAnimationFrame;
-
-    var rafSupported = !!requestAnimationFrame;
-    var raf = rafSupported
-      ? function(fn) {
-          var id = requestAnimationFrame(fn);
-          return function() {
-            cancelAnimationFrame(id);
-          };
-        }
-      : function(fn) {
-          var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666
-          return function() {
-            $timeout.cancel(timer);
-          };
-        };
-
-    raf.supported = rafSupported;
-
-    return raf;
-  }];
-}
-
-/**
- * DESIGN NOTES
- *
- * The design decisions behind the scope are heavily favored for speed and memory consumption.
- *
- * The typical use of scope is to watch the expressions, which most of the time return the same
- * value as last time so we optimize the operation.
- *
- * Closures construction is expensive in terms of speed as well as memory:
- *   - No closures, instead use prototypical inheritance for API
- *   - Internal state needs to be stored on scope directly, which means that private state is
- *     exposed as $$____ properties
- *
- * Loop operations are optimized by using while(count--) { ... }
- *   - This means that in order to keep the same order of execution as addition we have to add
- *     items to the array at the beginning (unshift) instead of at the end (push)
- *
- * Child scopes are created and removed often
- *   - Using an array would be slow since inserts in the middle are expensive; so we use linked lists
- *
- * There are fewer watches than observers. This is why you don't want the observer to be implemented
- * in the same way as watch. Watch requires return of the initialization function which is expensive
- * to construct.
- */
-
-
-/**
- * @ngdoc provider
- * @name $rootScopeProvider
- * @description
- *
- * Provider for the $rootScope service.
- */
-
-/**
- * @ngdoc method
- * @name $rootScopeProvider#digestTtl
- * @description
- *
- * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and
- * assuming that the model is unstable.
- *
- * The current default is 10 iterations.
- *
- * In complex applications it's possible that the dependencies between `$watch`s will result in
- * several digest iterations. However if an application needs more than the default 10 digest
- * iterations for its model to stabilize then you should investigate what is causing the model to
- * continuously change during the digest.
- *
- * Increasing the TTL could have performance implications, so you should not change it without
- * proper justification.
- *
- * @param {number} limit The number of digest iterations.
- */
-
-
-/**
- * @ngdoc service
- * @name $rootScope
- * @this
- *
- * @description
- *
- * Every application has a single root {@link ng.$rootScope.Scope scope}.
- * All other scopes are descendant scopes of the root scope. Scopes provide separation
- * between the model and the view, via a mechanism for watching the model for changes.
- * They also provide event emission/broadcast and subscription facility. See the
- * {@link guide/scope developer guide on scopes}.
- */
-function $RootScopeProvider() {
-  var TTL = 10;
-  var $rootScopeMinErr = minErr('$rootScope');
-  var lastDirtyWatch = null;
-  var applyAsyncId = null;
-
-  this.digestTtl = function(value) {
-    if (arguments.length) {
-      TTL = value;
-    }
-    return TTL;
-  };
-
-  function createChildScopeClass(parent) {
-    function ChildScope() {
-      this.$$watchers = this.$$nextSibling =
-          this.$$childHead = this.$$childTail = null;
-      this.$$listeners = {};
-      this.$$listenerCount = {};
-      this.$$watchersCount = 0;
-      this.$id = nextUid();
-      this.$$ChildScope = null;
-    }
-    ChildScope.prototype = parent;
-    return ChildScope;
-  }
-
-  this.$get = ['$exceptionHandler', '$parse', '$browser',
-      function($exceptionHandler, $parse, $browser) {
-
-    function destroyChildScope($event) {
-        $event.currentScope.$$destroyed = true;
-    }
-
-    function cleanUpScope($scope) {
-
-      // Support: IE 9 only
-      if (msie === 9) {
-        // There is a memory leak in IE9 if all child scopes are not disconnected
-        // completely when a scope is destroyed. So this code will recurse up through
-        // all this scopes children
-        //
-        // See issue https://github.com/angular/angular.js/issues/10706
-        if ($scope.$$childHead) {
-          cleanUpScope($scope.$$childHead);
-        }
-        if ($scope.$$nextSibling) {
-          cleanUpScope($scope.$$nextSibling);
-        }
-      }
-
-      // The code below works around IE9 and V8's memory leaks
-      //
-      // See:
-      // - https://code.google.com/p/v8/issues/detail?id=2073#c26
-      // - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909
-      // - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451
-
-      $scope.$parent = $scope.$$nextSibling = $scope.$$prevSibling = $scope.$$childHead =
-          $scope.$$childTail = $scope.$root = $scope.$$watchers = null;
-    }
-
-    /**
-     * @ngdoc type
-     * @name $rootScope.Scope
-     *
-     * @description
-     * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the
-     * {@link auto.$injector $injector}. Child scopes are created using the
-     * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when
-     * compiled HTML template is executed.) See also the {@link guide/scope Scopes guide} for
-     * an in-depth introduction and usage examples.
-     *
-     *
-     * # Inheritance
-     * A scope can inherit from a parent scope, as in this example:
-     * ```js
-         var parent = $rootScope;
-         var child = parent.$new();
-
-         parent.salutation = "Hello";
-         expect(child.salutation).toEqual('Hello');
-
-         child.salutation = "Welcome";
-         expect(child.salutation).toEqual('Welcome');
-         expect(parent.salutation).toEqual('Hello');
-     * ```
-     *
-     * When interacting with `Scope` in tests, additional helper methods are available on the
-     * instances of `Scope` type. See {@link ngMock.$rootScope.Scope ngMock Scope} for additional
-     * details.
-     *
-     *
-     * @param {Object.<string, function()>=} providers Map of service factory which need to be
-     *                                       provided for the current scope. Defaults to {@link ng}.
-     * @param {Object.<string, *>=} instanceCache Provides pre-instantiated services which should
-     *                              append/override services provided by `providers`. This is handy
-     *                              when unit-testing and having the need to override a default
-     *                              service.
-     * @returns {Object} Newly created scope.
-     *
-     */
-    function Scope() {
-      this.$id = nextUid();
-      this.$$phase = this.$parent = this.$$watchers =
-                     this.$$nextSibling = this.$$prevSibling =
-                     this.$$childHead = this.$$childTail = null;
-      this.$root = this;
-      this.$$destroyed = false;
-      this.$$listeners = {};
-      this.$$listenerCount = {};
-      this.$$watchersCount = 0;
-      this.$$isolateBindings = null;
-    }
-
-    /**
-     * @ngdoc property
-     * @name $rootScope.Scope#$id
-     *
-     * @description
-     * Unique scope ID (monotonically increasing) useful for debugging.
-     */
-
-     /**
-      * @ngdoc property
-      * @name $rootScope.Scope#$parent
-      *
-      * @description
-      * Reference to the parent scope.
-      */
-
-      /**
-       * @ngdoc property
-       * @name $rootScope.Scope#$root
-       *
-       * @description
-       * Reference to the root scope.
-       */
-
-    Scope.prototype = {
-      constructor: Scope,
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$new
-       * @kind function
-       *
-       * @description
-       * Creates a new child {@link ng.$rootScope.Scope scope}.
-       *
-       * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} event.
-       * The scope can be removed from the scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}.
-       *
-       * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is
-       * desired for the scope and its child scopes to be permanently detached from the parent and
-       * thus stop participating in model change detection and listener notification by invoking.
-       *
-       * @param {boolean} isolate If true, then the scope does not prototypically inherit from the
-       *         parent scope. The scope is isolated, as it can not see parent scope properties.
-       *         When creating widgets, it is useful for the widget to not accidentally read parent
-       *         state.
-       *
-       * @param {Scope} [parent=this] The {@link ng.$rootScope.Scope `Scope`} that will be the `$parent`
-       *                              of the newly created scope. Defaults to `this` scope if not provided.
-       *                              This is used when creating a transclude scope to correctly place it
-       *                              in the scope hierarchy while maintaining the correct prototypical
-       *                              inheritance.
-       *
-       * @returns {Object} The newly created child scope.
-       *
-       */
-      $new: function(isolate, parent) {
-        var child;
-
-        parent = parent || this;
-
-        if (isolate) {
-          child = new Scope();
-          child.$root = this.$root;
-        } else {
-          // Only create a child scope class if somebody asks for one,
-          // but cache it to allow the VM to optimize lookups.
-          if (!this.$$ChildScope) {
-            this.$$ChildScope = createChildScopeClass(this);
-          }
-          child = new this.$$ChildScope();
-        }
-        child.$parent = parent;
-        child.$$prevSibling = parent.$$childTail;
-        if (parent.$$childHead) {
-          parent.$$childTail.$$nextSibling = child;
-          parent.$$childTail = child;
-        } else {
-          parent.$$childHead = parent.$$childTail = child;
-        }
-
-        // When the new scope is not isolated or we inherit from `this`, and
-        // the parent scope is destroyed, the property `$$destroyed` is inherited
-        // prototypically. In all other cases, this property needs to be set
-        // when the parent scope is destroyed.
-        // The listener needs to be added after the parent is set
-        if (isolate || parent !== this) child.$on('$destroy', destroyChildScope);
-
-        return child;
-      },
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$watch
-       * @kind function
-       *
-       * @description
-       * Registers a `listener` callback to be executed whenever the `watchExpression` changes.
-       *
-       * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest
-       *   $digest()} and should return the value that will be watched. (`watchExpression` should not change
-       *   its value when executed multiple times with the same input because it may be executed multiple
-       *   times by {@link ng.$rootScope.Scope#$digest $digest()}. That is, `watchExpression` should be
-       *   [idempotent](http://en.wikipedia.org/wiki/Idempotence).)
-       * - The `listener` is called only when the value from the current `watchExpression` and the
-       *   previous call to `watchExpression` are not equal (with the exception of the initial run,
-       *   see below). Inequality is determined according to reference inequality,
-       *   [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)
-       *    via the `!==` Javascript operator, unless `objectEquality == true`
-       *   (see next point)
-       * - When `objectEquality == true`, inequality of the `watchExpression` is determined
-       *   according to the {@link angular.equals} function. To save the value of the object for
-       *   later comparison, the {@link angular.copy} function is used. This therefore means that
-       *   watching complex objects will have adverse memory and performance implications.
-       * - This should not be used to watch for changes in objects that are
-       *   or contain [File](https://developer.mozilla.org/docs/Web/API/File) objects due to limitations with {@link angular.copy `angular.copy`}.
-       * - The watch `listener` may change the model, which may trigger other `listener`s to fire.
-       *   This is achieved by rerunning the watchers until no changes are detected. The rerun
-       *   iteration limit is 10 to prevent an infinite loop deadlock.
-       *
-       *
-       * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called,
-       * you can register a `watchExpression` function with no `listener`. (Be prepared for
-       * multiple calls to your `watchExpression` because it will execute multiple times in a
-       * single {@link ng.$rootScope.Scope#$digest $digest} cycle if a change is detected.)
-       *
-       * After a watcher is registered with the scope, the `listener` fn is called asynchronously
-       * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the
-       * watcher. In rare cases, this is undesirable because the listener is called when the result
-       * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you
-       * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the
-       * listener was called due to initialization.
-       *
-       *
-       *
-       * # Example
-       * ```js
-           // let's assume that scope was dependency injected as the $rootScope
-           var scope = $rootScope;
-           scope.name = 'misko';
-           scope.counter = 0;
-
-           expect(scope.counter).toEqual(0);
-           scope.$watch('name', function(newValue, oldValue) {
-             scope.counter = scope.counter + 1;
-           });
-           expect(scope.counter).toEqual(0);
-
-           scope.$digest();
-           // the listener is always called during the first $digest loop after it was registered
-           expect(scope.counter).toEqual(1);
-
-           scope.$digest();
-           // but now it will not be called unless the value changes
-           expect(scope.counter).toEqual(1);
-
-           scope.name = 'adam';
-           scope.$digest();
-           expect(scope.counter).toEqual(2);
-
-
-
-           // Using a function as a watchExpression
-           var food;
-           scope.foodCounter = 0;
-           expect(scope.foodCounter).toEqual(0);
-           scope.$watch(
-             // This function returns the value being watched. It is called for each turn of the $digest loop
-             function() { return food; },
-             // This is the change listener, called when the value returned from the above function changes
-             function(newValue, oldValue) {
-               if ( newValue !== oldValue ) {
-                 // Only increment the counter if the value changed
-                 scope.foodCounter = scope.foodCounter + 1;
-               }
-             }
-           );
-           // No digest has been run so the counter will be zero
-           expect(scope.foodCounter).toEqual(0);
-
-           // Run the digest but since food has not changed count will still be zero
-           scope.$digest();
-           expect(scope.foodCounter).toEqual(0);
-
-           // Update food and run digest.  Now the counter will increment
-           food = 'cheeseburger';
-           scope.$digest();
-           expect(scope.foodCounter).toEqual(1);
-
-       * ```
-       *
-       *
-       *
-       * @param {(function()|string)} watchExpression Expression that is evaluated on each
-       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers
-       *    a call to the `listener`.
-       *
-       *    - `string`: Evaluated as {@link guide/expression expression}
-       *    - `function(scope)`: called with current `scope` as a parameter.
-       * @param {function(newVal, oldVal, scope)} listener Callback called whenever the value
-       *    of `watchExpression` changes.
-       *
-       *    - `newVal` contains the current value of the `watchExpression`
-       *    - `oldVal` contains the previous value of the `watchExpression`
-       *    - `scope` refers to the current scope
-       * @param {boolean=} [objectEquality=false] Compare for object equality using {@link angular.equals} instead of
-       *     comparing for reference equality.
-       * @returns {function()} Returns a deregistration function for this listener.
-       */
-      $watch: function(watchExp, listener, objectEquality, prettyPrintExpression) {
-        var get = $parse(watchExp);
-
-        if (get.$$watchDelegate) {
-          return get.$$watchDelegate(this, listener, objectEquality, get, watchExp);
-        }
-        var scope = this,
-            array = scope.$$watchers,
-            watcher = {
-              fn: listener,
-              last: initWatchVal,
-              get: get,
-              exp: prettyPrintExpression || watchExp,
-              eq: !!objectEquality
-            };
-
-        lastDirtyWatch = null;
-
-        if (!isFunction(listener)) {
-          watcher.fn = noop;
-        }
-
-        if (!array) {
-          array = scope.$$watchers = [];
-          array.$$digestWatchIndex = -1;
-        }
-        // we use unshift since we use a while loop in $digest for speed.
-        // the while loop reads in reverse order.
-        array.unshift(watcher);
-        array.$$digestWatchIndex++;
-        incrementWatchersCount(this, 1);
-
-        return function deregisterWatch() {
-          var index = arrayRemove(array, watcher);
-          if (index >= 0) {
-            incrementWatchersCount(scope, -1);
-            if (index < array.$$digestWatchIndex) {
-              array.$$digestWatchIndex--;
-            }
-          }
-          lastDirtyWatch = null;
-        };
-      },
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$watchGroup
-       * @kind function
-       *
-       * @description
-       * A variant of {@link ng.$rootScope.Scope#$watch $watch()} where it watches an array of `watchExpressions`.
-       * If any one expression in the collection changes the `listener` is executed.
-       *
-       * - The items in the `watchExpressions` array are observed via the standard `$watch` operation. Their return
-       *   values are examined for changes on every call to `$digest`.
-       * - The `listener` is called whenever any expression in the `watchExpressions` array changes.
-       *
-       * @param {Array.<string|Function(scope)>} watchExpressions Array of expressions that will be individually
-       * watched using {@link ng.$rootScope.Scope#$watch $watch()}
-       *
-       * @param {function(newValues, oldValues, scope)} listener Callback called whenever the return value of any
-       *    expression in `watchExpressions` changes
-       *    The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching
-       *    those of `watchExpression`
-       *    and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching
-       *    those of `watchExpression`
-       *    The `scope` refers to the current scope.
-       * @returns {function()} Returns a de-registration function for all listeners.
-       */
-      $watchGroup: function(watchExpressions, listener) {
-        var oldValues = new Array(watchExpressions.length);
-        var newValues = new Array(watchExpressions.length);
-        var deregisterFns = [];
-        var self = this;
-        var changeReactionScheduled = false;
-        var firstRun = true;
-
-        if (!watchExpressions.length) {
-          // No expressions means we call the listener ASAP
-          var shouldCall = true;
-          self.$evalAsync(function() {
-            if (shouldCall) listener(newValues, newValues, self);
-          });
-          return function deregisterWatchGroup() {
-            shouldCall = false;
-          };
-        }
-
-        if (watchExpressions.length === 1) {
-          // Special case size of one
-          return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {
-            newValues[0] = value;
-            oldValues[0] = oldValue;
-            listener(newValues, (value === oldValue) ? newValues : oldValues, scope);
-          });
-        }
-
-        forEach(watchExpressions, function(expr, i) {
-          var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) {
-            newValues[i] = value;
-            oldValues[i] = oldValue;
-            if (!changeReactionScheduled) {
-              changeReactionScheduled = true;
-              self.$evalAsync(watchGroupAction);
-            }
-          });
-          deregisterFns.push(unwatchFn);
-        });
-
-        function watchGroupAction() {
-          changeReactionScheduled = false;
-
-          if (firstRun) {
-            firstRun = false;
-            listener(newValues, newValues, self);
-          } else {
-            listener(newValues, oldValues, self);
-          }
-        }
-
-        return function deregisterWatchGroup() {
-          while (deregisterFns.length) {
-            deregisterFns.shift()();
-          }
-        };
-      },
-
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$watchCollection
-       * @kind function
-       *
-       * @description
-       * Shallow watches the properties of an object and fires whenever any of the properties change
-       * (for arrays, this implies watching the array items; for object maps, this implies watching
-       * the properties). If a change is detected, the `listener` callback is fired.
-       *
-       * - The `obj` collection is observed via standard $watch operation and is examined on every
-       *   call to $digest() to see if any items have been added, removed, or moved.
-       * - The `listener` is called whenever anything within the `obj` has changed. Examples include
-       *   adding, removing, and moving items belonging to an object or array.
-       *
-       *
-       * # Example
-       * ```js
-          $scope.names = ['igor', 'matias', 'misko', 'james'];
-          $scope.dataCount = 4;
-
-          $scope.$watchCollection('names', function(newNames, oldNames) {
-            $scope.dataCount = newNames.length;
-          });
-
-          expect($scope.dataCount).toEqual(4);
-          $scope.$digest();
-
-          //still at 4 ... no changes
-          expect($scope.dataCount).toEqual(4);
-
-          $scope.names.pop();
-          $scope.$digest();
-
-          //now there's been a change
-          expect($scope.dataCount).toEqual(3);
-       * ```
-       *
-       *
-       * @param {string|function(scope)} obj Evaluated as {@link guide/expression expression}. The
-       *    expression value should evaluate to an object or an array which is observed on each
-       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the
-       *    collection will trigger a call to the `listener`.
-       *
-       * @param {function(newCollection, oldCollection, scope)} listener a callback function called
-       *    when a change is detected.
-       *    - The `newCollection` object is the newly modified data obtained from the `obj` expression
-       *    - The `oldCollection` object is a copy of the former collection data.
-       *      Due to performance considerations, the`oldCollection` value is computed only if the
-       *      `listener` function declares two or more arguments.
-       *    - The `scope` argument refers to the current scope.
-       *
-       * @returns {function()} Returns a de-registration function for this listener. When the
-       *    de-registration function is executed, the internal watch operation is terminated.
-       */
-      $watchCollection: function(obj, listener) {
-        $watchCollectionInterceptor.$stateful = true;
-
-        var self = this;
-        // the current value, updated on each dirty-check run
-        var newValue;
-        // a shallow copy of the newValue from the last dirty-check run,
-        // updated to match newValue during dirty-check run
-        var oldValue;
-        // a shallow copy of the newValue from when the last change happened
-        var veryOldValue;
-        // only track veryOldValue if the listener is asking for it
-        var trackVeryOldValue = (listener.length > 1);
-        var changeDetected = 0;
-        var changeDetector = $parse(obj, $watchCollectionInterceptor);
-        var internalArray = [];
-        var internalObject = {};
-        var initRun = true;
-        var oldLength = 0;
-
-        function $watchCollectionInterceptor(_value) {
-          newValue = _value;
-          var newLength, key, bothNaN, newItem, oldItem;
-
-          // If the new value is undefined, then return undefined as the watch may be a one-time watch
-          if (isUndefined(newValue)) return;
-
-          if (!isObject(newValue)) { // if primitive
-            if (oldValue !== newValue) {
-              oldValue = newValue;
-              changeDetected++;
-            }
-          } else if (isArrayLike(newValue)) {
-            if (oldValue !== internalArray) {
-              // we are transitioning from something which was not an array into array.
-              oldValue = internalArray;
-              oldLength = oldValue.length = 0;
-              changeDetected++;
-            }
-
-            newLength = newValue.length;
-
-            if (oldLength !== newLength) {
-              // if lengths do not match we need to trigger change notification
-              changeDetected++;
-              oldValue.length = oldLength = newLength;
-            }
-            // copy the items to oldValue and look for changes.
-            for (var i = 0; i < newLength; i++) {
-              oldItem = oldValue[i];
-              newItem = newValue[i];
-
-              // eslint-disable-next-line no-self-compare
-              bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
-              if (!bothNaN && (oldItem !== newItem)) {
-                changeDetected++;
-                oldValue[i] = newItem;
-              }
-            }
-          } else {
-            if (oldValue !== internalObject) {
-              // we are transitioning from something which was not an object into object.
-              oldValue = internalObject = {};
-              oldLength = 0;
-              changeDetected++;
-            }
-            // copy the items to oldValue and look for changes.
-            newLength = 0;
-            for (key in newValue) {
-              if (hasOwnProperty.call(newValue, key)) {
-                newLength++;
-                newItem = newValue[key];
-                oldItem = oldValue[key];
-
-                if (key in oldValue) {
-                  // eslint-disable-next-line no-self-compare
-                  bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
-                  if (!bothNaN && (oldItem !== newItem)) {
-                    changeDetected++;
-                    oldValue[key] = newItem;
-                  }
-                } else {
-                  oldLength++;
-                  oldValue[key] = newItem;
-                  changeDetected++;
-                }
-              }
-            }
-            if (oldLength > newLength) {
-              // we used to have more keys, need to find them and destroy them.
-              changeDetected++;
-              for (key in oldValue) {
-                if (!hasOwnProperty.call(newValue, key)) {
-                  oldLength--;
-                  delete oldValue[key];
-                }
-              }
-            }
-          }
-          return changeDetected;
-        }
-
-        function $watchCollectionAction() {
-          if (initRun) {
-            initRun = false;
-            listener(newValue, newValue, self);
-          } else {
-            listener(newValue, veryOldValue, self);
-          }
-
-          // make a copy for the next time a collection is changed
-          if (trackVeryOldValue) {
-            if (!isObject(newValue)) {
-              //primitive
-              veryOldValue = newValue;
-            } else if (isArrayLike(newValue)) {
-              veryOldValue = new Array(newValue.length);
-              for (var i = 0; i < newValue.length; i++) {
-                veryOldValue[i] = newValue[i];
-              }
-            } else { // if object
-              veryOldValue = {};
-              for (var key in newValue) {
-                if (hasOwnProperty.call(newValue, key)) {
-                  veryOldValue[key] = newValue[key];
-                }
-              }
-            }
-          }
-        }
-
-        return this.$watch(changeDetector, $watchCollectionAction);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$digest
-       * @kind function
-       *
-       * @description
-       * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and
-       * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change
-       * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers}
-       * until no more listeners are firing. This means that it is possible to get into an infinite
-       * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of
-       * iterations exceeds 10.
-       *
-       * Usually, you don't call `$digest()` directly in
-       * {@link ng.directive:ngController controllers} or in
-       * {@link ng.$compileProvider#directive directives}.
-       * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within
-       * a {@link ng.$compileProvider#directive directive}), which will force a `$digest()`.
-       *
-       * If you want to be notified whenever `$digest()` is called,
-       * you can register a `watchExpression` function with
-       * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`.
-       *
-       * In unit tests, you may need to call `$digest()` to simulate the scope life cycle.
-       *
-       * # Example
-       * ```js
-           var scope = ...;
-           scope.name = 'misko';
-           scope.counter = 0;
-
-           expect(scope.counter).toEqual(0);
-           scope.$watch('name', function(newValue, oldValue) {
-             scope.counter = scope.counter + 1;
-           });
-           expect(scope.counter).toEqual(0);
-
-           scope.$digest();
-           // the listener is always called during the first $digest loop after it was registered
-           expect(scope.counter).toEqual(1);
-
-           scope.$digest();
-           // but now it will not be called unless the value changes
-           expect(scope.counter).toEqual(1);
-
-           scope.name = 'adam';
-           scope.$digest();
-           expect(scope.counter).toEqual(2);
-       * ```
-       *
-       */
-      $digest: function() {
-        var watch, value, last, fn, get,
-            watchers,
-            dirty, ttl = TTL,
-            next, current, target = this,
-            watchLog = [],
-            logIdx, asyncTask;
-
-        beginPhase('$digest');
-        // Check for changes to browser url that happened in sync before the call to $digest
-        $browser.$$checkUrlChange();
-
-        if (this === $rootScope && applyAsyncId !== null) {
-          // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then
-          // cancel the scheduled $apply and flush the queue of expressions to be evaluated.
-          $browser.defer.cancel(applyAsyncId);
-          flushApplyAsync();
-        }
-
-        lastDirtyWatch = null;
-
-        do { // "while dirty" loop
-          dirty = false;
-          current = target;
-
-          // It's safe for asyncQueuePosition to be a local variable here because this loop can't
-          // be reentered recursively. Calling $digest from a function passed to $evalAsync would
-          // lead to a '$digest already in progress' error.
-          for (var asyncQueuePosition = 0; asyncQueuePosition < asyncQueue.length; asyncQueuePosition++) {
-            try {
-              asyncTask = asyncQueue[asyncQueuePosition];
-              fn = asyncTask.fn;
-              fn(asyncTask.scope, asyncTask.locals);
-            } catch (e) {
-              $exceptionHandler(e);
-            }
-            lastDirtyWatch = null;
-          }
-          asyncQueue.length = 0;
-
-          traverseScopesLoop:
-          do { // "traverse the scopes" loop
-            if ((watchers = current.$$watchers)) {
-              // process our watches
-              watchers.$$digestWatchIndex = watchers.length;
-              while (watchers.$$digestWatchIndex--) {
-                try {
-                  watch = watchers[watchers.$$digestWatchIndex];
-                  // Most common watches are on primitives, in which case we can short
-                  // circuit it with === operator, only when === fails do we use .equals
-                  if (watch) {
-                    get = watch.get;
-                    if ((value = get(current)) !== (last = watch.last) &&
-                        !(watch.eq
-                            ? equals(value, last)
-                            : (isNumberNaN(value) && isNumberNaN(last)))) {
-                      dirty = true;
-                      lastDirtyWatch = watch;
-                      watch.last = watch.eq ? copy(value, null) : value;
-                      fn = watch.fn;
-                      fn(value, ((last === initWatchVal) ? value : last), current);
-                      if (ttl < 5) {
-                        logIdx = 4 - ttl;
-                        if (!watchLog[logIdx]) watchLog[logIdx] = [];
-                        watchLog[logIdx].push({
-                          msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,
-                          newVal: value,
-                          oldVal: last
-                        });
-                      }
-                    } else if (watch === lastDirtyWatch) {
-                      // If the most recently dirty watcher is now clean, short circuit since the remaining watchers
-                      // have already been tested.
-                      dirty = false;
-                      break traverseScopesLoop;
-                    }
-                  }
-                } catch (e) {
-                  $exceptionHandler(e);
-                }
-              }
-            }
-
-            // Insanity Warning: scope depth-first traversal
-            // yes, this code is a bit crazy, but it works and we have tests to prove it!
-            // this piece should be kept in sync with the traversal in $broadcast
-            if (!(next = ((current.$$watchersCount && current.$$childHead) ||
-                (current !== target && current.$$nextSibling)))) {
-              while (current !== target && !(next = current.$$nextSibling)) {
-                current = current.$parent;
-              }
-            }
-          } while ((current = next));
-
-          // `break traverseScopesLoop;` takes us to here
-
-          if ((dirty || asyncQueue.length) && !(ttl--)) {
-            clearPhase();
-            throw $rootScopeMinErr('infdig',
-                '{0} $digest() iterations reached. Aborting!\n' +
-                'Watchers fired in the last 5 iterations: {1}',
-                TTL, watchLog);
-          }
-
-        } while (dirty || asyncQueue.length);
-
-        clearPhase();
-
-        // postDigestQueuePosition isn't local here because this loop can be reentered recursively.
-        while (postDigestQueuePosition < postDigestQueue.length) {
-          try {
-            postDigestQueue[postDigestQueuePosition++]();
-          } catch (e) {
-            $exceptionHandler(e);
-          }
-        }
-        postDigestQueue.length = postDigestQueuePosition = 0;
-
-        // Check for changes to browser url that happened during the $digest
-        // (for which no event is fired; e.g. via `history.pushState()`)
-        $browser.$$checkUrlChange();
-      },
-
-
-      /**
-       * @ngdoc event
-       * @name $rootScope.Scope#$destroy
-       * @eventType broadcast on scope being destroyed
-       *
-       * @description
-       * Broadcasted when a scope and its children are being destroyed.
-       *
-       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
-       * clean up DOM bindings before an element is removed from the DOM.
-       */
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$destroy
-       * @kind function
-       *
-       * @description
-       * Removes the current scope (and all of its children) from the parent scope. Removal implies
-       * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer
-       * propagate to the current scope and its children. Removal also implies that the current
-       * scope is eligible for garbage collection.
-       *
-       * The `$destroy()` is usually used by directives such as
-       * {@link ng.directive:ngRepeat ngRepeat} for managing the
-       * unrolling of the loop.
-       *
-       * Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope.
-       * Application code can register a `$destroy` event handler that will give it a chance to
-       * perform any necessary cleanup.
-       *
-       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
-       * clean up DOM bindings before an element is removed from the DOM.
-       */
-      $destroy: function() {
-        // We can't destroy a scope that has been already destroyed.
-        if (this.$$destroyed) return;
-        var parent = this.$parent;
-
-        this.$broadcast('$destroy');
-        this.$$destroyed = true;
-
-        if (this === $rootScope) {
-          //Remove handlers attached to window when $rootScope is removed
-          $browser.$$applicationDestroyed();
-        }
-
-        incrementWatchersCount(this, -this.$$watchersCount);
-        for (var eventName in this.$$listenerCount) {
-          decrementListenerCount(this, this.$$listenerCount[eventName], eventName);
-        }
-
-        // sever all the references to parent scopes (after this cleanup, the current scope should
-        // not be retained by any of our references and should be eligible for garbage collection)
-        if (parent && parent.$$childHead === this) parent.$$childHead = this.$$nextSibling;
-        if (parent && parent.$$childTail === this) parent.$$childTail = this.$$prevSibling;
-        if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
-        if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;
-
-        // Disable listeners, watchers and apply/digest methods
-        this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop;
-        this.$on = this.$watch = this.$watchGroup = function() { return noop; };
-        this.$$listeners = {};
-
-        // Disconnect the next sibling to prevent `cleanUpScope` destroying those too
-        this.$$nextSibling = null;
-        cleanUpScope(this);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$eval
-       * @kind function
-       *
-       * @description
-       * Executes the `expression` on the current scope and returns the result. Any exceptions in
-       * the expression are propagated (uncaught). This is useful when evaluating Angular
-       * expressions.
-       *
-       * # Example
-       * ```js
-           var scope = ng.$rootScope.Scope();
-           scope.a = 1;
-           scope.b = 2;
-
-           expect(scope.$eval('a+b')).toEqual(3);
-           expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);
-       * ```
-       *
-       * @param {(string|function())=} expression An angular expression to be executed.
-       *
-       *    - `string`: execute using the rules as defined in  {@link guide/expression expression}.
-       *    - `function(scope)`: execute the function with the current `scope` parameter.
-       *
-       * @param {(object)=} locals Local variables object, useful for overriding values in scope.
-       * @returns {*} The result of evaluating the expression.
-       */
-      $eval: function(expr, locals) {
-        return $parse(expr)(this, locals);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$evalAsync
-       * @kind function
-       *
-       * @description
-       * Executes the expression on the current scope at a later point in time.
-       *
-       * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only
-       * that:
-       *
-       *   - it will execute after the function that scheduled the evaluation (preferably before DOM
-       *     rendering).
-       *   - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after
-       *     `expression` execution.
-       *
-       * Any exceptions from the execution of the expression are forwarded to the
-       * {@link ng.$exceptionHandler $exceptionHandler} service.
-       *
-       * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle
-       * will be scheduled. However, it is encouraged to always call code that changes the model
-       * from within an `$apply` call. That includes code evaluated via `$evalAsync`.
-       *
-       * @param {(string|function())=} expression An angular expression to be executed.
-       *
-       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
-       *    - `function(scope)`: execute the function with the current `scope` parameter.
-       *
-       * @param {(object)=} locals Local variables object, useful for overriding values in scope.
-       */
-      $evalAsync: function(expr, locals) {
-        // if we are outside of an $digest loop and this is the first time we are scheduling async
-        // task also schedule async auto-flush
-        if (!$rootScope.$$phase && !asyncQueue.length) {
-          $browser.defer(function() {
-            if (asyncQueue.length) {
-              $rootScope.$digest();
-            }
-          });
-        }
-
-        asyncQueue.push({scope: this, fn: $parse(expr), locals: locals});
-      },
-
-      $$postDigest: function(fn) {
-        postDigestQueue.push(fn);
-      },
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$apply
-       * @kind function
-       *
-       * @description
-       * `$apply()` is used to execute an expression in angular from outside of the angular
-       * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).
-       * Because we are calling into the angular framework we need to perform proper scope life
-       * cycle of {@link ng.$exceptionHandler exception handling},
-       * {@link ng.$rootScope.Scope#$digest executing watches}.
-       *
-       * ## Life cycle
-       *
-       * # Pseudo-Code of `$apply()`
-       * ```js
-           function $apply(expr) {
-             try {
-               return $eval(expr);
-             } catch (e) {
-               $exceptionHandler(e);
-             } finally {
-               $root.$digest();
-             }
-           }
-       * ```
-       *
-       *
-       * Scope's `$apply()` method transitions through the following stages:
-       *
-       * 1. The {@link guide/expression expression} is executed using the
-       *    {@link ng.$rootScope.Scope#$eval $eval()} method.
-       * 2. Any exceptions from the execution of the expression are forwarded to the
-       *    {@link ng.$exceptionHandler $exceptionHandler} service.
-       * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the
-       *    expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method.
-       *
-       *
-       * @param {(string|function())=} exp An angular expression to be executed.
-       *
-       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
-       *    - `function(scope)`: execute the function with current `scope` parameter.
-       *
-       * @returns {*} The result of evaluating the expression.
-       */
-      $apply: function(expr) {
-        try {
-          beginPhase('$apply');
-          try {
-            return this.$eval(expr);
-          } finally {
-            clearPhase();
-          }
-        } catch (e) {
-          $exceptionHandler(e);
-        } finally {
-          try {
-            $rootScope.$digest();
-          } catch (e) {
-            $exceptionHandler(e);
-            // eslint-disable-next-line no-unsafe-finally
-            throw e;
-          }
-        }
-      },
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$applyAsync
-       * @kind function
-       *
-       * @description
-       * Schedule the invocation of $apply to occur at a later time. The actual time difference
-       * varies across browsers, but is typically around ~10 milliseconds.
-       *
-       * This can be used to queue up multiple expressions which need to be evaluated in the same
-       * digest.
-       *
-       * @param {(string|function())=} exp An angular expression to be executed.
-       *
-       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
-       *    - `function(scope)`: execute the function with current `scope` parameter.
-       */
-      $applyAsync: function(expr) {
-        var scope = this;
-        if (expr) {
-          applyAsyncQueue.push($applyAsyncExpression);
-        }
-        expr = $parse(expr);
-        scheduleApplyAsync();
-
-        function $applyAsyncExpression() {
-          scope.$eval(expr);
-        }
-      },
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$on
-       * @kind function
-       *
-       * @description
-       * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for
-       * discussion of event life cycle.
-       *
-       * The event listener function format is: `function(event, args...)`. The `event` object
-       * passed into the listener has the following attributes:
-       *
-       *   - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or
-       *     `$broadcast`-ed.
-       *   - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the
-       *     event propagates through the scope hierarchy, this property is set to null.
-       *   - `name` - `{string}`: name of the event.
-       *   - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel
-       *     further event propagation (available only for events that were `$emit`-ed).
-       *   - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag
-       *     to true.
-       *   - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.
-       *
-       * @param {string} name Event name to listen on.
-       * @param {function(event, ...args)} listener Function to call when the event is emitted.
-       * @returns {function()} Returns a deregistration function for this listener.
-       */
-      $on: function(name, listener) {
-        var namedListeners = this.$$listeners[name];
-        if (!namedListeners) {
-          this.$$listeners[name] = namedListeners = [];
-        }
-        namedListeners.push(listener);
-
-        var current = this;
-        do {
-          if (!current.$$listenerCount[name]) {
-            current.$$listenerCount[name] = 0;
-          }
-          current.$$listenerCount[name]++;
-        } while ((current = current.$parent));
-
-        var self = this;
-        return function() {
-          var indexOfListener = namedListeners.indexOf(listener);
-          if (indexOfListener !== -1) {
-            namedListeners[indexOfListener] = null;
-            decrementListenerCount(self, 1, name);
-          }
-        };
-      },
-
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$emit
-       * @kind function
-       *
-       * @description
-       * Dispatches an event `name` upwards through the scope hierarchy notifying the
-       * registered {@link ng.$rootScope.Scope#$on} listeners.
-       *
-       * The event life cycle starts at the scope on which `$emit` was called. All
-       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get
-       * notified. Afterwards, the event traverses upwards toward the root scope and calls all
-       * registered listeners along the way. The event will stop propagating if one of the listeners
-       * cancels it.
-       *
-       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
-       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
-       *
-       * @param {string} name Event name to emit.
-       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
-       * @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}).
-       */
-      $emit: function(name, args) {
-        var empty = [],
-            namedListeners,
-            scope = this,
-            stopPropagation = false,
-            event = {
-              name: name,
-              targetScope: scope,
-              stopPropagation: function() {stopPropagation = true;},
-              preventDefault: function() {
-                event.defaultPrevented = true;
-              },
-              defaultPrevented: false
-            },
-            listenerArgs = concat([event], arguments, 1),
-            i, length;
-
-        do {
-          namedListeners = scope.$$listeners[name] || empty;
-          event.currentScope = scope;
-          for (i = 0, length = namedListeners.length; i < length; i++) {
-
-            // if listeners were deregistered, defragment the array
-            if (!namedListeners[i]) {
-              namedListeners.splice(i, 1);
-              i--;
-              length--;
-              continue;
-            }
-            try {
-              //allow all listeners attached to the current scope to run
-              namedListeners[i].apply(null, listenerArgs);
-            } catch (e) {
-              $exceptionHandler(e);
-            }
-          }
-          //if any listener on the current scope stops propagation, prevent bubbling
-          if (stopPropagation) {
-            event.currentScope = null;
-            return event;
-          }
-          //traverse upwards
-          scope = scope.$parent;
-        } while (scope);
-
-        event.currentScope = null;
-
-        return event;
-      },
-
-
-      /**
-       * @ngdoc method
-       * @name $rootScope.Scope#$broadcast
-       * @kind function
-       *
-       * @description
-       * Dispatches an event `name` downwards to all child scopes (and their children) notifying the
-       * registered {@link ng.$rootScope.Scope#$on} listeners.
-       *
-       * The event life cycle starts at the scope on which `$broadcast` was called. All
-       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get
-       * notified. Afterwards, the event propagates to all direct and indirect scopes of the current
-       * scope and calls all registered listeners along the way. The event cannot be canceled.
-       *
-       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
-       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
-       *
-       * @param {string} name Event name to broadcast.
-       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
-       * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}
-       */
-      $broadcast: function(name, args) {
-        var target = this,
-            current = target,
-            next = target,
-            event = {
-              name: name,
-              targetScope: target,
-              preventDefault: function() {
-                event.defaultPrevented = true;
-              },
-              defaultPrevented: false
-            };
-
-        if (!target.$$listenerCount[name]) return event;
-
-        var listenerArgs = concat([event], arguments, 1),
-            listeners, i, length;
-
-        //down while you can, then up and next sibling or up and next sibling until back at root
-        while ((current = next)) {
-          event.currentScope = current;
-          listeners = current.$$listeners[name] || [];
-          for (i = 0, length = listeners.length; i < length; i++) {
-            // if listeners were deregistered, defragment the array
-            if (!listeners[i]) {
-              listeners.splice(i, 1);
-              i--;
-              length--;
-              continue;
-            }
-
-            try {
-              listeners[i].apply(null, listenerArgs);
-            } catch (e) {
-              $exceptionHandler(e);
-            }
-          }
-
-          // Insanity Warning: scope depth-first traversal
-          // yes, this code is a bit crazy, but it works and we have tests to prove it!
-          // this piece should be kept in sync with the traversal in $digest
-          // (though it differs due to having the extra check for $$listenerCount)
-          if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
-              (current !== target && current.$$nextSibling)))) {
-            while (current !== target && !(next = current.$$nextSibling)) {
-              current = current.$parent;
-            }
-          }
-        }
-
-        event.currentScope = null;
-        return event;
-      }
-    };
-
-    var $rootScope = new Scope();
-
-    //The internal queues. Expose them on the $rootScope for debugging/testing purposes.
-    var asyncQueue = $rootScope.$$asyncQueue = [];
-    var postDigestQueue = $rootScope.$$postDigestQueue = [];
-    var applyAsyncQueue = $rootScope.$$applyAsyncQueue = [];
-
-    var postDigestQueuePosition = 0;
-
-    return $rootScope;
-
-
-    function beginPhase(phase) {
-      if ($rootScope.$$phase) {
-        throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);
-      }
-
-      $rootScope.$$phase = phase;
-    }
-
-    function clearPhase() {
-      $rootScope.$$phase = null;
-    }
-
-    function incrementWatchersCount(current, count) {
-      do {
-        current.$$watchersCount += count;
-      } while ((current = current.$parent));
-    }
-
-    function decrementListenerCount(current, count, name) {
-      do {
-        current.$$listenerCount[name] -= count;
-
-        if (current.$$listenerCount[name] === 0) {
-          delete current.$$listenerCount[name];
-        }
-      } while ((current = current.$parent));
-    }
-
-    /**
-     * function used as an initial value for watchers.
-     * because it's unique we can easily tell it apart from other values
-     */
-    function initWatchVal() {}
-
-    function flushApplyAsync() {
-      while (applyAsyncQueue.length) {
-        try {
-          applyAsyncQueue.shift()();
-        } catch (e) {
-          $exceptionHandler(e);
-        }
-      }
-      applyAsyncId = null;
-    }
-
-    function scheduleApplyAsync() {
-      if (applyAsyncId === null) {
-        applyAsyncId = $browser.defer(function() {
-          $rootScope.$apply(flushApplyAsync);
-        });
-      }
-    }
-  }];
-}
-
-/**
- * @ngdoc service
- * @name $rootElement
- *
- * @description
- * The root element of Angular application. This is either the element where {@link
- * ng.directive:ngApp ngApp} was declared or the element passed into
- * {@link angular.bootstrap}. The element represents the root element of application. It is also the
- * location where the application's {@link auto.$injector $injector} service gets
- * published, and can be retrieved using `$rootElement.injector()`.
- */
-
-
-// the implementation is in angular.bootstrap
-
-/**
- * @this
- * @description
- * Private service to sanitize uris for links and images. Used by $compile and $sanitize.
- */
-function $$SanitizeUriProvider() {
-  var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
-    imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file|blob):|data:image\/)/;
-
-  /**
-   * @description
-   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
-   * urls during a[href] sanitization.
-   *
-   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
-   *
-   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
-   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
-   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
-   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
-   *
-   * @param {RegExp=} regexp New regexp to whitelist urls with.
-   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
-   *    chaining otherwise.
-   */
-  this.aHrefSanitizationWhitelist = function(regexp) {
-    if (isDefined(regexp)) {
-      aHrefSanitizationWhitelist = regexp;
-      return this;
-    }
-    return aHrefSanitizationWhitelist;
-  };
-
-
-  /**
-   * @description
-   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
-   * urls during img[src] sanitization.
-   *
-   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
-   *
-   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into
-   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
-   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
-   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
-   *
-   * @param {RegExp=} regexp New regexp to whitelist urls with.
-   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
-   *    chaining otherwise.
-   */
-  this.imgSrcSanitizationWhitelist = function(regexp) {
-    if (isDefined(regexp)) {
-      imgSrcSanitizationWhitelist = regexp;
-      return this;
-    }
-    return imgSrcSanitizationWhitelist;
-  };
-
-  this.$get = function() {
-    return function sanitizeUri(uri, isImage) {
-      var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
-      var normalizedVal;
-      normalizedVal = urlResolve(uri).href;
-      if (normalizedVal !== '' && !normalizedVal.match(regex)) {
-        return 'unsafe:' + normalizedVal;
-      }
-      return uri;
-    };
-  };
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *     Any commits to this file should be reviewed with security in mind.  *
- *   Changes to this file can potentially create security vulnerabilities. *
- *          An approval from 2 Core members with history of modifying      *
- *                         this file is required.                          *
- *                                                                         *
- *  Does the change somehow allow for arbitrary javascript to be executed? *
- *    Or allows for someone to change the prototype of built-in objects?   *
- *     Or gives undesired access to variables likes document or window?    *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/* exported $SceProvider, $SceDelegateProvider */
-
-var $sceMinErr = minErr('$sce');
-
-var SCE_CONTEXTS = {
-  HTML: 'html',
-  CSS: 'css',
-  URL: 'url',
-  // RESOURCE_URL is a subtype of URL used in contexts where a privileged resource is sourced from a
-  // url.  (e.g. ng-include, script src, templateUrl)
-  RESOURCE_URL: 'resourceUrl',
-  JS: 'js'
-};
-
-// Helper functions follow.
-
-var UNDERSCORE_LOWERCASE_REGEXP = /_([a-z])/g;
-
-function snakeToCamel(name) {
-  return name
-    .replace(UNDERSCORE_LOWERCASE_REGEXP, fnCamelCaseReplace);
-}
-
-function adjustMatcher(matcher) {
-  if (matcher === 'self') {
-    return matcher;
-  } else if (isString(matcher)) {
-    // Strings match exactly except for 2 wildcards - '*' and '**'.
-    // '*' matches any character except those from the set ':/.?&'.
-    // '**' matches any character (like .* in a RegExp).
-    // More than 2 *'s raises an error as it's ill defined.
-    if (matcher.indexOf('***') > -1) {
-      throw $sceMinErr('iwcard',
-          'Illegal sequence *** in string matcher.  String: {0}', matcher);
-    }
-    matcher = escapeForRegexp(matcher).
-                  replace(/\\\*\\\*/g, '.*').
-                  replace(/\\\*/g, '[^:/.?&;]*');
-    return new RegExp('^' + matcher + '$');
-  } else if (isRegExp(matcher)) {
-    // The only other type of matcher allowed is a Regexp.
-    // Match entire URL / disallow partial matches.
-    // Flags are reset (i.e. no global, ignoreCase or multiline)
-    return new RegExp('^' + matcher.source + '$');
-  } else {
-    throw $sceMinErr('imatcher',
-        'Matchers may only be "self", string patterns or RegExp objects');
-  }
-}
-
-
-function adjustMatchers(matchers) {
-  var adjustedMatchers = [];
-  if (isDefined(matchers)) {
-    forEach(matchers, function(matcher) {
-      adjustedMatchers.push(adjustMatcher(matcher));
-    });
-  }
-  return adjustedMatchers;
-}
-
-
-/**
- * @ngdoc service
- * @name $sceDelegate
- * @kind function
- *
- * @description
- *
- * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict
- * Contextual Escaping (SCE)} services to AngularJS.
- *
- * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of
- * the `$sce` service to customize the way Strict Contextual Escaping works in AngularJS.  This is
- * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to
- * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things
- * work because `$sce` delegates to `$sceDelegate` for these operations.
- *
- * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.
- *
- * The default instance of `$sceDelegate` should work out of the box with little pain.  While you
- * can override it completely to change the behavior of `$sce`, the common case would
- * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting
- * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as
- * templates.  Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist
- * $sceDelegateProvider.resourceUrlWhitelist} and {@link
- * ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
- */
-
-/**
- * @ngdoc provider
- * @name $sceDelegateProvider
- * @this
- *
- * @description
- *
- * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
- * $sceDelegate} service.  This allows one to get/set the whitelists and blacklists used to ensure
- * that the URLs used for sourcing Angular templates are safe.  Refer {@link
- * ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and
- * {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
- *
- * For the general details about this service in Angular, read the main page for {@link ng.$sce
- * Strict Contextual Escaping (SCE)}.
- *
- * **Example**:  Consider the following case. <a name="example"></a>
- *
- * - your app is hosted at url `http://myapp.example.com/`
- * - but some of your templates are hosted on other domains you control such as
- *   `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc.
- * - and you have an open redirect at `http://myapp.example.com/clickThru?...`.
- *
- * Here is what a secure configuration for this scenario might look like:
- *
- * ```
- *  angular.module('myApp', []).config(function($sceDelegateProvider) {
- *    $sceDelegateProvider.resourceUrlWhitelist([
- *      // Allow same origin resource loads.
- *      'self',
- *      // Allow loading from our assets domain.  Notice the difference between * and **.
- *      'http://srv*.assets.example.com/**'
- *    ]);
- *
- *    // The blacklist overrides the whitelist so the open redirect here is blocked.
- *    $sceDelegateProvider.resourceUrlBlacklist([
- *      'http://myapp.example.com/clickThru**'
- *    ]);
- *  });
- * ```
- */
-
-function $SceDelegateProvider() {
-  this.SCE_CONTEXTS = SCE_CONTEXTS;
-
-  // Resource URLs can also be trusted by policy.
-  var resourceUrlWhitelist = ['self'],
-      resourceUrlBlacklist = [];
-
-  /**
-   * @ngdoc method
-   * @name $sceDelegateProvider#resourceUrlWhitelist
-   * @kind function
-   *
-   * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
-   *    provided.  This must be an array or null.  A snapshot of this array is used so further
-   *    changes to the array are ignored.
-   *
-   *    Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
-   *    allowed in this array.
-   *
-   *    <div class="alert alert-warning">
-   *    **Note:** an empty whitelist array will block all URLs!
-   *    </div>
-   *
-   * @return {Array} the currently set whitelist array.
-   *
-   * The **default value** when no whitelist has been explicitly set is `['self']` allowing only
-   * same origin resource requests.
-   *
-   * @description
-   * Sets/Gets the whitelist of trusted resource URLs.
-   */
-  this.resourceUrlWhitelist = function(value) {
-    if (arguments.length) {
-      resourceUrlWhitelist = adjustMatchers(value);
-    }
-    return resourceUrlWhitelist;
-  };
-
-  /**
-   * @ngdoc method
-   * @name $sceDelegateProvider#resourceUrlBlacklist
-   * @kind function
-   *
-   * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
-   *    provided.  This must be an array or null.  A snapshot of this array is used so further
-   *    changes to the array are ignored.
-   *
-   *    Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
-   *    allowed in this array.
-   *
-   *    The typical usage for the blacklist is to **block
-   *    [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
-   *    these would otherwise be trusted but actually return content from the redirected domain.
-   *
-   *    Finally, **the blacklist overrides the whitelist** and has the final say.
-   *
-   * @return {Array} the currently set blacklist array.
-   *
-   * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there
-   * is no blacklist.)
-   *
-   * @description
-   * Sets/Gets the blacklist of trusted resource URLs.
-   */
-
-  this.resourceUrlBlacklist = function(value) {
-    if (arguments.length) {
-      resourceUrlBlacklist = adjustMatchers(value);
-    }
-    return resourceUrlBlacklist;
-  };
-
-  this.$get = ['$injector', function($injector) {
-
-    var htmlSanitizer = function htmlSanitizer(html) {
-      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
-    };
-
-    if ($injector.has('$sanitize')) {
-      htmlSanitizer = $injector.get('$sanitize');
-    }
-
-
-    function matchUrl(matcher, parsedUrl) {
-      if (matcher === 'self') {
-        return urlIsSameOrigin(parsedUrl);
-      } else {
-        // definitely a regex.  See adjustMatchers()
-        return !!matcher.exec(parsedUrl.href);
-      }
-    }
-
-    function isResourceUrlAllowedByPolicy(url) {
-      var parsedUrl = urlResolve(url.toString());
-      var i, n, allowed = false;
-      // Ensure that at least one item from the whitelist allows this url.
-      for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {
-        if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {
-          allowed = true;
-          break;
-        }
-      }
-      if (allowed) {
-        // Ensure that no item from the blacklist blocked this url.
-        for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {
-          if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {
-            allowed = false;
-            break;
-          }
-        }
-      }
-      return allowed;
-    }
-
-    function generateHolderType(Base) {
-      var holderType = function TrustedValueHolderType(trustedValue) {
-        this.$$unwrapTrustedValue = function() {
-          return trustedValue;
-        };
-      };
-      if (Base) {
-        holderType.prototype = new Base();
-      }
-      holderType.prototype.valueOf = function sceValueOf() {
-        return this.$$unwrapTrustedValue();
-      };
-      holderType.prototype.toString = function sceToString() {
-        return this.$$unwrapTrustedValue().toString();
-      };
-      return holderType;
-    }
-
-    var trustedValueHolderBase = generateHolderType(),
-        byType = {};
-
-    byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);
-    byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);
-    byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase);
-    byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);
-    byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]);
-
-    /**
-     * @ngdoc method
-     * @name $sceDelegate#trustAs
-     *
-     * @description
-     * Returns an object that is trusted by angular for use in specified strict
-     * contextual escaping contexts (such as ng-bind-html, ng-include, any src
-     * attribute interpolation, any dom event binding attribute interpolation
-     * such as for onclick,  etc.) that uses the provided value.
-     * See {@link ng.$sce $sce} for enabling strict contextual escaping.
-     *
-     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,
-     *   resourceUrl, html, js and css.
-     * @param {*} value The value that that should be considered trusted/safe.
-     * @returns {*} A value that can be used to stand in for the provided `value` in places
-     * where Angular expects a $sce.trustAs() return value.
-     */
-    function trustAs(type, trustedValue) {
-      var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
-      if (!Constructor) {
-        throw $sceMinErr('icontext',
-            'Attempted to trust a value in invalid context. Context: {0}; Value: {1}',
-            type, trustedValue);
-      }
-      if (trustedValue === null || isUndefined(trustedValue) || trustedValue === '') {
-        return trustedValue;
-      }
-      // All the current contexts in SCE_CONTEXTS happen to be strings.  In order to avoid trusting
-      // mutable objects, we ensure here that the value passed in is actually a string.
-      if (typeof trustedValue !== 'string') {
-        throw $sceMinErr('itype',
-            'Attempted to trust a non-string value in a content requiring a string: Context: {0}',
-            type);
-      }
-      return new Constructor(trustedValue);
-    }
-
-    /**
-     * @ngdoc method
-     * @name $sceDelegate#valueOf
-     *
-     * @description
-     * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs
-     * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link
-     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.
-     *
-     * If the passed parameter is not a value that had been returned by {@link
-     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, returns it as-is.
-     *
-     * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}
-     *      call or anything else.
-     * @returns {*} The `value` that was originally provided to {@link ng.$sceDelegate#trustAs
-     *     `$sceDelegate.trustAs`} if `value` is the result of such a call.  Otherwise, returns
-     *     `value` unchanged.
-     */
-    function valueOf(maybeTrusted) {
-      if (maybeTrusted instanceof trustedValueHolderBase) {
-        return maybeTrusted.$$unwrapTrustedValue();
-      } else {
-        return maybeTrusted;
-      }
-    }
-
-    /**
-     * @ngdoc method
-     * @name $sceDelegate#getTrusted
-     *
-     * @description
-     * Takes the result of a {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call and
-     * returns the originally supplied value if the queried context type is a supertype of the
-     * created type.  If this condition isn't satisfied, throws an exception.
-     *
-     * <div class="alert alert-danger">
-     * Disabling auto-escaping is extremely dangerous, it usually creates a Cross Site Scripting
-     * (XSS) vulnerability in your application.
-     * </div>
-     *
-     * @param {string} type The kind of context in which this value is to be used.
-     * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs
-     *     `$sceDelegate.trustAs`} call.
-     * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs
-     *     `$sceDelegate.trustAs`} if valid in this context.  Otherwise, throws an exception.
-     */
-    function getTrusted(type, maybeTrusted) {
-      if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') {
-        return maybeTrusted;
-      }
-      var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
-      if (constructor && maybeTrusted instanceof constructor) {
-        return maybeTrusted.$$unwrapTrustedValue();
-      }
-      // If we get here, then we may only take one of two actions.
-      // 1. sanitize the value for the requested type, or
-      // 2. throw an exception.
-      if (type === SCE_CONTEXTS.RESOURCE_URL) {
-        if (isResourceUrlAllowedByPolicy(maybeTrusted)) {
-          return maybeTrusted;
-        } else {
-          throw $sceMinErr('insecurl',
-              'Blocked loading resource from url not allowed by $sceDelegate policy.  URL: {0}',
-              maybeTrusted.toString());
-        }
-      } else if (type === SCE_CONTEXTS.HTML) {
-        return htmlSanitizer(maybeTrusted);
-      }
-      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
-    }
-
-    return { trustAs: trustAs,
-             getTrusted: getTrusted,
-             valueOf: valueOf };
-  }];
-}
-
-
-/**
- * @ngdoc provider
- * @name $sceProvider
- * @this
- *
- * @description
- *
- * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service.
- * -   enable/disable Strict Contextual Escaping (SCE) in a module
- * -   override the default implementation with a custom delegate
- *
- * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}.
- */
-
-/**
- * @ngdoc service
- * @name $sce
- * @kind function
- *
- * @description
- *
- * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS.
- *
- * # Strict Contextual Escaping
- *
- * Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain
- * contexts to result in a value that is marked as safe to use for that context.  One example of
- * such a context is binding arbitrary html controlled by the user via `ng-bind-html`.  We refer
- * to these contexts as privileged or SCE contexts.
- *
- * As of version 1.2, Angular ships with SCE enabled by default.
- *
- * Note:  When enabled (the default), IE<11 in quirks mode is not supported.  In this mode, IE<11 allow
- * one to execute arbitrary javascript by the use of the expression() syntax.  Refer
- * <http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx> to learn more about them.
- * You can ensure your document is in standards mode and not quirks mode by adding `<!doctype html>`
- * to the top of your HTML document.
- *
- * SCE assists in writing code in a way that (a) is secure by default and (b) makes auditing for
- * security vulnerabilities such as XSS, clickjacking, etc. a lot easier.
- *
- * Here's an example of a binding in a privileged context:
- *
- * ```
- * <input ng-model="userHtml" aria-label="User input">
- * <div ng-bind-html="userHtml"></div>
- * ```
- *
- * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user.  With SCE
- * disabled, this application allows the user to render arbitrary HTML into the DIV.
- * In a more realistic example, one may be rendering user comments, blog articles, etc. via
- * bindings.  (HTML is just one example of a context where rendering user controlled input creates
- * security vulnerabilities.)
- *
- * For the case of HTML, you might use a library, either on the client side, or on the server side,
- * to sanitize unsafe HTML before binding to the value and rendering it in the document.
- *
- * How would you ensure that every place that used these types of bindings was bound to a value that
- * was sanitized by your library (or returned as safe for rendering by your server?)  How can you
- * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some
- * properties/fields and forgot to update the binding to the sanitized value?
- *
- * To be secure by default, you want to ensure that any such bindings are disallowed unless you can
- * determine that something explicitly says it's safe to use a value for binding in that
- * context.  You can then audit your code (a simple grep would do) to ensure that this is only done
- * for those values that you can easily tell are safe - because they were received from your server,
- * sanitized by your library, etc.  You can organize your codebase to help with this - perhaps
- * allowing only the files in a specific directory to do this.  Ensuring that the internal API
- * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task.
- *
- * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs}
- * (and shorthand methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to
- * obtain values that will be accepted by SCE / privileged contexts.
- *
- *
- * ## How does it work?
- *
- * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted
- * $sce.getTrusted(context, value)} rather than to the value directly.  Directives use {@link
- * ng.$sce#parseAs $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the
- * {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals.
- *
- * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link
- * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}.  Here's the actual code (slightly
- * simplified):
- *
- * ```
- * var ngBindHtmlDirective = ['$sce', function($sce) {
- *   return function(scope, element, attr) {
- *     scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
- *       element.html(value || '');
- *     });
- *   };
- * }];
- * ```
- *
- * ## Impact on loading templates
- *
- * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as
- * `templateUrl`'s specified by {@link guide/directive directives}.
- *
- * By default, Angular only loads templates from the same domain and protocol as the application
- * document.  This is done by calling {@link ng.$sce#getTrustedResourceUrl
- * $sce.getTrustedResourceUrl} on the template URL.  To load templates from other domains and/or
- * protocols, you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist
- * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value.
- *
- * *Please note*:
- * The browser's
- * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)
- * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)
- * policy apply in addition to this and may further restrict whether the template is successfully
- * loaded.  This means that without the right CORS policy, loading templates from a different domain
- * won't work on all browsers.  Also, loading templates from `file://` URL does not work on some
- * browsers.
- *
- * ## This feels like too much overhead
- *
- * It's important to remember that SCE only applies to interpolation expressions.
- *
- * If your expressions are constant literals, they're automatically trusted and you don't need to
- * call `$sce.trustAs` on them (remember to include the `ngSanitize` module) (e.g.
- * `<div ng-bind-html="'<b>implicitly trusted</b>'"></div>`) just works.
- *
- * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them
- * through {@link ng.$sce#getTrusted $sce.getTrusted}.  SCE doesn't play a role here.
- *
- * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load
- * templates in `ng-include` from your application's domain without having to even know about SCE.
- * It blocks loading templates from other domains or loading templates over http from an https
- * served document.  You can change these by setting your own custom {@link
- * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link
- * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs.
- *
- * This significantly reduces the overhead.  It is far easier to pay the small overhead and have an
- * application that's secure and can be audited to verify that with much more ease than bolting
- * security onto an application later.
- *
- * <a name="contexts"></a>
- * ## What trusted context types are supported?
- *
- * | Context             | Notes          |
- * |---------------------|----------------|
- * | `$sce.HTML`         | For HTML that's safe to source into the application.  The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. |
- * | `$sce.CSS`          | For CSS that's safe to source into the application.  Currently unused.  Feel free to use it in your own directives. |
- * | `$sce.URL`          | For URLs that are safe to follow as links.  Currently unused (`<a href=` and `<img src=` sanitize their urls and don't constitute an SCE context. |
- * | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application.  Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG`, `VIDEO`, `AUDIO`, `SOURCE`, and `TRACK` (e.g. `IFRAME`, `OBJECT`, etc.)  <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |
- * | `$sce.JS`           | For JavaScript that is safe to execute in your application's context.  Currently unused.  Feel free to use it in your own directives. |
- *
- * ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist} <a name="resourceUrlPatternItem"></a>
- *
- *  Each element in these arrays must be one of the following:
- *
- *  - **'self'**
- *    - The special **string**, `'self'`, can be used to match against all URLs of the **same
- *      domain** as the application document using the **same protocol**.
- *  - **String** (except the special value `'self'`)
- *    - The string is matched against the full *normalized / absolute URL* of the resource
- *      being tested (substring matches are not good enough.)
- *    - There are exactly **two wildcard sequences** - `*` and `**`.  All other characters
- *      match themselves.
- *    - `*`: matches zero or more occurrences of any character other than one of the following 6
- *      characters: '`:`', '`/`', '`.`', '`?`', '`&`' and '`;`'.  It's a useful wildcard for use
- *      in a whitelist.
- *    - `**`: matches zero or more occurrences of *any* character.  As such, it's not
- *      appropriate for use in a scheme, domain, etc. as it would match too much.  (e.g.
- *      http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might
- *      not have been the intention.)  Its usage at the very end of the path is ok.  (e.g.
- *      http://foo.example.com/templates/**).
- *  - **RegExp** (*see caveat below*)
- *    - *Caveat*:  While regular expressions are powerful and offer great flexibility,  their syntax
- *      (and all the inevitable escaping) makes them *harder to maintain*.  It's easy to
- *      accidentally introduce a bug when one updates a complex expression (imho, all regexes should
- *      have good test coverage).  For instance, the use of `.` in the regex is correct only in a
- *      small number of cases.  A `.` character in the regex used when matching the scheme or a
- *      subdomain could be matched against a `:` or literal `.` that was likely not intended.   It
- *      is highly recommended to use the string patterns and only fall back to regular expressions
- *      as a last resort.
- *    - The regular expression must be an instance of RegExp (i.e. not a string.)  It is
- *      matched against the **entire** *normalized / absolute URL* of the resource being tested
- *      (even when the RegExp did not have the `^` and `$` codes.)  In addition, any flags
- *      present on the RegExp (such as multiline, global, ignoreCase) are ignored.
- *    - If you are generating your JavaScript from some other templating engine (not
- *      recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)),
- *      remember to escape your regular expression (and be aware that you might need more than
- *      one level of escaping depending on your templating engine and the way you interpolated
- *      the value.)  Do make use of your platform's escaping mechanism as it might be good
- *      enough before coding your own.  E.g. Ruby has
- *      [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape)
- *      and Python has [re.escape](http://docs.python.org/library/re.html#re.escape).
- *      Javascript lacks a similar built in function for escaping.  Take a look at Google
- *      Closure library's [goog.string.regExpEscape(s)](
- *      http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962).
- *
- * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example.
- *
- * ## Show me an example using SCE.
- *
- * <example module="mySceApp" deps="angular-sanitize.js" name="sce-service">
- * <file name="index.html">
- *   <div ng-controller="AppController as myCtrl">
- *     <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
- *     <b>User comments</b><br>
- *     By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when
- *     $sanitize is available.  If $sanitize isn't available, this results in an error instead of an
- *     exploit.
- *     <div class="well">
- *       <div ng-repeat="userComment in myCtrl.userComments">
- *         <b>{{userComment.name}}</b>:
- *         <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
- *         <br>
- *       </div>
- *     </div>
- *   </div>
- * </file>
- *
- * <file name="script.js">
- *   angular.module('mySceApp', ['ngSanitize'])
- *     .controller('AppController', ['$http', '$templateCache', '$sce',
- *       function AppController($http, $templateCache, $sce) {
- *         var self = this;
- *         $http.get('test_data.json', {cache: $templateCache}).then(function(response) {
- *           self.userComments = response.data;
- *         });
- *         self.explicitlyTrustedHtml = $sce.trustAsHtml(
- *             '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
- *             'sanitization.&quot;">Hover over this text.</span>');
- *       }]);
- * </file>
- *
- * <file name="test_data.json">
- * [
- *   { "name": "Alice",
- *     "htmlComment":
- *         "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>"
- *   },
- *   { "name": "Bob",
- *     "htmlComment": "<i>Yes!</i>  Am I the only other one?"
- *   }
- * ]
- * </file>
- *
- * <file name="protractor.js" type="protractor">
- *   describe('SCE doc demo', function() {
- *     it('should sanitize untrusted values', function() {
- *       expect(element.all(by.css('.htmlComment')).first().getAttribute('innerHTML'))
- *           .toBe('<span>Is <i>anyone</i> reading this?</span>');
- *     });
- *
- *     it('should NOT sanitize explicitly trusted values', function() {
- *       expect(element(by.id('explicitlyTrustedHtml')).getAttribute('innerHTML')).toBe(
- *           '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
- *           'sanitization.&quot;">Hover over this text.</span>');
- *     });
- *   });
- * </file>
- * </example>
- *
- *
- *
- * ## Can I disable SCE completely?
- *
- * Yes, you can.  However, this is strongly discouraged.  SCE gives you a lot of security benefits
- * for little coding overhead.  It will be much harder to take an SCE disabled application and
- * either secure it on your own or enable SCE at a later stage.  It might make sense to disable SCE
- * for cases where you have a lot of existing code that was written before SCE was introduced and
- * you're migrating them a module at a time.
- *
- * That said, here's how you can completely disable SCE:
- *
- * ```
- * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
- *   // Completely disable SCE.  For demonstration purposes only!
- *   // Do not use in new projects.
- *   $sceProvider.enabled(false);
- * });
- * ```
- *
- */
-
-function $SceProvider() {
-  var enabled = true;
-
-  /**
-   * @ngdoc method
-   * @name $sceProvider#enabled
-   * @kind function
-   *
-   * @param {boolean=} value If provided, then enables/disables SCE.
-   * @return {boolean} true if SCE is enabled, false otherwise.
-   *
-   * @description
-   * Enables/disables SCE and returns the current value.
-   */
-  this.enabled = function(value) {
-    if (arguments.length) {
-      enabled = !!value;
-    }
-    return enabled;
-  };
-
-
-  /* Design notes on the default implementation for SCE.
-   *
-   * The API contract for the SCE delegate
-   * -------------------------------------
-   * The SCE delegate object must provide the following 3 methods:
-   *
-   * - trustAs(contextEnum, value)
-   *     This method is used to tell the SCE service that the provided value is OK to use in the
-   *     contexts specified by contextEnum.  It must return an object that will be accepted by
-   *     getTrusted() for a compatible contextEnum and return this value.
-   *
-   * - valueOf(value)
-   *     For values that were not produced by trustAs(), return them as is.  For values that were
-   *     produced by trustAs(), return the corresponding input value to trustAs.  Basically, if
-   *     trustAs is wrapping the given values into some type, this operation unwraps it when given
-   *     such a value.
-   *
-   * - getTrusted(contextEnum, value)
-   *     This function should return the a value that is safe to use in the context specified by
-   *     contextEnum or throw and exception otherwise.
-   *
-   * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be
-   * opaque or wrapped in some holder object.  That happens to be an implementation detail.  For
-   * instance, an implementation could maintain a registry of all trusted objects by context.  In
-   * such a case, trustAs() would return the same object that was passed in.  getTrusted() would
-   * return the same object passed in if it was found in the registry under a compatible context or
-   * throw an exception otherwise.  An implementation might only wrap values some of the time based
-   * on some criteria.  getTrusted() might return a value and not throw an exception for special
-   * constants or objects even if not wrapped.  All such implementations fulfill this contract.
-   *
-   *
-   * A note on the inheritance model for SCE contexts
-   * ------------------------------------------------
-   * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types.  This
-   * is purely an implementation details.
-   *
-   * The contract is simply this:
-   *
-   *     getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value)
-   *     will also succeed.
-   *
-   * Inheritance happens to capture this in a natural way.  In some future, we
-   * may not use inheritance anymore.  That is OK because no code outside of
-   * sce.js and sceSpecs.js would need to be aware of this detail.
-   */
-
-  this.$get = ['$parse', '$sceDelegate', function(
-                $parse,   $sceDelegate) {
-    // Support: IE 9-11 only
-    // Prereq: Ensure that we're not running in IE<11 quirks mode.  In that mode, IE < 11 allow
-    // the "expression(javascript expression)" syntax which is insecure.
-    if (enabled && msie < 8) {
-      throw $sceMinErr('iequirks',
-        'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +
-        'mode.  You can fix this by adding the text <!doctype html> to the top of your HTML ' +
-        'document.  See http://docs.angularjs.org/api/ng.$sce for more information.');
-    }
-
-    var sce = shallowCopy(SCE_CONTEXTS);
-
-    /**
-     * @ngdoc method
-     * @name $sce#isEnabled
-     * @kind function
-     *
-     * @return {Boolean} true if SCE is enabled, false otherwise.  If you want to set the value, you
-     * have to do it at module config time on {@link ng.$sceProvider $sceProvider}.
-     *
-     * @description
-     * Returns a boolean indicating if SCE is enabled.
-     */
-    sce.isEnabled = function() {
-      return enabled;
-    };
-    sce.trustAs = $sceDelegate.trustAs;
-    sce.getTrusted = $sceDelegate.getTrusted;
-    sce.valueOf = $sceDelegate.valueOf;
-
-    if (!enabled) {
-      sce.trustAs = sce.getTrusted = function(type, value) { return value; };
-      sce.valueOf = identity;
-    }
-
-    /**
-     * @ngdoc method
-     * @name $sce#parseAs
-     *
-     * @description
-     * Converts Angular {@link guide/expression expression} into a function.  This is like {@link
-     * ng.$parse $parse} and is identical when the expression is a literal constant.  Otherwise, it
-     * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*,
-     * *result*)}
-     *
-     * @param {string} type The kind of SCE context in which this result will be used.
-     * @param {string} expression String expression to compile.
-     * @returns {function(context, locals)} a function which represents the compiled expression:
-     *
-     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
-     *      are evaluated against (typically a scope object).
-     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
-     *      `context`.
-     */
-    sce.parseAs = function sceParseAs(type, expr) {
-      var parsed = $parse(expr);
-      if (parsed.literal && parsed.constant) {
-        return parsed;
-      } else {
-        return $parse(expr, function(value) {
-          return sce.getTrusted(type, value);
-        });
-      }
-    };
-
-    /**
-     * @ngdoc method
-     * @name $sce#trustAs
-     *
-     * @description
-     * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.  As such,
-     * returns an object that is trusted by angular for use in specified strict contextual
-     * escaping contexts (such as ng-bind-html, ng-include, any src attribute
-     * interpolation, any dom event binding attribute interpolation such as for onclick,  etc.)
-     * that uses the provided value.  See * {@link ng.$sce $sce} for enabling strict contextual
-     * escaping.
-     *
-     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,
-     *   resourceUrl, html, js and css.
-     * @param {*} value The value that that should be considered trusted/safe.
-     * @returns {*} A value that can be used to stand in for the provided `value` in places
-     * where Angular expects a $sce.trustAs() return value.
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#trustAsHtml
-     *
-     * @description
-     * Shorthand method.  `$sce.trustAsHtml(value)` →
-     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`}
-     *
-     * @param {*} value The value to trustAs.
-     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedHtml
-     *     $sce.getTrustedHtml(value)} to obtain the original value.  (privileged directives
-     *     only accept expressions that are either literal constants or are the
-     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#trustAsUrl
-     *
-     * @description
-     * Shorthand method.  `$sce.trustAsUrl(value)` →
-     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`}
-     *
-     * @param {*} value The value to trustAs.
-     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedUrl
-     *     $sce.getTrustedUrl(value)} to obtain the original value.  (privileged directives
-     *     only accept expressions that are either literal constants or are the
-     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#trustAsResourceUrl
-     *
-     * @description
-     * Shorthand method.  `$sce.trustAsResourceUrl(value)` →
-     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`}
-     *
-     * @param {*} value The value to trustAs.
-     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedResourceUrl
-     *     $sce.getTrustedResourceUrl(value)} to obtain the original value.  (privileged directives
-     *     only accept expressions that are either literal constants or are the return
-     *     value of {@link ng.$sce#trustAs $sce.trustAs}.)
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#trustAsJs
-     *
-     * @description
-     * Shorthand method.  `$sce.trustAsJs(value)` →
-     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`}
-     *
-     * @param {*} value The value to trustAs.
-     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedJs
-     *     $sce.getTrustedJs(value)} to obtain the original value.  (privileged directives
-     *     only accept expressions that are either literal constants or are the
-     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#getTrusted
-     *
-     * @description
-     * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}.  As such,
-     * takes the result of a {@link ng.$sce#trustAs `$sce.trustAs`}() call and returns the
-     * originally supplied value if the queried context type is a supertype of the created type.
-     * If this condition isn't satisfied, throws an exception.
-     *
-     * @param {string} type The kind of context in which this value is to be used.
-     * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs `$sce.trustAs`}
-     *                         call.
-     * @returns {*} The value the was originally provided to
-     *              {@link ng.$sce#trustAs `$sce.trustAs`} if valid in this context.
-     *              Otherwise, throws an exception.
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#getTrustedHtml
-     *
-     * @description
-     * Shorthand method.  `$sce.getTrustedHtml(value)` →
-     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`}
-     *
-     * @param {*} value The value to pass to `$sce.getTrusted`.
-     * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)`
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#getTrustedCss
-     *
-     * @description
-     * Shorthand method.  `$sce.getTrustedCss(value)` →
-     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`}
-     *
-     * @param {*} value The value to pass to `$sce.getTrusted`.
-     * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)`
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#getTrustedUrl
-     *
-     * @description
-     * Shorthand method.  `$sce.getTrustedUrl(value)` →
-     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`}
-     *
-     * @param {*} value The value to pass to `$sce.getTrusted`.
-     * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)`
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#getTrustedResourceUrl
-     *
-     * @description
-     * Shorthand method.  `$sce.getTrustedResourceUrl(value)` →
-     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`}
-     *
-     * @param {*} value The value to pass to `$sceDelegate.getTrusted`.
-     * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)`
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#getTrustedJs
-     *
-     * @description
-     * Shorthand method.  `$sce.getTrustedJs(value)` →
-     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`}
-     *
-     * @param {*} value The value to pass to `$sce.getTrusted`.
-     * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)`
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#parseAsHtml
-     *
-     * @description
-     * Shorthand method.  `$sce.parseAsHtml(expression string)` →
-     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`}
-     *
-     * @param {string} expression String expression to compile.
-     * @returns {function(context, locals)} a function which represents the compiled expression:
-     *
-     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
-     *      are evaluated against (typically a scope object).
-     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
-     *      `context`.
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#parseAsCss
-     *
-     * @description
-     * Shorthand method.  `$sce.parseAsCss(value)` →
-     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`}
-     *
-     * @param {string} expression String expression to compile.
-     * @returns {function(context, locals)} a function which represents the compiled expression:
-     *
-     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
-     *      are evaluated against (typically a scope object).
-     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
-     *      `context`.
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#parseAsUrl
-     *
-     * @description
-     * Shorthand method.  `$sce.parseAsUrl(value)` →
-     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`}
-     *
-     * @param {string} expression String expression to compile.
-     * @returns {function(context, locals)} a function which represents the compiled expression:
-     *
-     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
-     *      are evaluated against (typically a scope object).
-     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
-     *      `context`.
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#parseAsResourceUrl
-     *
-     * @description
-     * Shorthand method.  `$sce.parseAsResourceUrl(value)` →
-     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}
-     *
-     * @param {string} expression String expression to compile.
-     * @returns {function(context, locals)} a function which represents the compiled expression:
-     *
-     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
-     *      are evaluated against (typically a scope object).
-     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
-     *      `context`.
-     */
-
-    /**
-     * @ngdoc method
-     * @name $sce#parseAsJs
-     *
-     * @description
-     * Shorthand method.  `$sce.parseAsJs(value)` →
-     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`}
-     *
-     * @param {string} expression String expression to compile.
-     * @returns {function(context, locals)} a function which represents the compiled expression:
-     *
-     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
-     *      are evaluated against (typically a scope object).
-     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
-     *      `context`.
-     */
-
-    // Shorthand delegations.
-    var parse = sce.parseAs,
-        getTrusted = sce.getTrusted,
-        trustAs = sce.trustAs;
-
-    forEach(SCE_CONTEXTS, function(enumValue, name) {
-      var lName = lowercase(name);
-      sce[snakeToCamel('parse_as_' + lName)] = function(expr) {
-        return parse(enumValue, expr);
-      };
-      sce[snakeToCamel('get_trusted_' + lName)] = function(value) {
-        return getTrusted(enumValue, value);
-      };
-      sce[snakeToCamel('trust_as_' + lName)] = function(value) {
-        return trustAs(enumValue, value);
-      };
-    });
-
-    return sce;
-  }];
-}
-
-/* exported $SnifferProvider */
-
-/**
- * !!! This is an undocumented "private" service !!!
- *
- * @name $sniffer
- * @requires $window
- * @requires $document
- * @this
- *
- * @property {boolean} history Does the browser support html5 history api ?
- * @property {boolean} transitions Does the browser support CSS transition events ?
- * @property {boolean} animations Does the browser support CSS animation events ?
- *
- * @description
- * This is very simple implementation of testing browser's features.
- */
-function $SnifferProvider() {
-  this.$get = ['$window', '$document', function($window, $document) {
-    var eventSupport = {},
-        // Chrome Packaged Apps are not allowed to access `history.pushState`.
-        // If not sandboxed, they can be detected by the presence of `chrome.app.runtime`
-        // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by
-        // the presence of an extension runtime ID and the absence of other Chrome runtime APIs
-        // (see https://developer.chrome.com/apps/manifest/sandbox).
-        // (NW.js apps have access to Chrome APIs, but do support `history`.)
-        isNw = $window.nw && $window.nw.process,
-        isChromePackagedApp =
-            !isNw &&
-            $window.chrome &&
-            ($window.chrome.app && $window.chrome.app.runtime ||
-                !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id),
-        hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,
-        android =
-          toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
-        boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
-        document = $document[0] || {},
-        bodyStyle = document.body && document.body.style,
-        transitions = false,
-        animations = false;
-
-    if (bodyStyle) {
-      // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x
-      // Mentioned browsers need a -webkit- prefix for transitions & animations.
-      transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle);
-      animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle);
-    }
-
-
-    return {
-      // Android has history.pushState, but it does not update location correctly
-      // so let's not use the history API at all.
-      // http://code.google.com/p/android/issues/detail?id=17471
-      // https://github.com/angular/angular.js/issues/904
-
-      // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has
-      // so let's not use the history API also
-      // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
-      history: !!(hasHistoryPushState && !(android < 4) && !boxee),
-      hasEvent: function(event) {
-        // Support: IE 9-11 only
-        // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
-        // it. In particular the event is not fired when backspace or delete key are pressed or
-        // when cut operation is performed.
-        // IE10+ implements 'input' event but it erroneously fires under various situations,
-        // e.g. when placeholder changes, or a form is focused.
-        if (event === 'input' && msie) return false;
-
-        if (isUndefined(eventSupport[event])) {
-          var divElm = document.createElement('div');
-          eventSupport[event] = 'on' + event in divElm;
-        }
-
-        return eventSupport[event];
-      },
-      csp: csp(),
-      transitions: transitions,
-      animations: animations,
-      android: android
-    };
-  }];
-}
-
-var $templateRequestMinErr = minErr('$compile');
-
-/**
- * @ngdoc provider
- * @name $templateRequestProvider
- * @this
- *
- * @description
- * Used to configure the options passed to the {@link $http} service when making a template request.
- *
- * For example, it can be used for specifying the "Accept" header that is sent to the server, when
- * requesting a template.
- */
-function $TemplateRequestProvider() {
-
-  var httpOptions;
-
-  /**
-   * @ngdoc method
-   * @name $templateRequestProvider#httpOptions
-   * @description
-   * The options to be passed to the {@link $http} service when making the request.
-   * You can use this to override options such as the "Accept" header for template requests.
-   *
-   * The {@link $templateRequest} will set the `cache` and the `transformResponse` properties of the
-   * options if not overridden here.
-   *
-   * @param {string=} value new value for the {@link $http} options.
-   * @returns {string|self} Returns the {@link $http} options when used as getter and self if used as setter.
-   */
-  this.httpOptions = function(val) {
-    if (val) {
-      httpOptions = val;
-      return this;
-    }
-    return httpOptions;
-  };
-
-  /**
-   * @ngdoc service
-   * @name $templateRequest
-   *
-   * @description
-   * The `$templateRequest` service runs security checks then downloads the provided template using
-   * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request
-   * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the
-   * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the
-   * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted
-   * when `tpl` is of type string and `$templateCache` has the matching entry.
-   *
-   * If you want to pass custom options to the `$http` service, such as setting the Accept header you
-   * can configure this via {@link $templateRequestProvider#httpOptions}.
-   *
-   * @param {string|TrustedResourceUrl} tpl The HTTP request template URL
-   * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty
-   *
-   * @return {Promise} a promise for the HTTP response data of the given URL.
-   *
-   * @property {number} totalPendingRequests total amount of pending template requests being downloaded.
-   */
-  this.$get = ['$exceptionHandler', '$templateCache', '$http', '$q', '$sce',
-    function($exceptionHandler, $templateCache, $http, $q, $sce) {
-
-      function handleRequestFn(tpl, ignoreRequestError) {
-        handleRequestFn.totalPendingRequests++;
-
-        // We consider the template cache holds only trusted templates, so
-        // there's no need to go through whitelisting again for keys that already
-        // are included in there. This also makes Angular accept any script
-        // directive, no matter its name. However, we still need to unwrap trusted
-        // types.
-        if (!isString(tpl) || isUndefined($templateCache.get(tpl))) {
-          tpl = $sce.getTrustedResourceUrl(tpl);
-        }
-
-        var transformResponse = $http.defaults && $http.defaults.transformResponse;
-
-        if (isArray(transformResponse)) {
-          transformResponse = transformResponse.filter(function(transformer) {
-            return transformer !== defaultHttpResponseTransform;
-          });
-        } else if (transformResponse === defaultHttpResponseTransform) {
-          transformResponse = null;
-        }
-
-        return $http.get(tpl, extend({
-            cache: $templateCache,
-            transformResponse: transformResponse
-          }, httpOptions))
-          .finally(function() {
-            handleRequestFn.totalPendingRequests--;
-          })
-          .then(function(response) {
-            $templateCache.put(tpl, response.data);
-            return response.data;
-          }, handleError);
-
-        function handleError(resp) {
-          if (!ignoreRequestError) {
-            resp = $templateRequestMinErr('tpload',
-                'Failed to load template: {0} (HTTP status: {1} {2})',
-                tpl, resp.status, resp.statusText);
-
-            $exceptionHandler(resp);
-          }
-
-          return $q.reject(resp);
-        }
-      }
-
-      handleRequestFn.totalPendingRequests = 0;
-
-      return handleRequestFn;
-    }
-  ];
-}
-
-/** @this */
-function $$TestabilityProvider() {
-  this.$get = ['$rootScope', '$browser', '$location',
-       function($rootScope,   $browser,   $location) {
-
-    /**
-     * @name $testability
-     *
-     * @description
-     * The private $$testability service provides a collection of methods for use when debugging
-     * or by automated test and debugging tools.
-     */
-    var testability = {};
-
-    /**
-     * @name $$testability#findBindings
-     *
-     * @description
-     * Returns an array of elements that are bound (via ng-bind or {{}})
-     * to expressions matching the input.
-     *
-     * @param {Element} element The element root to search from.
-     * @param {string} expression The binding expression to match.
-     * @param {boolean} opt_exactMatch If true, only returns exact matches
-     *     for the expression. Filters and whitespace are ignored.
-     */
-    testability.findBindings = function(element, expression, opt_exactMatch) {
-      var bindings = element.getElementsByClassName('ng-binding');
-      var matches = [];
-      forEach(bindings, function(binding) {
-        var dataBinding = angular.element(binding).data('$binding');
-        if (dataBinding) {
-          forEach(dataBinding, function(bindingName) {
-            if (opt_exactMatch) {
-              var matcher = new RegExp('(^|\\s)' + escapeForRegexp(expression) + '(\\s|\\||$)');
-              if (matcher.test(bindingName)) {
-                matches.push(binding);
-              }
-            } else {
-              if (bindingName.indexOf(expression) !== -1) {
-                matches.push(binding);
-              }
-            }
-          });
-        }
-      });
-      return matches;
-    };
-
-    /**
-     * @name $$testability#findModels
-     *
-     * @description
-     * Returns an array of elements that are two-way found via ng-model to
-     * expressions matching the input.
-     *
-     * @param {Element} element The element root to search from.
-     * @param {string} expression The model expression to match.
-     * @param {boolean} opt_exactMatch If true, only returns exact matches
-     *     for the expression.
-     */
-    testability.findModels = function(element, expression, opt_exactMatch) {
-      var prefixes = ['ng-', 'data-ng-', 'ng\\:'];
-      for (var p = 0; p < prefixes.length; ++p) {
-        var attributeEquals = opt_exactMatch ? '=' : '*=';
-        var selector = '[' + prefixes[p] + 'model' + attributeEquals + '"' + expression + '"]';
-        var elements = element.querySelectorAll(selector);
-        if (elements.length) {
-          return elements;
-        }
-      }
-    };
-
-    /**
-     * @name $$testability#getLocation
-     *
-     * @description
-     * Shortcut for getting the location in a browser agnostic way. Returns
-     *     the path, search, and hash. (e.g. /path?a=b#hash)
-     */
-    testability.getLocation = function() {
-      return $location.url();
-    };
-
-    /**
-     * @name $$testability#setLocation
-     *
-     * @description
-     * Shortcut for navigating to a location without doing a full page reload.
-     *
-     * @param {string} url The location url (path, search and hash,
-     *     e.g. /path?a=b#hash) to go to.
-     */
-    testability.setLocation = function(url) {
-      if (url !== $location.url()) {
-        $location.url(url);
-        $rootScope.$digest();
-      }
-    };
-
-    /**
-     * @name $$testability#whenStable
-     *
-     * @description
-     * Calls the callback when $timeout and $http requests are completed.
-     *
-     * @param {function} callback
-     */
-    testability.whenStable = function(callback) {
-      $browser.notifyWhenNoOutstandingRequests(callback);
-    };
-
-    return testability;
-  }];
-}
-
-/** @this */
-function $TimeoutProvider() {
-  this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
-       function($rootScope,   $browser,   $q,   $$q,   $exceptionHandler) {
-
-    var deferreds = {};
-
-
-     /**
-      * @ngdoc service
-      * @name $timeout
-      *
-      * @description
-      * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch
-      * block and delegates any exceptions to
-      * {@link ng.$exceptionHandler $exceptionHandler} service.
-      *
-      * The return value of calling `$timeout` is a promise, which will be resolved when
-      * the delay has passed and the timeout function, if provided, is executed.
-      *
-      * To cancel a timeout request, call `$timeout.cancel(promise)`.
-      *
-      * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
-      * synchronously flush the queue of deferred functions.
-      *
-      * If you only want a promise that will be resolved after some specified delay
-      * then you can call `$timeout` without the `fn` function.
-      *
-      * @param {function()=} fn A function, whose execution should be delayed.
-      * @param {number=} [delay=0] Delay in milliseconds.
-      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
-      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
-      * @param {...*=} Pass additional parameters to the executed function.
-      * @returns {Promise} Promise that will be resolved when the timeout is reached. The promise
-      *   will be resolved with the return value of the `fn` function.
-      *
-      */
-    function timeout(fn, delay, invokeApply) {
-      if (!isFunction(fn)) {
-        invokeApply = delay;
-        delay = fn;
-        fn = noop;
-      }
-
-      var args = sliceArgs(arguments, 3),
-          skipApply = (isDefined(invokeApply) && !invokeApply),
-          deferred = (skipApply ? $$q : $q).defer(),
-          promise = deferred.promise,
-          timeoutId;
-
-      timeoutId = $browser.defer(function() {
-        try {
-          deferred.resolve(fn.apply(null, args));
-        } catch (e) {
-          deferred.reject(e);
-          $exceptionHandler(e);
-        } finally {
-          delete deferreds[promise.$$timeoutId];
-        }
-
-        if (!skipApply) $rootScope.$apply();
-      }, delay);
-
-      promise.$$timeoutId = timeoutId;
-      deferreds[timeoutId] = deferred;
-
-      return promise;
-    }
-
-
-     /**
-      * @ngdoc method
-      * @name $timeout#cancel
-      *
-      * @description
-      * Cancels a task associated with the `promise`. As a result of this, the promise will be
-      * resolved with a rejection.
-      *
-      * @param {Promise=} promise Promise returned by the `$timeout` function.
-      * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
-      *   canceled.
-      */
-    timeout.cancel = function(promise) {
-      if (promise && promise.$$timeoutId in deferreds) {
-        // Timeout cancels should not report an unhandled promise.
-        deferreds[promise.$$timeoutId].promise.catch(noop);
-        deferreds[promise.$$timeoutId].reject('canceled');
-        delete deferreds[promise.$$timeoutId];
-        return $browser.defer.cancel(promise.$$timeoutId);
-      }
-      return false;
-    };
-
-    return timeout;
-  }];
-}
-
-// NOTE:  The usage of window and document instead of $window and $document here is
-// deliberate.  This service depends on the specific behavior of anchor nodes created by the
-// browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and
-// cause us to break tests.  In addition, when the browser resolves a URL for XHR, it
-// doesn't know about mocked locations and resolves URLs to the real document - which is
-// exactly the behavior needed here.  There is little value is mocking these out for this
-// service.
-var urlParsingNode = window.document.createElement('a');
-var originUrl = urlResolve(window.location.href);
-
-
-/**
- *
- * Implementation Notes for non-IE browsers
- * ----------------------------------------
- * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,
- * results both in the normalizing and parsing of the URL.  Normalizing means that a relative
- * URL will be resolved into an absolute URL in the context of the application document.
- * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related
- * properties are all populated to reflect the normalized URL.  This approach has wide
- * compatibility - Safari 1+, Mozilla 1+ etc.  See
- * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
- *
- * Implementation Notes for IE
- * ---------------------------
- * IE <= 10 normalizes the URL when assigned to the anchor node similar to the other
- * browsers.  However, the parsed components will not be set if the URL assigned did not specify
- * them.  (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.)  We
- * work around that by performing the parsing in a 2nd step by taking a previously normalized
- * URL (e.g. by assigning to a.href) and assigning it a.href again.  This correctly populates the
- * properties such as protocol, hostname, port, etc.
- *
- * References:
- *   http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement
- *   http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
- *   http://url.spec.whatwg.org/#urlutils
- *   https://github.com/angular/angular.js/pull/2902
- *   http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
- *
- * @kind function
- * @param {string} url The URL to be parsed.
- * @description Normalizes and parses a URL.
- * @returns {object} Returns the normalized URL as a dictionary.
- *
- *   | member name   | Description    |
- *   |---------------|----------------|
- *   | href          | A normalized version of the provided URL if it was not an absolute URL |
- *   | protocol      | The protocol including the trailing colon                              |
- *   | host          | The host and port (if the port is non-default) of the normalizedUrl    |
- *   | search        | The search params, minus the question mark                             |
- *   | hash          | The hash string, minus the hash symbol
- *   | hostname      | The hostname
- *   | port          | The port, without ":"
- *   | pathname      | The pathname, beginning with "/"
- *
- */
-function urlResolve(url) {
-  var href = url;
-
-  // Support: IE 9-11 only
-  if (msie) {
-    // Normalize before parse.  Refer Implementation Notes on why this is
-    // done in two steps on IE.
-    urlParsingNode.setAttribute('href', href);
-    href = urlParsingNode.href;
-  }
-
-  urlParsingNode.setAttribute('href', href);
-
-  // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
-  return {
-    href: urlParsingNode.href,
-    protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
-    host: urlParsingNode.host,
-    search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
-    hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
-    hostname: urlParsingNode.hostname,
-    port: urlParsingNode.port,
-    pathname: (urlParsingNode.pathname.charAt(0) === '/')
-      ? urlParsingNode.pathname
-      : '/' + urlParsingNode.pathname
-  };
-}
-
-/**
- * Parse a request URL and determine whether this is a same-origin request as the application document.
- *
- * @param {string|object} requestUrl The url of the request as a string that will be resolved
- * or a parsed URL object.
- * @returns {boolean} Whether the request is for the same origin as the application document.
- */
-function urlIsSameOrigin(requestUrl) {
-  var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl;
-  return (parsed.protocol === originUrl.protocol &&
-          parsed.host === originUrl.host);
-}
-
-/**
- * @ngdoc service
- * @name $window
- * @this
- *
- * @description
- * A reference to the browser's `window` object. While `window`
- * is globally available in JavaScript, it causes testability problems, because
- * it is a global variable. In angular we always refer to it through the
- * `$window` service, so it may be overridden, removed or mocked for testing.
- *
- * Expressions, like the one defined for the `ngClick` directive in the example
- * below, are evaluated with respect to the current scope.  Therefore, there is
- * no risk of inadvertently coding in a dependency on a global value in such an
- * expression.
- *
- * @example
-   <example module="windowExample" name="window-service">
-     <file name="index.html">
-       <script>
-         angular.module('windowExample', [])
-           .controller('ExampleController', ['$scope', '$window', function($scope, $window) {
-             $scope.greeting = 'Hello, World!';
-             $scope.doGreeting = function(greeting) {
-               $window.alert(greeting);
-             };
-           }]);
-       </script>
-       <div ng-controller="ExampleController">
-         <input type="text" ng-model="greeting" aria-label="greeting" />
-         <button ng-click="doGreeting(greeting)">ALERT</button>
-       </div>
-     </file>
-     <file name="protractor.js" type="protractor">
-      it('should display the greeting in the input box', function() {
-       element(by.model('greeting')).sendKeys('Hello, E2E Tests');
-       // If we click the button it will block the test runner
-       // element(':button').click();
-      });
-     </file>
-   </example>
- */
-function $WindowProvider() {
-  this.$get = valueFn(window);
-}
-
-/**
- * @name $$cookieReader
- * @requires $document
- *
- * @description
- * This is a private service for reading cookies used by $http and ngCookies
- *
- * @return {Object} a key/value map of the current cookies
- */
-function $$CookieReader($document) {
-  var rawDocument = $document[0] || {};
-  var lastCookies = {};
-  var lastCookieString = '';
-
-  function safeGetCookie(rawDocument) {
-    try {
-      return rawDocument.cookie || '';
-    } catch (e) {
-      return '';
-    }
-  }
-
-  function safeDecodeURIComponent(str) {
-    try {
-      return decodeURIComponent(str);
-    } catch (e) {
-      return str;
-    }
-  }
-
-  return function() {
-    var cookieArray, cookie, i, index, name;
-    var currentCookieString = safeGetCookie(rawDocument);
-
-    if (currentCookieString !== lastCookieString) {
-      lastCookieString = currentCookieString;
-      cookieArray = lastCookieString.split('; ');
-      lastCookies = {};
-
-      for (i = 0; i < cookieArray.length; i++) {
-        cookie = cookieArray[i];
-        index = cookie.indexOf('=');
-        if (index > 0) { //ignore nameless cookies
-          name = safeDecodeURIComponent(cookie.substring(0, index));
-          // the first value that is seen for a cookie is the most
-          // specific one.  values for the same cookie name that
-          // follow are for less specific paths.
-          if (isUndefined(lastCookies[name])) {
-            lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
-          }
-        }
-      }
-    }
-    return lastCookies;
-  };
-}
-
-$$CookieReader.$inject = ['$document'];
-
-/** @this */
-function $$CookieReaderProvider() {
-  this.$get = $$CookieReader;
-}
-
-/* global currencyFilter: true,
- dateFilter: true,
- filterFilter: true,
- jsonFilter: true,
- limitToFilter: true,
- lowercaseFilter: true,
- numberFilter: true,
- orderByFilter: true,
- uppercaseFilter: true,
- */
-
-/**
- * @ngdoc provider
- * @name $filterProvider
- * @description
- *
- * Filters are just functions which transform input to an output. However filters need to be
- * Dependency Injected. To achieve this a filter definition consists of a factory function which is
- * annotated with dependencies and is responsible for creating a filter function.
- *
- * <div class="alert alert-warning">
- * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
- * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
- * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
- * (`myapp_subsection_filterx`).
- * </div>
- *
- * ```js
- *   // Filter registration
- *   function MyModule($provide, $filterProvider) {
- *     // create a service to demonstrate injection (not always needed)
- *     $provide.value('greet', function(name){
- *       return 'Hello ' + name + '!';
- *     });
- *
- *     // register a filter factory which uses the
- *     // greet service to demonstrate DI.
- *     $filterProvider.register('greet', function(greet){
- *       // return the filter function which uses the greet service
- *       // to generate salutation
- *       return function(text) {
- *         // filters need to be forgiving so check input validity
- *         return text && greet(text) || text;
- *       };
- *     });
- *   }
- * ```
- *
- * The filter function is registered with the `$injector` under the filter name suffix with
- * `Filter`.
- *
- * ```js
- *   it('should be the same instance', inject(
- *     function($filterProvider) {
- *       $filterProvider.register('reverse', function(){
- *         return ...;
- *       });
- *     },
- *     function($filter, reverseFilter) {
- *       expect($filter('reverse')).toBe(reverseFilter);
- *     });
- * ```
- *
- *
- * For more information about how angular filters work, and how to create your own filters, see
- * {@link guide/filter Filters} in the Angular Developer Guide.
- */
-
-/**
- * @ngdoc service
- * @name $filter
- * @kind function
- * @description
- * Filters are used for formatting data displayed to the user.
- *
- * They can be used in view templates, controllers or services.Angular comes
- * with a collection of [built-in filters](api/ng/filter), but it is easy to
- * define your own as well.
- *
- * The general syntax in templates is as follows:
- *
- * ```html
- * {{ expression [| filter_name[:parameter_value] ... ] }}
- * ```
- *
- * @param {String} name Name of the filter function to retrieve
- * @return {Function} the filter function
- * @example
-   <example name="$filter" module="filterExample">
-     <file name="index.html">
-       <div ng-controller="MainCtrl">
-        <h3>{{ originalText }}</h3>
-        <h3>{{ filteredText }}</h3>
-       </div>
-     </file>
-
-     <file name="script.js">
-      angular.module('filterExample', [])
-      .controller('MainCtrl', function($scope, $filter) {
-        $scope.originalText = 'hello';
-        $scope.filteredText = $filter('uppercase')($scope.originalText);
-      });
-     </file>
-   </example>
-  */
-$FilterProvider.$inject = ['$provide'];
-/** @this */
-function $FilterProvider($provide) {
-  var suffix = 'Filter';
-
-  /**
-   * @ngdoc method
-   * @name $filterProvider#register
-   * @param {string|Object} name Name of the filter function, or an object map of filters where
-   *    the keys are the filter names and the values are the filter factories.
-   *
-   *    <div class="alert alert-warning">
-   *    **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
-   *    Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
-   *    your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
-   *    (`myapp_subsection_filterx`).
-   *    </div>
-    * @param {Function} factory If the first argument was a string, a factory function for the filter to be registered.
-   * @returns {Object} Registered filter instance, or if a map of filters was provided then a map
-   *    of the registered filter instances.
-   */
-  function register(name, factory) {
-    if (isObject(name)) {
-      var filters = {};
-      forEach(name, function(filter, key) {
-        filters[key] = register(key, filter);
-      });
-      return filters;
-    } else {
-      return $provide.factory(name + suffix, factory);
-    }
-  }
-  this.register = register;
-
-  this.$get = ['$injector', function($injector) {
-    return function(name) {
-      return $injector.get(name + suffix);
-    };
-  }];
-
-  ////////////////////////////////////////
-
-  /* global
-    currencyFilter: false,
-    dateFilter: false,
-    filterFilter: false,
-    jsonFilter: false,
-    limitToFilter: false,
-    lowercaseFilter: false,
-    numberFilter: false,
-    orderByFilter: false,
-    uppercaseFilter: false
-  */
-
-  register('currency', currencyFilter);
-  register('date', dateFilter);
-  register('filter', filterFilter);
-  register('json', jsonFilter);
-  register('limitTo', limitToFilter);
-  register('lowercase', lowercaseFilter);
-  register('number', numberFilter);
-  register('orderBy', orderByFilter);
-  register('uppercase', uppercaseFilter);
-}
-
-/**
- * @ngdoc filter
- * @name filter
- * @kind function
- *
- * @description
- * Selects a subset of items from `array` and returns it as a new array.
- *
- * @param {Array} array The source array.
- * <div class="alert alert-info">
- *   **Note**: If the array contains objects that reference themselves, filtering is not possible.
- * </div>
- * @param {string|Object|function()} expression The predicate to be used for selecting items from
- *   `array`.
- *
- *   Can be one of:
- *
- *   - `string`: The string is used for matching against the contents of the `array`. All strings or
- *     objects with string properties in `array` that match this string will be returned. This also
- *     applies to nested object properties.
- *     The predicate can be negated by prefixing the string with `!`.
- *
- *   - `Object`: A pattern object can be used to filter specific properties on objects contained
- *     by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items
- *     which have property `name` containing "M" and property `phone` containing "1". A special
- *     property name (`$` by default) can be used (e.g. as in `{$: "text"}`) to accept a match
- *     against any property of the object or its nested object properties. That's equivalent to the
- *     simple substring match with a `string` as described above. The special property name can be
- *     overwritten, using the `anyPropertyKey` parameter.
- *     The predicate can be negated by prefixing the string with `!`.
- *     For example `{name: "!M"}` predicate will return an array of items which have property `name`
- *     not containing "M".
- *
- *     Note that a named property will match properties on the same level only, while the special
- *     `$` property will match properties on the same level or deeper. E.g. an array item like
- *     `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but
- *     **will** be matched by `{$: 'John'}`.
- *
- *   - `function(value, index, array)`: A predicate function can be used to write arbitrary filters.
- *     The function is called for each element of the array, with the element, its index, and
- *     the entire array itself as arguments.
- *
- *     The final result is an array of those elements that the predicate returned true for.
- *
- * @param {function(actual, expected)|true|false} [comparator] Comparator which is used in
- *     determining if the expected value (from the filter expression) and actual value (from
- *     the object in the array) should be considered a match.
- *
- *   Can be one of:
- *
- *   - `function(actual, expected)`:
- *     The function will be given the object value and the predicate value to compare and
- *     should return true if both values should be considered equal.
- *
- *   - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected)}`.
- *     This is essentially strict comparison of expected and actual.
- *
- *   - `false`: A short hand for a function which will look for a substring match in a case
- *     insensitive way. Primitive values are converted to strings. Objects are not compared against
- *     primitives, unless they have a custom `toString` method (e.g. `Date` objects).
- *
- *
- *   Defaults to `false`.
- *
- * @param {string} [anyPropertyKey] The special property name that matches against any property.
- *     By default `$`.
- *
- * @example
-   <example name="filter-filter">
-     <file name="index.html">
-       <div ng-init="friends = [{name:'John', phone:'555-1276'},
-                                {name:'Mary', phone:'800-BIG-MARY'},
-                                {name:'Mike', phone:'555-4321'},
-                                {name:'Adam', phone:'555-5678'},
-                                {name:'Julie', phone:'555-8765'},
-                                {name:'Juliette', phone:'555-5678'}]"></div>
-
-       <label>Search: <input ng-model="searchText"></label>
-       <table id="searchTextResults">
-         <tr><th>Name</th><th>Phone</th></tr>
-         <tr ng-repeat="friend in friends | filter:searchText">
-           <td>{{friend.name}}</td>
-           <td>{{friend.phone}}</td>
-         </tr>
-       </table>
-       <hr>
-       <label>Any: <input ng-model="search.$"></label> <br>
-       <label>Name only <input ng-model="search.name"></label><br>
-       <label>Phone only <input ng-model="search.phone"></label><br>
-       <label>Equality <input type="checkbox" ng-model="strict"></label><br>
-       <table id="searchObjResults">
-         <tr><th>Name</th><th>Phone</th></tr>
-         <tr ng-repeat="friendObj in friends | filter:search:strict">
-           <td>{{friendObj.name}}</td>
-           <td>{{friendObj.phone}}</td>
-         </tr>
-       </table>
-     </file>
-     <file name="protractor.js" type="protractor">
-       var expectFriendNames = function(expectedNames, key) {
-         element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
-           arr.forEach(function(wd, i) {
-             expect(wd.getText()).toMatch(expectedNames[i]);
-           });
-         });
-       };
-
-       it('should search across all fields when filtering with a string', function() {
-         var searchText = element(by.model('searchText'));
-         searchText.clear();
-         searchText.sendKeys('m');
-         expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');
-
-         searchText.clear();
-         searchText.sendKeys('76');
-         expectFriendNames(['John', 'Julie'], 'friend');
-       });
-
-       it('should search in specific fields when filtering with a predicate object', function() {
-         var searchAny = element(by.model('search.$'));
-         searchAny.clear();
-         searchAny.sendKeys('i');
-         expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
-       });
-       it('should use a equal comparison when comparator is true', function() {
-         var searchName = element(by.model('search.name'));
-         var strict = element(by.model('strict'));
-         searchName.clear();
-         searchName.sendKeys('Julie');
-         strict.click();
-         expectFriendNames(['Julie'], 'friendObj');
-       });
-     </file>
-   </example>
- */
-
-function filterFilter() {
-  return function(array, expression, comparator, anyPropertyKey) {
-    if (!isArrayLike(array)) {
-      if (array == null) {
-        return array;
-      } else {
-        throw minErr('filter')('notarray', 'Expected array but received: {0}', array);
-      }
-    }
-
-    anyPropertyKey = anyPropertyKey || '$';
-    var expressionType = getTypeForFilter(expression);
-    var predicateFn;
-    var matchAgainstAnyProp;
-
-    switch (expressionType) {
-      case 'function':
-        predicateFn = expression;
-        break;
-      case 'boolean':
-      case 'null':
-      case 'number':
-      case 'string':
-        matchAgainstAnyProp = true;
-        // falls through
-      case 'object':
-        predicateFn = createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp);
-        break;
-      default:
-        return array;
-    }
-
-    return Array.prototype.filter.call(array, predicateFn);
-  };
-}
-
-// Helper functions for `filterFilter`
-function createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp) {
-  var shouldMatchPrimitives = isObject(expression) && (anyPropertyKey in expression);
-  var predicateFn;
-
-  if (comparator === true) {
-    comparator = equals;
-  } else if (!isFunction(comparator)) {
-    comparator = function(actual, expected) {
-      if (isUndefined(actual)) {
-        // No substring matching against `undefined`
-        return false;
-      }
-      if ((actual === null) || (expected === null)) {
-        // No substring matching against `null`; only match against `null`
-        return actual === expected;
-      }
-      if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual))) {
-        // Should not compare primitives against objects, unless they have custom `toString` method
-        return false;
-      }
-
-      actual = lowercase('' + actual);
-      expected = lowercase('' + expected);
-      return actual.indexOf(expected) !== -1;
-    };
-  }
-
-  predicateFn = function(item) {
-    if (shouldMatchPrimitives && !isObject(item)) {
-      return deepCompare(item, expression[anyPropertyKey], comparator, anyPropertyKey, false);
-    }
-    return deepCompare(item, expression, comparator, anyPropertyKey, matchAgainstAnyProp);
-  };
-
-  return predicateFn;
-}
-
-function deepCompare(actual, expected, comparator, anyPropertyKey, matchAgainstAnyProp, dontMatchWholeObject) {
-  var actualType = getTypeForFilter(actual);
-  var expectedType = getTypeForFilter(expected);
-
-  if ((expectedType === 'string') && (expected.charAt(0) === '!')) {
-    return !deepCompare(actual, expected.substring(1), comparator, anyPropertyKey, matchAgainstAnyProp);
-  } else if (isArray(actual)) {
-    // In case `actual` is an array, consider it a match
-    // if ANY of it's items matches `expected`
-    return actual.some(function(item) {
-      return deepCompare(item, expected, comparator, anyPropertyKey, matchAgainstAnyProp);
-    });
-  }
-
-  switch (actualType) {
-    case 'object':
-      var key;
-      if (matchAgainstAnyProp) {
-        for (key in actual) {
-          // Under certain, rare, circumstances, key may not be a string and `charAt` will be undefined
-          // See: https://github.com/angular/angular.js/issues/15644
-          if (key.charAt && (key.charAt(0) !== '$') &&
-              deepCompare(actual[key], expected, comparator, anyPropertyKey, true)) {
-            return true;
-          }
-        }
-        return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, anyPropertyKey, false);
-      } else if (expectedType === 'object') {
-        for (key in expected) {
-          var expectedVal = expected[key];
-          if (isFunction(expectedVal) || isUndefined(expectedVal)) {
-            continue;
-          }
-
-          var matchAnyProperty = key === anyPropertyKey;
-          var actualVal = matchAnyProperty ? actual : actual[key];
-          if (!deepCompare(actualVal, expectedVal, comparator, anyPropertyKey, matchAnyProperty, matchAnyProperty)) {
-            return false;
-          }
-        }
-        return true;
-      } else {
-        return comparator(actual, expected);
-      }
-    case 'function':
-      return false;
-    default:
-      return comparator(actual, expected);
-  }
-}
-
-// Used for easily differentiating between `null` and actual `object`
-function getTypeForFilter(val) {
-  return (val === null) ? 'null' : typeof val;
-}
-
-var MAX_DIGITS = 22;
-var DECIMAL_SEP = '.';
-var ZERO_CHAR = '0';
-
-/**
- * @ngdoc filter
- * @name currency
- * @kind function
- *
- * @description
- * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default
- * symbol for current locale is used.
- *
- * @param {number} amount Input to filter.
- * @param {string=} symbol Currency symbol or identifier to be displayed.
- * @param {number=} fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale
- * @returns {string} Formatted number.
- *
- *
- * @example
-   <example module="currencyExample" name="currency-filter">
-     <file name="index.html">
-       <script>
-         angular.module('currencyExample', [])
-           .controller('ExampleController', ['$scope', function($scope) {
-             $scope.amount = 1234.56;
-           }]);
-       </script>
-       <div ng-controller="ExampleController">
-         <input type="number" ng-model="amount" aria-label="amount"> <br>
-         default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
-         custom currency identifier (USD$): <span id="currency-custom">{{amount | currency:"USD$"}}</span><br>
-         no fractions (0): <span id="currency-no-fractions">{{amount | currency:"USD$":0}}</span>
-       </div>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should init with 1234.56', function() {
-         expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');
-         expect(element(by.id('currency-custom')).getText()).toBe('USD$1,234.56');
-         expect(element(by.id('currency-no-fractions')).getText()).toBe('USD$1,235');
-       });
-       it('should update', function() {
-         if (browser.params.browser === 'safari') {
-           // Safari does not understand the minus key. See
-           // https://github.com/angular/protractor/issues/481
-           return;
-         }
-         element(by.model('amount')).clear();
-         element(by.model('amount')).sendKeys('-1234');
-         expect(element(by.id('currency-default')).getText()).toBe('-$1,234.00');
-         expect(element(by.id('currency-custom')).getText()).toBe('-USD$1,234.00');
-         expect(element(by.id('currency-no-fractions')).getText()).toBe('-USD$1,234');
-       });
-     </file>
-   </example>
- */
-currencyFilter.$inject = ['$locale'];
-function currencyFilter($locale) {
-  var formats = $locale.NUMBER_FORMATS;
-  return function(amount, currencySymbol, fractionSize) {
-    if (isUndefined(currencySymbol)) {
-      currencySymbol = formats.CURRENCY_SYM;
-    }
-
-    if (isUndefined(fractionSize)) {
-      fractionSize = formats.PATTERNS[1].maxFrac;
-    }
-
-    // if null or undefined pass it through
-    return (amount == null)
-        ? amount
-        : formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize).
-            replace(/\u00A4/g, currencySymbol);
-  };
-}
-
-/**
- * @ngdoc filter
- * @name number
- * @kind function
- *
- * @description
- * Formats a number as text.
- *
- * If the input is null or undefined, it will just be returned.
- * If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively.
- * If the input is not a number an empty string is returned.
- *
- *
- * @param {number|string} number Number to format.
- * @param {(number|string)=} fractionSize Number of decimal places to round the number to.
- * If this is not provided then the fraction size is computed from the current locale's number
- * formatting pattern. In the case of the default locale, it will be 3.
- * @returns {string} Number rounded to `fractionSize` appropriately formatted based on the current
- *                   locale (e.g., in the en_US locale it will have "." as the decimal separator and
- *                   include "," group separators after each third digit).
- *
- * @example
-   <example module="numberFilterExample" name="number-filter">
-     <file name="index.html">
-       <script>
-         angular.module('numberFilterExample', [])
-           .controller('ExampleController', ['$scope', function($scope) {
-             $scope.val = 1234.56789;
-           }]);
-       </script>
-       <div ng-controller="ExampleController">
-         <label>Enter number: <input ng-model='val'></label><br>
-         Default formatting: <span id='number-default'>{{val | number}}</span><br>
-         No fractions: <span>{{val | number:0}}</span><br>
-         Negative number: <span>{{-val | number:4}}</span>
-       </div>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should format numbers', function() {
-         expect(element(by.id('number-default')).getText()).toBe('1,234.568');
-         expect(element(by.binding('val | number:0')).getText()).toBe('1,235');
-         expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');
-       });
-
-       it('should update', function() {
-         element(by.model('val')).clear();
-         element(by.model('val')).sendKeys('3374.333');
-         expect(element(by.id('number-default')).getText()).toBe('3,374.333');
-         expect(element(by.binding('val | number:0')).getText()).toBe('3,374');
-         expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');
-      });
-     </file>
-   </example>
- */
-numberFilter.$inject = ['$locale'];
-function numberFilter($locale) {
-  var formats = $locale.NUMBER_FORMATS;
-  return function(number, fractionSize) {
-
-    // if null or undefined pass it through
-    return (number == null)
-        ? number
-        : formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP,
-                       fractionSize);
-  };
-}
-
-/**
- * Parse a number (as a string) into three components that can be used
- * for formatting the number.
- *
- * (Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/)
- *
- * @param  {string} numStr The number to parse
- * @return {object} An object describing this number, containing the following keys:
- *  - d : an array of digits containing leading zeros as necessary
- *  - i : the number of the digits in `d` that are to the left of the decimal point
- *  - e : the exponent for numbers that would need more than `MAX_DIGITS` digits in `d`
- *
- */
-function parse(numStr) {
-  var exponent = 0, digits, numberOfIntegerDigits;
-  var i, j, zeros;
-
-  // Decimal point?
-  if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) {
-    numStr = numStr.replace(DECIMAL_SEP, '');
-  }
-
-  // Exponential form?
-  if ((i = numStr.search(/e/i)) > 0) {
-    // Work out the exponent.
-    if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i;
-    numberOfIntegerDigits += +numStr.slice(i + 1);
-    numStr = numStr.substring(0, i);
-  } else if (numberOfIntegerDigits < 0) {
-    // There was no decimal point or exponent so it is an integer.
-    numberOfIntegerDigits = numStr.length;
-  }
-
-  // Count the number of leading zeros.
-  for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) { /* empty */ }
-
-  if (i === (zeros = numStr.length)) {
-    // The digits are all zero.
-    digits = [0];
-    numberOfIntegerDigits = 1;
-  } else {
-    // Count the number of trailing zeros
-    zeros--;
-    while (numStr.charAt(zeros) === ZERO_CHAR) zeros--;
-
-    // Trailing zeros are insignificant so ignore them
-    numberOfIntegerDigits -= i;
-    digits = [];
-    // Convert string to array of digits without leading/trailing zeros.
-    for (j = 0; i <= zeros; i++, j++) {
-      digits[j] = +numStr.charAt(i);
-    }
-  }
-
-  // If the number overflows the maximum allowed digits then use an exponent.
-  if (numberOfIntegerDigits > MAX_DIGITS) {
-    digits = digits.splice(0, MAX_DIGITS - 1);
-    exponent = numberOfIntegerDigits - 1;
-    numberOfIntegerDigits = 1;
-  }
-
-  return { d: digits, e: exponent, i: numberOfIntegerDigits };
-}
-
-/**
- * Round the parsed number to the specified number of decimal places
- * This function changed the parsedNumber in-place
- */
-function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
-    var digits = parsedNumber.d;
-    var fractionLen = digits.length - parsedNumber.i;
-
-    // determine fractionSize if it is not specified; `+fractionSize` converts it to a number
-    fractionSize = (isUndefined(fractionSize)) ? Math.min(Math.max(minFrac, fractionLen), maxFrac) : +fractionSize;
-
-    // The index of the digit to where rounding is to occur
-    var roundAt = fractionSize + parsedNumber.i;
-    var digit = digits[roundAt];
-
-    if (roundAt > 0) {
-      // Drop fractional digits beyond `roundAt`
-      digits.splice(Math.max(parsedNumber.i, roundAt));
-
-      // Set non-fractional digits beyond `roundAt` to 0
-      for (var j = roundAt; j < digits.length; j++) {
-        digits[j] = 0;
-      }
-    } else {
-      // We rounded to zero so reset the parsedNumber
-      fractionLen = Math.max(0, fractionLen);
-      parsedNumber.i = 1;
-      digits.length = Math.max(1, roundAt = fractionSize + 1);
-      digits[0] = 0;
-      for (var i = 1; i < roundAt; i++) digits[i] = 0;
-    }
-
-    if (digit >= 5) {
-      if (roundAt - 1 < 0) {
-        for (var k = 0; k > roundAt; k--) {
-          digits.unshift(0);
-          parsedNumber.i++;
-        }
-        digits.unshift(1);
-        parsedNumber.i++;
-      } else {
-        digits[roundAt - 1]++;
-      }
-    }
-
-    // Pad out with zeros to get the required fraction length
-    for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
-
-
-    // Do any carrying, e.g. a digit was rounded up to 10
-    var carry = digits.reduceRight(function(carry, d, i, digits) {
-      d = d + carry;
-      digits[i] = d % 10;
-      return Math.floor(d / 10);
-    }, 0);
-    if (carry) {
-      digits.unshift(carry);
-      parsedNumber.i++;
-    }
-}
-
-/**
- * Format a number into a string
- * @param  {number} number       The number to format
- * @param  {{
- *           minFrac, // the minimum number of digits required in the fraction part of the number
- *           maxFrac, // the maximum number of digits required in the fraction part of the number
- *           gSize,   // number of digits in each group of separated digits
- *           lgSize,  // number of digits in the last group of digits before the decimal separator
- *           negPre,  // the string to go in front of a negative number (e.g. `-` or `(`))
- *           posPre,  // the string to go in front of a positive number
- *           negSuf,  // the string to go after a negative number (e.g. `)`)
- *           posSuf   // the string to go after a positive number
- *         }} pattern
- * @param  {string} groupSep     The string to separate groups of number (e.g. `,`)
- * @param  {string} decimalSep   The string to act as the decimal separator (e.g. `.`)
- * @param  {[type]} fractionSize The size of the fractional part of the number
- * @return {string}              The number formatted as a string
- */
-function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
-
-  if (!(isString(number) || isNumber(number)) || isNaN(number)) return '';
-
-  var isInfinity = !isFinite(number);
-  var isZero = false;
-  var numStr = Math.abs(number) + '',
-      formattedText = '',
-      parsedNumber;
-
-  if (isInfinity) {
-    formattedText = '\u221e';
-  } else {
-    parsedNumber = parse(numStr);
-
-    roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac);
-
-    var digits = parsedNumber.d;
-    var integerLen = parsedNumber.i;
-    var exponent = parsedNumber.e;
-    var decimals = [];
-    isZero = digits.reduce(function(isZero, d) { return isZero && !d; }, true);
-
-    // pad zeros for small numbers
-    while (integerLen < 0) {
-      digits.unshift(0);
-      integerLen++;
-    }
-
-    // extract decimals digits
-    if (integerLen > 0) {
-      decimals = digits.splice(integerLen, digits.length);
-    } else {
-      decimals = digits;
-      digits = [0];
-    }
-
-    // format the integer digits with grouping separators
-    var groups = [];
-    if (digits.length >= pattern.lgSize) {
-      groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(''));
-    }
-    while (digits.length > pattern.gSize) {
-      groups.unshift(digits.splice(-pattern.gSize, digits.length).join(''));
-    }
-    if (digits.length) {
-      groups.unshift(digits.join(''));
-    }
-    formattedText = groups.join(groupSep);
-
-    // append the decimal digits
-    if (decimals.length) {
-      formattedText += decimalSep + decimals.join('');
-    }
-
-    if (exponent) {
-      formattedText += 'e+' + exponent;
-    }
-  }
-  if (number < 0 && !isZero) {
-    return pattern.negPre + formattedText + pattern.negSuf;
-  } else {
-    return pattern.posPre + formattedText + pattern.posSuf;
-  }
-}
-
-function padNumber(num, digits, trim, negWrap) {
-  var neg = '';
-  if (num < 0 || (negWrap && num <= 0)) {
-    if (negWrap) {
-      num = -num + 1;
-    } else {
-      num = -num;
-      neg = '-';
-    }
-  }
-  num = '' + num;
-  while (num.length < digits) num = ZERO_CHAR + num;
-  if (trim) {
-    num = num.substr(num.length - digits);
-  }
-  return neg + num;
-}
-
-
-function dateGetter(name, size, offset, trim, negWrap) {
-  offset = offset || 0;
-  return function(date) {
-    var value = date['get' + name]();
-    if (offset > 0 || value > -offset) {
-      value += offset;
-    }
-    if (value === 0 && offset === -12) value = 12;
-    return padNumber(value, size, trim, negWrap);
-  };
-}
-
-function dateStrGetter(name, shortForm, standAlone) {
-  return function(date, formats) {
-    var value = date['get' + name]();
-    var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');
-    var get = uppercase(propPrefix + name);
-
-    return formats[get][value];
-  };
-}
-
-function timeZoneGetter(date, formats, offset) {
-  var zone = -1 * offset;
-  var paddedZone = (zone >= 0) ? '+' : '';
-
-  paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
-                padNumber(Math.abs(zone % 60), 2);
-
-  return paddedZone;
-}
-
-function getFirstThursdayOfYear(year) {
-    // 0 = index of January
-    var dayOfWeekOnFirst = (new Date(year, 0, 1)).getDay();
-    // 4 = index of Thursday (+1 to account for 1st = 5)
-    // 11 = index of *next* Thursday (+1 account for 1st = 12)
-    return new Date(year, 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst);
-}
-
-function getThursdayThisWeek(datetime) {
-    return new Date(datetime.getFullYear(), datetime.getMonth(),
-      // 4 = index of Thursday
-      datetime.getDate() + (4 - datetime.getDay()));
-}
-
-function weekGetter(size) {
-   return function(date) {
-      var firstThurs = getFirstThursdayOfYear(date.getFullYear()),
-         thisThurs = getThursdayThisWeek(date);
-
-      var diff = +thisThurs - +firstThurs,
-         result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week
-
-      return padNumber(result, size);
-   };
-}
-
-function ampmGetter(date, formats) {
-  return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];
-}
-
-function eraGetter(date, formats) {
-  return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1];
-}
-
-function longEraGetter(date, formats) {
-  return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1];
-}
-
-var DATE_FORMATS = {
-  yyyy: dateGetter('FullYear', 4, 0, false, true),
-    yy: dateGetter('FullYear', 2, 0, true, true),
-     y: dateGetter('FullYear', 1, 0, false, true),
-  MMMM: dateStrGetter('Month'),
-   MMM: dateStrGetter('Month', true),
-    MM: dateGetter('Month', 2, 1),
-     M: dateGetter('Month', 1, 1),
-  LLLL: dateStrGetter('Month', false, true),
-    dd: dateGetter('Date', 2),
-     d: dateGetter('Date', 1),
-    HH: dateGetter('Hours', 2),
-     H: dateGetter('Hours', 1),
-    hh: dateGetter('Hours', 2, -12),
-     h: dateGetter('Hours', 1, -12),
-    mm: dateGetter('Minutes', 2),
-     m: dateGetter('Minutes', 1),
-    ss: dateGetter('Seconds', 2),
-     s: dateGetter('Seconds', 1),
-     // while ISO 8601 requires fractions to be prefixed with `.` or `,`
-     // we can be just safely rely on using `sss` since we currently don't support single or two digit fractions
-   sss: dateGetter('Milliseconds', 3),
-  EEEE: dateStrGetter('Day'),
-   EEE: dateStrGetter('Day', true),
-     a: ampmGetter,
-     Z: timeZoneGetter,
-    ww: weekGetter(2),
-     w: weekGetter(1),
-     G: eraGetter,
-     GG: eraGetter,
-     GGG: eraGetter,
-     GGGG: longEraGetter
-};
-
-var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
-    NUMBER_STRING = /^-?\d+$/;
-
-/**
- * @ngdoc filter
- * @name date
- * @kind function
- *
- * @description
- *   Formats `date` to a string based on the requested `format`.
- *
- *   `format` string can be composed of the following elements:
- *
- *   * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010)
- *   * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)
- *   * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199)
- *   * `'MMMM'`: Month in year (January-December)
- *   * `'MMM'`: Month in year (Jan-Dec)
- *   * `'MM'`: Month in year, padded (01-12)
- *   * `'M'`: Month in year (1-12)
- *   * `'LLLL'`: Stand-alone month in year (January-December)
- *   * `'dd'`: Day in month, padded (01-31)
- *   * `'d'`: Day in month (1-31)
- *   * `'EEEE'`: Day in Week,(Sunday-Saturday)
- *   * `'EEE'`: Day in Week, (Sun-Sat)
- *   * `'HH'`: Hour in day, padded (00-23)
- *   * `'H'`: Hour in day (0-23)
- *   * `'hh'`: Hour in AM/PM, padded (01-12)
- *   * `'h'`: Hour in AM/PM, (1-12)
- *   * `'mm'`: Minute in hour, padded (00-59)
- *   * `'m'`: Minute in hour (0-59)
- *   * `'ss'`: Second in minute, padded (00-59)
- *   * `'s'`: Second in minute (0-59)
- *   * `'sss'`: Millisecond in second, padded (000-999)
- *   * `'a'`: AM/PM marker
- *   * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
- *   * `'ww'`: Week of year, padded (00-53). Week 01 is the week with the first Thursday of the year
- *   * `'w'`: Week of year (0-53). Week 1 is the week with the first Thursday of the year
- *   * `'G'`, `'GG'`, `'GGG'`: The abbreviated form of the era string (e.g. 'AD')
- *   * `'GGGG'`: The long form of the era string (e.g. 'Anno Domini')
- *
- *   `format` string can also be one of the following predefined
- *   {@link guide/i18n localizable formats}:
- *
- *   * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale
- *     (e.g. Sep 3, 2010 12:05:08 PM)
- *   * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US  locale (e.g. 9/3/10 12:05 PM)
- *   * `'fullDate'`: equivalent to `'EEEE, MMMM d, y'` for en_US  locale
- *     (e.g. Friday, September 3, 2010)
- *   * `'longDate'`: equivalent to `'MMMM d, y'` for en_US  locale (e.g. September 3, 2010)
- *   * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US  locale (e.g. Sep 3, 2010)
- *   * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)
- *   * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 PM)
- *   * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 PM)
- *
- *   `format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g.
- *   `"h 'in the morning'"`). In order to output a single quote, escape it - i.e., two single quotes in a sequence
- *   (e.g. `"h 'o''clock'"`).
- *
- * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
- *    number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its
- *    shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
- *    specified in the string input, the time is considered to be in the local timezone.
- * @param {string=} format Formatting rules (see Description). If not specified,
- *    `mediumDate` is used.
- * @param {string=} timezone Timezone to be used for formatting. It understands UTC/GMT and the
- *    continental US time zone abbreviations, but for general use, use a time zone offset, for
- *    example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)
- *    If not specified, the timezone of the browser will be used.
- * @returns {string} Formatted string or the input if input is not recognized as date/millis.
- *
- * @example
-   <example name="filter-date">
-     <file name="index.html">
-       <span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
-           <span>{{1288323623006 | date:'medium'}}</span><br>
-       <span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
-          <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
-       <span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:
-          <span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>
-       <span ng-non-bindable>{{1288323623006 | date:"MM/dd/yyyy 'at' h:mma"}}</span>:
-          <span>{{'1288323623006' | date:"MM/dd/yyyy 'at' h:mma"}}</span><br>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should format date', function() {
-         expect(element(by.binding("1288323623006 | date:'medium'")).getText()).
-            toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
-         expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()).
-            toMatch(/2010-10-2\d \d{2}:\d{2}:\d{2} (-|\+)?\d{4}/);
-         expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()).
-            toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
-         expect(element(by.binding("'1288323623006' | date:\"MM/dd/yyyy 'at' h:mma\"")).getText()).
-            toMatch(/10\/2\d\/2010 at \d{1,2}:\d{2}(AM|PM)/);
-       });
-     </file>
-   </example>
- */
-dateFilter.$inject = ['$locale'];
-function dateFilter($locale) {
-
-
-  var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
-                     // 1        2       3         4          5          6          7          8  9     10      11
-  function jsonStringToDate(string) {
-    var match;
-    if ((match = string.match(R_ISO8601_STR))) {
-      var date = new Date(0),
-          tzHour = 0,
-          tzMin  = 0,
-          dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
-          timeSetter = match[8] ? date.setUTCHours : date.setHours;
-
-      if (match[9]) {
-        tzHour = toInt(match[9] + match[10]);
-        tzMin = toInt(match[9] + match[11]);
-      }
-      dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));
-      var h = toInt(match[4] || 0) - tzHour;
-      var m = toInt(match[5] || 0) - tzMin;
-      var s = toInt(match[6] || 0);
-      var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
-      timeSetter.call(date, h, m, s, ms);
-      return date;
-    }
-    return string;
-  }
-
-
-  return function(date, format, timezone) {
-    var text = '',
-        parts = [],
-        fn, match;
-
-    format = format || 'mediumDate';
-    format = $locale.DATETIME_FORMATS[format] || format;
-    if (isString(date)) {
-      date = NUMBER_STRING.test(date) ? toInt(date) : jsonStringToDate(date);
-    }
-
-    if (isNumber(date)) {
-      date = new Date(date);
-    }
-
-    if (!isDate(date) || !isFinite(date.getTime())) {
-      return date;
-    }
-
-    while (format) {
-      match = DATE_FORMATS_SPLIT.exec(format);
-      if (match) {
-        parts = concat(parts, match, 1);
-        format = parts.pop();
-      } else {
-        parts.push(format);
-        format = null;
-      }
-    }
-
-    var dateTimezoneOffset = date.getTimezoneOffset();
-    if (timezone) {
-      dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
-      date = convertTimezoneToLocal(date, timezone, true);
-    }
-    forEach(parts, function(value) {
-      fn = DATE_FORMATS[value];
-      text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset)
-                 : value === '\'\'' ? '\'' : value.replace(/(^'|'$)/g, '').replace(/''/g, '\'');
-    });
-
-    return text;
-  };
-}
-
-
-/**
- * @ngdoc filter
- * @name json
- * @kind function
- *
- * @description
- *   Allows you to convert a JavaScript object into JSON string.
- *
- *   This filter is mostly useful for debugging. When using the double curly {{value}} notation
- *   the binding is automatically converted to JSON.
- *
- * @param {*} object Any JavaScript object (including arrays and primitive types) to filter.
- * @param {number=} spacing The number of spaces to use per indentation, defaults to 2.
- * @returns {string} JSON string.
- *
- *
- * @example
-   <example name="filter-json">
-     <file name="index.html">
-       <pre id="default-spacing">{{ {'name':'value'} | json }}</pre>
-       <pre id="custom-spacing">{{ {'name':'value'} | json:4 }}</pre>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should jsonify filtered objects', function() {
-         expect(element(by.id('default-spacing')).getText()).toMatch(/\{\n {2}"name": ?"value"\n}/);
-         expect(element(by.id('custom-spacing')).getText()).toMatch(/\{\n {4}"name": ?"value"\n}/);
-       });
-     </file>
-   </example>
- *
- */
-function jsonFilter() {
-  return function(object, spacing) {
-    if (isUndefined(spacing)) {
-        spacing = 2;
-    }
-    return toJson(object, spacing);
-  };
-}
-
-
-/**
- * @ngdoc filter
- * @name lowercase
- * @kind function
- * @description
- * Converts string to lowercase.
- * @see angular.lowercase
- */
-var lowercaseFilter = valueFn(lowercase);
-
-
-/**
- * @ngdoc filter
- * @name uppercase
- * @kind function
- * @description
- * Converts string to uppercase.
- * @see angular.uppercase
- */
-var uppercaseFilter = valueFn(uppercase);
-
-/**
- * @ngdoc filter
- * @name limitTo
- * @kind function
- *
- * @description
- * Creates a new array or string containing only a specified number of elements. The elements are
- * taken from either the beginning or the end of the source array, string or number, as specified by
- * the value and sign (positive or negative) of `limit`. Other array-like objects are also supported
- * (e.g. array subclasses, NodeLists, jqLite/jQuery collections etc). If a number is used as input,
- * it is converted to a string.
- *
- * @param {Array|ArrayLike|string|number} input - Array/array-like, string or number to be limited.
- * @param {string|number} limit - The length of the returned array or string. If the `limit` number
- *     is positive, `limit` number of items from the beginning of the source array/string are copied.
- *     If the number is negative, `limit` number  of items from the end of the source array/string
- *     are copied. The `limit` will be trimmed if it exceeds `array.length`. If `limit` is undefined,
- *     the input will be returned unchanged.
- * @param {(string|number)=} begin - Index at which to begin limitation. As a negative index,
- *     `begin` indicates an offset from the end of `input`. Defaults to `0`.
- * @returns {Array|string} A new sub-array or substring of length `limit` or less if the input had
- *     less than `limit` elements.
- *
- * @example
-   <example module="limitToExample" name="limit-to-filter">
-     <file name="index.html">
-       <script>
-         angular.module('limitToExample', [])
-           .controller('ExampleController', ['$scope', function($scope) {
-             $scope.numbers = [1,2,3,4,5,6,7,8,9];
-             $scope.letters = "abcdefghi";
-             $scope.longNumber = 2345432342;
-             $scope.numLimit = 3;
-             $scope.letterLimit = 3;
-             $scope.longNumberLimit = 3;
-           }]);
-       </script>
-       <div ng-controller="ExampleController">
-         <label>
-            Limit {{numbers}} to:
-            <input type="number" step="1" ng-model="numLimit">
-         </label>
-         <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
-         <label>
-            Limit {{letters}} to:
-            <input type="number" step="1" ng-model="letterLimit">
-         </label>
-         <p>Output letters: {{ letters | limitTo:letterLimit }}</p>
-         <label>
-            Limit {{longNumber}} to:
-            <input type="number" step="1" ng-model="longNumberLimit">
-         </label>
-         <p>Output long number: {{ longNumber | limitTo:longNumberLimit }}</p>
-       </div>
-     </file>
-     <file name="protractor.js" type="protractor">
-       var numLimitInput = element(by.model('numLimit'));
-       var letterLimitInput = element(by.model('letterLimit'));
-       var longNumberLimitInput = element(by.model('longNumberLimit'));
-       var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
-       var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
-       var limitedLongNumber = element(by.binding('longNumber | limitTo:longNumberLimit'));
-
-       it('should limit the number array to first three items', function() {
-         expect(numLimitInput.getAttribute('value')).toBe('3');
-         expect(letterLimitInput.getAttribute('value')).toBe('3');
-         expect(longNumberLimitInput.getAttribute('value')).toBe('3');
-         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
-         expect(limitedLetters.getText()).toEqual('Output letters: abc');
-         expect(limitedLongNumber.getText()).toEqual('Output long number: 234');
-       });
-
-       // There is a bug in safari and protractor that doesn't like the minus key
-       // it('should update the output when -3 is entered', function() {
-       //   numLimitInput.clear();
-       //   numLimitInput.sendKeys('-3');
-       //   letterLimitInput.clear();
-       //   letterLimitInput.sendKeys('-3');
-       //   longNumberLimitInput.clear();
-       //   longNumberLimitInput.sendKeys('-3');
-       //   expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
-       //   expect(limitedLetters.getText()).toEqual('Output letters: ghi');
-       //   expect(limitedLongNumber.getText()).toEqual('Output long number: 342');
-       // });
-
-       it('should not exceed the maximum size of input array', function() {
-         numLimitInput.clear();
-         numLimitInput.sendKeys('100');
-         letterLimitInput.clear();
-         letterLimitInput.sendKeys('100');
-         longNumberLimitInput.clear();
-         longNumberLimitInput.sendKeys('100');
-         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
-         expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
-         expect(limitedLongNumber.getText()).toEqual('Output long number: 2345432342');
-       });
-     </file>
-   </example>
-*/
-function limitToFilter() {
-  return function(input, limit, begin) {
-    if (Math.abs(Number(limit)) === Infinity) {
-      limit = Number(limit);
-    } else {
-      limit = toInt(limit);
-    }
-    if (isNumberNaN(limit)) return input;
-
-    if (isNumber(input)) input = input.toString();
-    if (!isArrayLike(input)) return input;
-
-    begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);
-    begin = (begin < 0) ? Math.max(0, input.length + begin) : begin;
-
-    if (limit >= 0) {
-      return sliceFn(input, begin, begin + limit);
-    } else {
-      if (begin === 0) {
-        return sliceFn(input, limit, input.length);
-      } else {
-        return sliceFn(input, Math.max(0, begin + limit), begin);
-      }
-    }
-  };
-}
-
-function sliceFn(input, begin, end) {
-  if (isString(input)) return input.slice(begin, end);
-
-  return slice.call(input, begin, end);
-}
-
-/**
- * @ngdoc filter
- * @name orderBy
- * @kind function
- *
- * @description
- * Returns an array containing the items from the specified `collection`, ordered by a `comparator`
- * function based on the values computed using the `expression` predicate.
- *
- * For example, `[{id: 'foo'}, {id: 'bar'}] | orderBy:'id'` would result in
- * `[{id: 'bar'}, {id: 'foo'}]`.
- *
- * The `collection` can be an Array or array-like object (e.g. NodeList, jQuery object, TypedArray,
- * String, etc).
- *
- * The `expression` can be a single predicate, or a list of predicates each serving as a tie-breaker
- * for the preceding one. The `expression` is evaluated against each item and the output is used
- * for comparing with other items.
- *
- * You can change the sorting order by setting `reverse` to `true`. By default, items are sorted in
- * ascending order.
- *
- * The comparison is done using the `comparator` function. If none is specified, a default, built-in
- * comparator is used (see below for details - in a nutshell, it compares numbers numerically and
- * strings alphabetically).
- *
- * ### Under the hood
- *
- * Ordering the specified `collection` happens in two phases:
- *
- * 1. All items are passed through the predicate (or predicates), and the returned values are saved
- *    along with their type (`string`, `number` etc). For example, an item `{label: 'foo'}`, passed
- *    through a predicate that extracts the value of the `label` property, would be transformed to:
- *    ```
- *    {
- *      value: 'foo',
- *      type: 'string',
- *      index: ...
- *    }
- *    ```
- * 2. The comparator function is used to sort the items, based on the derived values, types and
- *    indices.
- *
- * If you use a custom comparator, it will be called with pairs of objects of the form
- * `{value: ..., type: '...', index: ...}` and is expected to return `0` if the objects are equal
- * (as far as the comparator is concerned), `-1` if the 1st one should be ranked higher than the
- * second, or `1` otherwise.
- *
- * In order to ensure that the sorting will be deterministic across platforms, if none of the
- * specified predicates can distinguish between two items, `orderBy` will automatically introduce a
- * dummy predicate that returns the item's index as `value`.
- * (If you are using a custom comparator, make sure it can handle this predicate as well.)
- *
- * Finally, in an attempt to simplify things, if a predicate returns an object as the extracted
- * value for an item, `orderBy` will try to convert that object to a primitive value, before passing
- * it to the comparator. The following rules govern the conversion:
- *
- * 1. If the object has a `valueOf()` method that returns a primitive, its return value will be
- *    used instead.<br />
- *    (If the object has a `valueOf()` method that returns another object, then the returned object
- *    will be used in subsequent steps.)
- * 2. If the object has a custom `toString()` method (i.e. not the one inherited from `Object`) that
- *    returns a primitive, its return value will be used instead.<br />
- *    (If the object has a `toString()` method that returns another object, then the returned object
- *    will be used in subsequent steps.)
- * 3. No conversion; the object itself is used.
- *
- * ### The default comparator
- *
- * The default, built-in comparator should be sufficient for most usecases. In short, it compares
- * numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to
- * using their index in the original collection, and sorts values of different types by type.
- *
- * More specifically, it follows these steps to determine the relative order of items:
- *
- * 1. If the compared values are of different types, compare the types themselves alphabetically.
- * 2. If both values are of type `string`, compare them alphabetically in a case- and
- *    locale-insensitive way.
- * 3. If both values are objects, compare their indices instead.
- * 4. Otherwise, return:
- *    -  `0`, if the values are equal (by strict equality comparison, i.e. using `===`).
- *    - `-1`, if the 1st value is "less than" the 2nd value (compared using the `<` operator).
- *    -  `1`, otherwise.
- *
- * **Note:** If you notice numbers not being sorted as expected, make sure they are actually being
- *           saved as numbers and not strings.
- * **Note:** For the purpose of sorting, `null` values are treated as the string `'null'` (i.e.
- *           `type: 'string'`, `value: 'null'`). This may cause unexpected sort order relative to
- *           other values.
- *
- * @param {Array|ArrayLike} collection - The collection (array or array-like object) to sort.
- * @param {(Function|string|Array.<Function|string>)=} expression - A predicate (or list of
- *    predicates) to be used by the comparator to determine the order of elements.
- *
- *    Can be one of:
- *
- *    - `Function`: A getter function. This function will be called with each item as argument and
- *      the return value will be used for sorting.
- *    - `string`: An Angular expression. This expression will be evaluated against each item and the
- *      result will be used for sorting. For example, use `'label'` to sort by a property called
- *      `label` or `'label.substring(0, 3)'` to sort by the first 3 characters of the `label`
- *      property.<br />
- *      (The result of a constant expression is interpreted as a property name to be used for
- *      comparison. For example, use `'"special name"'` (note the extra pair of quotes) to sort by a
- *      property called `special name`.)<br />
- *      An expression can be optionally prefixed with `+` or `-` to control the sorting direction,
- *      ascending or descending. For example, `'+label'` or `'-label'`. If no property is provided,
- *      (e.g. `'+'` or `'-'`), the collection element itself is used in comparisons.
- *    - `Array`: An array of function and/or string predicates. If a predicate cannot determine the
- *      relative order of two items, the next predicate is used as a tie-breaker.
- *
- * **Note:** If the predicate is missing or empty then it defaults to `'+'`.
- *
- * @param {boolean=} reverse - If `true`, reverse the sorting order.
- * @param {(Function)=} comparator - The comparator function used to determine the relative order of
- *    value pairs. If omitted, the built-in comparator will be used.
- *
- * @returns {Array} - The sorted array.
- *
- *
- * @example
- * ### Ordering a table with `ngRepeat`
- *
- * The example below demonstrates a simple {@link ngRepeat ngRepeat}, where the data is sorted by
- * age in descending order (expression is set to `'-age'`). The `comparator` is not set, which means
- * it defaults to the built-in comparator.
- *
-   <example name="orderBy-static" module="orderByExample1">
-     <file name="index.html">
-       <div ng-controller="ExampleController">
-         <table class="friends">
-           <tr>
-             <th>Name</th>
-             <th>Phone Number</th>
-             <th>Age</th>
-           </tr>
-           <tr ng-repeat="friend in friends | orderBy:'-age'">
-             <td>{{friend.name}}</td>
-             <td>{{friend.phone}}</td>
-             <td>{{friend.age}}</td>
-           </tr>
-         </table>
-       </div>
-     </file>
-     <file name="script.js">
-       angular.module('orderByExample1', [])
-         .controller('ExampleController', ['$scope', function($scope) {
-           $scope.friends = [
-             {name: 'John',   phone: '555-1212',  age: 10},
-             {name: 'Mary',   phone: '555-9876',  age: 19},
-             {name: 'Mike',   phone: '555-4321',  age: 21},
-             {name: 'Adam',   phone: '555-5678',  age: 35},
-             {name: 'Julie',  phone: '555-8765',  age: 29}
-           ];
-         }]);
-     </file>
-     <file name="style.css">
-       .friends {
-         border-collapse: collapse;
-       }
-
-       .friends th {
-         border-bottom: 1px solid;
-       }
-       .friends td, .friends th {
-         border-left: 1px solid;
-         padding: 5px 10px;
-       }
-       .friends td:first-child, .friends th:first-child {
-         border-left: none;
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       // Element locators
-       var names = element.all(by.repeater('friends').column('friend.name'));
-
-       it('should sort friends by age in reverse order', function() {
-         expect(names.get(0).getText()).toBe('Adam');
-         expect(names.get(1).getText()).toBe('Julie');
-         expect(names.get(2).getText()).toBe('Mike');
-         expect(names.get(3).getText()).toBe('Mary');
-         expect(names.get(4).getText()).toBe('John');
-       });
-     </file>
-   </example>
- * <hr />
- *
- * @example
- * ### Changing parameters dynamically
- *
- * All parameters can be changed dynamically. The next example shows how you can make the columns of
- * a table sortable, by binding the `expression` and `reverse` parameters to scope properties.
- *
-   <example name="orderBy-dynamic" module="orderByExample2">
-     <file name="index.html">
-       <div ng-controller="ExampleController">
-         <pre>Sort by = {{propertyName}}; reverse = {{reverse}}</pre>
-         <hr/>
-         <button ng-click="propertyName = null; reverse = false">Set to unsorted</button>
-         <hr/>
-         <table class="friends">
-           <tr>
-             <th>
-               <button ng-click="sortBy('name')">Name</button>
-               <span class="sortorder" ng-show="propertyName === 'name'" ng-class="{reverse: reverse}"></span>
-             </th>
-             <th>
-               <button ng-click="sortBy('phone')">Phone Number</button>
-               <span class="sortorder" ng-show="propertyName === 'phone'" ng-class="{reverse: reverse}"></span>
-             </th>
-             <th>
-               <button ng-click="sortBy('age')">Age</button>
-               <span class="sortorder" ng-show="propertyName === 'age'" ng-class="{reverse: reverse}"></span>
-             </th>
-           </tr>
-           <tr ng-repeat="friend in friends | orderBy:propertyName:reverse">
-             <td>{{friend.name}}</td>
-             <td>{{friend.phone}}</td>
-             <td>{{friend.age}}</td>
-           </tr>
-         </table>
-       </div>
-     </file>
-     <file name="script.js">
-       angular.module('orderByExample2', [])
-         .controller('ExampleController', ['$scope', function($scope) {
-           var friends = [
-             {name: 'John',   phone: '555-1212',  age: 10},
-             {name: 'Mary',   phone: '555-9876',  age: 19},
-             {name: 'Mike',   phone: '555-4321',  age: 21},
-             {name: 'Adam',   phone: '555-5678',  age: 35},
-             {name: 'Julie',  phone: '555-8765',  age: 29}
-           ];
-
-           $scope.propertyName = 'age';
-           $scope.reverse = true;
-           $scope.friends = friends;
-
-           $scope.sortBy = function(propertyName) {
-             $scope.reverse = ($scope.propertyName === propertyName) ? !$scope.reverse : false;
-             $scope.propertyName = propertyName;
-           };
-         }]);
-     </file>
-     <file name="style.css">
-       .friends {
-         border-collapse: collapse;
-       }
-
-       .friends th {
-         border-bottom: 1px solid;
-       }
-       .friends td, .friends th {
-         border-left: 1px solid;
-         padding: 5px 10px;
-       }
-       .friends td:first-child, .friends th:first-child {
-         border-left: none;
-       }
-
-       .sortorder:after {
-         content: '\25b2';   // BLACK UP-POINTING TRIANGLE
-       }
-       .sortorder.reverse:after {
-         content: '\25bc';   // BLACK DOWN-POINTING TRIANGLE
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       // Element locators
-       var unsortButton = element(by.partialButtonText('unsorted'));
-       var nameHeader = element(by.partialButtonText('Name'));
-       var phoneHeader = element(by.partialButtonText('Phone'));
-       var ageHeader = element(by.partialButtonText('Age'));
-       var firstName = element(by.repeater('friends').column('friend.name').row(0));
-       var lastName = element(by.repeater('friends').column('friend.name').row(4));
-
-       it('should sort friends by some property, when clicking on the column header', function() {
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('John');
-
-         phoneHeader.click();
-         expect(firstName.getText()).toBe('John');
-         expect(lastName.getText()).toBe('Mary');
-
-         nameHeader.click();
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('Mike');
-
-         ageHeader.click();
-         expect(firstName.getText()).toBe('John');
-         expect(lastName.getText()).toBe('Adam');
-       });
-
-       it('should sort friends in reverse order, when clicking on the same column', function() {
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('John');
-
-         ageHeader.click();
-         expect(firstName.getText()).toBe('John');
-         expect(lastName.getText()).toBe('Adam');
-
-         ageHeader.click();
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('John');
-       });
-
-       it('should restore the original order, when clicking "Set to unsorted"', function() {
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('John');
-
-         unsortButton.click();
-         expect(firstName.getText()).toBe('John');
-         expect(lastName.getText()).toBe('Julie');
-       });
-     </file>
-   </example>
- * <hr />
- *
- * @example
- * ### Using `orderBy` inside a controller
- *
- * It is also possible to call the `orderBy` filter manually, by injecting `orderByFilter`, and
- * calling it with the desired parameters. (Alternatively, you could inject the `$filter` factory
- * and retrieve the `orderBy` filter with `$filter('orderBy')`.)
- *
-   <example name="orderBy-call-manually" module="orderByExample3">
-     <file name="index.html">
-       <div ng-controller="ExampleController">
-         <pre>Sort by = {{propertyName}}; reverse = {{reverse}}</pre>
-         <hr/>
-         <button ng-click="sortBy(null)">Set to unsorted</button>
-         <hr/>
-         <table class="friends">
-           <tr>
-             <th>
-               <button ng-click="sortBy('name')">Name</button>
-               <span class="sortorder" ng-show="propertyName === 'name'" ng-class="{reverse: reverse}"></span>
-             </th>
-             <th>
-               <button ng-click="sortBy('phone')">Phone Number</button>
-               <span class="sortorder" ng-show="propertyName === 'phone'" ng-class="{reverse: reverse}"></span>
-             </th>
-             <th>
-               <button ng-click="sortBy('age')">Age</button>
-               <span class="sortorder" ng-show="propertyName === 'age'" ng-class="{reverse: reverse}"></span>
-             </th>
-           </tr>
-           <tr ng-repeat="friend in friends">
-             <td>{{friend.name}}</td>
-             <td>{{friend.phone}}</td>
-             <td>{{friend.age}}</td>
-           </tr>
-         </table>
-       </div>
-     </file>
-     <file name="script.js">
-       angular.module('orderByExample3', [])
-         .controller('ExampleController', ['$scope', 'orderByFilter', function($scope, orderBy) {
-           var friends = [
-             {name: 'John',   phone: '555-1212',  age: 10},
-             {name: 'Mary',   phone: '555-9876',  age: 19},
-             {name: 'Mike',   phone: '555-4321',  age: 21},
-             {name: 'Adam',   phone: '555-5678',  age: 35},
-             {name: 'Julie',  phone: '555-8765',  age: 29}
-           ];
-
-           $scope.propertyName = 'age';
-           $scope.reverse = true;
-           $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse);
-
-           $scope.sortBy = function(propertyName) {
-             $scope.reverse = (propertyName !== null && $scope.propertyName === propertyName)
-                 ? !$scope.reverse : false;
-             $scope.propertyName = propertyName;
-             $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse);
-           };
-         }]);
-     </file>
-     <file name="style.css">
-       .friends {
-         border-collapse: collapse;
-       }
-
-       .friends th {
-         border-bottom: 1px solid;
-       }
-       .friends td, .friends th {
-         border-left: 1px solid;
-         padding: 5px 10px;
-       }
-       .friends td:first-child, .friends th:first-child {
-         border-left: none;
-       }
-
-       .sortorder:after {
-         content: '\25b2';   // BLACK UP-POINTING TRIANGLE
-       }
-       .sortorder.reverse:after {
-         content: '\25bc';   // BLACK DOWN-POINTING TRIANGLE
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       // Element locators
-       var unsortButton = element(by.partialButtonText('unsorted'));
-       var nameHeader = element(by.partialButtonText('Name'));
-       var phoneHeader = element(by.partialButtonText('Phone'));
-       var ageHeader = element(by.partialButtonText('Age'));
-       var firstName = element(by.repeater('friends').column('friend.name').row(0));
-       var lastName = element(by.repeater('friends').column('friend.name').row(4));
-
-       it('should sort friends by some property, when clicking on the column header', function() {
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('John');
-
-         phoneHeader.click();
-         expect(firstName.getText()).toBe('John');
-         expect(lastName.getText()).toBe('Mary');
-
-         nameHeader.click();
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('Mike');
-
-         ageHeader.click();
-         expect(firstName.getText()).toBe('John');
-         expect(lastName.getText()).toBe('Adam');
-       });
-
-       it('should sort friends in reverse order, when clicking on the same column', function() {
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('John');
-
-         ageHeader.click();
-         expect(firstName.getText()).toBe('John');
-         expect(lastName.getText()).toBe('Adam');
-
-         ageHeader.click();
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('John');
-       });
-
-       it('should restore the original order, when clicking "Set to unsorted"', function() {
-         expect(firstName.getText()).toBe('Adam');
-         expect(lastName.getText()).toBe('John');
-
-         unsortButton.click();
-         expect(firstName.getText()).toBe('John');
-         expect(lastName.getText()).toBe('Julie');
-       });
-     </file>
-   </example>
- * <hr />
- *
- * @example
- * ### Using a custom comparator
- *
- * If you have very specific requirements about the way items are sorted, you can pass your own
- * comparator function. For example, you might need to compare some strings in a locale-sensitive
- * way. (When specifying a custom comparator, you also need to pass a value for the `reverse`
- * argument - passing `false` retains the default sorting order, i.e. ascending.)
- *
-   <example name="orderBy-custom-comparator" module="orderByExample4">
-     <file name="index.html">
-       <div ng-controller="ExampleController">
-         <div class="friends-container custom-comparator">
-           <h3>Locale-sensitive Comparator</h3>
-           <table class="friends">
-             <tr>
-               <th>Name</th>
-               <th>Favorite Letter</th>
-             </tr>
-             <tr ng-repeat="friend in friends | orderBy:'favoriteLetter':false:localeSensitiveComparator">
-               <td>{{friend.name}}</td>
-               <td>{{friend.favoriteLetter}}</td>
-             </tr>
-           </table>
-         </div>
-         <div class="friends-container default-comparator">
-           <h3>Default Comparator</h3>
-           <table class="friends">
-             <tr>
-               <th>Name</th>
-               <th>Favorite Letter</th>
-             </tr>
-             <tr ng-repeat="friend in friends | orderBy:'favoriteLetter'">
-               <td>{{friend.name}}</td>
-               <td>{{friend.favoriteLetter}}</td>
-             </tr>
-           </table>
-         </div>
-       </div>
-     </file>
-     <file name="script.js">
-       angular.module('orderByExample4', [])
-         .controller('ExampleController', ['$scope', function($scope) {
-           $scope.friends = [
-             {name: 'John',   favoriteLetter: 'Ä'},
-             {name: 'Mary',   favoriteLetter: 'Ü'},
-             {name: 'Mike',   favoriteLetter: 'Ö'},
-             {name: 'Adam',   favoriteLetter: 'H'},
-             {name: 'Julie',  favoriteLetter: 'Z'}
-           ];
-
-           $scope.localeSensitiveComparator = function(v1, v2) {
-             // If we don't get strings, just compare by index
-             if (v1.type !== 'string' || v2.type !== 'string') {
-               return (v1.index < v2.index) ? -1 : 1;
-             }
-
-             // Compare strings alphabetically, taking locale into account
-             return v1.value.localeCompare(v2.value);
-           };
-         }]);
-     </file>
-     <file name="style.css">
-       .friends-container {
-         display: inline-block;
-         margin: 0 30px;
-       }
-
-       .friends {
-         border-collapse: collapse;
-       }
-
-       .friends th {
-         border-bottom: 1px solid;
-       }
-       .friends td, .friends th {
-         border-left: 1px solid;
-         padding: 5px 10px;
-       }
-       .friends td:first-child, .friends th:first-child {
-         border-left: none;
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       // Element locators
-       var container = element(by.css('.custom-comparator'));
-       var names = container.all(by.repeater('friends').column('friend.name'));
-
-       it('should sort friends by favorite letter (in correct alphabetical order)', function() {
-         expect(names.get(0).getText()).toBe('John');
-         expect(names.get(1).getText()).toBe('Adam');
-         expect(names.get(2).getText()).toBe('Mike');
-         expect(names.get(3).getText()).toBe('Mary');
-         expect(names.get(4).getText()).toBe('Julie');
-       });
-     </file>
-   </example>
- *
- */
-orderByFilter.$inject = ['$parse'];
-function orderByFilter($parse) {
-  return function(array, sortPredicate, reverseOrder, compareFn) {
-
-    if (array == null) return array;
-    if (!isArrayLike(array)) {
-      throw minErr('orderBy')('notarray', 'Expected array but received: {0}', array);
-    }
-
-    if (!isArray(sortPredicate)) { sortPredicate = [sortPredicate]; }
-    if (sortPredicate.length === 0) { sortPredicate = ['+']; }
-
-    var predicates = processPredicates(sortPredicate);
-
-    var descending = reverseOrder ? -1 : 1;
-
-    // Define the `compare()` function. Use a default comparator if none is specified.
-    var compare = isFunction(compareFn) ? compareFn : defaultCompare;
-
-    // The next three lines are a version of a Swartzian Transform idiom from Perl
-    // (sometimes called the Decorate-Sort-Undecorate idiom)
-    // See https://en.wikipedia.org/wiki/Schwartzian_transform
-    var compareValues = Array.prototype.map.call(array, getComparisonObject);
-    compareValues.sort(doComparison);
-    array = compareValues.map(function(item) { return item.value; });
-
-    return array;
-
-    function getComparisonObject(value, index) {
-      // NOTE: We are adding an extra `tieBreaker` value based on the element's index.
-      // This will be used to keep the sort stable when none of the input predicates can
-      // distinguish between two elements.
-      return {
-        value: value,
-        tieBreaker: {value: index, type: 'number', index: index},
-        predicateValues: predicates.map(function(predicate) {
-          return getPredicateValue(predicate.get(value), index);
-        })
-      };
-    }
-
-    function doComparison(v1, v2) {
-      for (var i = 0, ii = predicates.length; i < ii; i++) {
-        var result = compare(v1.predicateValues[i], v2.predicateValues[i]);
-        if (result) {
-          return result * predicates[i].descending * descending;
-        }
-      }
-
-      return compare(v1.tieBreaker, v2.tieBreaker) * descending;
-    }
-  };
-
-  function processPredicates(sortPredicates) {
-    return sortPredicates.map(function(predicate) {
-      var descending = 1, get = identity;
-
-      if (isFunction(predicate)) {
-        get = predicate;
-      } else if (isString(predicate)) {
-        if ((predicate.charAt(0) === '+' || predicate.charAt(0) === '-')) {
-          descending = predicate.charAt(0) === '-' ? -1 : 1;
-          predicate = predicate.substring(1);
-        }
-        if (predicate !== '') {
-          get = $parse(predicate);
-          if (get.constant) {
-            var key = get();
-            get = function(value) { return value[key]; };
-          }
-        }
-      }
-      return {get: get, descending: descending};
-    });
-  }
-
-  function isPrimitive(value) {
-    switch (typeof value) {
-      case 'number': /* falls through */
-      case 'boolean': /* falls through */
-      case 'string':
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  function objectValue(value) {
-    // If `valueOf` is a valid function use that
-    if (isFunction(value.valueOf)) {
-      value = value.valueOf();
-      if (isPrimitive(value)) return value;
-    }
-    // If `toString` is a valid function and not the one from `Object.prototype` use that
-    if (hasCustomToString(value)) {
-      value = value.toString();
-      if (isPrimitive(value)) return value;
-    }
-
-    return value;
-  }
-
-  function getPredicateValue(value, index) {
-    var type = typeof value;
-    if (value === null) {
-      type = 'string';
-      value = 'null';
-    } else if (type === 'object') {
-      value = objectValue(value);
-    }
-    return {value: value, type: type, index: index};
-  }
-
-  function defaultCompare(v1, v2) {
-    var result = 0;
-    var type1 = v1.type;
-    var type2 = v2.type;
-
-    if (type1 === type2) {
-      var value1 = v1.value;
-      var value2 = v2.value;
-
-      if (type1 === 'string') {
-        // Compare strings case-insensitively
-        value1 = value1.toLowerCase();
-        value2 = value2.toLowerCase();
-      } else if (type1 === 'object') {
-        // For basic objects, use the position of the object
-        // in the collection instead of the value
-        if (isObject(value1)) value1 = v1.index;
-        if (isObject(value2)) value2 = v2.index;
-      }
-
-      if (value1 !== value2) {
-        result = value1 < value2 ? -1 : 1;
-      }
-    } else {
-      result = type1 < type2 ? -1 : 1;
-    }
-
-    return result;
-  }
-}
-
-function ngDirective(directive) {
-  if (isFunction(directive)) {
-    directive = {
-      link: directive
-    };
-  }
-  directive.restrict = directive.restrict || 'AC';
-  return valueFn(directive);
-}
-
-/**
- * @ngdoc directive
- * @name a
- * @restrict E
- *
- * @description
- * Modifies the default behavior of the html a tag so that the default action is prevented when
- * the href attribute is empty.
- *
- * For dynamically creating `href` attributes for a tags, see the {@link ng.ngHref `ngHref`} directive.
- */
-var htmlAnchorDirective = valueFn({
-  restrict: 'E',
-  compile: function(element, attr) {
-    if (!attr.href && !attr.xlinkHref) {
-      return function(scope, element) {
-        // If the linked element is not an anchor tag anymore, do nothing
-        if (element[0].nodeName.toLowerCase() !== 'a') return;
-
-        // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
-        var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
-                   'xlink:href' : 'href';
-        element.on('click', function(event) {
-          // if we have no href url, then don't navigate anywhere.
-          if (!element.attr(href)) {
-            event.preventDefault();
-          }
-        });
-      };
-    }
-  }
-});
-
-/**
- * @ngdoc directive
- * @name ngHref
- * @restrict A
- * @priority 99
- *
- * @description
- * Using Angular markup like `{{hash}}` in an href attribute will
- * make the link go to the wrong URL if the user clicks it before
- * Angular has a chance to replace the `{{hash}}` markup with its
- * value. Until Angular replaces the markup the link will be broken
- * and will most likely return a 404 error. The `ngHref` directive
- * solves this problem.
- *
- * The wrong way to write it:
- * ```html
- * <a href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
- * ```
- *
- * The correct way to write it:
- * ```html
- * <a ng-href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
- * ```
- *
- * @element A
- * @param {template} ngHref any string which can contain `{{}}` markup.
- *
- * @example
- * This example shows various combinations of `href`, `ng-href` and `ng-click` attributes
- * in links and their different behaviors:
-    <example name="ng-href">
-      <file name="index.html">
-        <input ng-model="value" /><br />
-        <a id="link-1" href ng-click="value = 1">link 1</a> (link, don't reload)<br />
-        <a id="link-2" href="" ng-click="value = 2">link 2</a> (link, don't reload)<br />
-        <a id="link-3" ng-href="/{{'123'}}">link 3</a> (link, reload!)<br />
-        <a id="link-4" href="" name="xx" ng-click="value = 4">anchor</a> (link, don't reload)<br />
-        <a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />
-        <a id="link-6" ng-href="{{value}}">link</a> (link, change location)
-      </file>
-      <file name="protractor.js" type="protractor">
-        it('should execute ng-click but not reload when href without value', function() {
-          element(by.id('link-1')).click();
-          expect(element(by.model('value')).getAttribute('value')).toEqual('1');
-          expect(element(by.id('link-1')).getAttribute('href')).toBe('');
-        });
-
-        it('should execute ng-click but not reload when href empty string', function() {
-          element(by.id('link-2')).click();
-          expect(element(by.model('value')).getAttribute('value')).toEqual('2');
-          expect(element(by.id('link-2')).getAttribute('href')).toBe('');
-        });
-
-        it('should execute ng-click and change url when ng-href specified', function() {
-          expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/);
-
-          element(by.id('link-3')).click();
-
-          // At this point, we navigate away from an Angular page, so we need
-          // to use browser.driver to get the base webdriver.
-
-          browser.wait(function() {
-            return browser.driver.getCurrentUrl().then(function(url) {
-              return url.match(/\/123$/);
-            });
-          }, 5000, 'page should navigate to /123');
-        });
-
-        it('should execute ng-click but not reload when href empty string and name specified', function() {
-          element(by.id('link-4')).click();
-          expect(element(by.model('value')).getAttribute('value')).toEqual('4');
-          expect(element(by.id('link-4')).getAttribute('href')).toBe('');
-        });
-
-        it('should execute ng-click but not reload when no href but name specified', function() {
-          element(by.id('link-5')).click();
-          expect(element(by.model('value')).getAttribute('value')).toEqual('5');
-          expect(element(by.id('link-5')).getAttribute('href')).toBe(null);
-        });
-
-        it('should only change url when only ng-href', function() {
-          element(by.model('value')).clear();
-          element(by.model('value')).sendKeys('6');
-          expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/);
-
-          element(by.id('link-6')).click();
-
-          // At this point, we navigate away from an Angular page, so we need
-          // to use browser.driver to get the base webdriver.
-          browser.wait(function() {
-            return browser.driver.getCurrentUrl().then(function(url) {
-              return url.match(/\/6$/);
-            });
-          }, 5000, 'page should navigate to /6');
-        });
-      </file>
-    </example>
- */
-
-/**
- * @ngdoc directive
- * @name ngSrc
- * @restrict A
- * @priority 99
- *
- * @description
- * Using Angular markup like `{{hash}}` in a `src` attribute doesn't
- * work right: The browser will fetch from the URL with the literal
- * text `{{hash}}` until Angular replaces the expression inside
- * `{{hash}}`. The `ngSrc` directive solves this problem.
- *
- * The buggy way to write it:
- * ```html
- * <img src="http://www.gravatar.com/avatar/{{hash}}" alt="Description"/>
- * ```
- *
- * The correct way to write it:
- * ```html
- * <img ng-src="http://www.gravatar.com/avatar/{{hash}}" alt="Description" />
- * ```
- *
- * @element IMG
- * @param {template} ngSrc any string which can contain `{{}}` markup.
- */
-
-/**
- * @ngdoc directive
- * @name ngSrcset
- * @restrict A
- * @priority 99
- *
- * @description
- * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't
- * work right: The browser will fetch from the URL with the literal
- * text `{{hash}}` until Angular replaces the expression inside
- * `{{hash}}`. The `ngSrcset` directive solves this problem.
- *
- * The buggy way to write it:
- * ```html
- * <img srcset="http://www.gravatar.com/avatar/{{hash}} 2x" alt="Description"/>
- * ```
- *
- * The correct way to write it:
- * ```html
- * <img ng-srcset="http://www.gravatar.com/avatar/{{hash}} 2x" alt="Description" />
- * ```
- *
- * @element IMG
- * @param {template} ngSrcset any string which can contain `{{}}` markup.
- */
-
-/**
- * @ngdoc directive
- * @name ngDisabled
- * @restrict A
- * @priority 100
- *
- * @description
- *
- * This directive sets the `disabled` attribute on the element (typically a form control,
- * e.g. `input`, `button`, `select` etc.) if the
- * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.
- *
- * A special directive is necessary because we cannot use interpolation inside the `disabled`
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
- *
- * @example
-    <example name="ng-disabled">
-      <file name="index.html">
-        <label>Click me to toggle: <input type="checkbox" ng-model="checked"></label><br/>
-        <button ng-model="button" ng-disabled="checked">Button</button>
-      </file>
-      <file name="protractor.js" type="protractor">
-        it('should toggle button', function() {
-          expect(element(by.css('button')).getAttribute('disabled')).toBeFalsy();
-          element(by.model('checked')).click();
-          expect(element(by.css('button')).getAttribute('disabled')).toBeTruthy();
-        });
-      </file>
-    </example>
- *
- * @element INPUT
- * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,
- *     then the `disabled` attribute will be set on the element
- */
-
-
-/**
- * @ngdoc directive
- * @name ngChecked
- * @restrict A
- * @priority 100
- *
- * @description
- * Sets the `checked` attribute on the element, if the expression inside `ngChecked` is truthy.
- *
- * Note that this directive should not be used together with {@link ngModel `ngModel`},
- * as this can lead to unexpected behavior.
- *
- * A special directive is necessary because we cannot use interpolation inside the `checked`
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
- *
- * @example
-    <example name="ng-checked">
-      <file name="index.html">
-        <label>Check me to check both: <input type="checkbox" ng-model="master"></label><br/>
-        <input id="checkSlave" type="checkbox" ng-checked="master" aria-label="Slave input">
-      </file>
-      <file name="protractor.js" type="protractor">
-        it('should check both checkBoxes', function() {
-          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();
-          element(by.model('master')).click();
-          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();
-        });
-      </file>
-    </example>
- *
- * @element INPUT
- * @param {expression} ngChecked If the {@link guide/expression expression} is truthy,
- *     then the `checked` attribute will be set on the element
- */
-
-
-/**
- * @ngdoc directive
- * @name ngReadonly
- * @restrict A
- * @priority 100
- *
- * @description
- *
- * Sets the `readonly` attribute on the element, if the expression inside `ngReadonly` is truthy.
- * Note that `readonly` applies only to `input` elements with specific types. [See the input docs on
- * MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-readonly) for more information.
- *
- * A special directive is necessary because we cannot use interpolation inside the `readonly`
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
- *
- * @example
-    <example name="ng-readonly">
-      <file name="index.html">
-        <label>Check me to make text readonly: <input type="checkbox" ng-model="checked"></label><br/>
-        <input type="text" ng-readonly="checked" value="I'm Angular" aria-label="Readonly field" />
-      </file>
-      <file name="protractor.js" type="protractor">
-        it('should toggle readonly attr', function() {
-          expect(element(by.css('[type="text"]')).getAttribute('readonly')).toBeFalsy();
-          element(by.model('checked')).click();
-          expect(element(by.css('[type="text"]')).getAttribute('readonly')).toBeTruthy();
-        });
-      </file>
-    </example>
- *
- * @element INPUT
- * @param {expression} ngReadonly If the {@link guide/expression expression} is truthy,
- *     then special attribute "readonly" will be set on the element
- */
-
-
-/**
- * @ngdoc directive
- * @name ngSelected
- * @restrict A
- * @priority 100
- *
- * @description
- *
- * Sets the `selected` attribute on the element, if the expression inside `ngSelected` is truthy.
- *
- * A special directive is necessary because we cannot use interpolation inside the `selected`
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
- *
- * <div class="alert alert-warning">
- *   **Note:** `ngSelected` does not interact with the `select` and `ngModel` directives, it only
- *   sets the `selected` attribute on the element. If you are using `ngModel` on the select, you
- *   should not use `ngSelected` on the options, as `ngModel` will set the select value and
- *   selected options.
- * </div>
- *
- * @example
-    <example name="ng-selected">
-      <file name="index.html">
-        <label>Check me to select: <input type="checkbox" ng-model="selected"></label><br/>
-        <select aria-label="ngSelected demo">
-          <option>Hello!</option>
-          <option id="greet" ng-selected="selected">Greetings!</option>
-        </select>
-      </file>
-      <file name="protractor.js" type="protractor">
-        it('should select Greetings!', function() {
-          expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();
-          element(by.model('selected')).click();
-          expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();
-        });
-      </file>
-    </example>
- *
- * @element OPTION
- * @param {expression} ngSelected If the {@link guide/expression expression} is truthy,
- *     then special attribute "selected" will be set on the element
- */
-
-/**
- * @ngdoc directive
- * @name ngOpen
- * @restrict A
- * @priority 100
- *
- * @description
- *
- * Sets the `open` attribute on the element, if the expression inside `ngOpen` is truthy.
- *
- * A special directive is necessary because we cannot use interpolation inside the `open`
- * attribute. See the {@link guide/interpolation interpolation guide} for more info.
- *
- * ## A note about browser compatibility
- *
- * Edge, Firefox, and Internet Explorer do not support the `details` element, it is
- * recommended to use {@link ng.ngShow} and {@link ng.ngHide} instead.
- *
- * @example
-     <example name="ng-open">
-       <file name="index.html">
-         <label>Check me check multiple: <input type="checkbox" ng-model="open"></label><br/>
-         <details id="details" ng-open="open">
-            <summary>Show/Hide me</summary>
-         </details>
-       </file>
-       <file name="protractor.js" type="protractor">
-         it('should toggle open', function() {
-           expect(element(by.id('details')).getAttribute('open')).toBeFalsy();
-           element(by.model('open')).click();
-           expect(element(by.id('details')).getAttribute('open')).toBeTruthy();
-         });
-       </file>
-     </example>
- *
- * @element DETAILS
- * @param {expression} ngOpen If the {@link guide/expression expression} is truthy,
- *     then special attribute "open" will be set on the element
- */
-
-var ngAttributeAliasDirectives = {};
-
-// boolean attrs are evaluated
-forEach(BOOLEAN_ATTR, function(propName, attrName) {
-  // binding to multiple is not supported
-  if (propName === 'multiple') return;
-
-  function defaultLinkFn(scope, element, attr) {
-    scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
-      attr.$set(attrName, !!value);
-    });
-  }
-
-  var normalized = directiveNormalize('ng-' + attrName);
-  var linkFn = defaultLinkFn;
-
-  if (propName === 'checked') {
-    linkFn = function(scope, element, attr) {
-      // ensuring ngChecked doesn't interfere with ngModel when both are set on the same input
-      if (attr.ngModel !== attr[normalized]) {
-        defaultLinkFn(scope, element, attr);
-      }
-    };
-  }
-
-  ngAttributeAliasDirectives[normalized] = function() {
-    return {
-      restrict: 'A',
-      priority: 100,
-      link: linkFn
-    };
-  };
-});
-
-// aliased input attrs are evaluated
-forEach(ALIASED_ATTR, function(htmlAttr, ngAttr) {
-  ngAttributeAliasDirectives[ngAttr] = function() {
-    return {
-      priority: 100,
-      link: function(scope, element, attr) {
-        //special case ngPattern when a literal regular expression value
-        //is used as the expression (this way we don't have to watch anything).
-        if (ngAttr === 'ngPattern' && attr.ngPattern.charAt(0) === '/') {
-          var match = attr.ngPattern.match(REGEX_STRING_REGEXP);
-          if (match) {
-            attr.$set('ngPattern', new RegExp(match[1], match[2]));
-            return;
-          }
-        }
-
-        scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {
-          attr.$set(ngAttr, value);
-        });
-      }
-    };
-  };
-});
-
-// ng-src, ng-srcset, ng-href are interpolated
-forEach(['src', 'srcset', 'href'], function(attrName) {
-  var normalized = directiveNormalize('ng-' + attrName);
-  ngAttributeAliasDirectives[normalized] = function() {
-    return {
-      priority: 99, // it needs to run after the attributes are interpolated
-      link: function(scope, element, attr) {
-        var propName = attrName,
-            name = attrName;
-
-        if (attrName === 'href' &&
-            toString.call(element.prop('href')) === '[object SVGAnimatedString]') {
-          name = 'xlinkHref';
-          attr.$attr[name] = 'xlink:href';
-          propName = null;
-        }
-
-        attr.$observe(normalized, function(value) {
-          if (!value) {
-            if (attrName === 'href') {
-              attr.$set(name, null);
-            }
-            return;
-          }
-
-          attr.$set(name, value);
-
-          // Support: IE 9-11 only
-          // On IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
-          // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
-          // to set the property as well to achieve the desired effect.
-          // We use attr[attrName] value since $set can sanitize the url.
-          if (msie && propName) element.prop(propName, attr[name]);
-        });
-      }
-    };
-  };
-});
-
-/* global -nullFormCtrl, -PENDING_CLASS, -SUBMITTED_CLASS
- */
-var nullFormCtrl = {
-  $addControl: noop,
-  $$renameControl: nullFormRenameControl,
-  $removeControl: noop,
-  $setValidity: noop,
-  $setDirty: noop,
-  $setPristine: noop,
-  $setSubmitted: noop
-},
-PENDING_CLASS = 'ng-pending',
-SUBMITTED_CLASS = 'ng-submitted';
-
-function nullFormRenameControl(control, name) {
-  control.$name = name;
-}
-
-/**
- * @ngdoc type
- * @name form.FormController
- *
- * @property {boolean} $pristine True if user has not interacted with the form yet.
- * @property {boolean} $dirty True if user has already interacted with the form.
- * @property {boolean} $valid True if all of the containing forms and controls are valid.
- * @property {boolean} $invalid True if at least one containing control or form is invalid.
- * @property {boolean} $pending True if at least one containing control or form is pending.
- * @property {boolean} $submitted True if user has submitted the form even if its invalid.
- *
- * @property {Object} $error Is an object hash, containing references to controls or
- *  forms with failing validators, where:
- *
- *  - keys are validation tokens (error names),
- *  - values are arrays of controls or forms that have a failing validator for given error name.
- *
- *  Built-in validation tokens:
- *
- *  - `email`
- *  - `max`
- *  - `maxlength`
- *  - `min`
- *  - `minlength`
- *  - `number`
- *  - `pattern`
- *  - `required`
- *  - `url`
- *  - `date`
- *  - `datetimelocal`
- *  - `time`
- *  - `week`
- *  - `month`
- *
- * @description
- * `FormController` keeps track of all its controls and nested forms as well as the state of them,
- * such as being valid/invalid or dirty/pristine.
- *
- * Each {@link ng.directive:form form} directive creates an instance
- * of `FormController`.
- *
- */
-//asks for $scope to fool the BC controller module
-FormController.$inject = ['$element', '$attrs', '$scope', '$animate', '$interpolate'];
-function FormController($element, $attrs, $scope, $animate, $interpolate) {
-  this.$$controls = [];
-
-  // init state
-  this.$error = {};
-  this.$$success = {};
-  this.$pending = undefined;
-  this.$name = $interpolate($attrs.name || $attrs.ngForm || '')($scope);
-  this.$dirty = false;
-  this.$pristine = true;
-  this.$valid = true;
-  this.$invalid = false;
-  this.$submitted = false;
-  this.$$parentForm = nullFormCtrl;
-
-  this.$$element = $element;
-  this.$$animate = $animate;
-
-  setupValidity(this);
-}
-
-FormController.prototype = {
-  /**
-   * @ngdoc method
-   * @name form.FormController#$rollbackViewValue
-   *
-   * @description
-   * Rollback all form controls pending updates to the `$modelValue`.
-   *
-   * Updates may be pending by a debounced event or because the input is waiting for a some future
-   * event defined in `ng-model-options`. This method is typically needed by the reset button of
-   * a form that uses `ng-model-options` to pend updates.
-   */
-  $rollbackViewValue: function() {
-    forEach(this.$$controls, function(control) {
-      control.$rollbackViewValue();
-    });
-  },
-
-  /**
-   * @ngdoc method
-   * @name form.FormController#$commitViewValue
-   *
-   * @description
-   * Commit all form controls pending updates to the `$modelValue`.
-   *
-   * Updates may be pending by a debounced event or because the input is waiting for a some future
-   * event defined in `ng-model-options`. This method is rarely needed as `NgModelController`
-   * usually handles calling this in response to input events.
-   */
-  $commitViewValue: function() {
-    forEach(this.$$controls, function(control) {
-      control.$commitViewValue();
-    });
-  },
-
-  /**
-   * @ngdoc method
-   * @name form.FormController#$addControl
-   * @param {object} control control object, either a {@link form.FormController} or an
-   * {@link ngModel.NgModelController}
-   *
-   * @description
-   * Register a control with the form. Input elements using ngModelController do this automatically
-   * when they are linked.
-   *
-   * Note that the current state of the control will not be reflected on the new parent form. This
-   * is not an issue with normal use, as freshly compiled and linked controls are in a `$pristine`
-   * state.
-   *
-   * However, if the method is used programmatically, for example by adding dynamically created controls,
-   * or controls that have been previously removed without destroying their corresponding DOM element,
-   * it's the developers responsibility to make sure the current state propagates to the parent form.
-   *
-   * For example, if an input control is added that is already `$dirty` and has `$error` properties,
-   * calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form.
-   */
-  $addControl: function(control) {
-    // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
-    // and not added to the scope.  Now we throw an error.
-    assertNotHasOwnProperty(control.$name, 'input');
-    this.$$controls.push(control);
-
-    if (control.$name) {
-      this[control.$name] = control;
-    }
-
-    control.$$parentForm = this;
-  },
-
-  // Private API: rename a form control
-  $$renameControl: function(control, newName) {
-    var oldName = control.$name;
-
-    if (this[oldName] === control) {
-      delete this[oldName];
-    }
-    this[newName] = control;
-    control.$name = newName;
-  },
-
-  /**
-   * @ngdoc method
-   * @name form.FormController#$removeControl
-   * @param {object} control control object, either a {@link form.FormController} or an
-   * {@link ngModel.NgModelController}
-   *
-   * @description
-   * Deregister a control from the form.
-   *
-   * Input elements using ngModelController do this automatically when they are destroyed.
-   *
-   * Note that only the removed control's validation state (`$errors`etc.) will be removed from the
-   * form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be
-   * different from case to case. For example, removing the only `$dirty` control from a form may or
-   * may not mean that the form is still `$dirty`.
-   */
-  $removeControl: function(control) {
-    if (control.$name && this[control.$name] === control) {
-      delete this[control.$name];
-    }
-    forEach(this.$pending, function(value, name) {
-      // eslint-disable-next-line no-invalid-this
-      this.$setValidity(name, null, control);
-    }, this);
-    forEach(this.$error, function(value, name) {
-      // eslint-disable-next-line no-invalid-this
-      this.$setValidity(name, null, control);
-    }, this);
-    forEach(this.$$success, function(value, name) {
-      // eslint-disable-next-line no-invalid-this
-      this.$setValidity(name, null, control);
-    }, this);
-
-    arrayRemove(this.$$controls, control);
-    control.$$parentForm = nullFormCtrl;
-  },
-
-  /**
-   * @ngdoc method
-   * @name form.FormController#$setDirty
-   *
-   * @description
-   * Sets the form to a dirty state.
-   *
-   * This method can be called to add the 'ng-dirty' class and set the form to a dirty
-   * state (ng-dirty class). This method will also propagate to parent forms.
-   */
-  $setDirty: function() {
-    this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);
-    this.$$animate.addClass(this.$$element, DIRTY_CLASS);
-    this.$dirty = true;
-    this.$pristine = false;
-    this.$$parentForm.$setDirty();
-  },
-
-  /**
-   * @ngdoc method
-   * @name form.FormController#$setPristine
-   *
-   * @description
-   * Sets the form to its pristine state.
-   *
-   * This method sets the form's `$pristine` state to true, the `$dirty` state to false, removes
-   * the `ng-dirty` class and adds the `ng-pristine` class. Additionally, it sets the `$submitted`
-   * state to false.
-   *
-   * This method will also propagate to all the controls contained in this form.
-   *
-   * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
-   * saving or resetting it.
-   */
-  $setPristine: function() {
-    this.$$animate.setClass(this.$$element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);
-    this.$dirty = false;
-    this.$pristine = true;
-    this.$submitted = false;
-    forEach(this.$$controls, function(control) {
-      control.$setPristine();
-    });
-  },
-
-  /**
-   * @ngdoc method
-   * @name form.FormController#$setUntouched
-   *
-   * @description
-   * Sets the form to its untouched state.
-   *
-   * This method can be called to remove the 'ng-touched' class and set the form controls to their
-   * untouched state (ng-untouched class).
-   *
-   * Setting a form controls back to their untouched state is often useful when setting the form
-   * back to its pristine state.
-   */
-  $setUntouched: function() {
-    forEach(this.$$controls, function(control) {
-      control.$setUntouched();
-    });
-  },
-
-  /**
-   * @ngdoc method
-   * @name form.FormController#$setSubmitted
-   *
-   * @description
-   * Sets the form to its submitted state.
-   */
-  $setSubmitted: function() {
-    this.$$animate.addClass(this.$$element, SUBMITTED_CLASS);
-    this.$submitted = true;
-    this.$$parentForm.$setSubmitted();
-  }
-};
-
-/**
- * @ngdoc method
- * @name form.FormController#$setValidity
- *
- * @description
- * Sets the validity of a form control.
- *
- * This method will also propagate to parent forms.
- */
-addSetValidityMethod({
-  clazz: FormController,
-  set: function(object, property, controller) {
-    var list = object[property];
-    if (!list) {
-      object[property] = [controller];
-    } else {
-      var index = list.indexOf(controller);
-      if (index === -1) {
-        list.push(controller);
-      }
-    }
-  },
-  unset: function(object, property, controller) {
-    var list = object[property];
-    if (!list) {
-      return;
-    }
-    arrayRemove(list, controller);
-    if (list.length === 0) {
-      delete object[property];
-    }
-  }
-});
-
-/**
- * @ngdoc directive
- * @name ngForm
- * @restrict EAC
- *
- * @description
- * Nestable alias of {@link ng.directive:form `form`} directive. HTML
- * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a
- * sub-group of controls needs to be determined.
- *
- * Note: the purpose of `ngForm` is to group controls,
- * but not to be a replacement for the `<form>` tag with all of its capabilities
- * (e.g. posting to the server, ...).
- *
- * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into
- *                       related scope, under this name.
- *
- */
-
- /**
- * @ngdoc directive
- * @name form
- * @restrict E
- *
- * @description
- * Directive that instantiates
- * {@link form.FormController FormController}.
- *
- * If the `name` attribute is specified, the form controller is published onto the current scope under
- * this name.
- *
- * # Alias: {@link ng.directive:ngForm `ngForm`}
- *
- * In Angular, forms can be nested. This means that the outer form is valid when all of the child
- * forms are valid as well. However, browsers do not allow nesting of `<form>` elements, so
- * Angular provides the {@link ng.directive:ngForm `ngForm`} directive, which behaves identically to
- * `form` but can be nested. Nested forms can be useful, for example, if the validity of a sub-group
- * of controls needs to be determined.
- *
- * # CSS classes
- *  - `ng-valid` is set if the form is valid.
- *  - `ng-invalid` is set if the form is invalid.
- *  - `ng-pending` is set if the form is pending.
- *  - `ng-pristine` is set if the form is pristine.
- *  - `ng-dirty` is set if the form is dirty.
- *  - `ng-submitted` is set if the form was submitted.
- *
- * Keep in mind that ngAnimate can detect each of these classes when added and removed.
- *
- *
- * # Submitting a form and preventing the default action
- *
- * Since the role of forms in client-side Angular applications is different than in classical
- * roundtrip apps, it is desirable for the browser not to translate the form submission into a full
- * page reload that sends the data to the server. Instead some javascript logic should be triggered
- * to handle the form submission in an application-specific way.
- *
- * For this reason, Angular prevents the default action (form submission to the server) unless the
- * `<form>` element has an `action` attribute specified.
- *
- * You can use one of the following two ways to specify what javascript method should be called when
- * a form is submitted:
- *
- * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element
- * - {@link ng.directive:ngClick ngClick} directive on the first
-  *  button or input field of type submit (input[type=submit])
- *
- * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit}
- * or {@link ng.directive:ngClick ngClick} directives.
- * This is because of the following form submission rules in the HTML specification:
- *
- * - If a form has only one input field then hitting enter in this field triggers form submit
- * (`ngSubmit`)
- * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter
- * doesn't trigger submit
- * - if a form has one or more input fields and one or more buttons or input[type=submit] then
- * hitting enter in any of the input fields will trigger the click handler on the *first* button or
- * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`)
- *
- * Any pending `ngModelOptions` changes will take place immediately when an enclosing form is
- * submitted. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`
- * to have access to the updated model.
- *
- * ## Animation Hooks
- *
- * Animations in ngForm are triggered when any of the associated CSS classes are added and removed.
- * These classes are: `.ng-pristine`, `.ng-dirty`, `.ng-invalid` and `.ng-valid` as well as any
- * other validations that are performed within the form. Animations in ngForm are similar to how
- * they work in ngClass and animations can be hooked into using CSS transitions, keyframes as well
- * as JS animations.
- *
- * The following example shows a simple way to utilize CSS transitions to style a form element
- * that has been rendered as invalid after it has been validated:
- *
- * <pre>
- * //be sure to include ngAnimate as a module to hook into more
- * //advanced animations
- * .my-form {
- *   transition:0.5s linear all;
- *   background: white;
- * }
- * .my-form.ng-invalid {
- *   background: red;
- *   color:white;
- * }
- * </pre>
- *
- * @example
-    <example name="ng-form" deps="angular-animate.js" animations="true" fixBase="true" module="formExample">
-      <file name="index.html">
-       <script>
-         angular.module('formExample', [])
-           .controller('FormController', ['$scope', function($scope) {
-             $scope.userType = 'guest';
-           }]);
-       </script>
-       <style>
-        .my-form {
-          transition:all linear 0.5s;
-          background: transparent;
-        }
-        .my-form.ng-invalid {
-          background: red;
-        }
-       </style>
-       <form name="myForm" ng-controller="FormController" class="my-form">
-         userType: <input name="input" ng-model="userType" required>
-         <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
-         <code>userType = {{userType}}</code><br>
-         <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br>
-         <code>myForm.input.$error = {{myForm.input.$error}}</code><br>
-         <code>myForm.$valid = {{myForm.$valid}}</code><br>
-         <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br>
-        </form>
-      </file>
-      <file name="protractor.js" type="protractor">
-        it('should initialize to model', function() {
-          var userType = element(by.binding('userType'));
-          var valid = element(by.binding('myForm.input.$valid'));
-
-          expect(userType.getText()).toContain('guest');
-          expect(valid.getText()).toContain('true');
-        });
-
-        it('should be invalid if empty', function() {
-          var userType = element(by.binding('userType'));
-          var valid = element(by.binding('myForm.input.$valid'));
-          var userInput = element(by.model('userType'));
-
-          userInput.clear();
-          userInput.sendKeys('');
-
-          expect(userType.getText()).toEqual('userType =');
-          expect(valid.getText()).toContain('false');
-        });
-      </file>
-    </example>
- *
- * @param {string=} name Name of the form. If specified, the form controller will be published into
- *                       related scope, under this name.
- */
-var formDirectiveFactory = function(isNgForm) {
-  return ['$timeout', '$parse', function($timeout, $parse) {
-    var formDirective = {
-      name: 'form',
-      restrict: isNgForm ? 'EAC' : 'E',
-      require: ['form', '^^?form'], //first is the form's own ctrl, second is an optional parent form
-      controller: FormController,
-      compile: function ngFormCompile(formElement, attr) {
-        // Setup initial state of the control
-        formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS);
-
-        var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false);
-
-        return {
-          pre: function ngFormPreLink(scope, formElement, attr, ctrls) {
-            var controller = ctrls[0];
-
-            // if `action` attr is not present on the form, prevent the default action (submission)
-            if (!('action' in attr)) {
-              // we can't use jq events because if a form is destroyed during submission the default
-              // action is not prevented. see #1238
-              //
-              // IE 9 is not affected because it doesn't fire a submit event and try to do a full
-              // page reload if the form was destroyed by submission of the form via a click handler
-              // on a button in the form. Looks like an IE9 specific bug.
-              var handleFormSubmission = function(event) {
-                scope.$apply(function() {
-                  controller.$commitViewValue();
-                  controller.$setSubmitted();
-                });
-
-                event.preventDefault();
-              };
-
-              formElement[0].addEventListener('submit', handleFormSubmission);
-
-              // unregister the preventDefault listener so that we don't not leak memory but in a
-              // way that will achieve the prevention of the default action.
-              formElement.on('$destroy', function() {
-                $timeout(function() {
-                  formElement[0].removeEventListener('submit', handleFormSubmission);
-                }, 0, false);
-              });
-            }
-
-            var parentFormCtrl = ctrls[1] || controller.$$parentForm;
-            parentFormCtrl.$addControl(controller);
-
-            var setter = nameAttr ? getSetter(controller.$name) : noop;
-
-            if (nameAttr) {
-              setter(scope, controller);
-              attr.$observe(nameAttr, function(newValue) {
-                if (controller.$name === newValue) return;
-                setter(scope, undefined);
-                controller.$$parentForm.$$renameControl(controller, newValue);
-                setter = getSetter(controller.$name);
-                setter(scope, controller);
-              });
-            }
-            formElement.on('$destroy', function() {
-              controller.$$parentForm.$removeControl(controller);
-              setter(scope, undefined);
-              extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
-            });
-          }
-        };
-      }
-    };
-
-    return formDirective;
-
-    function getSetter(expression) {
-      if (expression === '') {
-        //create an assignable expression, so forms with an empty name can be renamed later
-        return $parse('this[""]').assign;
-      }
-      return $parse(expression).assign || noop;
-    }
-  }];
-};
-
-var formDirective = formDirectiveFactory();
-var ngFormDirective = formDirectiveFactory(true);
-
-
-
-// helper methods
-function setupValidity(instance) {
-  instance.$$classCache = {};
-  instance.$$classCache[INVALID_CLASS] = !(instance.$$classCache[VALID_CLASS] = instance.$$element.hasClass(VALID_CLASS));
-}
-function addSetValidityMethod(context) {
-  var clazz = context.clazz,
-      set = context.set,
-      unset = context.unset;
-
-  clazz.prototype.$setValidity = function(validationErrorKey, state, controller) {
-    if (isUndefined(state)) {
-      createAndSet(this, '$pending', validationErrorKey, controller);
-    } else {
-      unsetAndCleanup(this, '$pending', validationErrorKey, controller);
-    }
-    if (!isBoolean(state)) {
-      unset(this.$error, validationErrorKey, controller);
-      unset(this.$$success, validationErrorKey, controller);
-    } else {
-      if (state) {
-        unset(this.$error, validationErrorKey, controller);
-        set(this.$$success, validationErrorKey, controller);
-      } else {
-        set(this.$error, validationErrorKey, controller);
-        unset(this.$$success, validationErrorKey, controller);
-      }
-    }
-    if (this.$pending) {
-      cachedToggleClass(this, PENDING_CLASS, true);
-      this.$valid = this.$invalid = undefined;
-      toggleValidationCss(this, '', null);
-    } else {
-      cachedToggleClass(this, PENDING_CLASS, false);
-      this.$valid = isObjectEmpty(this.$error);
-      this.$invalid = !this.$valid;
-      toggleValidationCss(this, '', this.$valid);
-    }
-
-    // re-read the state as the set/unset methods could have
-    // combined state in this.$error[validationError] (used for forms),
-    // where setting/unsetting only increments/decrements the value,
-    // and does not replace it.
-    var combinedState;
-    if (this.$pending && this.$pending[validationErrorKey]) {
-      combinedState = undefined;
-    } else if (this.$error[validationErrorKey]) {
-      combinedState = false;
-    } else if (this.$$success[validationErrorKey]) {
-      combinedState = true;
-    } else {
-      combinedState = null;
-    }
-
-    toggleValidationCss(this, validationErrorKey, combinedState);
-    this.$$parentForm.$setValidity(validationErrorKey, combinedState, this);
-  };
-
-  function createAndSet(ctrl, name, value, controller) {
-    if (!ctrl[name]) {
-      ctrl[name] = {};
-    }
-    set(ctrl[name], value, controller);
-  }
-
-  function unsetAndCleanup(ctrl, name, value, controller) {
-    if (ctrl[name]) {
-      unset(ctrl[name], value, controller);
-    }
-    if (isObjectEmpty(ctrl[name])) {
-      ctrl[name] = undefined;
-    }
-  }
-
-  function cachedToggleClass(ctrl, className, switchValue) {
-    if (switchValue && !ctrl.$$classCache[className]) {
-      ctrl.$$animate.addClass(ctrl.$$element, className);
-      ctrl.$$classCache[className] = true;
-    } else if (!switchValue && ctrl.$$classCache[className]) {
-      ctrl.$$animate.removeClass(ctrl.$$element, className);
-      ctrl.$$classCache[className] = false;
-    }
-  }
-
-  function toggleValidationCss(ctrl, validationErrorKey, isValid) {
-    validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';
-
-    cachedToggleClass(ctrl, VALID_CLASS + validationErrorKey, isValid === true);
-    cachedToggleClass(ctrl, INVALID_CLASS + validationErrorKey, isValid === false);
-  }
-}
-
-function isObjectEmpty(obj) {
-  if (obj) {
-    for (var prop in obj) {
-      if (obj.hasOwnProperty(prop)) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-/* global
-  VALID_CLASS: false,
-  INVALID_CLASS: false,
-  PRISTINE_CLASS: false,
-  DIRTY_CLASS: false,
-  ngModelMinErr: false
-*/
-
-// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231
-var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/;
-// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)
-// Note: We are being more lenient, because browsers are too.
-//   1. Scheme
-//   2. Slashes
-//   3. Username
-//   4. Password
-//   5. Hostname
-//   6. Port
-//   7. Path
-//   8. Query
-//   9. Fragment
-//                 1111111111111111 222   333333    44444        55555555555555555555555     666     77777777     8888888     999
-var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i;
-// eslint-disable-next-line max-len
-var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
-var NUMBER_REGEXP = /^\s*(-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/;
-var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/;
-var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
-var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/;
-var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/;
-var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
-
-var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown';
-var PARTIAL_VALIDATION_TYPES = createMap();
-forEach('date,datetime-local,month,time,week'.split(','), function(type) {
-  PARTIAL_VALIDATION_TYPES[type] = true;
-});
-
-var inputType = {
-
-  /**
-   * @ngdoc input
-   * @name input[text]
-   *
-   * @description
-   * Standard HTML text input with angular data binding, inherited by most of the `input` elements.
-   *
-   *
-   * @param {string} ngModel Assignable angular expression to data-bind to.
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {string=} required Adds `required` validation error key if the value is not entered.
-   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-   *    `required` when you want to data-bind to the `required` attribute.
-   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
-   *    minlength.
-   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
-   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
-   *    any length.
-   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
-   *    that contains the regular expression body that will be converted to a regular expression
-   *    as in the ngPattern directive.
-   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
-   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
-   *    If the expression evaluates to a RegExp object, then this is used directly.
-   *    If the expression evaluates to a string, then it will be converted to a RegExp
-   *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
-   *    `new RegExp('^abc$')`.<br />
-   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
-   *    start at the index of the last search's match, thus not taking the whole input value into
-   *    account.
-   * @param {string=} ngChange Angular expression to be executed when input changes due to user
-   *    interaction with the input element.
-   * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
-   *    This parameter is ignored for input[type=password] controls, which will never trim the
-   *    input.
-   *
-   * @example
-      <example name="text-input-directive" module="textInputExample">
-        <file name="index.html">
-         <script>
-           angular.module('textInputExample', [])
-             .controller('ExampleController', ['$scope', function($scope) {
-               $scope.example = {
-                 text: 'guest',
-                 word: /^\s*\w*\s*$/
-               };
-             }]);
-         </script>
-         <form name="myForm" ng-controller="ExampleController">
-           <label>Single word:
-             <input type="text" name="input" ng-model="example.text"
-                    ng-pattern="example.word" required ng-trim="false">
-           </label>
-           <div role="alert">
-             <span class="error" ng-show="myForm.input.$error.required">
-               Required!</span>
-             <span class="error" ng-show="myForm.input.$error.pattern">
-               Single word only!</span>
-           </div>
-           <code>text = {{example.text}}</code><br/>
-           <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br/>
-           <code>myForm.input.$error = {{myForm.input.$error}}</code><br/>
-           <code>myForm.$valid = {{myForm.$valid}}</code><br/>
-           <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br/>
-          </form>
-        </file>
-        <file name="protractor.js" type="protractor">
-          var text = element(by.binding('example.text'));
-          var valid = element(by.binding('myForm.input.$valid'));
-          var input = element(by.model('example.text'));
-
-          it('should initialize to model', function() {
-            expect(text.getText()).toContain('guest');
-            expect(valid.getText()).toContain('true');
-          });
-
-          it('should be invalid if empty', function() {
-            input.clear();
-            input.sendKeys('');
-
-            expect(text.getText()).toEqual('text =');
-            expect(valid.getText()).toContain('false');
-          });
-
-          it('should be invalid if multi word', function() {
-            input.clear();
-            input.sendKeys('hello world');
-
-            expect(valid.getText()).toContain('false');
-          });
-        </file>
-      </example>
-   */
-  'text': textInputType,
-
-    /**
-     * @ngdoc input
-     * @name input[date]
-     *
-     * @description
-     * Input with date validation and transformation. In browsers that do not yet support
-     * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601
-     * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many
-     * modern browsers do not yet support this input type, it is important to provide cues to users on the
-     * expected input format via a placeholder or label.
-     *
-     * The model must always be a Date object, otherwise Angular will throw an error.
-     * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
-     *
-     * The timezone to be used to read/write the `Date` instance in the model can be defined using
-     * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
-     *
-     * @param {string} ngModel Assignable angular expression to data-bind to.
-     * @param {string=} name Property name of the form under which the control is published.
-     * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
-     *   valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute
-     *   (e.g. `min="{{minDate | date:'yyyy-MM-dd'}}"`). Note that `min` will also add native HTML5
-     *   constraint validation.
-     * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be
-     *   a valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute
-     *   (e.g. `max="{{maxDate | date:'yyyy-MM-dd'}}"`). Note that `max` will also add native HTML5
-     *   constraint validation.
-     * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO date string
-     *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
-     * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO date string
-     *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
-     * @param {string=} required Sets `required` validation error key if the value is not entered.
-     * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-     *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-     *    `required` when you want to data-bind to the `required` attribute.
-     * @param {string=} ngChange Angular expression to be executed when input changes due to user
-     *    interaction with the input element.
-     *
-     * @example
-     <example name="date-input-directive" module="dateInputExample">
-     <file name="index.html">
-       <script>
-          angular.module('dateInputExample', [])
-            .controller('DateController', ['$scope', function($scope) {
-              $scope.example = {
-                value: new Date(2013, 9, 22)
-              };
-            }]);
-       </script>
-       <form name="myForm" ng-controller="DateController as dateCtrl">
-          <label for="exampleInput">Pick a date in 2013:</label>
-          <input type="date" id="exampleInput" name="input" ng-model="example.value"
-              placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required />
-          <div role="alert">
-            <span class="error" ng-show="myForm.input.$error.required">
-                Required!</span>
-            <span class="error" ng-show="myForm.input.$error.date">
-                Not a valid date!</span>
-           </div>
-           <tt>value = {{example.value | date: "yyyy-MM-dd"}}</tt><br/>
-           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
-           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
-           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-       </form>
-     </file>
-     <file name="protractor.js" type="protractor">
-        var value = element(by.binding('example.value | date: "yyyy-MM-dd"'));
-        var valid = element(by.binding('myForm.input.$valid'));
-
-        // currently protractor/webdriver does not support
-        // sending keys to all known HTML5 input controls
-        // for various browsers (see https://github.com/angular/protractor/issues/562).
-        function setInput(val) {
-          // set the value of the element and force validation.
-          var scr = "var ipt = document.getElementById('exampleInput'); " +
-          "ipt.value = '" + val + "';" +
-          "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
-          browser.executeScript(scr);
-        }
-
-        it('should initialize to model', function() {
-          expect(value.getText()).toContain('2013-10-22');
-          expect(valid.getText()).toContain('myForm.input.$valid = true');
-        });
-
-        it('should be invalid if empty', function() {
-          setInput('');
-          expect(value.getText()).toEqual('value =');
-          expect(valid.getText()).toContain('myForm.input.$valid = false');
-        });
-
-        it('should be invalid if over max', function() {
-          setInput('2015-01-01');
-          expect(value.getText()).toContain('');
-          expect(valid.getText()).toContain('myForm.input.$valid = false');
-        });
-     </file>
-     </example>
-     */
-  'date': createDateInputType('date', DATE_REGEXP,
-         createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']),
-         'yyyy-MM-dd'),
-
-   /**
-    * @ngdoc input
-    * @name input[datetime-local]
-    *
-    * @description
-    * Input with datetime validation and transformation. In browsers that do not yet support
-    * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
-    * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`.
-    *
-    * The model must always be a Date object, otherwise Angular will throw an error.
-    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
-    *
-    * The timezone to be used to read/write the `Date` instance in the model can be defined using
-    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
-    *
-    * @param {string} ngModel Assignable angular expression to data-bind to.
-    * @param {string=} name Property name of the form under which the control is published.
-    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
-    *   This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation
-    *   inside this attribute (e.g. `min="{{minDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`).
-    *   Note that `min` will also add native HTML5 constraint validation.
-    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
-    *   This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation
-    *   inside this attribute (e.g. `max="{{maxDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`).
-    *   Note that `max` will also add native HTML5 constraint validation.
-    * @param {(date|string)=} ngMin Sets the `min` validation error key to the Date / ISO datetime string
-    *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
-    * @param {(date|string)=} ngMax Sets the `max` validation error key to the Date / ISO datetime string
-    *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
-    * @param {string=} required Sets `required` validation error key if the value is not entered.
-    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-    *    `required` when you want to data-bind to the `required` attribute.
-    * @param {string=} ngChange Angular expression to be executed when input changes due to user
-    *    interaction with the input element.
-    *
-    * @example
-    <example name="datetimelocal-input-directive" module="dateExample">
-    <file name="index.html">
-      <script>
-        angular.module('dateExample', [])
-          .controller('DateController', ['$scope', function($scope) {
-            $scope.example = {
-              value: new Date(2010, 11, 28, 14, 57)
-            };
-          }]);
-      </script>
-      <form name="myForm" ng-controller="DateController as dateCtrl">
-        <label for="exampleInput">Pick a date between in 2013:</label>
-        <input type="datetime-local" id="exampleInput" name="input" ng-model="example.value"
-            placeholder="yyyy-MM-ddTHH:mm:ss" min="2001-01-01T00:00:00" max="2013-12-31T00:00:00" required />
-        <div role="alert">
-          <span class="error" ng-show="myForm.input.$error.required">
-              Required!</span>
-          <span class="error" ng-show="myForm.input.$error.datetimelocal">
-              Not a valid date!</span>
-        </div>
-        <tt>value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}</tt><br/>
-        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
-        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
-        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-      </form>
-    </file>
-    <file name="protractor.js" type="protractor">
-      var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"'));
-      var valid = element(by.binding('myForm.input.$valid'));
-
-      // currently protractor/webdriver does not support
-      // sending keys to all known HTML5 input controls
-      // for various browsers (https://github.com/angular/protractor/issues/562).
-      function setInput(val) {
-        // set the value of the element and force validation.
-        var scr = "var ipt = document.getElementById('exampleInput'); " +
-        "ipt.value = '" + val + "';" +
-        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
-        browser.executeScript(scr);
-      }
-
-      it('should initialize to model', function() {
-        expect(value.getText()).toContain('2010-12-28T14:57:00');
-        expect(valid.getText()).toContain('myForm.input.$valid = true');
-      });
-
-      it('should be invalid if empty', function() {
-        setInput('');
-        expect(value.getText()).toEqual('value =');
-        expect(valid.getText()).toContain('myForm.input.$valid = false');
-      });
-
-      it('should be invalid if over max', function() {
-        setInput('2015-01-01T23:59:00');
-        expect(value.getText()).toContain('');
-        expect(valid.getText()).toContain('myForm.input.$valid = false');
-      });
-    </file>
-    </example>
-    */
-  'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP,
-      createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']),
-      'yyyy-MM-ddTHH:mm:ss.sss'),
-
-  /**
-   * @ngdoc input
-   * @name input[time]
-   *
-   * @description
-   * Input with time validation and transformation. In browsers that do not yet support
-   * the HTML5 time input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
-   * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a
-   * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`.
-   *
-   * The model must always be a Date object, otherwise Angular will throw an error.
-   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
-   *
-   * The timezone to be used to read/write the `Date` instance in the model can be defined using
-   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
-   *
-   * @param {string} ngModel Assignable angular expression to data-bind to.
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
-   *   This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this
-   *   attribute (e.g. `min="{{minTime | date:'HH:mm:ss'}}"`). Note that `min` will also add
-   *   native HTML5 constraint validation.
-   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
-   *   This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this
-   *   attribute (e.g. `max="{{maxTime | date:'HH:mm:ss'}}"`). Note that `max` will also add
-   *   native HTML5 constraint validation.
-   * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO time string the
-   *   `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
-   * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO time string the
-   *   `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
-   * @param {string=} required Sets `required` validation error key if the value is not entered.
-   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-   *    `required` when you want to data-bind to the `required` attribute.
-   * @param {string=} ngChange Angular expression to be executed when input changes due to user
-   *    interaction with the input element.
-   *
-   * @example
-   <example name="time-input-directive" module="timeExample">
-   <file name="index.html">
-     <script>
-      angular.module('timeExample', [])
-        .controller('DateController', ['$scope', function($scope) {
-          $scope.example = {
-            value: new Date(1970, 0, 1, 14, 57, 0)
-          };
-        }]);
-     </script>
-     <form name="myForm" ng-controller="DateController as dateCtrl">
-        <label for="exampleInput">Pick a time between 8am and 5pm:</label>
-        <input type="time" id="exampleInput" name="input" ng-model="example.value"
-            placeholder="HH:mm:ss" min="08:00:00" max="17:00:00" required />
-        <div role="alert">
-          <span class="error" ng-show="myForm.input.$error.required">
-              Required!</span>
-          <span class="error" ng-show="myForm.input.$error.time">
-              Not a valid date!</span>
-        </div>
-        <tt>value = {{example.value | date: "HH:mm:ss"}}</tt><br/>
-        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
-        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
-        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-     </form>
-   </file>
-   <file name="protractor.js" type="protractor">
-      var value = element(by.binding('example.value | date: "HH:mm:ss"'));
-      var valid = element(by.binding('myForm.input.$valid'));
-
-      // currently protractor/webdriver does not support
-      // sending keys to all known HTML5 input controls
-      // for various browsers (https://github.com/angular/protractor/issues/562).
-      function setInput(val) {
-        // set the value of the element and force validation.
-        var scr = "var ipt = document.getElementById('exampleInput'); " +
-        "ipt.value = '" + val + "';" +
-        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
-        browser.executeScript(scr);
-      }
-
-      it('should initialize to model', function() {
-        expect(value.getText()).toContain('14:57:00');
-        expect(valid.getText()).toContain('myForm.input.$valid = true');
-      });
-
-      it('should be invalid if empty', function() {
-        setInput('');
-        expect(value.getText()).toEqual('value =');
-        expect(valid.getText()).toContain('myForm.input.$valid = false');
-      });
-
-      it('should be invalid if over max', function() {
-        setInput('23:59:00');
-        expect(value.getText()).toContain('');
-        expect(valid.getText()).toContain('myForm.input.$valid = false');
-      });
-   </file>
-   </example>
-   */
-  'time': createDateInputType('time', TIME_REGEXP,
-      createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']),
-     'HH:mm:ss.sss'),
-
-   /**
-    * @ngdoc input
-    * @name input[week]
-    *
-    * @description
-    * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support
-    * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
-    * week format (yyyy-W##), for example: `2013-W02`.
-    *
-    * The model must always be a Date object, otherwise Angular will throw an error.
-    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
-    *
-    * The timezone to be used to read/write the `Date` instance in the model can be defined using
-    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
-    *
-    * @param {string} ngModel Assignable angular expression to data-bind to.
-    * @param {string=} name Property name of the form under which the control is published.
-    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
-    *   This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this
-    *   attribute (e.g. `min="{{minWeek | date:'yyyy-Www'}}"`). Note that `min` will also add
-    *   native HTML5 constraint validation.
-    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
-    *   This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this
-    *   attribute (e.g. `max="{{maxWeek | date:'yyyy-Www'}}"`). Note that `max` will also add
-    *   native HTML5 constraint validation.
-    * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string
-    *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
-    * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string
-    *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
-    * @param {string=} required Sets `required` validation error key if the value is not entered.
-    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-    *    `required` when you want to data-bind to the `required` attribute.
-    * @param {string=} ngChange Angular expression to be executed when input changes due to user
-    *    interaction with the input element.
-    *
-    * @example
-    <example name="week-input-directive" module="weekExample">
-    <file name="index.html">
-      <script>
-      angular.module('weekExample', [])
-        .controller('DateController', ['$scope', function($scope) {
-          $scope.example = {
-            value: new Date(2013, 0, 3)
-          };
-        }]);
-      </script>
-      <form name="myForm" ng-controller="DateController as dateCtrl">
-        <label>Pick a date between in 2013:
-          <input id="exampleInput" type="week" name="input" ng-model="example.value"
-                 placeholder="YYYY-W##" min="2012-W32"
-                 max="2013-W52" required />
-        </label>
-        <div role="alert">
-          <span class="error" ng-show="myForm.input.$error.required">
-              Required!</span>
-          <span class="error" ng-show="myForm.input.$error.week">
-              Not a valid date!</span>
-        </div>
-        <tt>value = {{example.value | date: "yyyy-Www"}}</tt><br/>
-        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
-        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
-        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-      </form>
-    </file>
-    <file name="protractor.js" type="protractor">
-      var value = element(by.binding('example.value | date: "yyyy-Www"'));
-      var valid = element(by.binding('myForm.input.$valid'));
-
-      // currently protractor/webdriver does not support
-      // sending keys to all known HTML5 input controls
-      // for various browsers (https://github.com/angular/protractor/issues/562).
-      function setInput(val) {
-        // set the value of the element and force validation.
-        var scr = "var ipt = document.getElementById('exampleInput'); " +
-        "ipt.value = '" + val + "';" +
-        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
-        browser.executeScript(scr);
-      }
-
-      it('should initialize to model', function() {
-        expect(value.getText()).toContain('2013-W01');
-        expect(valid.getText()).toContain('myForm.input.$valid = true');
-      });
-
-      it('should be invalid if empty', function() {
-        setInput('');
-        expect(value.getText()).toEqual('value =');
-        expect(valid.getText()).toContain('myForm.input.$valid = false');
-      });
-
-      it('should be invalid if over max', function() {
-        setInput('2015-W01');
-        expect(value.getText()).toContain('');
-        expect(valid.getText()).toContain('myForm.input.$valid = false');
-      });
-    </file>
-    </example>
-    */
-  'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'),
-
-  /**
-   * @ngdoc input
-   * @name input[month]
-   *
-   * @description
-   * Input with month validation and transformation. In browsers that do not yet support
-   * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
-   * month format (yyyy-MM), for example: `2009-01`.
-   *
-   * The model must always be a Date object, otherwise Angular will throw an error.
-   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
-   * If the model is not set to the first of the month, the next view to model update will set it
-   * to the first of the month.
-   *
-   * The timezone to be used to read/write the `Date` instance in the model can be defined using
-   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
-   *
-   * @param {string} ngModel Assignable angular expression to data-bind to.
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
-   *   This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this
-   *   attribute (e.g. `min="{{minMonth | date:'yyyy-MM'}}"`). Note that `min` will also add
-   *   native HTML5 constraint validation.
-   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
-   *   This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this
-   *   attribute (e.g. `max="{{maxMonth | date:'yyyy-MM'}}"`). Note that `max` will also add
-   *   native HTML5 constraint validation.
-   * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string
-   *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
-   * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string
-   *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
-
-   * @param {string=} required Sets `required` validation error key if the value is not entered.
-   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-   *    `required` when you want to data-bind to the `required` attribute.
-   * @param {string=} ngChange Angular expression to be executed when input changes due to user
-   *    interaction with the input element.
-   *
-   * @example
-   <example name="month-input-directive" module="monthExample">
-   <file name="index.html">
-     <script>
-      angular.module('monthExample', [])
-        .controller('DateController', ['$scope', function($scope) {
-          $scope.example = {
-            value: new Date(2013, 9, 1)
-          };
-        }]);
-     </script>
-     <form name="myForm" ng-controller="DateController as dateCtrl">
-       <label for="exampleInput">Pick a month in 2013:</label>
-       <input id="exampleInput" type="month" name="input" ng-model="example.value"
-          placeholder="yyyy-MM" min="2013-01" max="2013-12" required />
-       <div role="alert">
-         <span class="error" ng-show="myForm.input.$error.required">
-            Required!</span>
-         <span class="error" ng-show="myForm.input.$error.month">
-            Not a valid month!</span>
-       </div>
-       <tt>value = {{example.value | date: "yyyy-MM"}}</tt><br/>
-       <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
-       <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
-       <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-       <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-     </form>
-   </file>
-   <file name="protractor.js" type="protractor">
-      var value = element(by.binding('example.value | date: "yyyy-MM"'));
-      var valid = element(by.binding('myForm.input.$valid'));
-
-      // currently protractor/webdriver does not support
-      // sending keys to all known HTML5 input controls
-      // for various browsers (https://github.com/angular/protractor/issues/562).
-      function setInput(val) {
-        // set the value of the element and force validation.
-        var scr = "var ipt = document.getElementById('exampleInput'); " +
-        "ipt.value = '" + val + "';" +
-        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
-        browser.executeScript(scr);
-      }
-
-      it('should initialize to model', function() {
-        expect(value.getText()).toContain('2013-10');
-        expect(valid.getText()).toContain('myForm.input.$valid = true');
-      });
-
-      it('should be invalid if empty', function() {
-        setInput('');
-        expect(value.getText()).toEqual('value =');
-        expect(valid.getText()).toContain('myForm.input.$valid = false');
-      });
-
-      it('should be invalid if over max', function() {
-        setInput('2015-01');
-        expect(value.getText()).toContain('');
-        expect(valid.getText()).toContain('myForm.input.$valid = false');
-      });
-   </file>
-   </example>
-   */
-  'month': createDateInputType('month', MONTH_REGEXP,
-     createDateParser(MONTH_REGEXP, ['yyyy', 'MM']),
-     'yyyy-MM'),
-
-  /**
-   * @ngdoc input
-   * @name input[number]
-   *
-   * @description
-   * Text input with number validation and transformation. Sets the `number` validation
-   * error if not a valid number.
-   *
-   * <div class="alert alert-warning">
-   * The model must always be of type `number` otherwise Angular will throw an error.
-   * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt}
-   * error docs for more information and an example of how to convert your model if necessary.
-   * </div>
-   *
-   * ## Issues with HTML5 constraint validation
-   *
-   * In browsers that follow the
-   * [HTML5 specification](https://html.spec.whatwg.org/multipage/forms.html#number-state-%28type=number%29),
-   * `input[number]` does not work as expected with {@link ngModelOptions `ngModelOptions.allowInvalid`}.
-   * If a non-number is entered in the input, the browser will report the value as an empty string,
-   * which means the view / model values in `ngModel` and subsequently the scope value
-   * will also be an empty string.
-   *
-   *
-   * @param {string} ngModel Assignable angular expression to data-bind to.
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
-   *    Can be interpolated.
-   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
-   *    Can be interpolated.
-   * @param {string=} ngMin Like `min`, sets the `min` validation error key if the value entered is less than `ngMin`,
-   *    but does not trigger HTML5 native validation. Takes an expression.
-   * @param {string=} ngMax Like `max`, sets the `max` validation error key if the value entered is greater than `ngMax`,
-   *    but does not trigger HTML5 native validation. Takes an expression.
-   * @param {string=} step Sets the `step` validation error key if the value entered does not fit the `step` constraint.
-   *    Can be interpolated.
-   * @param {string=} ngStep Like `step`, sets the `step` validation error key if the value entered does not fit the `ngStep` constraint,
-   *    but does not trigger HTML5 native validation. Takes an expression.
-   * @param {string=} required Sets `required` validation error key if the value is not entered.
-   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-   *    `required` when you want to data-bind to the `required` attribute.
-   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
-   *    minlength.
-   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
-   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
-   *    any length.
-   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
-   *    that contains the regular expression body that will be converted to a regular expression
-   *    as in the ngPattern directive.
-   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
-   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
-   *    If the expression evaluates to a RegExp object, then this is used directly.
-   *    If the expression evaluates to a string, then it will be converted to a RegExp
-   *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
-   *    `new RegExp('^abc$')`.<br />
-   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
-   *    start at the index of the last search's match, thus not taking the whole input value into
-   *    account.
-   * @param {string=} ngChange Angular expression to be executed when input changes due to user
-   *    interaction with the input element.
-   *
-   * @example
-      <example name="number-input-directive" module="numberExample">
-        <file name="index.html">
-         <script>
-           angular.module('numberExample', [])
-             .controller('ExampleController', ['$scope', function($scope) {
-               $scope.example = {
-                 value: 12
-               };
-             }]);
-         </script>
-         <form name="myForm" ng-controller="ExampleController">
-           <label>Number:
-             <input type="number" name="input" ng-model="example.value"
-                    min="0" max="99" required>
-          </label>
-           <div role="alert">
-             <span class="error" ng-show="myForm.input.$error.required">
-               Required!</span>
-             <span class="error" ng-show="myForm.input.$error.number">
-               Not valid number!</span>
-           </div>
-           <tt>value = {{example.value}}</tt><br/>
-           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
-           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
-           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-          </form>
-        </file>
-        <file name="protractor.js" type="protractor">
-          var value = element(by.binding('example.value'));
-          var valid = element(by.binding('myForm.input.$valid'));
-          var input = element(by.model('example.value'));
-
-          it('should initialize to model', function() {
-            expect(value.getText()).toContain('12');
-            expect(valid.getText()).toContain('true');
-          });
-
-          it('should be invalid if empty', function() {
-            input.clear();
-            input.sendKeys('');
-            expect(value.getText()).toEqual('value =');
-            expect(valid.getText()).toContain('false');
-          });
-
-          it('should be invalid if over max', function() {
-            input.clear();
-            input.sendKeys('123');
-            expect(value.getText()).toEqual('value =');
-            expect(valid.getText()).toContain('false');
-          });
-        </file>
-      </example>
-   */
-  'number': numberInputType,
-
-
-  /**
-   * @ngdoc input
-   * @name input[url]
-   *
-   * @description
-   * Text input with URL validation. Sets the `url` validation error key if the content is not a
-   * valid URL.
-   *
-   * <div class="alert alert-warning">
-   * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex
-   * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify
-   * the built-in validators (see the {@link guide/forms Forms guide})
-   * </div>
-   *
-   * @param {string} ngModel Assignable angular expression to data-bind to.
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {string=} required Sets `required` validation error key if the value is not entered.
-   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-   *    `required` when you want to data-bind to the `required` attribute.
-   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
-   *    minlength.
-   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
-   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
-   *    any length.
-   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
-   *    that contains the regular expression body that will be converted to a regular expression
-   *    as in the ngPattern directive.
-   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
-   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
-   *    If the expression evaluates to a RegExp object, then this is used directly.
-   *    If the expression evaluates to a string, then it will be converted to a RegExp
-   *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
-   *    `new RegExp('^abc$')`.<br />
-   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
-   *    start at the index of the last search's match, thus not taking the whole input value into
-   *    account.
-   * @param {string=} ngChange Angular expression to be executed when input changes due to user
-   *    interaction with the input element.
-   *
-   * @example
-      <example name="url-input-directive" module="urlExample">
-        <file name="index.html">
-         <script>
-           angular.module('urlExample', [])
-             .controller('ExampleController', ['$scope', function($scope) {
-               $scope.url = {
-                 text: 'http://google.com'
-               };
-             }]);
-         </script>
-         <form name="myForm" ng-controller="ExampleController">
-           <label>URL:
-             <input type="url" name="input" ng-model="url.text" required>
-           <label>
-           <div role="alert">
-             <span class="error" ng-show="myForm.input.$error.required">
-               Required!</span>
-             <span class="error" ng-show="myForm.input.$error.url">
-               Not valid url!</span>
-           </div>
-           <tt>text = {{url.text}}</tt><br/>
-           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
-           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
-           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-           <tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>
-          </form>
-        </file>
-        <file name="protractor.js" type="protractor">
-          var text = element(by.binding('url.text'));
-          var valid = element(by.binding('myForm.input.$valid'));
-          var input = element(by.model('url.text'));
-
-          it('should initialize to model', function() {
-            expect(text.getText()).toContain('http://google.com');
-            expect(valid.getText()).toContain('true');
-          });
-
-          it('should be invalid if empty', function() {
-            input.clear();
-            input.sendKeys('');
-
-            expect(text.getText()).toEqual('text =');
-            expect(valid.getText()).toContain('false');
-          });
-
-          it('should be invalid if not url', function() {
-            input.clear();
-            input.sendKeys('box');
-
-            expect(valid.getText()).toContain('false');
-          });
-        </file>
-      </example>
-   */
-  'url': urlInputType,
-
-
-  /**
-   * @ngdoc input
-   * @name input[email]
-   *
-   * @description
-   * Text input with email validation. Sets the `email` validation error key if not a valid email
-   * address.
-   *
-   * <div class="alert alert-warning">
-   * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex
-   * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can
-   * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide})
-   * </div>
-   *
-   * @param {string} ngModel Assignable angular expression to data-bind to.
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {string=} required Sets `required` validation error key if the value is not entered.
-   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
-   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
-   *    `required` when you want to data-bind to the `required` attribute.
-   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
-   *    minlength.
-   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
-   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
-   *    any length.
-   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
-   *    that contains the regular expression body that will be converted to a regular expression
-   *    as in the ngPattern directive.
-   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
-   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
-   *    If the expression evaluates to a RegExp object, then this is used directly.
-   *    If the expression evaluates to a string, then it will be converted to a RegExp
-   *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
-   *    `new RegExp('^abc$')`.<br />
-   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
-   *    start at the index of the last search's match, thus not taking the whole input value into
-   *    account.
-   * @param {string=} ngChange Angular expression to be executed when input changes due to user
-   *    interaction with the input element.
-   *
-   * @example
-      <example name="email-input-directive" module="emailExample">
-        <file name="index.html">
-         <script>
-           angular.module('emailExample', [])
-             .controller('ExampleController', ['$scope', function($scope) {
-               $scope.email = {
-                 text: 'me@example.com'
-               };
-             }]);
-         </script>
-           <form name="myForm" ng-controller="ExampleController">
-             <label>Email:
-               <input type="email" name="input" ng-model="email.text" required>
-             </label>
-             <div role="alert">
-               <span class="error" ng-show="myForm.input.$error.required">
-                 Required!</span>
-               <span class="error" ng-show="myForm.input.$error.email">
-                 Not valid email!</span>
-             </div>
-             <tt>text = {{email.text}}</tt><br/>
-             <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
-             <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
-             <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-             <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-             <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>
-           </form>
-         </file>
-        <file name="protractor.js" type="protractor">
-          var text = element(by.binding('email.text'));
-          var valid = element(by.binding('myForm.input.$valid'));
-          var input = element(by.model('email.text'));
-
-          it('should initialize to model', function() {
-            expect(text.getText()).toContain('me@example.com');
-            expect(valid.getText()).toContain('true');
-          });
-
-          it('should be invalid if empty', function() {
-            input.clear();
-            input.sendKeys('');
-            expect(text.getText()).toEqual('text =');
-            expect(valid.getText()).toContain('false');
-          });
-
-          it('should be invalid if not email', function() {
-            input.clear();
-            input.sendKeys('xxx');
-
-            expect(valid.getText()).toContain('false');
-          });
-        </file>
-      </example>
-   */
-  'email': emailInputType,
-
-
-  /**
-   * @ngdoc input
-   * @name input[radio]
-   *
-   * @description
-   * HTML radio button.
-   *
-   * @param {string} ngModel Assignable angular expression to data-bind to.
-   * @param {string} value The value to which the `ngModel` expression should be set when selected.
-   *    Note that `value` only supports `string` values, i.e. the scope model needs to be a string,
-   *    too. Use `ngValue` if you need complex models (`number`, `object`, ...).
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {string=} ngChange Angular expression to be executed when input changes due to user
-   *    interaction with the input element.
-   * @param {string} ngValue Angular expression to which `ngModel` will be be set when the radio
-   *    is selected. Should be used instead of the `value` attribute if you need
-   *    a non-string `ngModel` (`boolean`, `array`, ...).
-   *
-   * @example
-      <example name="radio-input-directive" module="radioExample">
-        <file name="index.html">
-         <script>
-           angular.module('radioExample', [])
-             .controller('ExampleController', ['$scope', function($scope) {
-               $scope.color = {
-                 name: 'blue'
-               };
-               $scope.specialValue = {
-                 "id": "12345",
-                 "value": "green"
-               };
-             }]);
-         </script>
-         <form name="myForm" ng-controller="ExampleController">
-           <label>
-             <input type="radio" ng-model="color.name" value="red">
-             Red
-           </label><br/>
-           <label>
-             <input type="radio" ng-model="color.name" ng-value="specialValue">
-             Green
-           </label><br/>
-           <label>
-             <input type="radio" ng-model="color.name" value="blue">
-             Blue
-           </label><br/>
-           <tt>color = {{color.name | json}}</tt><br/>
-          </form>
-          Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
-        </file>
-        <file name="protractor.js" type="protractor">
-          it('should change state', function() {
-            var inputs = element.all(by.model('color.name'));
-            var color = element(by.binding('color.name'));
-
-            expect(color.getText()).toContain('blue');
-
-            inputs.get(0).click();
-            expect(color.getText()).toContain('red');
-
-            inputs.get(1).click();
-            expect(color.getText()).toContain('green');
-          });
-        </file>
-      </example>
-   */
-  'radio': radioInputType,
-
-  /**
-   * @ngdoc input
-   * @name input[range]
-   *
-   * @description
-   * Native range input with validation and transformation.
-   *
-   * The model for the range input must always be a `Number`.
-   *
-   * IE9 and other browsers that do not support the `range` type fall back
-   * to a text input without any default values for `min`, `max` and `step`. Model binding,
-   * validation and number parsing are nevertheless supported.
-   *
-   * Browsers that support range (latest Chrome, Safari, Firefox, Edge) treat `input[range]`
-   * in a way that never allows the input to hold an invalid value. That means:
-   * - any non-numerical value is set to `(max + min) / 2`.
-   * - any numerical value that is less than the current min val, or greater than the current max val
-   * is set to the min / max val respectively.
-   * - additionally, the current `step` is respected, so the nearest value that satisfies a step
-   * is used.
-   *
-   * See the [HTML Spec on input[type=range]](https://www.w3.org/TR/html5/forms.html#range-state-(type=range))
-   * for more info.
-   *
-   * This has the following consequences for Angular:
-   *
-   * Since the element value should always reflect the current model value, a range input
-   * will set the bound ngModel expression to the value that the browser has set for the
-   * input element. For example, in the following input `<input type="range" ng-model="model.value">`,
-   * if the application sets `model.value = null`, the browser will set the input to `'50'`.
-   * Angular will then set the model to `50`, to prevent input and model value being out of sync.
-   *
-   * That means the model for range will immediately be set to `50` after `ngModel` has been
-   * initialized. It also means a range input can never have the required error.
-   *
-   * This does not only affect changes to the model value, but also to the values of the `min`,
-   * `max`, and `step` attributes. When these change in a way that will cause the browser to modify
-   * the input value, Angular will also update the model value.
-   *
-   * Automatic value adjustment also means that a range input element can never have the `required`,
-   * `min`, or `max` errors.
-   *
-   * However, `step` is currently only fully implemented by Firefox. Other browsers have problems
-   * when the step value changes dynamically - they do not adjust the element value correctly, but
-   * instead may set the `stepMismatch` error. If that's the case, the Angular will set the `step`
-   * error on the input, and set the model to `undefined`.
-   *
-   * Note that `input[range]` is not compatible with`ngMax`, `ngMin`, and `ngStep`, because they do
-   * not set the `min` and `max` attributes, which means that the browser won't automatically adjust
-   * the input value based on their values, and will always assume min = 0, max = 100, and step = 1.
-   *
-   * @param {string}  ngModel Assignable angular expression to data-bind to.
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {string=} min Sets the `min` validation to ensure that the value entered is greater
-   *                  than `min`. Can be interpolated.
-   * @param {string=} max Sets the `max` validation to ensure that the value entered is less than `max`.
-   *                  Can be interpolated.
-   * @param {string=} step Sets the `step` validation to ensure that the value entered matches the `step`
-   *                  Can be interpolated.
-   * @param {string=} ngChange Angular expression to be executed when the ngModel value changes due
-   *                  to user interaction with the input element.
-   * @param {expression=} ngChecked If the expression is truthy, then the `checked` attribute will be set on the
-   *                      element. **Note** : `ngChecked` should not be used alongside `ngModel`.
-   *                      Checkout {@link ng.directive:ngChecked ngChecked} for usage.
-   *
-   * @example
-      <example name="range-input-directive" module="rangeExample">
-        <file name="index.html">
-          <script>
-            angular.module('rangeExample', [])
-              .controller('ExampleController', ['$scope', function($scope) {
-                $scope.value = 75;
-                $scope.min = 10;
-                $scope.max = 90;
-              }]);
-          </script>
-          <form name="myForm" ng-controller="ExampleController">
-
-            Model as range: <input type="range" name="range" ng-model="value" min="{{min}}"  max="{{max}}">
-            <hr>
-            Model as number: <input type="number" ng-model="value"><br>
-            Min: <input type="number" ng-model="min"><br>
-            Max: <input type="number" ng-model="max"><br>
-            value = <code>{{value}}</code><br/>
-            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>
-            myForm.range.$error = <code>{{myForm.range.$error}}</code>
-          </form>
-        </file>
-      </example>
-
-   * ## Range Input with ngMin & ngMax attributes
-
-   * @example
-      <example name="range-input-directive-ng" module="rangeExample">
-        <file name="index.html">
-          <script>
-            angular.module('rangeExample', [])
-              .controller('ExampleController', ['$scope', function($scope) {
-                $scope.value = 75;
-                $scope.min = 10;
-                $scope.max = 90;
-              }]);
-          </script>
-          <form name="myForm" ng-controller="ExampleController">
-            Model as range: <input type="range" name="range" ng-model="value" ng-min="min" ng-max="max">
-            <hr>
-            Model as number: <input type="number" ng-model="value"><br>
-            Min: <input type="number" ng-model="min"><br>
-            Max: <input type="number" ng-model="max"><br>
-            value = <code>{{value}}</code><br/>
-            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>
-            myForm.range.$error = <code>{{myForm.range.$error}}</code>
-          </form>
-        </file>
-      </example>
-
-   */
-  'range': rangeInputType,
-
-  /**
-   * @ngdoc input
-   * @name input[checkbox]
-   *
-   * @description
-   * HTML checkbox.
-   *
-   * @param {string} ngModel Assignable angular expression to data-bind to.
-   * @param {string=} name Property name of the form under which the control is published.
-   * @param {expression=} ngTrueValue The value to which the expression should be set when selected.
-   * @param {expression=} ngFalseValue The value to which the expression should be set when not selected.
-   * @param {string=} ngChange Angular expression to be executed when input changes due to user
-   *    interaction with the input element.
-   *
-   * @example
-      <example name="checkbox-input-directive" module="checkboxExample">
-        <file name="index.html">
-         <script>
-           angular.module('checkboxExample', [])
-             .controller('ExampleController', ['$scope', function($scope) {
-               $scope.checkboxModel = {
-                value1 : true,
-                value2 : 'YES'
-              };
-             }]);
-         </script>
-         <form name="myForm" ng-controller="ExampleController">
-           <label>Value1:
-             <input type="checkbox" ng-model="checkboxModel.value1">
-           </label><br/>
-           <label>Value2:
-             <input type="checkbox" ng-model="checkboxModel.value2"
-                    ng-true-value="'YES'" ng-false-value="'NO'">
-            </label><br/>
-           <tt>value1 = {{checkboxModel.value1}}</tt><br/>
-           <tt>value2 = {{checkboxModel.value2}}</tt><br/>
-          </form>
-        </file>
-        <file name="protractor.js" type="protractor">
-          it('should change state', function() {
-            var value1 = element(by.binding('checkboxModel.value1'));
-            var value2 = element(by.binding('checkboxModel.value2'));
-
-            expect(value1.getText()).toContain('true');
-            expect(value2.getText()).toContain('YES');
-
-            element(by.model('checkboxModel.value1')).click();
-            element(by.model('checkboxModel.value2')).click();
-
-            expect(value1.getText()).toContain('false');
-            expect(value2.getText()).toContain('NO');
-          });
-        </file>
-      </example>
-   */
-  'checkbox': checkboxInputType,
-
-  'hidden': noop,
-  'button': noop,
-  'submit': noop,
-  'reset': noop,
-  'file': noop
-};
-
-function stringBasedInputType(ctrl) {
-  ctrl.$formatters.push(function(value) {
-    return ctrl.$isEmpty(value) ? value : value.toString();
-  });
-}
-
-function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
-  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
-  stringBasedInputType(ctrl);
-}
-
-function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
-  var type = lowercase(element[0].type);
-
-  // In composition mode, users are still inputting intermediate text buffer,
-  // hold the listener until composition is done.
-  // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
-  if (!$sniffer.android) {
-    var composing = false;
-
-    element.on('compositionstart', function() {
-      composing = true;
-    });
-
-    element.on('compositionend', function() {
-      composing = false;
-      listener();
-    });
-  }
-
-  var timeout;
-
-  var listener = function(ev) {
-    if (timeout) {
-      $browser.defer.cancel(timeout);
-      timeout = null;
-    }
-    if (composing) return;
-    var value = element.val(),
-        event = ev && ev.type;
-
-    // By default we will trim the value
-    // If the attribute ng-trim exists we will avoid trimming
-    // If input type is 'password', the value is never trimmed
-    if (type !== 'password' && (!attr.ngTrim || attr.ngTrim !== 'false')) {
-      value = trim(value);
-    }
-
-    // If a control is suffering from bad input (due to native validators), browsers discard its
-    // value, so it may be necessary to revalidate (by calling $setViewValue again) even if the
-    // control's value is the same empty value twice in a row.
-    if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {
-      ctrl.$setViewValue(value, event);
-    }
-  };
-
-  // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
-  // input event on backspace, delete or cut
-  if ($sniffer.hasEvent('input')) {
-    element.on('input', listener);
-  } else {
-    var deferListener = function(ev, input, origValue) {
-      if (!timeout) {
-        timeout = $browser.defer(function() {
-          timeout = null;
-          if (!input || input.value !== origValue) {
-            listener(ev);
-          }
-        });
-      }
-    };
-
-    element.on('keydown', /** @this */ function(event) {
-      var key = event.keyCode;
-
-      // ignore
-      //    command            modifiers                   arrows
-      if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
-
-      deferListener(event, this, this.value);
-    });
-
-    // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
-    if ($sniffer.hasEvent('paste')) {
-      element.on('paste cut', deferListener);
-    }
-  }
-
-  // if user paste into input using mouse on older browser
-  // or form autocomplete on newer browser, we need "change" event to catch it
-  element.on('change', listener);
-
-  // Some native input types (date-family) have the ability to change validity without
-  // firing any input/change events.
-  // For these event types, when native validators are present and the browser supports the type,
-  // check for validity changes on various DOM events.
-  if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) {
-    element.on(PARTIAL_VALIDATION_EVENTS, /** @this */ function(ev) {
-      if (!timeout) {
-        var validity = this[VALIDITY_STATE_PROPERTY];
-        var origBadInput = validity.badInput;
-        var origTypeMismatch = validity.typeMismatch;
-        timeout = $browser.defer(function() {
-          timeout = null;
-          if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) {
-            listener(ev);
-          }
-        });
-      }
-    });
-  }
-
-  ctrl.$render = function() {
-    // Workaround for Firefox validation #12102.
-    var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue;
-    if (element.val() !== value) {
-      element.val(value);
-    }
-  };
-}
-
-function weekParser(isoWeek, existingDate) {
-  if (isDate(isoWeek)) {
-    return isoWeek;
-  }
-
-  if (isString(isoWeek)) {
-    WEEK_REGEXP.lastIndex = 0;
-    var parts = WEEK_REGEXP.exec(isoWeek);
-    if (parts) {
-      var year = +parts[1],
-          week = +parts[2],
-          hours = 0,
-          minutes = 0,
-          seconds = 0,
-          milliseconds = 0,
-          firstThurs = getFirstThursdayOfYear(year),
-          addDays = (week - 1) * 7;
-
-      if (existingDate) {
-        hours = existingDate.getHours();
-        minutes = existingDate.getMinutes();
-        seconds = existingDate.getSeconds();
-        milliseconds = existingDate.getMilliseconds();
-      }
-
-      return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds);
-    }
-  }
-
-  return NaN;
-}
-
-function createDateParser(regexp, mapping) {
-  return function(iso, date) {
-    var parts, map;
-
-    if (isDate(iso)) {
-      return iso;
-    }
-
-    if (isString(iso)) {
-      // When a date is JSON'ified to wraps itself inside of an extra
-      // set of double quotes. This makes the date parsing code unable
-      // to match the date string and parse it as a date.
-      if (iso.charAt(0) === '"' && iso.charAt(iso.length - 1) === '"') {
-        iso = iso.substring(1, iso.length - 1);
-      }
-      if (ISO_DATE_REGEXP.test(iso)) {
-        return new Date(iso);
-      }
-      regexp.lastIndex = 0;
-      parts = regexp.exec(iso);
-
-      if (parts) {
-        parts.shift();
-        if (date) {
-          map = {
-            yyyy: date.getFullYear(),
-            MM: date.getMonth() + 1,
-            dd: date.getDate(),
-            HH: date.getHours(),
-            mm: date.getMinutes(),
-            ss: date.getSeconds(),
-            sss: date.getMilliseconds() / 1000
-          };
-        } else {
-          map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 };
-        }
-
-        forEach(parts, function(part, index) {
-          if (index < mapping.length) {
-            map[mapping[index]] = +part;
-          }
-        });
-        return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0);
-      }
-    }
-
-    return NaN;
-  };
-}
-
-function createDateInputType(type, regexp, parseDate, format) {
-  return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
-    badInputChecker(scope, element, attr, ctrl);
-    baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
-    var timezone = ctrl && ctrl.$options.getOption('timezone');
-    var previousDate;
-
-    ctrl.$$parserName = type;
-    ctrl.$parsers.push(function(value) {
-      if (ctrl.$isEmpty(value)) return null;
-      if (regexp.test(value)) {
-        // Note: We cannot read ctrl.$modelValue, as there might be a different
-        // parser/formatter in the processing chain so that the model
-        // contains some different data format!
-        var parsedDate = parseDate(value, previousDate);
-        if (timezone) {
-          parsedDate = convertTimezoneToLocal(parsedDate, timezone);
-        }
-        return parsedDate;
-      }
-      return undefined;
-    });
-
-    ctrl.$formatters.push(function(value) {
-      if (value && !isDate(value)) {
-        throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);
-      }
-      if (isValidDate(value)) {
-        previousDate = value;
-        if (previousDate && timezone) {
-          previousDate = convertTimezoneToLocal(previousDate, timezone, true);
-        }
-        return $filter('date')(value, format, timezone);
-      } else {
-        previousDate = null;
-        return '';
-      }
-    });
-
-    if (isDefined(attr.min) || attr.ngMin) {
-      var minVal;
-      ctrl.$validators.min = function(value) {
-        return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal;
-      };
-      attr.$observe('min', function(val) {
-        minVal = parseObservedDateValue(val);
-        ctrl.$validate();
-      });
-    }
-
-    if (isDefined(attr.max) || attr.ngMax) {
-      var maxVal;
-      ctrl.$validators.max = function(value) {
-        return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;
-      };
-      attr.$observe('max', function(val) {
-        maxVal = parseObservedDateValue(val);
-        ctrl.$validate();
-      });
-    }
-
-    function isValidDate(value) {
-      // Invalid Date: getTime() returns NaN
-      return value && !(value.getTime && value.getTime() !== value.getTime());
-    }
-
-    function parseObservedDateValue(val) {
-      return isDefined(val) && !isDate(val) ? parseDate(val) || undefined : val;
-    }
-  };
-}
-
-function badInputChecker(scope, element, attr, ctrl) {
-  var node = element[0];
-  var nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity);
-  if (nativeValidation) {
-    ctrl.$parsers.push(function(value) {
-      var validity = element.prop(VALIDITY_STATE_PROPERTY) || {};
-      return validity.badInput || validity.typeMismatch ? undefined : value;
-    });
-  }
-}
-
-function numberFormatterParser(ctrl) {
-  ctrl.$$parserName = 'number';
-  ctrl.$parsers.push(function(value) {
-    if (ctrl.$isEmpty(value))      return null;
-    if (NUMBER_REGEXP.test(value)) return parseFloat(value);
-    return undefined;
-  });
-
-  ctrl.$formatters.push(function(value) {
-    if (!ctrl.$isEmpty(value)) {
-      if (!isNumber(value)) {
-        throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value);
-      }
-      value = value.toString();
-    }
-    return value;
-  });
-}
-
-function parseNumberAttrVal(val) {
-  if (isDefined(val) && !isNumber(val)) {
-    val = parseFloat(val);
-  }
-  return !isNumberNaN(val) ? val : undefined;
-}
-
-function isNumberInteger(num) {
-  // See http://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript#14794066
-  // (minus the assumption that `num` is a number)
-
-  // eslint-disable-next-line no-bitwise
-  return (num | 0) === num;
-}
-
-function countDecimals(num) {
-  var numString = num.toString();
-  var decimalSymbolIndex = numString.indexOf('.');
-
-  if (decimalSymbolIndex === -1) {
-    if (-1 < num && num < 1) {
-      // It may be in the exponential notation format (`1e-X`)
-      var match = /e-(\d+)$/.exec(numString);
-
-      if (match) {
-        return Number(match[1]);
-      }
-    }
-
-    return 0;
-  }
-
-  return numString.length - decimalSymbolIndex - 1;
-}
-
-function isValidForStep(viewValue, stepBase, step) {
-  // At this point `stepBase` and `step` are expected to be non-NaN values
-  // and `viewValue` is expected to be a valid stringified number.
-  var value = Number(viewValue);
-
-  var isNonIntegerValue = !isNumberInteger(value);
-  var isNonIntegerStepBase = !isNumberInteger(stepBase);
-  var isNonIntegerStep = !isNumberInteger(step);
-
-  // Due to limitations in Floating Point Arithmetic (e.g. `0.3 - 0.2 !== 0.1` or
-  // `0.5 % 0.1 !== 0`), we need to convert all numbers to integers.
-  if (isNonIntegerValue || isNonIntegerStepBase || isNonIntegerStep) {
-    var valueDecimals = isNonIntegerValue ? countDecimals(value) : 0;
-    var stepBaseDecimals = isNonIntegerStepBase ? countDecimals(stepBase) : 0;
-    var stepDecimals = isNonIntegerStep ? countDecimals(step) : 0;
-
-    var decimalCount = Math.max(valueDecimals, stepBaseDecimals, stepDecimals);
-    var multiplier = Math.pow(10, decimalCount);
-
-    value = value * multiplier;
-    stepBase = stepBase * multiplier;
-    step = step * multiplier;
-
-    if (isNonIntegerValue) value = Math.round(value);
-    if (isNonIntegerStepBase) stepBase = Math.round(stepBase);
-    if (isNonIntegerStep) step = Math.round(step);
-  }
-
-  return (value - stepBase) % step === 0;
-}
-
-function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
-  badInputChecker(scope, element, attr, ctrl);
-  numberFormatterParser(ctrl);
-  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
-
-  var minVal;
-  var maxVal;
-
-  if (isDefined(attr.min) || attr.ngMin) {
-    ctrl.$validators.min = function(value) {
-      return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
-    };
-
-    attr.$observe('min', function(val) {
-      minVal = parseNumberAttrVal(val);
-      // TODO(matsko): implement validateLater to reduce number of validations
-      ctrl.$validate();
-    });
-  }
-
-  if (isDefined(attr.max) || attr.ngMax) {
-    ctrl.$validators.max = function(value) {
-      return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
-    };
-
-    attr.$observe('max', function(val) {
-      maxVal = parseNumberAttrVal(val);
-      // TODO(matsko): implement validateLater to reduce number of validations
-      ctrl.$validate();
-    });
-  }
-
-  if (isDefined(attr.step) || attr.ngStep) {
-    var stepVal;
-    ctrl.$validators.step = function(modelValue, viewValue) {
-      return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) ||
-             isValidForStep(viewValue, minVal || 0, stepVal);
-    };
-
-    attr.$observe('step', function(val) {
-      stepVal = parseNumberAttrVal(val);
-      // TODO(matsko): implement validateLater to reduce number of validations
-      ctrl.$validate();
-    });
-  }
-}
-
-function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
-  badInputChecker(scope, element, attr, ctrl);
-  numberFormatterParser(ctrl);
-  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
-
-  var supportsRange = ctrl.$$hasNativeValidators && element[0].type === 'range',
-      minVal = supportsRange ? 0 : undefined,
-      maxVal = supportsRange ? 100 : undefined,
-      stepVal = supportsRange ? 1 : undefined,
-      validity = element[0].validity,
-      hasMinAttr = isDefined(attr.min),
-      hasMaxAttr = isDefined(attr.max),
-      hasStepAttr = isDefined(attr.step);
-
-  var originalRender = ctrl.$render;
-
-  ctrl.$render = supportsRange && isDefined(validity.rangeUnderflow) && isDefined(validity.rangeOverflow) ?
-    //Browsers that implement range will set these values automatically, but reading the adjusted values after
-    //$render would cause the min / max validators to be applied with the wrong value
-    function rangeRender() {
-      originalRender();
-      ctrl.$setViewValue(element.val());
-    } :
-    originalRender;
-
-  if (hasMinAttr) {
-    ctrl.$validators.min = supportsRange ?
-      // Since all browsers set the input to a valid value, we don't need to check validity
-      function noopMinValidator() { return true; } :
-      // non-support browsers validate the min val
-      function minValidator(modelValue, viewValue) {
-        return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal;
-      };
-
-    setInitialValueAndObserver('min', minChange);
-  }
-
-  if (hasMaxAttr) {
-    ctrl.$validators.max = supportsRange ?
-      // Since all browsers set the input to a valid value, we don't need to check validity
-      function noopMaxValidator() { return true; } :
-      // non-support browsers validate the max val
-      function maxValidator(modelValue, viewValue) {
-        return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal;
-      };
-
-    setInitialValueAndObserver('max', maxChange);
-  }
-
-  if (hasStepAttr) {
-    ctrl.$validators.step = supportsRange ?
-      function nativeStepValidator() {
-        // Currently, only FF implements the spec on step change correctly (i.e. adjusting the
-        // input element value to a valid value). It's possible that other browsers set the stepMismatch
-        // validity error instead, so we can at least report an error in that case.
-        return !validity.stepMismatch;
-      } :
-      // ngStep doesn't set the setp attr, so the browser doesn't adjust the input value as setting step would
-      function stepValidator(modelValue, viewValue) {
-        return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) ||
-               isValidForStep(viewValue, minVal || 0, stepVal);
-      };
-
-    setInitialValueAndObserver('step', stepChange);
-  }
-
-  function setInitialValueAndObserver(htmlAttrName, changeFn) {
-    // interpolated attributes set the attribute value only after a digest, but we need the
-    // attribute value when the input is first rendered, so that the browser can adjust the
-    // input value based on the min/max value
-    element.attr(htmlAttrName, attr[htmlAttrName]);
-    attr.$observe(htmlAttrName, changeFn);
-  }
-
-  function minChange(val) {
-    minVal = parseNumberAttrVal(val);
-    // ignore changes before model is initialized
-    if (isNumberNaN(ctrl.$modelValue)) {
-      return;
-    }
-
-    if (supportsRange) {
-      var elVal = element.val();
-      // IE11 doesn't set the el val correctly if the minVal is greater than the element value
-      if (minVal > elVal) {
-        elVal = minVal;
-        element.val(elVal);
-      }
-      ctrl.$setViewValue(elVal);
-    } else {
-      // TODO(matsko): implement validateLater to reduce number of validations
-      ctrl.$validate();
-    }
-  }
-
-  function maxChange(val) {
-    maxVal = parseNumberAttrVal(val);
-    // ignore changes before model is initialized
-    if (isNumberNaN(ctrl.$modelValue)) {
-      return;
-    }
-
-    if (supportsRange) {
-      var elVal = element.val();
-      // IE11 doesn't set the el val correctly if the maxVal is less than the element value
-      if (maxVal < elVal) {
-        element.val(maxVal);
-        // IE11 and Chrome don't set the value to the minVal when max < min
-        elVal = maxVal < minVal ? minVal : maxVal;
-      }
-      ctrl.$setViewValue(elVal);
-    } else {
-      // TODO(matsko): implement validateLater to reduce number of validations
-      ctrl.$validate();
-    }
-  }
-
-  function stepChange(val) {
-    stepVal = parseNumberAttrVal(val);
-    // ignore changes before model is initialized
-    if (isNumberNaN(ctrl.$modelValue)) {
-      return;
-    }
-
-    // Some browsers don't adjust the input value correctly, but set the stepMismatch error
-    if (supportsRange && ctrl.$viewValue !== element.val()) {
-      ctrl.$setViewValue(element.val());
-    } else {
-      // TODO(matsko): implement validateLater to reduce number of validations
-      ctrl.$validate();
-    }
-  }
-}
-
-function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
-  // Note: no badInputChecker here by purpose as `url` is only a validation
-  // in browsers, i.e. we can always read out input.value even if it is not valid!
-  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
-  stringBasedInputType(ctrl);
-
-  ctrl.$$parserName = 'url';
-  ctrl.$validators.url = function(modelValue, viewValue) {
-    var value = modelValue || viewValue;
-    return ctrl.$isEmpty(value) || URL_REGEXP.test(value);
-  };
-}
-
-function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
-  // Note: no badInputChecker here by purpose as `url` is only a validation
-  // in browsers, i.e. we can always read out input.value even if it is not valid!
-  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
-  stringBasedInputType(ctrl);
-
-  ctrl.$$parserName = 'email';
-  ctrl.$validators.email = function(modelValue, viewValue) {
-    var value = modelValue || viewValue;
-    return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);
-  };
-}
-
-function radioInputType(scope, element, attr, ctrl) {
-  var doTrim = !attr.ngTrim || trim(attr.ngTrim) !== 'false';
-  // make the name unique, if not defined
-  if (isUndefined(attr.name)) {
-    element.attr('name', nextUid());
-  }
-
-  var listener = function(ev) {
-    var value;
-    if (element[0].checked) {
-      value = attr.value;
-      if (doTrim) {
-        value = trim(value);
-      }
-      ctrl.$setViewValue(value, ev && ev.type);
-    }
-  };
-
-  element.on('click', listener);
-
-  ctrl.$render = function() {
-    var value = attr.value;
-    if (doTrim) {
-      value = trim(value);
-    }
-    element[0].checked = (value === ctrl.$viewValue);
-  };
-
-  attr.$observe('value', ctrl.$render);
-}
-
-function parseConstantExpr($parse, context, name, expression, fallback) {
-  var parseFn;
-  if (isDefined(expression)) {
-    parseFn = $parse(expression);
-    if (!parseFn.constant) {
-      throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' +
-                                   '`{1}`.', name, expression);
-    }
-    return parseFn(context);
-  }
-  return fallback;
-}
-
-function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {
-  var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true);
-  var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);
-
-  var listener = function(ev) {
-    ctrl.$setViewValue(element[0].checked, ev && ev.type);
-  };
-
-  element.on('click', listener);
-
-  ctrl.$render = function() {
-    element[0].checked = ctrl.$viewValue;
-  };
-
-  // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false`
-  // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert
-  // it to a boolean.
-  ctrl.$isEmpty = function(value) {
-    return value === false;
-  };
-
-  ctrl.$formatters.push(function(value) {
-    return equals(value, trueValue);
-  });
-
-  ctrl.$parsers.push(function(value) {
-    return value ? trueValue : falseValue;
-  });
-}
-
-
-/**
- * @ngdoc directive
- * @name textarea
- * @restrict E
- *
- * @description
- * HTML textarea element control with angular data-binding. The data-binding and validation
- * properties of this element are exactly the same as those of the
- * {@link ng.directive:input input element}.
- *
- * @param {string} ngModel Assignable angular expression to data-bind to.
- * @param {string=} name Property name of the form under which the control is published.
- * @param {string=} required Sets `required` validation error key if the value is not entered.
- * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
- *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
- *    `required` when you want to data-bind to the `required` attribute.
- * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
- *    minlength.
- * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
- *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
- *    length.
- * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
- *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
- *    If the expression evaluates to a RegExp object, then this is used directly.
- *    If the expression evaluates to a string, then it will be converted to a RegExp
- *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
- *    `new RegExp('^abc$')`.<br />
- *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
- *    start at the index of the last search's match, thus not taking the whole input value into
- *    account.
- * @param {string=} ngChange Angular expression to be executed when input changes due to user
- *    interaction with the input element.
- * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
- *
- * @knownIssue
- *
- * When specifying the `placeholder` attribute of `<textarea>`, Internet Explorer will temporarily
- * insert the placeholder value as the textarea's content. If the placeholder value contains
- * interpolation (`{{ ... }}`), an error will be logged in the console when Angular tries to update
- * the value of the by-then-removed text node. This doesn't affect the functionality of the
- * textarea, but can be undesirable.
- *
- * You can work around this Internet Explorer issue by using `ng-attr-placeholder` instead of
- * `placeholder` on textareas, whenever you need interpolation in the placeholder value. You can
- * find more details on `ngAttr` in the
- * [Interpolation](guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes) section of the
- * Developer Guide.
- */
-
-
-/**
- * @ngdoc directive
- * @name input
- * @restrict E
- *
- * @description
- * HTML input element control. When used together with {@link ngModel `ngModel`}, it provides data-binding,
- * input state control, and validation.
- * Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers.
- *
- * <div class="alert alert-warning">
- * **Note:** Not every feature offered is available for all input types.
- * Specifically, data binding and event handling via `ng-model` is unsupported for `input[file]`.
- * </div>
- *
- * @param {string} ngModel Assignable angular expression to data-bind to.
- * @param {string=} name Property name of the form under which the control is published.
- * @param {string=} required Sets `required` validation error key if the value is not entered.
- * @param {boolean=} ngRequired Sets `required` attribute if set to true
- * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
- *    minlength.
- * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
- *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
- *    length.
- * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
- *    value does not match a RegExp found by evaluating the Angular expression given in the attribute value.
- *    If the expression evaluates to a RegExp object, then this is used directly.
- *    If the expression evaluates to a string, then it will be converted to a RegExp
- *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
- *    `new RegExp('^abc$')`.<br />
- *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
- *    start at the index of the last search's match, thus not taking the whole input value into
- *    account.
- * @param {string=} ngChange Angular expression to be executed when input changes due to user
- *    interaction with the input element.
- * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
- *    This parameter is ignored for input[type=password] controls, which will never trim the
- *    input.
- *
- * @example
-    <example name="input-directive" module="inputExample">
-      <file name="index.html">
-       <script>
-          angular.module('inputExample', [])
-            .controller('ExampleController', ['$scope', function($scope) {
-              $scope.user = {name: 'guest', last: 'visitor'};
-            }]);
-       </script>
-       <div ng-controller="ExampleController">
-         <form name="myForm">
-           <label>
-              User name:
-              <input type="text" name="userName" ng-model="user.name" required>
-           </label>
-           <div role="alert">
-             <span class="error" ng-show="myForm.userName.$error.required">
-              Required!</span>
-           </div>
-           <label>
-              Last name:
-              <input type="text" name="lastName" ng-model="user.last"
-              ng-minlength="3" ng-maxlength="10">
-           </label>
-           <div role="alert">
-             <span class="error" ng-show="myForm.lastName.$error.minlength">
-               Too short!</span>
-             <span class="error" ng-show="myForm.lastName.$error.maxlength">
-               Too long!</span>
-           </div>
-         </form>
-         <hr>
-         <tt>user = {{user}}</tt><br/>
-         <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br/>
-         <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br/>
-         <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br/>
-         <tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br/>
-         <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
-         <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
-         <tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br/>
-         <tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br/>
-       </div>
-      </file>
-      <file name="protractor.js" type="protractor">
-        var user = element(by.exactBinding('user'));
-        var userNameValid = element(by.binding('myForm.userName.$valid'));
-        var lastNameValid = element(by.binding('myForm.lastName.$valid'));
-        var lastNameError = element(by.binding('myForm.lastName.$error'));
-        var formValid = element(by.binding('myForm.$valid'));
-        var userNameInput = element(by.model('user.name'));
-        var userLastInput = element(by.model('user.last'));
-
-        it('should initialize to model', function() {
-          expect(user.getText()).toContain('{"name":"guest","last":"visitor"}');
-          expect(userNameValid.getText()).toContain('true');
-          expect(formValid.getText()).toContain('true');
-        });
-
-        it('should be invalid if empty when required', function() {
-          userNameInput.clear();
-          userNameInput.sendKeys('');
-
-          expect(user.getText()).toContain('{"last":"visitor"}');
-          expect(userNameValid.getText()).toContain('false');
-          expect(formValid.getText()).toContain('false');
-        });
-
-        it('should be valid if empty when min length is set', function() {
-          userLastInput.clear();
-          userLastInput.sendKeys('');
-
-          expect(user.getText()).toContain('{"name":"guest","last":""}');
-          expect(lastNameValid.getText()).toContain('true');
-          expect(formValid.getText()).toContain('true');
-        });
-
-        it('should be invalid if less than required min length', function() {
-          userLastInput.clear();
-          userLastInput.sendKeys('xx');
-
-          expect(user.getText()).toContain('{"name":"guest"}');
-          expect(lastNameValid.getText()).toContain('false');
-          expect(lastNameError.getText()).toContain('minlength');
-          expect(formValid.getText()).toContain('false');
-        });
-
-        it('should be invalid if longer than max length', function() {
-          userLastInput.clear();
-          userLastInput.sendKeys('some ridiculously long name');
-
-          expect(user.getText()).toContain('{"name":"guest"}');
-          expect(lastNameValid.getText()).toContain('false');
-          expect(lastNameError.getText()).toContain('maxlength');
-          expect(formValid.getText()).toContain('false');
-        });
-      </file>
-    </example>
- */
-var inputDirective = ['$browser', '$sniffer', '$filter', '$parse',
-    function($browser, $sniffer, $filter, $parse) {
-  return {
-    restrict: 'E',
-    require: ['?ngModel'],
-    link: {
-      pre: function(scope, element, attr, ctrls) {
-        if (ctrls[0]) {
-          (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer,
-                                                              $browser, $filter, $parse);
-        }
-      }
-    }
-  };
-}];
-
-
-
-var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
-/**
- * @ngdoc directive
- * @name ngValue
- *
- * @description
- * Binds the given expression to the value of the element.
- *
- * It is mainly used on {@link input[radio] `input[radio]`} and option elements,
- * so that when the element is selected, the {@link ngModel `ngModel`} of that element (or its
- * {@link select `select`} parent element) is set to the bound value. It is especially useful
- * for dynamically generated lists using {@link ngRepeat `ngRepeat`}, as shown below.
- *
- * It can also be used to achieve one-way binding of a given expression to an input element
- * such as an `input[text]` or a `textarea`, when that element does not use ngModel.
- *
- * @element input
- * @param {string=} ngValue angular expression, whose value will be bound to the `value` attribute
- * and `value` property of the element.
- *
- * @example
-    <example name="ngValue-directive" module="valueExample">
-      <file name="index.html">
-       <script>
-          angular.module('valueExample', [])
-            .controller('ExampleController', ['$scope', function($scope) {
-              $scope.names = ['pizza', 'unicorns', 'robots'];
-              $scope.my = { favorite: 'unicorns' };
-            }]);
-       </script>
-        <form ng-controller="ExampleController">
-          <h2>Which is your favorite?</h2>
-            <label ng-repeat="name in names" for="{{name}}">
-              {{name}}
-              <input type="radio"
-                     ng-model="my.favorite"
-                     ng-value="name"
-                     id="{{name}}"
-                     name="favorite">
-            </label>
-          <div>You chose {{my.favorite}}</div>
-        </form>
-      </file>
-      <file name="protractor.js" type="protractor">
-        var favorite = element(by.binding('my.favorite'));
-
-        it('should initialize to model', function() {
-          expect(favorite.getText()).toContain('unicorns');
-        });
-        it('should bind the values to the inputs', function() {
-          element.all(by.model('my.favorite')).get(0).click();
-          expect(favorite.getText()).toContain('pizza');
-        });
-      </file>
-    </example>
- */
-var ngValueDirective = function() {
-  /**
-   *  inputs use the value attribute as their default value if the value property is not set.
-   *  Once the value property has been set (by adding input), it will not react to changes to
-   *  the value attribute anymore. Setting both attribute and property fixes this behavior, and
-   *  makes it possible to use ngValue as a sort of one-way bind.
-   */
-  function updateElementValue(element, attr, value) {
-    // Support: IE9 only
-    // In IE9 values are converted to string (e.g. `input.value = null` results in `input.value === 'null'`).
-    var propValue = isDefined(value) ? value : (msie === 9) ? '' : null;
-    element.prop('value', propValue);
-    attr.$set('value', value);
-  }
-
-  return {
-    restrict: 'A',
-    priority: 100,
-    compile: function(tpl, tplAttr) {
-      if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
-        return function ngValueConstantLink(scope, elm, attr) {
-          var value = scope.$eval(attr.ngValue);
-          updateElementValue(elm, attr, value);
-        };
-      } else {
-        return function ngValueLink(scope, elm, attr) {
-          scope.$watch(attr.ngValue, function valueWatchAction(value) {
-            updateElementValue(elm, attr, value);
-          });
-        };
-      }
-    }
-  };
-};
-
-/**
- * @ngdoc directive
- * @name ngBind
- * @restrict AC
- *
- * @description
- * The `ngBind` attribute tells Angular to replace the text content of the specified HTML element
- * with the value of a given expression, and to update the text content when the value of that
- * expression changes.
- *
- * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
- * `{{ expression }}` which is similar but less verbose.
- *
- * It is preferable to use `ngBind` instead of `{{ expression }}` if a template is momentarily
- * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
- * element attribute, it makes the bindings invisible to the user while the page is loading.
- *
- * An alternative solution to this problem would be using the
- * {@link ng.directive:ngCloak ngCloak} directive.
- *
- *
- * @element ANY
- * @param {expression} ngBind {@link guide/expression Expression} to evaluate.
- *
- * @example
- * Enter a name in the Live Preview text box; the greeting below the text box changes instantly.
-   <example module="bindExample" name="ng-bind">
-     <file name="index.html">
-       <script>
-         angular.module('bindExample', [])
-           .controller('ExampleController', ['$scope', function($scope) {
-             $scope.name = 'Whirled';
-           }]);
-       </script>
-       <div ng-controller="ExampleController">
-         <label>Enter name: <input type="text" ng-model="name"></label><br>
-         Hello <span ng-bind="name"></span>!
-       </div>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should check ng-bind', function() {
-         var nameInput = element(by.model('name'));
-
-         expect(element(by.binding('name')).getText()).toBe('Whirled');
-         nameInput.clear();
-         nameInput.sendKeys('world');
-         expect(element(by.binding('name')).getText()).toBe('world');
-       });
-     </file>
-   </example>
- */
-var ngBindDirective = ['$compile', function($compile) {
-  return {
-    restrict: 'AC',
-    compile: function ngBindCompile(templateElement) {
-      $compile.$$addBindingClass(templateElement);
-      return function ngBindLink(scope, element, attr) {
-        $compile.$$addBindingInfo(element, attr.ngBind);
-        element = element[0];
-        scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
-          element.textContent = stringify(value);
-        });
-      };
-    }
-  };
-}];
-
-
-/**
- * @ngdoc directive
- * @name ngBindTemplate
- *
- * @description
- * The `ngBindTemplate` directive specifies that the element
- * text content should be replaced with the interpolation of the template
- * in the `ngBindTemplate` attribute.
- * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`
- * expressions. This directive is needed since some HTML elements
- * (such as TITLE and OPTION) cannot contain SPAN elements.
- *
- * @element ANY
- * @param {string} ngBindTemplate template of form
- *   <tt>{{</tt> <tt>expression</tt> <tt>}}</tt> to eval.
- *
- * @example
- * Try it here: enter text in text box and watch the greeting change.
-   <example module="bindExample" name="ng-bind-template">
-     <file name="index.html">
-       <script>
-         angular.module('bindExample', [])
-           .controller('ExampleController', ['$scope', function($scope) {
-             $scope.salutation = 'Hello';
-             $scope.name = 'World';
-           }]);
-       </script>
-       <div ng-controller="ExampleController">
-        <label>Salutation: <input type="text" ng-model="salutation"></label><br>
-        <label>Name: <input type="text" ng-model="name"></label><br>
-        <pre ng-bind-template="{{salutation}} {{name}}!"></pre>
-       </div>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should check ng-bind', function() {
-         var salutationElem = element(by.binding('salutation'));
-         var salutationInput = element(by.model('salutation'));
-         var nameInput = element(by.model('name'));
-
-         expect(salutationElem.getText()).toBe('Hello World!');
-
-         salutationInput.clear();
-         salutationInput.sendKeys('Greetings');
-         nameInput.clear();
-         nameInput.sendKeys('user');
-
-         expect(salutationElem.getText()).toBe('Greetings user!');
-       });
-     </file>
-   </example>
- */
-var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate, $compile) {
-  return {
-    compile: function ngBindTemplateCompile(templateElement) {
-      $compile.$$addBindingClass(templateElement);
-      return function ngBindTemplateLink(scope, element, attr) {
-        var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate));
-        $compile.$$addBindingInfo(element, interpolateFn.expressions);
-        element = element[0];
-        attr.$observe('ngBindTemplate', function(value) {
-          element.textContent = isUndefined(value) ? '' : value;
-        });
-      };
-    }
-  };
-}];
-
-
-/**
- * @ngdoc directive
- * @name ngBindHtml
- *
- * @description
- * Evaluates the expression and inserts the resulting HTML into the element in a secure way. By default,
- * the resulting HTML content will be sanitized using the {@link ngSanitize.$sanitize $sanitize} service.
- * To utilize this functionality, ensure that `$sanitize` is available, for example, by including {@link
- * ngSanitize} in your module's dependencies (not in core Angular). In order to use {@link ngSanitize}
- * in your module's dependencies, you need to include "angular-sanitize.js" in your application.
- *
- * You may also bypass sanitization for values you know are safe. To do so, bind to
- * an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}.  See the example
- * under {@link ng.$sce#show-me-an-example-using-sce- Strict Contextual Escaping (SCE)}.
- *
- * Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you
- * will have an exception (instead of an exploit.)
- *
- * @element ANY
- * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
- *
- * @example
-
-   <example module="bindHtmlExample" deps="angular-sanitize.js" name="ng-bind-html">
-     <file name="index.html">
-       <div ng-controller="ExampleController">
-        <p ng-bind-html="myHTML"></p>
-       </div>
-     </file>
-
-     <file name="script.js">
-       angular.module('bindHtmlExample', ['ngSanitize'])
-         .controller('ExampleController', ['$scope', function($scope) {
-           $scope.myHTML =
-              'I am an <code>HTML</code>string with ' +
-              '<a href="#">links!</a> and other <em>stuff</em>';
-         }]);
-     </file>
-
-     <file name="protractor.js" type="protractor">
-       it('should check ng-bind-html', function() {
-         expect(element(by.binding('myHTML')).getText()).toBe(
-             'I am an HTMLstring with links! and other stuff');
-       });
-     </file>
-   </example>
- */
-var ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {
-  return {
-    restrict: 'A',
-    compile: function ngBindHtmlCompile(tElement, tAttrs) {
-      var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);
-      var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function sceValueOf(val) {
-        // Unwrap the value to compare the actual inner safe value, not the wrapper object.
-        return $sce.valueOf(val);
-      });
-      $compile.$$addBindingClass(tElement);
-
-      return function ngBindHtmlLink(scope, element, attr) {
-        $compile.$$addBindingInfo(element, attr.ngBindHtml);
-
-        scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {
-          // The watched value is the unwrapped value. To avoid re-escaping, use the direct getter.
-          var value = ngBindHtmlGetter(scope);
-          element.html($sce.getTrustedHtml(value) || '');
-        });
-      };
-    }
-  };
-}];
-
-/**
- * @ngdoc directive
- * @name ngChange
- *
- * @description
- * Evaluate the given expression when the user changes the input.
- * The expression is evaluated immediately, unlike the JavaScript onchange event
- * which only triggers at the end of a change (usually, when the user leaves the
- * form element or presses the return key).
- *
- * The `ngChange` expression is only evaluated when a change in the input value causes
- * a new value to be committed to the model.
- *
- * It will not be evaluated:
- * * if the value returned from the `$parsers` transformation pipeline has not changed
- * * if the input has continued to be invalid since the model will stay `null`
- * * if the model is changed programmatically and not by a change to the input value
- *
- *
- * Note, this directive requires `ngModel` to be present.
- *
- * @element input
- * @param {expression} ngChange {@link guide/expression Expression} to evaluate upon change
- * in input value.
- *
- * @example
- * <example name="ngChange-directive" module="changeExample">
- *   <file name="index.html">
- *     <script>
- *       angular.module('changeExample', [])
- *         .controller('ExampleController', ['$scope', function($scope) {
- *           $scope.counter = 0;
- *           $scope.change = function() {
- *             $scope.counter++;
- *           };
- *         }]);
- *     </script>
- *     <div ng-controller="ExampleController">
- *       <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
- *       <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
- *       <label for="ng-change-example2">Confirmed</label><br />
- *       <tt>debug = {{confirmed}}</tt><br/>
- *       <tt>counter = {{counter}}</tt><br/>
- *     </div>
- *   </file>
- *   <file name="protractor.js" type="protractor">
- *     var counter = element(by.binding('counter'));
- *     var debug = element(by.binding('confirmed'));
- *
- *     it('should evaluate the expression if changing from view', function() {
- *       expect(counter.getText()).toContain('0');
- *
- *       element(by.id('ng-change-example1')).click();
- *
- *       expect(counter.getText()).toContain('1');
- *       expect(debug.getText()).toContain('true');
- *     });
- *
- *     it('should not evaluate the expression if changing from model', function() {
- *       element(by.id('ng-change-example2')).click();
-
- *       expect(counter.getText()).toContain('0');
- *       expect(debug.getText()).toContain('true');
- *     });
- *   </file>
- * </example>
- */
-var ngChangeDirective = valueFn({
-  restrict: 'A',
-  require: 'ngModel',
-  link: function(scope, element, attr, ctrl) {
-    ctrl.$viewChangeListeners.push(function() {
-      scope.$eval(attr.ngChange);
-    });
-  }
-});
-
-/* exported
-  ngClassDirective,
-  ngClassEvenDirective,
-  ngClassOddDirective
-*/
-
-function classDirective(name, selector) {
-  name = 'ngClass' + name;
-  var indexWatchExpression;
-
-  return ['$parse', function($parse) {
-    return {
-      restrict: 'AC',
-      link: function(scope, element, attr) {
-        var expression = attr[name].trim();
-        var isOneTime = (expression.charAt(0) === ':') && (expression.charAt(1) === ':');
-
-        var watchInterceptor = isOneTime ? toFlatValue : toClassString;
-        var watchExpression = $parse(expression, watchInterceptor);
-        var watchAction = isOneTime ? ngClassOneTimeWatchAction : ngClassWatchAction;
-
-        var classCounts = element.data('$classCounts');
-        var oldModulo = true;
-        var oldClassString;
-
-        if (!classCounts) {
-          // Use createMap() to prevent class assumptions involving property
-          // names in Object.prototype
-          classCounts = createMap();
-          element.data('$classCounts', classCounts);
-        }
-
-        if (name !== 'ngClass') {
-          if (!indexWatchExpression) {
-            indexWatchExpression = $parse('$index', function moduloTwo($index) {
-              // eslint-disable-next-line no-bitwise
-              return $index & 1;
-            });
-          }
-
-          scope.$watch(indexWatchExpression, ngClassIndexWatchAction);
-        }
-
-        scope.$watch(watchExpression, watchAction, isOneTime);
-
-        function addClasses(classString) {
-          classString = digestClassCounts(split(classString), 1);
-          attr.$addClass(classString);
-        }
-
-        function removeClasses(classString) {
-          classString = digestClassCounts(split(classString), -1);
-          attr.$removeClass(classString);
-        }
-
-        function updateClasses(oldClassString, newClassString) {
-          var oldClassArray = split(oldClassString);
-          var newClassArray = split(newClassString);
-
-          var toRemoveArray = arrayDifference(oldClassArray, newClassArray);
-          var toAddArray = arrayDifference(newClassArray, oldClassArray);
-
-          var toRemoveString = digestClassCounts(toRemoveArray, -1);
-          var toAddString = digestClassCounts(toAddArray, 1);
-
-          attr.$addClass(toAddString);
-          attr.$removeClass(toRemoveString);
-        }
-
-        function digestClassCounts(classArray, count) {
-          var classesToUpdate = [];
-
-          forEach(classArray, function(className) {
-            if (count > 0 || classCounts[className]) {
-              classCounts[className] = (classCounts[className] || 0) + count;
-              if (classCounts[className] === +(count > 0)) {
-                classesToUpdate.push(className);
-              }
-            }
-          });
-
-          return classesToUpdate.join(' ');
-        }
-
-        function ngClassIndexWatchAction(newModulo) {
-          // This watch-action should run before the `ngClass[OneTime]WatchAction()`, thus it
-          // adds/removes `oldClassString`. If the `ngClass` expression has changed as well, the
-          // `ngClass[OneTime]WatchAction()` will update the classes.
-          if (newModulo === selector) {
-            addClasses(oldClassString);
-          } else {
-            removeClasses(oldClassString);
-          }
-
-          oldModulo = newModulo;
-        }
-
-        function ngClassOneTimeWatchAction(newClassValue) {
-          var newClassString = toClassString(newClassValue);
-
-          if (newClassString !== oldClassString) {
-            ngClassWatchAction(newClassString);
-          }
-        }
-
-        function ngClassWatchAction(newClassString) {
-          if (oldModulo === selector) {
-            updateClasses(oldClassString, newClassString);
-          }
-
-          oldClassString = newClassString;
-        }
-      }
-    };
-  }];
-
-  // Helpers
-  function arrayDifference(tokens1, tokens2) {
-    if (!tokens1 || !tokens1.length) return [];
-    if (!tokens2 || !tokens2.length) return tokens1;
-
-    var values = [];
-
-    outer:
-    for (var i = 0; i < tokens1.length; i++) {
-      var token = tokens1[i];
-      for (var j = 0; j < tokens2.length; j++) {
-        if (token === tokens2[j]) continue outer;
-      }
-      values.push(token);
-    }
-
-    return values;
-  }
-
-  function split(classString) {
-    return classString && classString.split(' ');
-  }
-
-  function toClassString(classValue) {
-    var classString = classValue;
-
-    if (isArray(classValue)) {
-      classString = classValue.map(toClassString).join(' ');
-    } else if (isObject(classValue)) {
-      classString = Object.keys(classValue).
-        filter(function(key) { return classValue[key]; }).
-        join(' ');
-    }
-
-    return classString;
-  }
-
-  function toFlatValue(classValue) {
-    var flatValue = classValue;
-
-    if (isArray(classValue)) {
-      flatValue = classValue.map(toFlatValue);
-    } else if (isObject(classValue)) {
-      var hasUndefined = false;
-
-      flatValue = Object.keys(classValue).filter(function(key) {
-        var value = classValue[key];
-
-        if (!hasUndefined && isUndefined(value)) {
-          hasUndefined = true;
-        }
-
-        return value;
-      });
-
-      if (hasUndefined) {
-        // Prevent the `oneTimeLiteralWatchInterceptor` from unregistering
-        // the watcher, by including at least one `undefined` value.
-        flatValue.push(undefined);
-      }
-    }
-
-    return flatValue;
-  }
-}
-
-/**
- * @ngdoc directive
- * @name ngClass
- * @restrict AC
- *
- * @description
- * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding
- * an expression that represents all classes to be added.
- *
- * The directive operates in three different ways, depending on which of three types the expression
- * evaluates to:
- *
- * 1. If the expression evaluates to a string, the string should be one or more space-delimited class
- * names.
- *
- * 2. If the expression evaluates to an object, then for each key-value pair of the
- * object with a truthy value the corresponding key is used as a class name.
- *
- * 3. If the expression evaluates to an array, each element of the array should either be a string as in
- * type 1 or an object as in type 2. This means that you can mix strings and objects together in an array
- * to give you more control over what CSS classes appear. See the code below for an example of this.
- *
- *
- * The directive won't add duplicate classes if a particular class was already set.
- *
- * When the expression changes, the previously added classes are removed and only then are the
- * new classes added.
- *
- * @knownIssue
- * You should not use {@link guide/interpolation interpolation} in the value of the `class`
- * attribute, when using the `ngClass` directive on the same element.
- * See {@link guide/interpolation#known-issues here} for more info.
- *
- * @animations
- * | Animation                        | Occurs                              |
- * |----------------------------------|-------------------------------------|
- * | {@link ng.$animate#addClass addClass}       | just before the class is applied to the element   |
- * | {@link ng.$animate#removeClass removeClass} | just before the class is removed from the element |
- *
- * @element ANY
- * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
- *   of the evaluation can be a string representing space delimited class
- *   names, an array, or a map of class names to boolean values. In the case of a map, the
- *   names of the properties whose values are truthy will be added as css classes to the
- *   element.
- *
- * @example Example that demonstrates basic bindings via ngClass directive.
-   <example name="ng-class">
-     <file name="index.html">
-       <p ng-class="{strike: deleted, bold: important, 'has-error': error}">Map Syntax Example</p>
-       <label>
-          <input type="checkbox" ng-model="deleted">
-          deleted (apply "strike" class)
-       </label><br>
-       <label>
-          <input type="checkbox" ng-model="important">
-          important (apply "bold" class)
-       </label><br>
-       <label>
-          <input type="checkbox" ng-model="error">
-          error (apply "has-error" class)
-       </label>
-       <hr>
-       <p ng-class="style">Using String Syntax</p>
-       <input type="text" ng-model="style"
-              placeholder="Type: bold strike red" aria-label="Type: bold strike red">
-       <hr>
-       <p ng-class="[style1, style2, style3]">Using Array Syntax</p>
-       <input ng-model="style1"
-              placeholder="Type: bold, strike or red" aria-label="Type: bold, strike or red"><br>
-       <input ng-model="style2"
-              placeholder="Type: bold, strike or red" aria-label="Type: bold, strike or red 2"><br>
-       <input ng-model="style3"
-              placeholder="Type: bold, strike or red" aria-label="Type: bold, strike or red 3"><br>
-       <hr>
-       <p ng-class="[style4, {orange: warning}]">Using Array and Map Syntax</p>
-       <input ng-model="style4" placeholder="Type: bold, strike" aria-label="Type: bold, strike"><br>
-       <label><input type="checkbox" ng-model="warning"> warning (apply "orange" class)</label>
-     </file>
-     <file name="style.css">
-       .strike {
-           text-decoration: line-through;
-       }
-       .bold {
-           font-weight: bold;
-       }
-       .red {
-           color: red;
-       }
-       .has-error {
-           color: red;
-           background-color: yellow;
-       }
-       .orange {
-           color: orange;
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       var ps = element.all(by.css('p'));
-
-       it('should let you toggle the class', function() {
-
-         expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
-         expect(ps.first().getAttribute('class')).not.toMatch(/has-error/);
-
-         element(by.model('important')).click();
-         expect(ps.first().getAttribute('class')).toMatch(/bold/);
-
-         element(by.model('error')).click();
-         expect(ps.first().getAttribute('class')).toMatch(/has-error/);
-       });
-
-       it('should let you toggle string example', function() {
-         expect(ps.get(1).getAttribute('class')).toBe('');
-         element(by.model('style')).clear();
-         element(by.model('style')).sendKeys('red');
-         expect(ps.get(1).getAttribute('class')).toBe('red');
-       });
-
-       it('array example should have 3 classes', function() {
-         expect(ps.get(2).getAttribute('class')).toBe('');
-         element(by.model('style1')).sendKeys('bold');
-         element(by.model('style2')).sendKeys('strike');
-         element(by.model('style3')).sendKeys('red');
-         expect(ps.get(2).getAttribute('class')).toBe('bold strike red');
-       });
-
-       it('array with map example should have 2 classes', function() {
-         expect(ps.last().getAttribute('class')).toBe('');
-         element(by.model('style4')).sendKeys('bold');
-         element(by.model('warning')).click();
-         expect(ps.last().getAttribute('class')).toBe('bold orange');
-       });
-     </file>
-   </example>
-
-   ## Animations
-
-   The example below demonstrates how to perform animations using ngClass.
-
-   <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-class">
-     <file name="index.html">
-      <input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
-      <input id="clearbtn" type="button" value="clear" ng-click="myVar=''">
-      <br>
-      <span class="base-class" ng-class="myVar">Sample Text</span>
-     </file>
-     <file name="style.css">
-       .base-class {
-         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-       }
-
-       .base-class.my-class {
-         color: red;
-         font-size:3em;
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should check ng-class', function() {
-         expect(element(by.css('.base-class')).getAttribute('class')).not.
-           toMatch(/my-class/);
-
-         element(by.id('setbtn')).click();
-
-         expect(element(by.css('.base-class')).getAttribute('class')).
-           toMatch(/my-class/);
-
-         element(by.id('clearbtn')).click();
-
-         expect(element(by.css('.base-class')).getAttribute('class')).not.
-           toMatch(/my-class/);
-       });
-     </file>
-   </example>
-
-
-   ## ngClass and pre-existing CSS3 Transitions/Animations
-   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
-   Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder
-   any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure
-   to view the step by step details of {@link $animate#addClass $animate.addClass} and
-   {@link $animate#removeClass $animate.removeClass}.
- */
-var ngClassDirective = classDirective('', true);
-
-/**
- * @ngdoc directive
- * @name ngClassOdd
- * @restrict AC
- *
- * @description
- * The `ngClassOdd` and `ngClassEven` directives work exactly as
- * {@link ng.directive:ngClass ngClass}, except they work in
- * conjunction with `ngRepeat` and take effect only on odd (even) rows.
- *
- * This directive can be applied only within the scope of an
- * {@link ng.directive:ngRepeat ngRepeat}.
- *
- * @element ANY
- * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result
- *   of the evaluation can be a string representing space delimited class names or an array.
- *
- * @example
-   <example name="ng-class-odd">
-     <file name="index.html">
-        <ol ng-init="names=['John', 'Mary', 'Cate', 'Suz']">
-          <li ng-repeat="name in names">
-           <span ng-class-odd="'odd'" ng-class-even="'even'">
-             {{name}}
-           </span>
-          </li>
-        </ol>
-     </file>
-     <file name="style.css">
-       .odd {
-         color: red;
-       }
-       .even {
-         color: blue;
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should check ng-class-odd and ng-class-even', function() {
-         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
-           toMatch(/odd/);
-         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
-           toMatch(/even/);
-       });
-     </file>
-   </example>
- */
-var ngClassOddDirective = classDirective('Odd', 0);
-
-/**
- * @ngdoc directive
- * @name ngClassEven
- * @restrict AC
- *
- * @description
- * The `ngClassOdd` and `ngClassEven` directives work exactly as
- * {@link ng.directive:ngClass ngClass}, except they work in
- * conjunction with `ngRepeat` and take effect only on odd (even) rows.
- *
- * This directive can be applied only within the scope of an
- * {@link ng.directive:ngRepeat ngRepeat}.
- *
- * @element ANY
- * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The
- *   result of the evaluation can be a string representing space delimited class names or an array.
- *
- * @example
-   <example name="ng-class-even">
-     <file name="index.html">
-        <ol ng-init="names=['John', 'Mary', 'Cate', 'Suz']">
-          <li ng-repeat="name in names">
-           <span ng-class-odd="'odd'" ng-class-even="'even'">
-             {{name}} &nbsp; &nbsp; &nbsp;
-           </span>
-          </li>
-        </ol>
-     </file>
-     <file name="style.css">
-       .odd {
-         color: red;
-       }
-       .even {
-         color: blue;
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should check ng-class-odd and ng-class-even', function() {
-         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
-           toMatch(/odd/);
-         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
-           toMatch(/even/);
-       });
-     </file>
-   </example>
- */
-var ngClassEvenDirective = classDirective('Even', 1);
-
-/**
- * @ngdoc directive
- * @name ngCloak
- * @restrict AC
- *
- * @description
- * The `ngCloak` directive is used to prevent the Angular html template from being briefly
- * displayed by the browser in its raw (uncompiled) form while your application is loading. Use this
- * directive to avoid the undesirable flicker effect caused by the html template display.
- *
- * The directive can be applied to the `<body>` element, but the preferred usage is to apply
- * multiple `ngCloak` directives to small portions of the page to permit progressive rendering
- * of the browser view.
- *
- * `ngCloak` works in cooperation with the following css rule embedded within `angular.js` and
- * `angular.min.js`.
- * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).
- *
- * ```css
- * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
- *   display: none !important;
- * }
- * ```
- *
- * When this css rule is loaded by the browser, all html elements (including their children) that
- * are tagged with the `ngCloak` directive are hidden. When Angular encounters this directive
- * during the compilation of the template it deletes the `ngCloak` element attribute, making
- * the compiled element visible.
- *
- * For the best result, the `angular.js` script must be loaded in the head section of the html
- * document; alternatively, the css rule above must be included in the external stylesheet of the
- * application.
- *
- * @element ANY
- *
- * @example
-   <example name="ng-cloak">
-     <file name="index.html">
-        <div id="template1" ng-cloak>{{ 'hello' }}</div>
-        <div id="template2" class="ng-cloak">{{ 'world' }}</div>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should remove the template directive and css class', function() {
-         expect($('#template1').getAttribute('ng-cloak')).
-           toBeNull();
-         expect($('#template2').getAttribute('ng-cloak')).
-           toBeNull();
-       });
-     </file>
-   </example>
- *
- */
-var ngCloakDirective = ngDirective({
-  compile: function(element, attr) {
-    attr.$set('ngCloak', undefined);
-    element.removeClass('ng-cloak');
-  }
-});
-
-/**
- * @ngdoc directive
- * @name ngController
- *
- * @description
- * The `ngController` directive attaches a controller class to the view. This is a key aspect of how angular
- * supports the principles behind the Model-View-Controller design pattern.
- *
- * MVC components in angular:
- *
- * * Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties
- *   are accessed through bindings.
- * * View — The template (HTML with data bindings) that is rendered into the View.
- * * Controller — The `ngController` directive specifies a Controller class; the class contains business
- *   logic behind the application to decorate the scope with functions and values
- *
- * Note that you can also attach controllers to the DOM by declaring it in a route definition
- * via the {@link ngRoute.$route $route} service. A common mistake is to declare the controller
- * again using `ng-controller` in the template itself.  This will cause the controller to be attached
- * and executed twice.
- *
- * @element ANY
- * @scope
- * @priority 500
- * @param {expression} ngController Name of a constructor function registered with the current
- * {@link ng.$controllerProvider $controllerProvider} or an {@link guide/expression expression}
- * that on the current scope evaluates to a constructor function.
- *
- * The controller instance can be published into a scope property by specifying
- * `ng-controller="as propertyName"`.
- *
- * If the current `$controllerProvider` is configured to use globals (via
- * {@link ng.$controllerProvider#allowGlobals `$controllerProvider.allowGlobals()` }), this may
- * also be the name of a globally accessible constructor function (deprecated, not recommended).
- *
- * @example
- * Here is a simple form for editing user contact information. Adding, removing, clearing, and
- * greeting are methods declared on the controller (see source tab). These methods can
- * easily be called from the angular markup. Any changes to the data are automatically reflected
- * in the View without the need for a manual update.
- *
- * Two different declaration styles are included below:
- *
- * * one binds methods and properties directly onto the controller using `this`:
- * `ng-controller="SettingsController1 as settings"`
- * * one injects `$scope` into the controller:
- * `ng-controller="SettingsController2"`
- *
- * The second option is more common in the Angular community, and is generally used in boilerplates
- * and in this guide. However, there are advantages to binding properties directly to the controller
- * and avoiding scope.
- *
- * * Using `controller as` makes it obvious which controller you are accessing in the template when
- * multiple controllers apply to an element.
- * * If you are writing your controllers as classes you have easier access to the properties and
- * methods, which will appear on the scope, from inside the controller code.
- * * Since there is always a `.` in the bindings, you don't have to worry about prototypal
- * inheritance masking primitives.
- *
- * This example demonstrates the `controller as` syntax.
- *
- * <example name="ngControllerAs" module="controllerAsExample">
- *   <file name="index.html">
- *    <div id="ctrl-as-exmpl" ng-controller="SettingsController1 as settings">
- *      <label>Name: <input type="text" ng-model="settings.name"/></label>
- *      <button ng-click="settings.greet()">greet</button><br/>
- *      Contact:
- *      <ul>
- *        <li ng-repeat="contact in settings.contacts">
- *          <select ng-model="contact.type" aria-label="Contact method" id="select_{{$index}}">
- *             <option>phone</option>
- *             <option>email</option>
- *          </select>
- *          <input type="text" ng-model="contact.value" aria-labelledby="select_{{$index}}" />
- *          <button ng-click="settings.clearContact(contact)">clear</button>
- *          <button ng-click="settings.removeContact(contact)" aria-label="Remove">X</button>
- *        </li>
- *        <li><button ng-click="settings.addContact()">add</button></li>
- *     </ul>
- *    </div>
- *   </file>
- *   <file name="app.js">
- *    angular.module('controllerAsExample', [])
- *      .controller('SettingsController1', SettingsController1);
- *
- *    function SettingsController1() {
- *      this.name = 'John Smith';
- *      this.contacts = [
- *        {type: 'phone', value: '408 555 1212'},
- *        {type: 'email', value: 'john.smith@example.org'}
- *      ];
- *    }
- *
- *    SettingsController1.prototype.greet = function() {
- *      alert(this.name);
- *    };
- *
- *    SettingsController1.prototype.addContact = function() {
- *      this.contacts.push({type: 'email', value: 'yourname@example.org'});
- *    };
- *
- *    SettingsController1.prototype.removeContact = function(contactToRemove) {
- *     var index = this.contacts.indexOf(contactToRemove);
- *      this.contacts.splice(index, 1);
- *    };
- *
- *    SettingsController1.prototype.clearContact = function(contact) {
- *      contact.type = 'phone';
- *      contact.value = '';
- *    };
- *   </file>
- *   <file name="protractor.js" type="protractor">
- *     it('should check controller as', function() {
- *       var container = element(by.id('ctrl-as-exmpl'));
- *         expect(container.element(by.model('settings.name'))
- *           .getAttribute('value')).toBe('John Smith');
- *
- *       var firstRepeat =
- *           container.element(by.repeater('contact in settings.contacts').row(0));
- *       var secondRepeat =
- *           container.element(by.repeater('contact in settings.contacts').row(1));
- *
- *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
- *           .toBe('408 555 1212');
- *
- *       expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
- *           .toBe('john.smith@example.org');
- *
- *       firstRepeat.element(by.buttonText('clear')).click();
- *
- *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
- *           .toBe('');
- *
- *       container.element(by.buttonText('add')).click();
- *
- *       expect(container.element(by.repeater('contact in settings.contacts').row(2))
- *           .element(by.model('contact.value'))
- *           .getAttribute('value'))
- *           .toBe('yourname@example.org');
- *     });
- *   </file>
- * </example>
- *
- * This example demonstrates the "attach to `$scope`" style of controller.
- *
- * <example name="ngController" module="controllerExample">
- *  <file name="index.html">
- *   <div id="ctrl-exmpl" ng-controller="SettingsController2">
- *     <label>Name: <input type="text" ng-model="name"/></label>
- *     <button ng-click="greet()">greet</button><br/>
- *     Contact:
- *     <ul>
- *       <li ng-repeat="contact in contacts">
- *         <select ng-model="contact.type" id="select_{{$index}}">
- *            <option>phone</option>
- *            <option>email</option>
- *         </select>
- *         <input type="text" ng-model="contact.value" aria-labelledby="select_{{$index}}" />
- *         <button ng-click="clearContact(contact)">clear</button>
- *         <button ng-click="removeContact(contact)">X</button>
- *       </li>
- *       <li>[ <button ng-click="addContact()">add</button> ]</li>
- *    </ul>
- *   </div>
- *  </file>
- *  <file name="app.js">
- *   angular.module('controllerExample', [])
- *     .controller('SettingsController2', ['$scope', SettingsController2]);
- *
- *   function SettingsController2($scope) {
- *     $scope.name = 'John Smith';
- *     $scope.contacts = [
- *       {type:'phone', value:'408 555 1212'},
- *       {type:'email', value:'john.smith@example.org'}
- *     ];
- *
- *     $scope.greet = function() {
- *       alert($scope.name);
- *     };
- *
- *     $scope.addContact = function() {
- *       $scope.contacts.push({type:'email', value:'yourname@example.org'});
- *     };
- *
- *     $scope.removeContact = function(contactToRemove) {
- *       var index = $scope.contacts.indexOf(contactToRemove);
- *       $scope.contacts.splice(index, 1);
- *     };
- *
- *     $scope.clearContact = function(contact) {
- *       contact.type = 'phone';
- *       contact.value = '';
- *     };
- *   }
- *  </file>
- *  <file name="protractor.js" type="protractor">
- *    it('should check controller', function() {
- *      var container = element(by.id('ctrl-exmpl'));
- *
- *      expect(container.element(by.model('name'))
- *          .getAttribute('value')).toBe('John Smith');
- *
- *      var firstRepeat =
- *          container.element(by.repeater('contact in contacts').row(0));
- *      var secondRepeat =
- *          container.element(by.repeater('contact in contacts').row(1));
- *
- *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
- *          .toBe('408 555 1212');
- *      expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
- *          .toBe('john.smith@example.org');
- *
- *      firstRepeat.element(by.buttonText('clear')).click();
- *
- *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
- *          .toBe('');
- *
- *      container.element(by.buttonText('add')).click();
- *
- *      expect(container.element(by.repeater('contact in contacts').row(2))
- *          .element(by.model('contact.value'))
- *          .getAttribute('value'))
- *          .toBe('yourname@example.org');
- *    });
- *  </file>
- *</example>
-
- */
-var ngControllerDirective = [function() {
-  return {
-    restrict: 'A',
-    scope: true,
-    controller: '@',
-    priority: 500
-  };
-}];
-
-/**
- * @ngdoc directive
- * @name ngCsp
- *
- * @restrict A
- * @element ANY
- * @description
- *
- * Angular has some features that can conflict with certain restrictions that are applied when using
- * [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) rules.
- *
- * If you intend to implement CSP with these rules then you must tell Angular not to use these
- * features.
- *
- * This is necessary when developing things like Google Chrome Extensions or Universal Windows Apps.
- *
- *
- * The following default rules in CSP affect Angular:
- *
- * * The use of `eval()`, `Function(string)` and similar functions to dynamically create and execute
- * code from strings is forbidden. Angular makes use of this in the {@link $parse} service to
- * provide a 30% increase in the speed of evaluating Angular expressions. (This CSP rule can be
- * disabled with the CSP keyword `unsafe-eval`, but it is generally not recommended as it would
- * weaken the protections offered by CSP.)
- *
- * * The use of inline resources, such as inline `<script>` and `<style>` elements, are forbidden.
- * This prevents apps from injecting custom styles directly into the document. Angular makes use of
- * this to include some CSS rules (e.g. {@link ngCloak} and {@link ngHide}). To make these
- * directives work when a CSP rule is blocking inline styles, you must link to the `angular-csp.css`
- * in your HTML manually. (This CSP rule can be disabled with the CSP keyword `unsafe-inline`, but
- * it is generally not recommended as it would weaken the protections offered by CSP.)
- *
- * If you do not provide `ngCsp` then Angular tries to autodetect if CSP is blocking dynamic code
- * creation from strings (e.g., `unsafe-eval` not specified in CSP header) and automatically
- * deactivates this feature in the {@link $parse} service. This autodetection, however, triggers a
- * CSP error to be logged in the console:
- *
- * ```
- * Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of
- * script in the following Content Security Policy directive: "default-src 'self'". Note that
- * 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
- * ```
- *
- * This error is harmless but annoying. To prevent the error from showing up, put the `ngCsp`
- * directive on an element of the HTML document that appears before the `<script>` tag that loads
- * the `angular.js` file.
- *
- * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.*
- *
- * You can specify which of the CSP related Angular features should be deactivated by providing
- * a value for the `ng-csp` attribute. The options are as follows:
- *
- * * no-inline-style: this stops Angular from injecting CSS styles into the DOM
- *
- * * no-unsafe-eval: this stops Angular from optimizing $parse with unsafe eval of strings
- *
- * You can use these values in the following combinations:
- *
- *
- * * No declaration means that Angular will assume that you can do inline styles, but it will do
- * a runtime check for unsafe-eval. E.g. `<body>`. This is backwardly compatible with previous
- * versions of Angular.
- *
- * * A simple `ng-csp` (or `data-ng-csp`) attribute will tell Angular to deactivate both inline
- * styles and unsafe eval. E.g. `<body ng-csp>`. This is backwardly compatible with previous
- * versions of Angular.
- *
- * * Specifying only `no-unsafe-eval` tells Angular that we must not use eval, but that we can
- * inject inline styles. E.g. `<body ng-csp="no-unsafe-eval">`.
- *
- * * Specifying only `no-inline-style` tells Angular that we must not inject styles, but that we can
- * run eval - no automatic check for unsafe eval will occur. E.g. `<body ng-csp="no-inline-style">`
- *
- * * Specifying both `no-unsafe-eval` and `no-inline-style` tells Angular that we must not inject
- * styles nor use eval, which is the same as an empty: ng-csp.
- * E.g.`<body ng-csp="no-inline-style;no-unsafe-eval">`
- *
- * @example
- * This example shows how to apply the `ngCsp` directive to the `html` tag.
-   ```html
-     <!doctype html>
-     <html ng-app ng-csp>
-     ...
-     ...
-     </html>
-   ```
-  * @example
-      <!-- Note: the `.csp` suffix in the example name triggers CSP mode in our http server! -->
-      <example name="example.csp" module="cspExample" ng-csp="true">
-        <file name="index.html">
-          <div ng-controller="MainController as ctrl">
-            <div>
-              <button ng-click="ctrl.inc()" id="inc">Increment</button>
-              <span id="counter">
-                {{ctrl.counter}}
-              </span>
-            </div>
-
-            <div>
-              <button ng-click="ctrl.evil()" id="evil">Evil</button>
-              <span id="evilError">
-                {{ctrl.evilError}}
-              </span>
-            </div>
-          </div>
-        </file>
-        <file name="script.js">
-           angular.module('cspExample', [])
-             .controller('MainController', function MainController() {
-                this.counter = 0;
-                this.inc = function() {
-                  this.counter++;
-                };
-                this.evil = function() {
-                  try {
-                    eval('1+2'); // eslint-disable-line no-eval
-                  } catch (e) {
-                    this.evilError = e.message;
-                  }
-                };
-              });
-        </file>
-        <file name="protractor.js" type="protractor">
-          var util, webdriver;
-
-          var incBtn = element(by.id('inc'));
-          var counter = element(by.id('counter'));
-          var evilBtn = element(by.id('evil'));
-          var evilError = element(by.id('evilError'));
-
-          function getAndClearSevereErrors() {
-            return browser.manage().logs().get('browser').then(function(browserLog) {
-              return browserLog.filter(function(logEntry) {
-                return logEntry.level.value > webdriver.logging.Level.WARNING.value;
-              });
-            });
-          }
-
-          function clearErrors() {
-            getAndClearSevereErrors();
-          }
-
-          function expectNoErrors() {
-            getAndClearSevereErrors().then(function(filteredLog) {
-              expect(filteredLog.length).toEqual(0);
-              if (filteredLog.length) {
-                console.log('browser console errors: ' + util.inspect(filteredLog));
-              }
-            });
-          }
-
-          function expectError(regex) {
-            getAndClearSevereErrors().then(function(filteredLog) {
-              var found = false;
-              filteredLog.forEach(function(log) {
-                if (log.message.match(regex)) {
-                  found = true;
-                }
-              });
-              if (!found) {
-                throw new Error('expected an error that matches ' + regex);
-              }
-            });
-          }
-
-          beforeEach(function() {
-            util = require('util');
-            webdriver = require('selenium-webdriver');
-          });
-
-          // For now, we only test on Chrome,
-          // as Safari does not load the page with Protractor's injected scripts,
-          // and Firefox webdriver always disables content security policy (#6358)
-          if (browser.params.browser !== 'chrome') {
-            return;
-          }
-
-          it('should not report errors when the page is loaded', function() {
-            // clear errors so we are not dependent on previous tests
-            clearErrors();
-            // Need to reload the page as the page is already loaded when
-            // we come here
-            browser.driver.getCurrentUrl().then(function(url) {
-              browser.get(url);
-            });
-            expectNoErrors();
-          });
-
-          it('should evaluate expressions', function() {
-            expect(counter.getText()).toEqual('0');
-            incBtn.click();
-            expect(counter.getText()).toEqual('1');
-            expectNoErrors();
-          });
-
-          it('should throw and report an error when using "eval"', function() {
-            evilBtn.click();
-            expect(evilError.getText()).toMatch(/Content Security Policy/);
-            expectError(/Content Security Policy/);
-          });
-        </file>
-      </example>
-  */
-
-// `ngCsp` is not implemented as a proper directive any more, because we need it be processed while
-// we bootstrap the app (before `$parse` is instantiated). For this reason, we just have the `csp()`
-// fn that looks for the `ng-csp` attribute anywhere in the current doc.
-
-/**
- * @ngdoc directive
- * @name ngClick
- *
- * @description
- * The ngClick directive allows you to specify custom behavior when
- * an element is clicked.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon
- * click. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-click">
-     <file name="index.html">
-      <button ng-click="count = count + 1" ng-init="count=0">
-        Increment
-      </button>
-      <span>
-        count: {{count}}
-      </span>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should check ng-click', function() {
-         expect(element(by.binding('count')).getText()).toMatch('0');
-         element(by.css('button')).click();
-         expect(element(by.binding('count')).getText()).toMatch('1');
-       });
-     </file>
-   </example>
- */
-/*
- * A collection of directives that allows creation of custom event handlers that are defined as
- * angular expressions and are compiled and executed within the current scope.
- */
-var ngEventDirectives = {};
-
-// For events that might fire synchronously during DOM manipulation
-// we need to execute their event handlers asynchronously using $evalAsync,
-// so that they are not executed in an inconsistent state.
-var forceAsyncEvents = {
-  'blur': true,
-  'focus': true
-};
-forEach(
-  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
-  function(eventName) {
-    var directiveName = directiveNormalize('ng-' + eventName);
-    ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {
-      return {
-        restrict: 'A',
-        compile: function($element, attr) {
-          // NOTE:
-          // We expose the powerful `$event` object on the scope that provides access to the Window,
-          // etc. This is OK, because expressions are not sandboxed any more (and the expression
-          // sandbox was never meant to be a security feature anyway).
-          var fn = $parse(attr[directiveName]);
-          return function ngEventHandler(scope, element) {
-            element.on(eventName, function(event) {
-              var callback = function() {
-                fn(scope, {$event: event});
-              };
-              if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
-                scope.$evalAsync(callback);
-              } else {
-                scope.$apply(callback);
-              }
-            });
-          };
-        }
-      };
-    }];
-  }
-);
-
-/**
- * @ngdoc directive
- * @name ngDblclick
- *
- * @description
- * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon
- * a dblclick. (The Event object is available as `$event`)
- *
- * @example
-   <example name="ng-dblclick">
-     <file name="index.html">
-      <button ng-dblclick="count = count + 1" ng-init="count=0">
-        Increment (on double click)
-      </button>
-      count: {{count}}
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngMousedown
- *
- * @description
- * The ngMousedown directive allows you to specify custom behavior on mousedown event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon
- * mousedown. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-mousedown">
-     <file name="index.html">
-      <button ng-mousedown="count = count + 1" ng-init="count=0">
-        Increment (on mouse down)
-      </button>
-      count: {{count}}
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngMouseup
- *
- * @description
- * Specify custom behavior on mouseup event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon
- * mouseup. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-mouseup">
-     <file name="index.html">
-      <button ng-mouseup="count = count + 1" ng-init="count=0">
-        Increment (on mouse up)
-      </button>
-      count: {{count}}
-     </file>
-   </example>
- */
-
-/**
- * @ngdoc directive
- * @name ngMouseover
- *
- * @description
- * Specify custom behavior on mouseover event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon
- * mouseover. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-mouseover">
-     <file name="index.html">
-      <button ng-mouseover="count = count + 1" ng-init="count=0">
-        Increment (when mouse is over)
-      </button>
-      count: {{count}}
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngMouseenter
- *
- * @description
- * Specify custom behavior on mouseenter event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon
- * mouseenter. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-mouseenter">
-     <file name="index.html">
-      <button ng-mouseenter="count = count + 1" ng-init="count=0">
-        Increment (when mouse enters)
-      </button>
-      count: {{count}}
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngMouseleave
- *
- * @description
- * Specify custom behavior on mouseleave event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon
- * mouseleave. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-mouseleave">
-     <file name="index.html">
-      <button ng-mouseleave="count = count + 1" ng-init="count=0">
-        Increment (when mouse leaves)
-      </button>
-      count: {{count}}
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngMousemove
- *
- * @description
- * Specify custom behavior on mousemove event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon
- * mousemove. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-mousemove">
-     <file name="index.html">
-      <button ng-mousemove="count = count + 1" ng-init="count=0">
-        Increment (when mouse moves)
-      </button>
-      count: {{count}}
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngKeydown
- *
- * @description
- * Specify custom behavior on keydown event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
- * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
- *
- * @example
-   <example name="ng-keydown">
-     <file name="index.html">
-      <input ng-keydown="count = count + 1" ng-init="count=0">
-      key down count: {{count}}
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngKeyup
- *
- * @description
- * Specify custom behavior on keyup event.
- *
- * @element ANY
- * @priority 0
- * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
- * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
- *
- * @example
-   <example name="ng-keyup">
-     <file name="index.html">
-       <p>Typing in the input box below updates the key count</p>
-       <input ng-keyup="count = count + 1" ng-init="count=0"> key up count: {{count}}
-
-       <p>Typing in the input box below updates the keycode</p>
-       <input ng-keyup="event=$event">
-       <p>event keyCode: {{ event.keyCode }}</p>
-       <p>event altKey: {{ event.altKey }}</p>
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngKeypress
- *
- * @description
- * Specify custom behavior on keypress event.
- *
- * @element ANY
- * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon
- * keypress. ({@link guide/expression#-event- Event object is available as `$event`}
- * and can be interrogated for keyCode, altKey, etc.)
- *
- * @example
-   <example name="ng-keypress">
-     <file name="index.html">
-      <input ng-keypress="count = count + 1" ng-init="count=0">
-      key press count: {{count}}
-     </file>
-   </example>
- */
-
-
-/**
- * @ngdoc directive
- * @name ngSubmit
- *
- * @description
- * Enables binding angular expressions to onsubmit events.
- *
- * Additionally it prevents the default action (which for form means sending the request to the
- * server and reloading the current page), but only if the form does not contain `action`,
- * `data-action`, or `x-action` attributes.
- *
- * <div class="alert alert-warning">
- * **Warning:** Be careful not to cause "double-submission" by using both the `ngClick` and
- * `ngSubmit` handlers together. See the
- * {@link form#submitting-a-form-and-preventing-the-default-action `form` directive documentation}
- * for a detailed discussion of when `ngSubmit` may be triggered.
- * </div>
- *
- * @element form
- * @priority 0
- * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
- * ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example module="submitExample" name="ng-submit">
-     <file name="index.html">
-      <script>
-        angular.module('submitExample', [])
-          .controller('ExampleController', ['$scope', function($scope) {
-            $scope.list = [];
-            $scope.text = 'hello';
-            $scope.submit = function() {
-              if ($scope.text) {
-                $scope.list.push(this.text);
-                $scope.text = '';
-              }
-            };
-          }]);
-      </script>
-      <form ng-submit="submit()" ng-controller="ExampleController">
-        Enter text and hit enter:
-        <input type="text" ng-model="text" name="text" />
-        <input type="submit" id="submit" value="Submit" />
-        <pre>list={{list}}</pre>
-      </form>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should check ng-submit', function() {
-         expect(element(by.binding('list')).getText()).toBe('list=[]');
-         element(by.css('#submit')).click();
-         expect(element(by.binding('list')).getText()).toContain('hello');
-         expect(element(by.model('text')).getAttribute('value')).toBe('');
-       });
-       it('should ignore empty strings', function() {
-         expect(element(by.binding('list')).getText()).toBe('list=[]');
-         element(by.css('#submit')).click();
-         element(by.css('#submit')).click();
-         expect(element(by.binding('list')).getText()).toContain('hello');
-        });
-     </file>
-   </example>
- */
-
-/**
- * @ngdoc directive
- * @name ngFocus
- *
- * @description
- * Specify custom behavior on focus event.
- *
- * Note: As the `focus` event is executed synchronously when calling `input.focus()`
- * AngularJS executes the expression using `scope.$evalAsync` if the event is fired
- * during an `$apply` to ensure a consistent state.
- *
- * @element window, input, select, textarea, a
- * @priority 0
- * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon
- * focus. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
- * See {@link ng.directive:ngClick ngClick}
- */
-
-/**
- * @ngdoc directive
- * @name ngBlur
- *
- * @description
- * Specify custom behavior on blur event.
- *
- * A [blur event](https://developer.mozilla.org/en-US/docs/Web/Events/blur) fires when
- * an element has lost focus.
- *
- * Note: As the `blur` event is executed synchronously also during DOM manipulations
- * (e.g. removing a focussed input),
- * AngularJS executes the expression using `scope.$evalAsync` if the event is fired
- * during an `$apply` to ensure a consistent state.
- *
- * @element window, input, select, textarea, a
- * @priority 0
- * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon
- * blur. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
- * See {@link ng.directive:ngClick ngClick}
- */
-
-/**
- * @ngdoc directive
- * @name ngCopy
- *
- * @description
- * Specify custom behavior on copy event.
- *
- * @element window, input, select, textarea, a
- * @priority 0
- * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon
- * copy. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-copy">
-     <file name="index.html">
-      <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value">
-      copied: {{copied}}
-     </file>
-   </example>
- */
-
-/**
- * @ngdoc directive
- * @name ngCut
- *
- * @description
- * Specify custom behavior on cut event.
- *
- * @element window, input, select, textarea, a
- * @priority 0
- * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon
- * cut. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-cut">
-     <file name="index.html">
-      <input ng-cut="cut=true" ng-init="cut=false; value='cut me'" ng-model="value">
-      cut: {{cut}}
-     </file>
-   </example>
- */
-
-/**
- * @ngdoc directive
- * @name ngPaste
- *
- * @description
- * Specify custom behavior on paste event.
- *
- * @element window, input, select, textarea, a
- * @priority 0
- * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon
- * paste. ({@link guide/expression#-event- Event object is available as `$event`})
- *
- * @example
-   <example name="ng-paste">
-     <file name="index.html">
-      <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'>
-      pasted: {{paste}}
-     </file>
-   </example>
- */
-
-/**
- * @ngdoc directive
- * @name ngIf
- * @restrict A
- * @multiElement
- *
- * @description
- * The `ngIf` directive removes or recreates a portion of the DOM tree based on an
- * {expression}. If the expression assigned to `ngIf` evaluates to a false
- * value then the element is removed from the DOM, otherwise a clone of the
- * element is reinserted into the DOM.
- *
- * `ngIf` differs from `ngShow` and `ngHide` in that `ngIf` completely removes and recreates the
- * element in the DOM rather than changing its visibility via the `display` css property.  A common
- * case when this difference is significant is when using css selectors that rely on an element's
- * position within the DOM, such as the `:first-child` or `:last-child` pseudo-classes.
- *
- * Note that when an element is removed using `ngIf` its scope is destroyed and a new scope
- * is created when the element is restored.  The scope created within `ngIf` inherits from
- * its parent scope using
- * [prototypal inheritance](https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance).
- * An important implication of this is if `ngModel` is used within `ngIf` to bind to
- * a javascript primitive defined in the parent scope. In this case any modifications made to the
- * variable within the child scope will override (hide) the value in the parent scope.
- *
- * Also, `ngIf` recreates elements using their compiled state. An example of this behavior
- * is if an element's class attribute is directly modified after it's compiled, using something like
- * jQuery's `.addClass()` method, and the element is later removed. When `ngIf` recreates the element
- * the added class will be lost because the original compiled state is used to regenerate the element.
- *
- * Additionally, you can provide animations via the `ngAnimate` module to animate the `enter`
- * and `leave` effects.
- *
- * @animations
- * | Animation                        | Occurs                               |
- * |----------------------------------|-------------------------------------|
- * | {@link ng.$animate#enter enter}  | just after the `ngIf` contents change and a new DOM element is created and injected into the `ngIf` container |
- * | {@link ng.$animate#leave leave}  | just before the `ngIf` contents are removed from the DOM |
- *
- * @element ANY
- * @scope
- * @priority 600
- * @param {expression} ngIf If the {@link guide/expression expression} is falsy then
- *     the element is removed from the DOM tree. If it is truthy a copy of the compiled
- *     element is added to the DOM tree.
- *
- * @example
-  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-if">
-    <file name="index.html">
-      <label>Click me: <input type="checkbox" ng-model="checked" ng-init="checked=true" /></label><br/>
-      Show when checked:
-      <span ng-if="checked" class="animate-if">
-        This is removed when the checkbox is unchecked.
-      </span>
-    </file>
-    <file name="animations.css">
-      .animate-if {
-        background:white;
-        border:1px solid black;
-        padding:10px;
-      }
-
-      .animate-if.ng-enter, .animate-if.ng-leave {
-        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-      }
-
-      .animate-if.ng-enter,
-      .animate-if.ng-leave.ng-leave-active {
-        opacity:0;
-      }
-
-      .animate-if.ng-leave,
-      .animate-if.ng-enter.ng-enter-active {
-        opacity:1;
-      }
-    </file>
-  </example>
- */
-var ngIfDirective = ['$animate', '$compile', function($animate, $compile) {
-  return {
-    multiElement: true,
-    transclude: 'element',
-    priority: 600,
-    terminal: true,
-    restrict: 'A',
-    $$tlb: true,
-    link: function($scope, $element, $attr, ctrl, $transclude) {
-        var block, childScope, previousElements;
-        $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
-
-          if (value) {
-            if (!childScope) {
-              $transclude(function(clone, newScope) {
-                childScope = newScope;
-                clone[clone.length++] = $compile.$$createComment('end ngIf', $attr.ngIf);
-                // Note: We only need the first/last node of the cloned nodes.
-                // However, we need to keep the reference to the jqlite wrapper as it might be changed later
-                // by a directive with templateUrl when its template arrives.
-                block = {
-                  clone: clone
-                };
-                $animate.enter(clone, $element.parent(), $element);
-              });
-            }
-          } else {
-            if (previousElements) {
-              previousElements.remove();
-              previousElements = null;
-            }
-            if (childScope) {
-              childScope.$destroy();
-              childScope = null;
-            }
-            if (block) {
-              previousElements = getBlockNodes(block.clone);
-              $animate.leave(previousElements).done(function(response) {
-                if (response !== false) previousElements = null;
-              });
-              block = null;
-            }
-          }
-        });
-    }
-  };
-}];
-
-/**
- * @ngdoc directive
- * @name ngInclude
- * @restrict ECA
- *
- * @description
- * Fetches, compiles and includes an external HTML fragment.
- *
- * By default, the template URL is restricted to the same domain and protocol as the
- * application document. This is done by calling {@link $sce#getTrustedResourceUrl
- * $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols
- * you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or
- * {@link $sce#trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link
- * ng.$sce Strict Contextual Escaping}.
- *
- * In addition, the browser's
- * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)
- * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)
- * policy may further restrict whether the template is successfully loaded.
- * For example, `ngInclude` won't work for cross-domain requests on all browsers and for `file://`
- * access on some browsers.
- *
- * @animations
- * | Animation                        | Occurs                              |
- * |----------------------------------|-------------------------------------|
- * | {@link ng.$animate#enter enter}  | when the expression changes, on the new include |
- * | {@link ng.$animate#leave leave}  | when the expression changes, on the old include |
- *
- * The enter and leave animation occur concurrently.
- *
- * @scope
- * @priority 400
- *
- * @param {string} ngInclude|src angular expression evaluating to URL. If the source is a string constant,
- *                 make sure you wrap it in **single** quotes, e.g. `src="'myPartialTemplate.html'"`.
- * @param {string=} onload Expression to evaluate when a new partial is loaded.
- *                  <div class="alert alert-warning">
- *                  **Note:** When using onload on SVG elements in IE11, the browser will try to call
- *                  a function with the name on the window element, which will usually throw a
- *                  "function is undefined" error. To fix this, you can instead use `data-onload` or a
- *                  different form that {@link guide/directive#normalization matches} `onload`.
- *                  </div>
-   *
- * @param {string=} autoscroll Whether `ngInclude` should call {@link ng.$anchorScroll
- *                  $anchorScroll} to scroll the viewport after the content is loaded.
- *
- *                  - If the attribute is not set, disable scrolling.
- *                  - If the attribute is set without value, enable scrolling.
- *                  - Otherwise enable scrolling only if the expression evaluates to truthy value.
- *
- * @example
-  <example module="includeExample" deps="angular-animate.js" animations="true" name="ng-include">
-    <file name="index.html">
-     <div ng-controller="ExampleController">
-       <select ng-model="template" ng-options="t.name for t in templates">
-        <option value="">(blank)</option>
-       </select>
-       url of the template: <code>{{template.url}}</code>
-       <hr/>
-       <div class="slide-animate-container">
-         <div class="slide-animate" ng-include="template.url"></div>
-       </div>
-     </div>
-    </file>
-    <file name="script.js">
-      angular.module('includeExample', ['ngAnimate'])
-        .controller('ExampleController', ['$scope', function($scope) {
-          $scope.templates =
-            [{ name: 'template1.html', url: 'template1.html'},
-             { name: 'template2.html', url: 'template2.html'}];
-          $scope.template = $scope.templates[0];
-        }]);
-     </file>
-    <file name="template1.html">
-      Content of template1.html
-    </file>
-    <file name="template2.html">
-      Content of template2.html
-    </file>
-    <file name="animations.css">
-      .slide-animate-container {
-        position:relative;
-        background:white;
-        border:1px solid black;
-        height:40px;
-        overflow:hidden;
-      }
-
-      .slide-animate {
-        padding:10px;
-      }
-
-      .slide-animate.ng-enter, .slide-animate.ng-leave {
-        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-
-        position:absolute;
-        top:0;
-        left:0;
-        right:0;
-        bottom:0;
-        display:block;
-        padding:10px;
-      }
-
-      .slide-animate.ng-enter {
-        top:-50px;
-      }
-      .slide-animate.ng-enter.ng-enter-active {
-        top:0;
-      }
-
-      .slide-animate.ng-leave {
-        top:0;
-      }
-      .slide-animate.ng-leave.ng-leave-active {
-        top:50px;
-      }
-    </file>
-    <file name="protractor.js" type="protractor">
-      var templateSelect = element(by.model('template'));
-      var includeElem = element(by.css('[ng-include]'));
-
-      it('should load template1.html', function() {
-        expect(includeElem.getText()).toMatch(/Content of template1.html/);
-      });
-
-      it('should load template2.html', function() {
-        if (browser.params.browser === 'firefox') {
-          // Firefox can't handle using selects
-          // See https://github.com/angular/protractor/issues/480
-          return;
-        }
-        templateSelect.click();
-        templateSelect.all(by.css('option')).get(2).click();
-        expect(includeElem.getText()).toMatch(/Content of template2.html/);
-      });
-
-      it('should change to blank', function() {
-        if (browser.params.browser === 'firefox') {
-          // Firefox can't handle using selects
-          return;
-        }
-        templateSelect.click();
-        templateSelect.all(by.css('option')).get(0).click();
-        expect(includeElem.isPresent()).toBe(false);
-      });
-    </file>
-  </example>
- */
-
-
-/**
- * @ngdoc event
- * @name ngInclude#$includeContentRequested
- * @eventType emit on the scope ngInclude was declared in
- * @description
- * Emitted every time the ngInclude content is requested.
- *
- * @param {Object} angularEvent Synthetic event object.
- * @param {String} src URL of content to load.
- */
-
-
-/**
- * @ngdoc event
- * @name ngInclude#$includeContentLoaded
- * @eventType emit on the current ngInclude scope
- * @description
- * Emitted every time the ngInclude content is reloaded.
- *
- * @param {Object} angularEvent Synthetic event object.
- * @param {String} src URL of content to load.
- */
-
-
-/**
- * @ngdoc event
- * @name ngInclude#$includeContentError
- * @eventType emit on the scope ngInclude was declared in
- * @description
- * Emitted when a template HTTP request yields an erroneous response (status < 200 || status > 299)
- *
- * @param {Object} angularEvent Synthetic event object.
- * @param {String} src URL of content to load.
- */
-var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate',
-                  function($templateRequest,   $anchorScroll,   $animate) {
-  return {
-    restrict: 'ECA',
-    priority: 400,
-    terminal: true,
-    transclude: 'element',
-    controller: angular.noop,
-    compile: function(element, attr) {
-      var srcExp = attr.ngInclude || attr.src,
-          onloadExp = attr.onload || '',
-          autoScrollExp = attr.autoscroll;
-
-      return function(scope, $element, $attr, ctrl, $transclude) {
-        var changeCounter = 0,
-            currentScope,
-            previousElement,
-            currentElement;
-
-        var cleanupLastIncludeContent = function() {
-          if (previousElement) {
-            previousElement.remove();
-            previousElement = null;
-          }
-          if (currentScope) {
-            currentScope.$destroy();
-            currentScope = null;
-          }
-          if (currentElement) {
-            $animate.leave(currentElement).done(function(response) {
-              if (response !== false) previousElement = null;
-            });
-            previousElement = currentElement;
-            currentElement = null;
-          }
-        };
-
-        scope.$watch(srcExp, function ngIncludeWatchAction(src) {
-          var afterAnimation = function(response) {
-            if (response !== false && isDefined(autoScrollExp) &&
-              (!autoScrollExp || scope.$eval(autoScrollExp))) {
-                $anchorScroll();
-            }
-          };
-          var thisChangeId = ++changeCounter;
-
-          if (src) {
-            //set the 2nd param to true to ignore the template request error so that the inner
-            //contents and scope can be cleaned up.
-            $templateRequest(src, true).then(function(response) {
-              if (scope.$$destroyed) return;
-
-              if (thisChangeId !== changeCounter) return;
-              var newScope = scope.$new();
-              ctrl.template = response;
-
-              // Note: This will also link all children of ng-include that were contained in the original
-              // html. If that content contains controllers, ... they could pollute/change the scope.
-              // However, using ng-include on an element with additional content does not make sense...
-              // Note: We can't remove them in the cloneAttchFn of $transclude as that
-              // function is called before linking the content, which would apply child
-              // directives to non existing elements.
-              var clone = $transclude(newScope, function(clone) {
-                cleanupLastIncludeContent();
-                $animate.enter(clone, null, $element).done(afterAnimation);
-              });
-
-              currentScope = newScope;
-              currentElement = clone;
-
-              currentScope.$emit('$includeContentLoaded', src);
-              scope.$eval(onloadExp);
-            }, function() {
-              if (scope.$$destroyed) return;
-
-              if (thisChangeId === changeCounter) {
-                cleanupLastIncludeContent();
-                scope.$emit('$includeContentError', src);
-              }
-            });
-            scope.$emit('$includeContentRequested', src);
-          } else {
-            cleanupLastIncludeContent();
-            ctrl.template = null;
-          }
-        });
-      };
-    }
-  };
-}];
-
-// This directive is called during the $transclude call of the first `ngInclude` directive.
-// It will replace and compile the content of the element with the loaded template.
-// We need this directive so that the element content is already filled when
-// the link function of another directive on the same element as ngInclude
-// is called.
-var ngIncludeFillContentDirective = ['$compile',
-  function($compile) {
-    return {
-      restrict: 'ECA',
-      priority: -400,
-      require: 'ngInclude',
-      link: function(scope, $element, $attr, ctrl) {
-        if (toString.call($element[0]).match(/SVG/)) {
-          // WebKit: https://bugs.webkit.org/show_bug.cgi?id=135698 --- SVG elements do not
-          // support innerHTML, so detect this here and try to generate the contents
-          // specially.
-          $element.empty();
-          $compile(jqLiteBuildFragment(ctrl.template, window.document).childNodes)(scope,
-              function namespaceAdaptedClone(clone) {
-            $element.append(clone);
-          }, {futureParentElement: $element});
-          return;
-        }
-
-        $element.html(ctrl.template);
-        $compile($element.contents())(scope);
-      }
-    };
-  }];
-
-/**
- * @ngdoc directive
- * @name ngInit
- * @restrict AC
- *
- * @description
- * The `ngInit` directive allows you to evaluate an expression in the
- * current scope.
- *
- * <div class="alert alert-danger">
- * This directive can be abused to add unnecessary amounts of logic into your templates.
- * There are only a few appropriate uses of `ngInit`, such as for aliasing special properties of
- * {@link ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below; and for injecting data via
- * server side scripting. Besides these few cases, you should use {@link guide/controller controllers}
- * rather than `ngInit` to initialize values on a scope.
- * </div>
- *
- * <div class="alert alert-warning">
- * **Note**: If you have assignment in `ngInit` along with a {@link ng.$filter `filter`}, make
- * sure you have parentheses to ensure correct operator precedence:
- * <pre class="prettyprint">
- * `<div ng-init="test1 = ($index | toString)"></div>`
- * </pre>
- * </div>
- *
- * @priority 450
- *
- * @element ANY
- * @param {expression} ngInit {@link guide/expression Expression} to eval.
- *
- * @example
-   <example module="initExample" name="ng-init">
-     <file name="index.html">
-   <script>
-     angular.module('initExample', [])
-       .controller('ExampleController', ['$scope', function($scope) {
-         $scope.list = [['a', 'b'], ['c', 'd']];
-       }]);
-   </script>
-   <div ng-controller="ExampleController">
-     <div ng-repeat="innerList in list" ng-init="outerIndex = $index">
-       <div ng-repeat="value in innerList" ng-init="innerIndex = $index">
-          <span class="example-init">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>
-       </div>
-     </div>
-   </div>
-     </file>
-     <file name="protractor.js" type="protractor">
-       it('should alias index positions', function() {
-         var elements = element.all(by.css('.example-init'));
-         expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');
-         expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');
-         expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');
-         expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');
-       });
-     </file>
-   </example>
- */
-var ngInitDirective = ngDirective({
-  priority: 450,
-  compile: function() {
-    return {
-      pre: function(scope, element, attrs) {
-        scope.$eval(attrs.ngInit);
-      }
-    };
-  }
-});
-
-/**
- * @ngdoc directive
- * @name ngList
- *
- * @description
- * Text input that converts between a delimited string and an array of strings. The default
- * delimiter is a comma followed by a space - equivalent to `ng-list=", "`. You can specify a custom
- * delimiter as the value of the `ngList` attribute - for example, `ng-list=" | "`.
- *
- * The behaviour of the directive is affected by the use of the `ngTrim` attribute.
- * * If `ngTrim` is set to `"false"` then whitespace around both the separator and each
- *   list item is respected. This implies that the user of the directive is responsible for
- *   dealing with whitespace but also allows you to use whitespace as a delimiter, such as a
- *   tab or newline character.
- * * Otherwise whitespace around the delimiter is ignored when splitting (although it is respected
- *   when joining the list items back together) and whitespace around each list item is stripped
- *   before it is added to the model.
- *
- * ### Example with Validation
- *
- * <example name="ngList-directive" module="listExample">
- *   <file name="app.js">
- *      angular.module('listExample', [])
- *        .controller('ExampleController', ['$scope', function($scope) {
- *          $scope.names = ['morpheus', 'neo', 'trinity'];
- *        }]);
- *   </file>
- *   <file name="index.html">
- *    <form name="myForm" ng-controller="ExampleController">
- *      <label>List: <input name="namesInput" ng-model="names" ng-list required></label>
- *      <span role="alert">
- *        <span class="error" ng-show="myForm.namesInput.$error.required">
- *        Required!</span>
- *      </span>
- *      <br>
- *      <tt>names = {{names}}</tt><br/>
- *      <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
- *      <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
- *      <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
- *      <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
- *     </form>
- *   </file>
- *   <file name="protractor.js" type="protractor">
- *     var listInput = element(by.model('names'));
- *     var names = element(by.exactBinding('names'));
- *     var valid = element(by.binding('myForm.namesInput.$valid'));
- *     var error = element(by.css('span.error'));
- *
- *     it('should initialize to model', function() {
- *       expect(names.getText()).toContain('["morpheus","neo","trinity"]');
- *       expect(valid.getText()).toContain('true');
- *       expect(error.getCssValue('display')).toBe('none');
- *     });
- *
- *     it('should be invalid if empty', function() {
- *       listInput.clear();
- *       listInput.sendKeys('');
- *
- *       expect(names.getText()).toContain('');
- *       expect(valid.getText()).toContain('false');
- *       expect(error.getCssValue('display')).not.toBe('none');
- *     });
- *   </file>
- * </example>
- *
- * ### Example - splitting on newline
- * <example name="ngList-directive-newlines">
- *   <file name="index.html">
- *    <textarea ng-model="list" ng-list="&#10;" ng-trim="false"></textarea>
- *    <pre>{{ list | json }}</pre>
- *   </file>
- *   <file name="protractor.js" type="protractor">
- *     it("should split the text by newlines", function() {
- *       var listInput = element(by.model('list'));
- *       var output = element(by.binding('list | json'));
- *       listInput.sendKeys('abc\ndef\nghi');
- *       expect(output.getText()).toContain('[\n  "abc",\n  "def",\n  "ghi"\n]');
- *     });
- *   </file>
- * </example>
- *
- * @element input
- * @param {string=} ngList optional delimiter that should be used to split the value.
- */
-var ngListDirective = function() {
-  return {
-    restrict: 'A',
-    priority: 100,
-    require: 'ngModel',
-    link: function(scope, element, attr, ctrl) {
-      var ngList = attr.ngList || ', ';
-      var trimValues = attr.ngTrim !== 'false';
-      var separator = trimValues ? trim(ngList) : ngList;
-
-      var parse = function(viewValue) {
-        // If the viewValue is invalid (say required but empty) it will be `undefined`
-        if (isUndefined(viewValue)) return;
-
-        var list = [];
-
-        if (viewValue) {
-          forEach(viewValue.split(separator), function(value) {
-            if (value) list.push(trimValues ? trim(value) : value);
-          });
-        }
-
-        return list;
-      };
-
-      ctrl.$parsers.push(parse);
-      ctrl.$formatters.push(function(value) {
-        if (isArray(value)) {
-          return value.join(ngList);
-        }
-
-        return undefined;
-      });
-
-      // Override the standard $isEmpty because an empty array means the input is empty.
-      ctrl.$isEmpty = function(value) {
-        return !value || !value.length;
-      };
-    }
-  };
-};
-
-/* global VALID_CLASS: true,
-  INVALID_CLASS: true,
-  PRISTINE_CLASS: true,
-  DIRTY_CLASS: true,
-  UNTOUCHED_CLASS: true,
-  TOUCHED_CLASS: true,
-  PENDING_CLASS: true,
-  addSetValidityMethod: true,
-  setupValidity: true,
-  defaultModelOptions: false
-*/
-
-
-var VALID_CLASS = 'ng-valid',
-    INVALID_CLASS = 'ng-invalid',
-    PRISTINE_CLASS = 'ng-pristine',
-    DIRTY_CLASS = 'ng-dirty',
-    UNTOUCHED_CLASS = 'ng-untouched',
-    TOUCHED_CLASS = 'ng-touched',
-    EMPTY_CLASS = 'ng-empty',
-    NOT_EMPTY_CLASS = 'ng-not-empty';
-
-var ngModelMinErr = minErr('ngModel');
-
-/**
- * @ngdoc type
- * @name ngModel.NgModelController
- *
- * @property {*} $viewValue The actual value from the control's view. For `input` elements, this is a
- * String. See {@link ngModel.NgModelController#$setViewValue} for information about when the $viewValue
- * is set.
- *
- * @property {*} $modelValue The value in the model that the control is bound to.
- *
- * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
- *  the control updates the ngModelController with a new {@link ngModel.NgModelController#$viewValue
-    `$viewValue`} from the DOM, usually via user input.
-    See {@link ngModel.NgModelController#$setViewValue `$setViewValue()`} for a detailed lifecycle explanation.
-    Note that the `$parsers` are not called when the bound ngModel expression changes programmatically.
-
-  The functions are called in array order, each passing
-    its return value through to the next. The last return value is forwarded to the
-    {@link ngModel.NgModelController#$validators `$validators`} collection.
-
-  Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue
-    `$viewValue`}.
-
-  Returning `undefined` from a parser means a parse error occurred. In that case,
-    no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel`
-    will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`}
-    is set to `true`. The parse error is stored in `ngModel.$error.parse`.
-
-  This simple example shows a parser that would convert text input value to lowercase:
- * ```js
- * function parse(value) {
- *   if (value) {
- *     return value.toLowerCase();
- *   }
- * }
- * ngModelController.$parsers.push(parse);
- * ```
-
- *
- * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
-    the bound ngModel expression changes programmatically. The `$formatters` are not called when the
-    value of the control is changed by user interaction.
-
-  Formatters are used to format / convert the {@link ngModel.NgModelController#$modelValue
-    `$modelValue`} for display in the control.
-
-  The functions are called in reverse array order, each passing the value through to the
-    next. The last return value is used as the actual DOM value.
-
-  This simple example shows a formatter that would convert the model value to uppercase:
-
- * ```js
- * function format(value) {
- *   if (value) {
- *     return value.toUpperCase();
- *   }
- * }
- * ngModel.$formatters.push(format);
- * ```
- *
- * @property {Object.<string, function>} $validators A collection of validators that are applied
- *      whenever the model value changes. The key value within the object refers to the name of the
- *      validator while the function refers to the validation operation. The validation operation is
- *      provided with the model value as an argument and must return a true or false value depending
- *      on the response of that validation.
- *
- * ```js
- * ngModel.$validators.validCharacters = function(modelValue, viewValue) {
- *   var value = modelValue || viewValue;
- *   return /[0-9]+/.test(value) &&
- *          /[a-z]+/.test(value) &&
- *          /[A-Z]+/.test(value) &&
- *          /\W+/.test(value);
- * };
- * ```
- *
- * @property {Object.<string, function>} $asyncValidators A collection of validations that are expected to
- *      perform an asynchronous validation (e.g. a HTTP request). The validation function that is provided
- *      is expected to return a promise when it is run during the model validation process. Once the promise
- *      is delivered then the validation status will be set to true when fulfilled and false when rejected.
- *      When the asynchronous validators are triggered, each of the validators will run in parallel and the model
- *      value will only be updated once all validators have been fulfilled. As long as an asynchronous validator
- *      is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators
- *      will only run once all synchronous validators have passed.
- *
- * Please note that if $http is used then it is important that the server returns a success HTTP response code
- * in order to fulfill the validation and a status level of `4xx` in order to reject the validation.
- *
- * ```js
- * ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
- *   var value = modelValue || viewValue;
- *
- *   // Lookup user by username
- *   return $http.get('/api/users/' + value).
- *      then(function resolved() {
- *        //username exists, this means validation fails
- *        return $q.reject('exists');
- *      }, function rejected() {
- *        //username does not exist, therefore this validation passes
- *        return true;
- *      });
- * };
- * ```
- *
- * @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the
- *     view value has changed. It is called with no arguments, and its return value is ignored.
- *     This can be used in place of additional $watches against the model value.
- *
- * @property {Object} $error An object hash with all failing validator ids as keys.
- * @property {Object} $pending An object hash with all pending validator ids as keys.
- *
- * @property {boolean} $untouched True if control has not lost focus yet.
- * @property {boolean} $touched True if control has lost focus.
- * @property {boolean} $pristine True if user has not interacted with the control yet.
- * @property {boolean} $dirty True if user has already interacted with the control.
- * @property {boolean} $valid True if there is no error.
- * @property {boolean} $invalid True if at least one error on the control.
- * @property {string} $name The name attribute of the control.
- *
- * @description
- *
- * `NgModelController` provides API for the {@link ngModel `ngModel`} directive.
- * The controller contains services for data-binding, validation, CSS updates, and value formatting
- * and parsing. It purposefully does not contain any logic which deals with DOM rendering or
- * listening to DOM events.
- * Such DOM related logic should be provided by other directives which make use of
- * `NgModelController` for data-binding to control elements.
- * Angular provides this DOM logic for most {@link input `input`} elements.
- * At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example
- * custom control example} that uses `ngModelController` to bind to `contenteditable` elements.
- *
- * @example
- * ### Custom Control Example
- * This example shows how to use `NgModelController` with a custom control to achieve
- * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
- * collaborate together to achieve the desired result.
- *
- * `contenteditable` is an HTML5 attribute, which tells the browser to let the element
- * contents be edited in place by the user.
- *
- * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}
- * module to automatically remove "bad" content like inline event listener (e.g. `<span onclick="...">`).
- * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks
- * that content using the `$sce` service.
- *
- * <example name="NgModelController" module="customControl" deps="angular-sanitize.js">
-    <file name="style.css">
-      [contenteditable] {
-        border: 1px solid black;
-        background-color: white;
-        min-height: 20px;
-      }
-
-      .ng-invalid {
-        border: 1px solid red;
-      }
-
-    </file>
-    <file name="script.js">
-      angular.module('customControl', ['ngSanitize']).
-        directive('contenteditable', ['$sce', function($sce) {
-          return {
-            restrict: 'A', // only activate on element attribute
-            require: '?ngModel', // get a hold of NgModelController
-            link: function(scope, element, attrs, ngModel) {
-              if (!ngModel) return; // do nothing if no ng-model
-
-              // Specify how UI should be updated
-              ngModel.$render = function() {
-                element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
-              };
-
-              // Listen for change events to enable binding
-              element.on('blur keyup change', function() {
-                scope.$evalAsync(read);
-              });
-              read(); // initialize
-
-              // Write data to the model
-              function read() {
-                var html = element.html();
-                // When we clear the content editable the browser leaves a <br> behind
-                // If strip-br attribute is provided then we strip this out
-                if (attrs.stripBr && html === '<br>') {
-                  html = '';
-                }
-                ngModel.$setViewValue(html);
-              }
-            }
-          };
-        }]);
-    </file>
-    <file name="index.html">
-      <form name="myForm">
-       <div contenteditable
-            name="myWidget" ng-model="userContent"
-            strip-br="true"
-            required>Change me!</div>
-        <span ng-show="myForm.myWidget.$error.required">Required!</span>
-       <hr>
-       <textarea ng-model="userContent" aria-label="Dynamic textarea"></textarea>
-      </form>
-    </file>
-    <file name="protractor.js" type="protractor">
-    it('should data-bind and become invalid', function() {
-      if (browser.params.browser === 'safari' || browser.params.browser === 'firefox') {
-        // SafariDriver can't handle contenteditable
-        // and Firefox driver can't clear contenteditables very well
-        return;
-      }
-      var contentEditable = element(by.css('[contenteditable]'));
-      var content = 'Change me!';
-
-      expect(contentEditable.getText()).toEqual(content);
-
-      contentEditable.clear();
-      contentEditable.sendKeys(protractor.Key.BACK_SPACE);
-      expect(contentEditable.getText()).toEqual('');
-      expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);
-    });
-    </file>
- * </example>
- *
- *
- */
-NgModelController.$inject = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$q', '$interpolate'];
-function NgModelController($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $q, $interpolate) {
-  this.$viewValue = Number.NaN;
-  this.$modelValue = Number.NaN;
-  this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.
-  this.$validators = {};
-  this.$asyncValidators = {};
-  this.$parsers = [];
-  this.$formatters = [];
-  this.$viewChangeListeners = [];
-  this.$untouched = true;
-  this.$touched = false;
-  this.$pristine = true;
-  this.$dirty = false;
-  this.$valid = true;
-  this.$invalid = false;
-  this.$error = {}; // keep invalid keys here
-  this.$$success = {}; // keep valid keys here
-  this.$pending = undefined; // keep pending keys here
-  this.$name = $interpolate($attr.name || '', false)($scope);
-  this.$$parentForm = nullFormCtrl;
-  this.$options = defaultModelOptions;
-
-  this.$$parsedNgModel = $parse($attr.ngModel);
-  this.$$parsedNgModelAssign = this.$$parsedNgModel.assign;
-  this.$$ngModelGet = this.$$parsedNgModel;
-  this.$$ngModelSet = this.$$parsedNgModelAssign;
-  this.$$pendingDebounce = null;
-  this.$$parserValid = undefined;
-
-  this.$$currentValidationRunId = 0;
-
-  this.$$scope = $scope;
-  this.$$attr = $attr;
-  this.$$element = $element;
-  this.$$animate = $animate;
-  this.$$timeout = $timeout;
-  this.$$parse = $parse;
-  this.$$q = $q;
-  this.$$exceptionHandler = $exceptionHandler;
-
-  setupValidity(this);
-  setupModelWatcher(this);
-}
-
-NgModelController.prototype = {
-  $$initGetterSetters: function() {
-    if (this.$options.getOption('getterSetter')) {
-      var invokeModelGetter = this.$$parse(this.$$attr.ngModel + '()'),
-          invokeModelSetter = this.$$parse(this.$$attr.ngModel + '($$$p)');
-
-      this.$$ngModelGet = function($scope) {
-        var modelValue = this.$$parsedNgModel($scope);
-        if (isFunction(modelValue)) {
-          modelValue = invokeModelGetter($scope);
-        }
-        return modelValue;
-      };
-      this.$$ngModelSet = function($scope, newValue) {
-        if (isFunction(this.$$parsedNgModel($scope))) {
-          invokeModelSetter($scope, {$$$p: newValue});
-        } else {
-          this.$$parsedNgModelAssign($scope, newValue);
-        }
-      };
-    } else if (!this.$$parsedNgModel.assign) {
-      throw ngModelMinErr('nonassign', 'Expression \'{0}\' is non-assignable. Element: {1}',
-          this.$$attr.ngModel, startingTag(this.$$element));
-    }
-  },
-
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$render
-   *
-   * @description
-   * Called when the view needs to be updated. It is expected that the user of the ng-model
-   * directive will implement this method.
-   *
-   * The `$render()` method is invoked in the following situations:
-   *
-   * * `$rollbackViewValue()` is called.  If we are rolling back the view value to the last
-   *   committed value then `$render()` is called to update the input control.
-   * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and
-   *   the `$viewValue` are different from last time.
-   *
-   * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of
-   * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue`
-   * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be
-   * invoked if you only change a property on the objects.
-   */
-  $render: noop,
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$isEmpty
-   *
-   * @description
-   * This is called when we need to determine if the value of an input is empty.
-   *
-   * For instance, the required directive does this to work out if the input has data or not.
-   *
-   * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`.
-   *
-   * You can override this for input directives whose concept of being empty is different from the
-   * default. The `checkboxInputType` directive does this because in its case a value of `false`
-   * implies empty.
-   *
-   * @param {*} value The value of the input to check for emptiness.
-   * @returns {boolean} True if `value` is "empty".
-   */
-  $isEmpty: function(value) {
-    // eslint-disable-next-line no-self-compare
-    return isUndefined(value) || value === '' || value === null || value !== value;
-  },
-
-  $$updateEmptyClasses: function(value) {
-    if (this.$isEmpty(value)) {
-      this.$$animate.removeClass(this.$$element, NOT_EMPTY_CLASS);
-      this.$$animate.addClass(this.$$element, EMPTY_CLASS);
-    } else {
-      this.$$animate.removeClass(this.$$element, EMPTY_CLASS);
-      this.$$animate.addClass(this.$$element, NOT_EMPTY_CLASS);
-    }
-  },
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$setPristine
-   *
-   * @description
-   * Sets the control to its pristine state.
-   *
-   * This method can be called to remove the `ng-dirty` class and set the control to its pristine
-   * state (`ng-pristine` class). A model is considered to be pristine when the control
-   * has not been changed from when first compiled.
-   */
-  $setPristine: function() {
-    this.$dirty = false;
-    this.$pristine = true;
-    this.$$animate.removeClass(this.$$element, DIRTY_CLASS);
-    this.$$animate.addClass(this.$$element, PRISTINE_CLASS);
-  },
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$setDirty
-   *
-   * @description
-   * Sets the control to its dirty state.
-   *
-   * This method can be called to remove the `ng-pristine` class and set the control to its dirty
-   * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed
-   * from when first compiled.
-   */
-  $setDirty: function() {
-    this.$dirty = true;
-    this.$pristine = false;
-    this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);
-    this.$$animate.addClass(this.$$element, DIRTY_CLASS);
-    this.$$parentForm.$setDirty();
-  },
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$setUntouched
-   *
-   * @description
-   * Sets the control to its untouched state.
-   *
-   * This method can be called to remove the `ng-touched` class and set the control to its
-   * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched
-   * by default, however this function can be used to restore that state if the model has
-   * already been touched by the user.
-   */
-  $setUntouched: function() {
-    this.$touched = false;
-    this.$untouched = true;
-    this.$$animate.setClass(this.$$element, UNTOUCHED_CLASS, TOUCHED_CLASS);
-  },
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$setTouched
-   *
-   * @description
-   * Sets the control to its touched state.
-   *
-   * This method can be called to remove the `ng-untouched` class and set the control to its
-   * touched state (`ng-touched` class). A model is considered to be touched when the user has
-   * first focused the control element and then shifted focus away from the control (blur event).
-   */
-  $setTouched: function() {
-    this.$touched = true;
-    this.$untouched = false;
-    this.$$animate.setClass(this.$$element, TOUCHED_CLASS, UNTOUCHED_CLASS);
-  },
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$rollbackViewValue
-   *
-   * @description
-   * Cancel an update and reset the input element's value to prevent an update to the `$modelValue`,
-   * which may be caused by a pending debounced event or because the input is waiting for some
-   * future event.
-   *
-   * If you have an input that uses `ng-model-options` to set up debounced updates or updates that
-   * depend on special events such as `blur`, there can be a period when the `$viewValue` is out of
-   * sync with the ngModel's `$modelValue`.
-   *
-   * In this case, you can use `$rollbackViewValue()` to manually cancel the debounced / future update
-   * and reset the input to the last committed view value.
-   *
-   * It is also possible that you run into difficulties if you try to update the ngModel's `$modelValue`
-   * programmatically before these debounced/future events have resolved/occurred, because Angular's
-   * dirty checking mechanism is not able to tell whether the model has actually changed or not.
-   *
-   * The `$rollbackViewValue()` method should be called before programmatically changing the model of an
-   * input which may have such events pending. This is important in order to make sure that the
-   * input field will be updated with the new model value and any pending operations are cancelled.
-   *
-   * <example name="ng-model-cancel-update" module="cancel-update-example">
-   *   <file name="app.js">
-   *     angular.module('cancel-update-example', [])
-   *
-   *     .controller('CancelUpdateController', ['$scope', function($scope) {
-   *       $scope.model = {value1: '', value2: ''};
-   *
-   *       $scope.setEmpty = function(e, value, rollback) {
-   *         if (e.keyCode === 27) {
-   *           e.preventDefault();
-   *           if (rollback) {
-   *             $scope.myForm[value].$rollbackViewValue();
-   *           }
-   *           $scope.model[value] = '';
-   *         }
-   *       };
-   *     }]);
-   *   </file>
-   *   <file name="index.html">
-   *     <div ng-controller="CancelUpdateController">
-   *       <p>Both of these inputs are only updated if they are blurred. Hitting escape should
-   *       empty them. Follow these steps and observe the difference:</p>
-   *       <ol>
-   *         <li>Type something in the input. You will see that the model is not yet updated</li>
-   *         <li>Press the Escape key.
-   *           <ol>
-   *             <li> In the first example, nothing happens, because the model is already '', and no
-   *             update is detected. If you blur the input, the model will be set to the current view.
-   *             </li>
-   *             <li> In the second example, the pending update is cancelled, and the input is set back
-   *             to the last committed view value (''). Blurring the input does nothing.
-   *             </li>
-   *           </ol>
-   *         </li>
-   *       </ol>
-   *
-   *       <form name="myForm" ng-model-options="{ updateOn: 'blur' }">
-   *         <div>
-   *           <p id="inputDescription1">Without $rollbackViewValue():</p>
-   *           <input name="value1" aria-describedby="inputDescription1" ng-model="model.value1"
-   *                  ng-keydown="setEmpty($event, 'value1')">
-   *           value1: "{{ model.value1 }}"
-   *         </div>
-   *
-   *         <div>
-   *           <p id="inputDescription2">With $rollbackViewValue():</p>
-   *           <input name="value2" aria-describedby="inputDescription2" ng-model="model.value2"
-   *                  ng-keydown="setEmpty($event, 'value2', true)">
-   *           value2: "{{ model.value2 }}"
-   *         </div>
-   *       </form>
-   *     </div>
-   *   </file>
-       <file name="style.css">
-          div {
-            display: table-cell;
-          }
-          div:nth-child(1) {
-            padding-right: 30px;
-          }
-
-        </file>
-   * </example>
-   */
-  $rollbackViewValue: function() {
-    this.$$timeout.cancel(this.$$pendingDebounce);
-    this.$viewValue = this.$$lastCommittedViewValue;
-    this.$render();
-  },
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$validate
-   *
-   * @description
-   * Runs each of the registered validators (first synchronous validators and then
-   * asynchronous validators).
-   * If the validity changes to invalid, the model will be set to `undefined`,
-   * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.
-   * If the validity changes to valid, it will set the model to the last available valid
-   * `$modelValue`, i.e. either the last parsed value or the last value set from the scope.
-   */
-  $validate: function() {
-    // ignore $validate before model is initialized
-    if (isNumberNaN(this.$modelValue)) {
-      return;
-    }
-
-    var viewValue = this.$$lastCommittedViewValue;
-    // Note: we use the $$rawModelValue as $modelValue might have been
-    // set to undefined during a view -> model update that found validation
-    // errors. We can't parse the view here, since that could change
-    // the model although neither viewValue nor the model on the scope changed
-    var modelValue = this.$$rawModelValue;
-
-    var prevValid = this.$valid;
-    var prevModelValue = this.$modelValue;
-
-    var allowInvalid = this.$options.getOption('allowInvalid');
-
-    var that = this;
-    this.$$runValidators(modelValue, viewValue, function(allValid) {
-      // If there was no change in validity, don't update the model
-      // This prevents changing an invalid modelValue to undefined
-      if (!allowInvalid && prevValid !== allValid) {
-        // Note: Don't check this.$valid here, as we could have
-        // external validators (e.g. calculated on the server),
-        // that just call $setValidity and need the model value
-        // to calculate their validity.
-        that.$modelValue = allValid ? modelValue : undefined;
-
-        if (that.$modelValue !== prevModelValue) {
-          that.$$writeModelToScope();
-        }
-      }
-    });
-  },
-
-  $$runValidators: function(modelValue, viewValue, doneCallback) {
-    this.$$currentValidationRunId++;
-    var localValidationRunId = this.$$currentValidationRunId;
-    var that = this;
-
-    // check parser error
-    if (!processParseErrors()) {
-      validationDone(false);
-      return;
-    }
-    if (!processSyncValidators()) {
-      validationDone(false);
-      return;
-    }
-    processAsyncValidators();
-
-    function processParseErrors() {
-      var errorKey = that.$$parserName || 'parse';
-      if (isUndefined(that.$$parserValid)) {
-        setValidity(errorKey, null);
-      } else {
-        if (!that.$$parserValid) {
-          forEach(that.$validators, function(v, name) {
-            setValidity(name, null);
-          });
-          forEach(that.$asyncValidators, function(v, name) {
-            setValidity(name, null);
-          });
-        }
-        // Set the parse error last, to prevent unsetting it, should a $validators key == parserName
-        setValidity(errorKey, that.$$parserValid);
-        return that.$$parserValid;
-      }
-      return true;
-    }
-
-    function processSyncValidators() {
-      var syncValidatorsValid = true;
-      forEach(that.$validators, function(validator, name) {
-        var result = Boolean(validator(modelValue, viewValue));
-        syncValidatorsValid = syncValidatorsValid && result;
-        setValidity(name, result);
-      });
-      if (!syncValidatorsValid) {
-        forEach(that.$asyncValidators, function(v, name) {
-          setValidity(name, null);
-        });
-        return false;
-      }
-      return true;
-    }
-
-    function processAsyncValidators() {
-      var validatorPromises = [];
-      var allValid = true;
-      forEach(that.$asyncValidators, function(validator, name) {
-        var promise = validator(modelValue, viewValue);
-        if (!isPromiseLike(promise)) {
-          throw ngModelMinErr('nopromise',
-            'Expected asynchronous validator to return a promise but got \'{0}\' instead.', promise);
-        }
-        setValidity(name, undefined);
-        validatorPromises.push(promise.then(function() {
-          setValidity(name, true);
-        }, function() {
-          allValid = false;
-          setValidity(name, false);
-        }));
-      });
-      if (!validatorPromises.length) {
-        validationDone(true);
-      } else {
-        that.$$q.all(validatorPromises).then(function() {
-          validationDone(allValid);
-        }, noop);
-      }
-    }
-
-    function setValidity(name, isValid) {
-      if (localValidationRunId === that.$$currentValidationRunId) {
-        that.$setValidity(name, isValid);
-      }
-    }
-
-    function validationDone(allValid) {
-      if (localValidationRunId === that.$$currentValidationRunId) {
-
-        doneCallback(allValid);
-      }
-    }
-  },
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$commitViewValue
-   *
-   * @description
-   * Commit a pending update to the `$modelValue`.
-   *
-   * Updates may be pending by a debounced event or because the input is waiting for a some future
-   * event defined in `ng-model-options`. this method is rarely needed as `NgModelController`
-   * usually handles calling this in response to input events.
-   */
-  $commitViewValue: function() {
-    var viewValue = this.$viewValue;
-
-    this.$$timeout.cancel(this.$$pendingDebounce);
-
-    // If the view value has not changed then we should just exit, except in the case where there is
-    // a native validator on the element. In this case the validation state may have changed even though
-    // the viewValue has stayed empty.
-    if (this.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !this.$$hasNativeValidators)) {
-      return;
-    }
-    this.$$updateEmptyClasses(viewValue);
-    this.$$lastCommittedViewValue = viewValue;
-
-    // change to dirty
-    if (this.$pristine) {
-      this.$setDirty();
-    }
-    this.$$parseAndValidate();
-  },
-
-  $$parseAndValidate: function() {
-    var viewValue = this.$$lastCommittedViewValue;
-    var modelValue = viewValue;
-    var that = this;
-
-    this.$$parserValid = isUndefined(modelValue) ? undefined : true;
-
-    if (this.$$parserValid) {
-      for (var i = 0; i < this.$parsers.length; i++) {
-        modelValue = this.$parsers[i](modelValue);
-        if (isUndefined(modelValue)) {
-          this.$$parserValid = false;
-          break;
-        }
-      }
-    }
-    if (isNumberNaN(this.$modelValue)) {
-      // this.$modelValue has not been touched yet...
-      this.$modelValue = this.$$ngModelGet(this.$$scope);
-    }
-    var prevModelValue = this.$modelValue;
-    var allowInvalid = this.$options.getOption('allowInvalid');
-    this.$$rawModelValue = modelValue;
-
-    if (allowInvalid) {
-      this.$modelValue = modelValue;
-      writeToModelIfNeeded();
-    }
-
-    // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.
-    // This can happen if e.g. $setViewValue is called from inside a parser
-    this.$$runValidators(modelValue, this.$$lastCommittedViewValue, function(allValid) {
-      if (!allowInvalid) {
-        // Note: Don't check this.$valid here, as we could have
-        // external validators (e.g. calculated on the server),
-        // that just call $setValidity and need the model value
-        // to calculate their validity.
-        that.$modelValue = allValid ? modelValue : undefined;
-        writeToModelIfNeeded();
-      }
-    });
-
-    function writeToModelIfNeeded() {
-      if (that.$modelValue !== prevModelValue) {
-        that.$$writeModelToScope();
-      }
-    }
-  },
-
-  $$writeModelToScope: function() {
-    this.$$ngModelSet(this.$$scope, this.$modelValue);
-    forEach(this.$viewChangeListeners, function(listener) {
-      try {
-        listener();
-      } catch (e) {
-        // eslint-disable-next-line no-invalid-this
-        this.$$exceptionHandler(e);
-      }
-    }, this);
-  },
-
-  /**
-   * @ngdoc method
-   * @name ngModel.NgModelController#$setViewValue
-   *
-   * @description
-   * Update the view value.
-   *
-   * This method should be called when a control wants to change the view value; typically,
-   * this is done from within a DOM event handler. For example, the {@link ng.directive:input input}
-   * directive calls it when the value of the input changes and {@link ng.directive:select select}
-   * calls it when an option is selected.
-   *
-   * When `$setViewValue` is called, the new `value` will be staged for committing through the `$parsers`
-   * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged
-   * value is sent directly for processing through the `$parsers` pipeline. After this, the `$validators` and
-   * `$asyncValidators` are called and the value is applied to `$modelValue`.
-   * Finally, the value is set to the **expression** specified in the `ng-model` attribute and
-   * all the registered change listeners, in the `$viewChangeListeners` list are called.
-   *
-   * In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn`
-   * and the `default` trigger is not listed, all those actions will remain pending until one of the
-   * `updateOn` events is triggered on the DOM element.
-   * All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions}
-   * directive is used with a custom debounce for this particular event.
-   * Note that a `$digest` is only triggered once the `updateOn` events are fired, or if `debounce`
-   * is specified, once the timer runs out.
-   *
-   * When used with standard inputs, the view value will always be a string (which is in some cases
-   * parsed into another type, such as a `Date` object for `input[date]`.)
-   * However, custom controls might also pass objects to this method. In this case, we should make
-   * a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not
-   * perform a deep watch of objects, it only looks for a change of identity. If you only change
-   * the property of the object then ngModel will not realize that the object has changed and
-   * will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should
-   * not change properties of the copy once it has been passed to `$setViewValue`.
-   * Otherwise you may cause the model value on the scope to change incorrectly.
-   *
-   * <div class="alert alert-info">
-   * In any case, the value passed to the method should always reflect the current value
-   * of the control. For example, if you are calling `$setViewValue` for an input element,
-   * you should pass the input DOM value. Otherwise, the control and the scope model become
-   * out of sync. It's also important to note that `$setViewValue` does not call `$render` or change
-   * the control's DOM value in any way. If we want to change the control's DOM value
-   * programmatically, we should update the `ngModel` scope expression. Its new value will be
-   * picked up by the model controller, which will run it through the `$formatters`, `$render` it
-   * to update the DOM, and finally call `$validate` on it.
-   * </div>
-   *
-   * @param {*} value value from the view.
-   * @param {string} trigger Event that triggered the update.
-   */
-  $setViewValue: function(value, trigger) {
-    this.$viewValue = value;
-    if (this.$options.getOption('updateOnDefault')) {
-      this.$$debounceViewValueCommit(trigger);
-    }
-  },
-
-  $$debounceViewValueCommit: function(trigger) {
-    var debounceDelay = this.$options.getOption('debounce');
-
-    if (isNumber(debounceDelay[trigger])) {
-      debounceDelay = debounceDelay[trigger];
-    } else if (isNumber(debounceDelay['default'])) {
-      debounceDelay = debounceDelay['default'];
-    }
-
-    this.$$timeout.cancel(this.$$pendingDebounce);
-    var that = this;
-    if (debounceDelay > 0) { // this fails if debounceDelay is an object
-      this.$$pendingDebounce = this.$$timeout(function() {
-        that.$commitViewValue();
-      }, debounceDelay);
-    } else if (this.$$scope.$root.$$phase) {
-      this.$commitViewValue();
-    } else {
-      this.$$scope.$apply(function() {
-        that.$commitViewValue();
-      });
-    }
-  },
-
-  /**
-   * @ngdoc method
-   *
-   * @name ngModel.NgModelController#$overrideModelOptions
-   *
-   * @description
-   *
-   * Override the current model options settings programmatically.
-   *
-   * The previous `ModelOptions` value will not be modified. Instead, a
-   * new `ModelOptions` object will inherit from the previous one overriding
-   * or inheriting settings that are defined in the given parameter.
-   *
-   * See {@link ngModelOptions} for information about what options can be specified
-   * and how model option inheritance works.
-   *
-   * @param {Object} options a hash of settings to override the previous options
-   *
-   */
-  $overrideModelOptions: function(options) {
-    this.$options = this.$options.createChild(options);
-  }
-};
-
-function setupModelWatcher(ctrl) {
-  // model -> value
-  // Note: we cannot use a normal scope.$watch as we want to detect the following:
-  // 1. scope value is 'a'
-  // 2. user enters 'b'
-  // 3. ng-change kicks in and reverts scope value to 'a'
-  //    -> scope value did not change since the last digest as
-  //       ng-change executes in apply phase
-  // 4. view should be changed back to 'a'
-  ctrl.$$scope.$watch(function ngModelWatch() {
-    var modelValue = ctrl.$$ngModelGet(ctrl.$$scope);
-
-    // if scope model value and ngModel value are out of sync
-    // TODO(perf): why not move this to the action fn?
-    if (modelValue !== ctrl.$modelValue &&
-       // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator
-        // eslint-disable-next-line no-self-compare
-       (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)
-    ) {
-      ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
-      ctrl.$$parserValid = undefined;
-
-      var formatters = ctrl.$formatters,
-          idx = formatters.length;
-
-      var viewValue = modelValue;
-      while (idx--) {
-        viewValue = formatters[idx](viewValue);
-      }
-      if (ctrl.$viewValue !== viewValue) {
-        ctrl.$$updateEmptyClasses(viewValue);
-        ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
-        ctrl.$render();
-
-        // It is possible that model and view value have been updated during render
-        ctrl.$$runValidators(ctrl.$modelValue, ctrl.$viewValue, noop);
-      }
-    }
-
-    return modelValue;
-  });
-}
-
-/**
- * @ngdoc method
- * @name ngModel.NgModelController#$setValidity
- *
- * @description
- * Change the validity state, and notify the form.
- *
- * This method can be called within $parsers/$formatters or a custom validation implementation.
- * However, in most cases it should be sufficient to use the `ngModel.$validators` and
- * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically.
- *
- * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned
- *        to either `$error[validationErrorKey]` or `$pending[validationErrorKey]`
- *        (for unfulfilled `$asyncValidators`), so that it is available for data-binding.
- *        The `validationErrorKey` should be in camelCase and will get converted into dash-case
- *        for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`
- *        class and can be bound to as  `{{someForm.someControl.$error.myError}}` .
- * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined),
- *                          or skipped (null). Pending is used for unfulfilled `$asyncValidators`.
- *                          Skipped is used by Angular when validators do not run because of parse errors and
- *                          when `$asyncValidators` do not run because any of the `$validators` failed.
- */
-addSetValidityMethod({
-  clazz: NgModelController,
-  set: function(object, property) {
-    object[property] = true;
-  },
-  unset: function(object, property) {
-    delete object[property];
-  }
-});
-
-
-/**
- * @ngdoc directive
- * @name ngModel
- *
- * @element input
- * @priority 1
- *
- * @description
- * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a
- * property on the scope using {@link ngModel.NgModelController NgModelController},
- * which is created and exposed by this directive.
- *
- * `ngModel` is responsible for:
- *
- * - Binding the view into the model, which other directives such as `input`, `textarea` or `select`
- *   require.
- * - Providing validation behavior (i.e. required, number, email, url).
- * - Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).
- * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`,
- *   `ng-untouched`, `ng-empty`, `ng-not-empty`) including animations.
- * - Registering the control with its parent {@link ng.directive:form form}.
- *
- * Note: `ngModel` will try to bind to the property given by evaluating the expression on the
- * current scope. If the property doesn't already exist on this scope, it will be created
- * implicitly and added to the scope.
- *
- * For best practices on using `ngModel`, see:
- *
- *  - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes)
- *
- * For basic examples, how to use `ngModel`, see:
- *
- *  - {@link ng.directive:input input}
- *    - {@link input[text] text}
- *    - {@link input[checkbox] checkbox}
- *    - {@link input[radio] radio}
- *    - {@link input[number] number}
- *    - {@link input[email] email}
- *    - {@link input[url] url}
- *    - {@link input[date] date}
- *    - {@link input[datetime-local] datetime-local}
- *    - {@link input[time] time}
- *    - {@link input[month] month}
- *    - {@link input[week] week}
- *  - {@link ng.directive:select select}
- *  - {@link ng.directive:textarea textarea}
- *
- * # Complex Models (objects or collections)
- *
- * By default, `ngModel` watches the model by reference, not value. This is important to know when
- * binding inputs to models that are objects (e.g. `Date`) or collections (e.g. arrays). If only properties of the
- * object or collection change, `ngModel` will not be notified and so the input will not be  re-rendered.
- *
- * The model must be assigned an entirely new object or collection before a re-rendering will occur.
- *
- * Some directives have options that will cause them to use a custom `$watchCollection` on the model expression
- * - for example, `ngOptions` will do so when a `track by` clause is included in the comprehension expression or
- * if the select is given the `multiple` attribute.
- *
- * The `$watchCollection()` method only does a shallow comparison, meaning that changing properties deeper than the
- * first level of the object (or only changing the properties of an item in the collection if it's an array) will still
- * not trigger a re-rendering of the model.
- *
- * # CSS classes
- * The following CSS classes are added and removed on the associated input/select/textarea element
- * depending on the validity of the model.
- *
- *  - `ng-valid`: the model is valid
- *  - `ng-invalid`: the model is invalid
- *  - `ng-valid-[key]`: for each valid key added by `$setValidity`
- *  - `ng-invalid-[key]`: for each invalid key added by `$setValidity`
- *  - `ng-pristine`: the control hasn't been interacted with yet
- *  - `ng-dirty`: the control has been interacted with
- *  - `ng-touched`: the control has been blurred
- *  - `ng-untouched`: the control hasn't been blurred
- *  - `ng-pending`: any `$asyncValidators` are unfulfilled
- *  - `ng-empty`: the view does not contain a value or the value is deemed "empty", as defined
- *     by the {@link ngModel.NgModelController#$isEmpty} method
- *  - `ng-not-empty`: the view contains a non-empty value
- *
- * Keep in mind that ngAnimate can detect each of these classes when added and removed.
- *
- * ## Animation Hooks
- *
- * Animations within models are triggered when any of the associated CSS classes are added and removed
- * on the input element which is attached to the model. These classes include: `.ng-pristine`, `.ng-dirty`,
- * `.ng-invalid` and `.ng-valid` as well as any other validations that are performed on the model itself.
- * The animations that are triggered within ngModel are similar to how they work in ngClass and
- * animations can be hooked into using CSS transitions, keyframes as well as JS animations.
- *
- * The following example shows a simple way to utilize CSS transitions to style an input element
- * that has been rendered as invalid after it has been validated:
- *
- * <pre>
- * //be sure to include ngAnimate as a module to hook into more
- * //advanced animations
- * .my-input {
- *   transition:0.5s linear all;
- *   background: white;
- * }
- * .my-input.ng-invalid {
- *   background: red;
- *   color:white;
- * }
- * </pre>
- *
- * @example
- * <example deps="angular-animate.js" animations="true" fixBase="true" module="inputExample" name="ng-model">
-     <file name="index.html">
-       <script>
-        angular.module('inputExample', [])
-          .controller('ExampleController', ['$scope', function($scope) {
-            $scope.val = '1';
-          }]);
-       </script>
-       <style>
-         .my-input {
-           transition:all linear 0.5s;
-           background: transparent;
-         }
-         .my-input.ng-invalid {
-           color:white;
-           background: red;
-         }
-       </style>
-       <p id="inputDescription">
-        Update input to see transitions when valid/invalid.
-        Integer is a valid value.
-       </p>
-       <form name="testForm" ng-controller="ExampleController">
-         <input ng-model="val" ng-pattern="/^\d+$/" name="anim" class="my-input"
-                aria-describedby="inputDescription" />
-       </form>
-     </file>
- * </example>
- *
- * ## Binding to a getter/setter
- *
- * Sometimes it's helpful to bind `ngModel` to a getter/setter function.  A getter/setter is a
- * function that returns a representation of the model when called with zero arguments, and sets
- * the internal state of a model when called with an argument. It's sometimes useful to use this
- * for models that have an internal representation that's different from what the model exposes
- * to the view.
- *
- * <div class="alert alert-success">
- * **Best Practice:** It's best to keep getters fast because Angular is likely to call them more
- * frequently than other parts of your code.
- * </div>
- *
- * You use this behavior by adding `ng-model-options="{ getterSetter: true }"` to an element that
- * has `ng-model` attached to it. You can also add `ng-model-options="{ getterSetter: true }"` to
- * a `<form>`, which will enable this behavior for all `<input>`s within it. See
- * {@link ng.directive:ngModelOptions `ngModelOptions`} for more.
- *
- * The following example shows how to use `ngModel` with a getter/setter:
- *
- * @example
- * <example name="ngModel-getter-setter" module="getterSetterExample">
-     <file name="index.html">
-       <div ng-controller="ExampleController">
-         <form name="userForm">
-           <label>Name:
-             <input type="text" name="userName"
-                    ng-model="user.name"
-                    ng-model-options="{ getterSetter: true }" />
-           </label>
-         </form>
-         <pre>user.name = <span ng-bind="user.name()"></span></pre>
-       </div>
-     </file>
-     <file name="app.js">
-       angular.module('getterSetterExample', [])
-         .controller('ExampleController', ['$scope', function($scope) {
-           var _name = 'Brian';
-           $scope.user = {
-             name: function(newName) {
-              // Note that newName can be undefined for two reasons:
-              // 1. Because it is called as a getter and thus called with no arguments
-              // 2. Because the property should actually be set to undefined. This happens e.g. if the
-              //    input is invalid
-              return arguments.length ? (_name = newName) : _name;
-             }
-           };
-         }]);
-     </file>
- * </example>
- */
-var ngModelDirective = ['$rootScope', function($rootScope) {
-  return {
-    restrict: 'A',
-    require: ['ngModel', '^?form', '^?ngModelOptions'],
-    controller: NgModelController,
-    // Prelink needs to run before any input directive
-    // so that we can set the NgModelOptions in NgModelController
-    // before anyone else uses it.
-    priority: 1,
-    compile: function ngModelCompile(element) {
-      // Setup initial state of the control
-      element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS);
-
-      return {
-        pre: function ngModelPreLink(scope, element, attr, ctrls) {
-          var modelCtrl = ctrls[0],
-              formCtrl = ctrls[1] || modelCtrl.$$parentForm,
-              optionsCtrl = ctrls[2];
-
-          if (optionsCtrl) {
-            modelCtrl.$options = optionsCtrl.$options;
-          }
-
-          modelCtrl.$$initGetterSetters();
-
-          // notify others, especially parent forms
-          formCtrl.$addControl(modelCtrl);
-
-          attr.$observe('name', function(newValue) {
-            if (modelCtrl.$name !== newValue) {
-              modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);
-            }
-          });
-
-          scope.$on('$destroy', function() {
-            modelCtrl.$$parentForm.$removeControl(modelCtrl);
-          });
-        },
-        post: function ngModelPostLink(scope, element, attr, ctrls) {
-          var modelCtrl = ctrls[0];
-          if (modelCtrl.$options.getOption('updateOn')) {
-            element.on(modelCtrl.$options.getOption('updateOn'), function(ev) {
-              modelCtrl.$$debounceViewValueCommit(ev && ev.type);
-            });
-          }
-
-          function setTouched() {
-            modelCtrl.$setTouched();
-          }
-
-          element.on('blur', function() {
-            if (modelCtrl.$touched) return;
-
-            if ($rootScope.$$phase) {
-              scope.$evalAsync(setTouched);
-            } else {
-              scope.$apply(setTouched);
-            }
-          });
-        }
-      };
-    }
-  };
-}];
-
-/* exported defaultModelOptions */
-var defaultModelOptions;
-var DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/;
-
-/**
- * @ngdoc type
- * @name ModelOptions
- * @description
- * A container for the options set by the {@link ngModelOptions} directive
- */
-function ModelOptions(options) {
-  this.$$options = options;
-}
-
-ModelOptions.prototype = {
-
-  /**
-   * @ngdoc method
-   * @name ModelOptions#getOption
-   * @param {string} name the name of the option to retrieve
-   * @returns {*} the value of the option
-   * @description
-   * Returns the value of the given option
-   */
-  getOption: function(name) {
-    return this.$$options[name];
-  },
-
-  /**
-   * @ngdoc method
-   * @name ModelOptions#createChild
-   * @param {Object} options a hash of options for the new child that will override the parent's options
-   * @return {ModelOptions} a new `ModelOptions` object initialized with the given options.
-   */
-  createChild: function(options) {
-    var inheritAll = false;
-
-    // make a shallow copy
-    options = extend({}, options);
-
-    // Inherit options from the parent if specified by the value `"$inherit"`
-    forEach(options, /* @this */ function(option, key) {
-      if (option === '$inherit') {
-        if (key === '*') {
-          inheritAll = true;
-        } else {
-          options[key] = this.$$options[key];
-          // `updateOn` is special so we must also inherit the `updateOnDefault` option
-          if (key === 'updateOn') {
-            options.updateOnDefault = this.$$options.updateOnDefault;
-          }
-        }
-      } else {
-        if (key === 'updateOn') {
-          // If the `updateOn` property contains the `default` event then we have to remove
-          // it from the event list and set the `updateOnDefault` flag.
-          options.updateOnDefault = false;
-          options[key] = trim(option.replace(DEFAULT_REGEXP, function() {
-            options.updateOnDefault = true;
-            return ' ';
-          }));
-        }
-      }
-    }, this);
-
-    if (inheritAll) {
-      // We have a property of the form: `"*": "$inherit"`
-      delete options['*'];
-      defaults(options, this.$$options);
-    }
-
-    // Finally add in any missing defaults
-    defaults(options, defaultModelOptions.$$options);
-
-    return new ModelOptions(options);
-  }
-};
-
-
-defaultModelOptions = new ModelOptions({
-  updateOn: '',
-  updateOnDefault: true,
-  debounce: 0,
-  getterSetter: false,
-  allowInvalid: false,
-  timezone: null
-});
-
-
-/**
- * @ngdoc directive
- * @name ngModelOptions
- *
- * @description
- * This directive allows you to modify the behaviour of {@link ngModel} directives within your
- * application. You can specify an `ngModelOptions` directive on any element. All {@link ngModel}
- * directives will use the options of their nearest `ngModelOptions` ancestor.
- *
- * The `ngModelOptions` settings are found by evaluating the value of the attribute directive as
- * an Angular expression. This expression should evaluate to an object, whose properties contain
- * the settings. For example: `<div "ng-model-options"="{ debounce: 100 }"`.
- *
- * ## Inheriting Options
- *
- * You can specify that an `ngModelOptions` setting should be inherited from a parent `ngModelOptions`
- * directive by giving it the value of `"$inherit"`.
- * Then it will inherit that setting from the first `ngModelOptions` directive found by traversing up the
- * DOM tree. If there is no ancestor element containing an `ngModelOptions` directive then default settings
- * will be used.
- *
- * For example given the following fragment of HTML
- *
- *
- * ```html
- * <div ng-model-options="{ allowInvalid: true, debounce: 200 }">
- *   <form ng-model-options="{ updateOn: 'blur', allowInvalid: '$inherit' }">
- *     <input ng-model-options="{ updateOn: 'default', allowInvalid: '$inherit' }" />
- *   </form>
- * </div>
- * ```
- *
- * the `input` element will have the following settings
- *
- * ```js
- * { allowInvalid: true, updateOn: 'default', debounce: 0 }
- * ```
- *
- * Notice that the `debounce` setting was not inherited and used the default value instead.
- *
- * You can specify that all undefined settings are automatically inherited from an ancestor by
- * including a property with key of `"*"` and value of `"$inherit"`.
- *
- * For example given the following fragment of HTML
- *
- *
- * ```html
- * <div ng-model-options="{ allowInvalid: true, debounce: 200 }">
- *   <form ng-model-options="{ updateOn: 'blur', "*": '$inherit' }">
- *     <input ng-model-options="{ updateOn: 'default', "*": '$inherit' }" />
- *   </form>
- * </div>
- * ```
- *
- * the `input` element will have the following settings
- *
- * ```js
- * { allowInvalid: true, updateOn: 'default', debounce: 200 }
- * ```
- *
- * Notice that the `debounce` setting now inherits the value from the outer `<div>` element.
- *
- * If you are creating a reusable component then you should be careful when using `"*": "$inherit"`
- * since you may inadvertently inherit a setting in the future that changes the behavior of your component.
- *
- *
- * ## Triggering and debouncing model updates
- *
- * The `updateOn` and `debounce` properties allow you to specify a custom list of events that will
- * trigger a model update and/or a debouncing delay so that the actual update only takes place when
- * a timer expires; this timer will be reset after another change takes place.
- *
- * Given the nature of `ngModelOptions`, the value displayed inside input fields in the view might
- * be different from the value in the actual model. This means that if you update the model you
- * should also invoke {@link ngModel.NgModelController#$rollbackViewValue} on the relevant input field in
- * order to make sure it is synchronized with the model and that any debounced action is canceled.
- *
- * The easiest way to reference the control's {@link ngModel.NgModelController#$rollbackViewValue}
- * method is by making sure the input is placed inside a form that has a `name` attribute. This is
- * important because `form` controllers are published to the related scope under the name in their
- * `name` attribute.
- *
- * Any pending changes will take place immediately when an enclosing form is submitted via the
- * `submit` event. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`
- * to have access to the updated model.
- *
- * The following example shows how to override immediate updates. Changes on the inputs within the
- * form will update the model only when the control loses focus (blur event). If `escape` key is
- * pressed while the input field is focused, the value is reset to the value in the current model.
- *
- * <example name="ngModelOptions-directive-blur" module="optionsExample">
- *   <file name="index.html">
- *     <div ng-controller="ExampleController">
- *       <form name="userForm">
- *         <label>
- *           Name:
- *           <input type="text" name="userName"
- *                  ng-model="user.name"
- *                  ng-model-options="{ updateOn: 'blur' }"
- *                  ng-keyup="cancel($event)" />
- *         </label><br />
- *         <label>
- *           Other data:
- *           <input type="text" ng-model="user.data" />
- *         </label><br />
- *       </form>
- *       <pre>user.name = <span ng-bind="user.name"></span></pre>
- *     </div>
- *   </file>
- *   <file name="app.js">
- *     angular.module('optionsExample', [])
- *       .controller('ExampleController', ['$scope', function($scope) {
- *         $scope.user = { name: 'say', data: '' };
- *
- *         $scope.cancel = function(e) {
- *           if (e.keyCode === 27) {
- *             $scope.userForm.userName.$rollbackViewValue();
- *           }
- *         };
- *       }]);
- *   </file>
- *   <file name="protractor.js" type="protractor">
- *     var model = element(by.binding('user.name'));
- *     var input = element(by.model('user.name'));
- *     var other = element(by.model('user.data'));
- *
- *     it('should allow custom events', function() {
- *       input.sendKeys(' hello');
- *       input.click();
- *       expect(model.getText()).toEqual('say');
- *       other.click();
- *       expect(model.getText()).toEqual('say hello');
- *     });
- *
- *     it('should $rollbackViewValue when model changes', function() {
- *       input.sendKeys(' hello');
- *       expect(input.getAttribute('value')).toEqual('say hello');
- *       input.sendKeys(protractor.Key.ESCAPE);
- *       expect(input.getAttribute('value')).toEqual('say');
- *       other.click();
- *       expect(model.getText()).toEqual('say');
- *     });
- *   </file>
- * </example>
- *
- * The next example shows how to debounce model changes. Model will be updated only 1 sec after last change.
- * If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty.
- *
- * <example name="ngModelOptions-directive-debounce" module="optionsExample">
- *   <file name="index.html">
- *     <div ng-controller="ExampleController">
- *       <form name="userForm">
- *         Name:
- *         <input type="text" name="userName"
- *                ng-model="user.name"
- *                ng-model-options="{ debounce: 1000 }" />
- *         <button ng-click="userForm.userName.$rollbackViewValue(); user.name=''">Clear</button><br />
- *       </form>
- *       <pre>user.name = <span ng-bind="user.name"></span></pre>
- *     </div>
- *   </file>
- *   <file name="app.js">
- *     angular.module('optionsExample', [])
- *       .controller('ExampleController', ['$scope', function($scope) {
- *         $scope.user = { name: 'say' };
- *       }]);
- *   </file>
- * </example>
- *
- * ## Model updates and validation
- *
- * The default behaviour in `ngModel` is that the model value is set to `undefined` when the
- * validation determines that the value is invalid. By setting the `allowInvalid` property to true,
- * the model will still be updated even if the value is invalid.
- *
- *
- * ## Connecting to the scope
- *
- * By setting the `getterSetter` property to true you are telling ngModel that the `ngModel` expression
- * on the scope refers to a "getter/setter" function rather than the value itself.
- *
- * The following example shows how to bind to getter/setters:
- *
- * <example name="ngModelOptions-directive-getter-setter" module="getterSetterExample">
- *   <file name="index.html">
- *     <div ng-controller="ExampleController">
- *       <form name="userForm">
- *         <label>
- *           Name:
- *           <input type="text" name="userName"
- *                  ng-model="user.name"
- *                  ng-model-options="{ getterSetter: true }" />
- *         </label>
- *       </form>
- *       <pre>user.name = <span ng-bind="user.name()"></span></pre>
- *     </div>
- *   </file>
- *   <file name="app.js">
- *     angular.module('getterSetterExample', [])
- *       .controller('ExampleController', ['$scope', function($scope) {
- *         var _name = 'Brian';
- *         $scope.user = {
- *           name: function(newName) {
- *             return angular.isDefined(newName) ? (_name = newName) : _name;
- *           }
- *         };
- *       }]);
- *   </file>
- * </example>
- *
- *
- * ## Specifying timezones
- *
- * You can specify the timezone that date/time input directives expect by providing its name in the
- * `timezone` property.
- *
- * @param {Object} ngModelOptions options to apply to {@link ngModel} directives on this element and
- *   and its descendents. Valid keys are:
- *   - `updateOn`: string specifying which event should the input be bound to. You can set several
- *     events using an space delimited list. There is a special event called `default` that
- *     matches the default events belonging to the control.
- *   - `debounce`: integer value which contains the debounce model update value in milliseconds. A
- *     value of 0 triggers an immediate update. If an object is supplied instead, you can specify a
- *     custom value for each event. For example:
- *     ```
- *     ng-model-options="{
- *       updateOn: 'default blur',
- *       debounce: { 'default': 500, 'blur': 0 }
- *     }"
- *     ```
- *   - `allowInvalid`: boolean value which indicates that the model can be set with values that did
- *     not validate correctly instead of the default behavior of setting the model to undefined.
- *   - `getterSetter`: boolean value which determines whether or not to treat functions bound to
- *     `ngModel` as getters/setters.
- *   - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for
- *     `<input type="date" />`, `<input type="time" />`, ... . It understands UTC/GMT and the
- *     continental US time zone abbreviations, but for general use, use a time zone offset, for
- *     example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)
- *     If not specified, the timezone of the browser will be used.
- *
- */
-var ngModelOptionsDirective = function() {
-  NgModelOptionsController.$inject = ['$attrs', '$scope'];
-  function NgModelOptionsController($attrs, $scope) {
-    this.$$attrs = $attrs;
-    this.$$scope = $scope;
-  }
-  NgModelOptionsController.prototype = {
-    $onInit: function() {
-      var parentOptions = this.parentCtrl ? this.parentCtrl.$options : defaultModelOptions;
-      var modelOptionsDefinition = this.$$scope.$eval(this.$$attrs.ngModelOptions);
-
-      this.$options = parentOptions.createChild(modelOptionsDefinition);
-    }
-  };
-
-  return {
-    restrict: 'A',
-    // ngModelOptions needs to run before ngModel and input directives
-    priority: 10,
-    require: {parentCtrl: '?^^ngModelOptions'},
-    bindToController: true,
-    controller: NgModelOptionsController
-  };
-};
-
-
-// shallow copy over values from `src` that are not already specified on `dst`
-function defaults(dst, src) {
-  forEach(src, function(value, key) {
-    if (!isDefined(dst[key])) {
-      dst[key] = value;
-    }
-  });
-}
-
-/**
- * @ngdoc directive
- * @name ngNonBindable
- * @restrict AC
- * @priority 1000
- *
- * @description
- * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current
- * DOM element. This is useful if the element contains what appears to be Angular directives and
- * bindings but which should be ignored by Angular. This could be the case if you have a site that
- * displays snippets of code, for instance.
- *
- * @element ANY
- *
- * @example
- * In this example there are two locations where a simple interpolation binding (`{{}}`) is present,
- * but the one wrapped in `ngNonBindable` is left alone.
- *
- * @example
-    <example name="ng-non-bindable">
-      <file name="index.html">
-        <div>Normal: {{1 + 2}}</div>
-        <div ng-non-bindable>Ignored: {{1 + 2}}</div>
-      </file>
-      <file name="protractor.js" type="protractor">
-       it('should check ng-non-bindable', function() {
-         expect(element(by.binding('1 + 2')).getText()).toContain('3');
-         expect(element.all(by.css('div')).last().getText()).toMatch(/1 \+ 2/);
-       });
-      </file>
-    </example>
- */
-var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
-
-/* exported ngOptionsDirective */
-
-/* global jqLiteRemove */
-
-var ngOptionsMinErr = minErr('ngOptions');
-
-/**
- * @ngdoc directive
- * @name ngOptions
- * @restrict A
- *
- * @description
- *
- * The `ngOptions` attribute can be used to dynamically generate a list of `<option>`
- * elements for the `<select>` element using the array or object obtained by evaluating the
- * `ngOptions` comprehension expression.
- *
- * In many cases, {@link ng.directive:ngRepeat ngRepeat} can be used on `<option>` elements instead of
- * `ngOptions` to achieve a similar result. However, `ngOptions` provides some benefits:
- * - more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the
- * comprehension expression
- * - reduced memory consumption by not creating a new scope for each repeated instance
- * - increased render speed by creating the options in a documentFragment instead of individually
- *
- * When an item in the `<select>` menu is selected, the array element or object property
- * represented by the selected option will be bound to the model identified by the `ngModel`
- * directive.
- *
- * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
- * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
- * option. See example below for demonstration.
- *
- * ## Complex Models (objects or collections)
- *
- * By default, `ngModel` watches the model by reference, not value. This is important to know when
- * binding the select to a model that is an object or a collection.
- *
- * One issue occurs if you want to preselect an option. For example, if you set
- * the model to an object that is equal to an object in your collection, `ngOptions` won't be able to set the selection,
- * because the objects are not identical. So by default, you should always reference the item in your collection
- * for preselections, e.g.: `$scope.selected = $scope.collection[3]`.
- *
- * Another solution is to use a `track by` clause, because then `ngOptions` will track the identity
- * of the item not by reference, but by the result of the `track by` expression. For example, if your
- * collection items have an id property, you would `track by item.id`.
- *
- * A different issue with objects or collections is that ngModel won't detect if an object property or
- * a collection item changes. For that reason, `ngOptions` additionally watches the model using
- * `$watchCollection`, when the expression contains a `track by` clause or the the select has the `multiple` attribute.
- * This allows ngOptions to trigger a re-rendering of the options even if the actual object/collection
- * has not changed identity, but only a property on the object or an item in the collection changes.
- *
- * Note that `$watchCollection` does a shallow comparison of the properties of the object (or the items in the collection
- * if the model is an array). This means that changing a property deeper than the first level inside the
- * object/collection will not trigger a re-rendering.
- *
- * ## `select` **`as`**
- *
- * Using `select` **`as`** will bind the result of the `select` expression to the model, but
- * the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)
- * or property name (for object data sources) of the value within the collection. If a **`track by`** expression
- * is used, the result of that expression will be set as the value of the `option` and `select` elements.
- *
- *
- * ### `select` **`as`** and **`track by`**
- *
- * <div class="alert alert-warning">
- * Be careful when using `select` **`as`** and **`track by`** in the same expression.
- * </div>
- *
- * Given this array of items on the $scope:
- *
- * ```js
- * $scope.items = [{
- *   id: 1,
- *   label: 'aLabel',
- *   subItem: { name: 'aSubItem' }
- * }, {
- *   id: 2,
- *   label: 'bLabel',
- *   subItem: { name: 'bSubItem' }
- * }];
- * ```
- *
- * This will work:
- *
- * ```html
- * <select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
- * ```
- * ```js
- * $scope.selected = $scope.items[0];
- * ```
- *
- * but this will not work:
- *
- * ```html
- * <select ng-options="item.subItem as item.label for item in items track by item.id" ng-model="selected"></select>
- * ```
- * ```js
- * $scope.selected = $scope.items[0].subItem;
- * ```
- *
- * In both examples, the **`track by`** expression is applied successfully to each `item` in the
- * `items` array. Because the selected option has been set programmatically in the controller, the
- * **`track by`** expression is also applied to the `ngModel` value. In the first example, the
- * `ngModel` value is `items[0]` and the **`track by`** expression evaluates to `items[0].id` with
- * no issue. In the second example, the `ngModel` value is `items[0].subItem` and the **`track by`**
- * expression evaluates to `items[0].subItem.id` (which is undefined). As a result, the model value
- * is not matched against any `<option>` and the `<select>` appears as having no selected value.
- *
- *
- * @param {string} ngModel Assignable AngularJS expression to data-bind to.
- * @param {comprehension_expression} ngOptions in one of the following forms:
- *
- *   * for array data sources:
- *     * `label` **`for`** `value` **`in`** `array`
- *     * `select` **`as`** `label` **`for`** `value` **`in`** `array`
- *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array`
- *     * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array`
- *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
- *     * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
- *     * `label` **`for`** `value` **`in`** `array` | orderBy:`orderexpr` **`track by`** `trackexpr`
- *        (for including a filter with `track by`)
- *   * for object data sources:
- *     * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
- *     * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
- *     * `label` **`group by`** `group` **`for (`**`key`**`,`** `value`**`) in`** `object`
- *     * `label` **`disable when`** `disable` **`for (`**`key`**`,`** `value`**`) in`** `object`
- *     * `select` **`as`** `label` **`group by`** `group`
- *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`
- *     * `select` **`as`** `label` **`disable when`** `disable`
- *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`
- *
- * Where:
- *
- *   * `array` / `object`: an expression which evaluates to an array / object to iterate over.
- *   * `value`: local variable which will refer to each item in the `array` or each property value
- *      of `object` during iteration.
- *   * `key`: local variable which will refer to a property name in `object` during iteration.
- *   * `label`: The result of this expression will be the label for `<option>` element. The
- *     `expression` will most likely refer to the `value` variable (e.g. `value.propertyName`).
- *   * `select`: The result of this expression will be bound to the model of the parent `<select>`
- *      element. If not specified, `select` expression will default to `value`.
- *   * `group`: The result of this expression will be used to group options using the `<optgroup>`
- *      DOM element.
- *   * `disable`: The result of this expression will be used to disable the rendered `<option>`
- *      element. Return `true` to disable.
- *   * `trackexpr`: Used when working with an array of objects. The result of this expression will be
- *      used to identify the objects in the array. The `trackexpr` will most likely refer to the
- *     `value` variable (e.g. `value.propertyName`). With this the selection is preserved
- *      even when the options are recreated (e.g. reloaded from the server).
- * @param {string=} name Property name of the form under which the control is published.
- * @param {string=} required The control is considered valid only if value is entered.
- * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
- *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
- *    `required` when you want to data-bind to the `required` attribute.
- * @param {string=} ngAttrSize sets the size of the select element dynamically. Uses the
- * {@link guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes ngAttr} directive.
- *
- * @example
-    <example module="selectExample" name="select">
-      <file name="index.html">
-        <script>
-        angular.module('selectExample', [])
-          .controller('ExampleController', ['$scope', function($scope) {
-            $scope.colors = [
-              {name:'black', shade:'dark'},
-              {name:'white', shade:'light', notAnOption: true},
-              {name:'red', shade:'dark'},
-              {name:'blue', shade:'dark', notAnOption: true},
-              {name:'yellow', shade:'light', notAnOption: false}
-            ];
-            $scope.myColor = $scope.colors[2]; // red
-          }]);
-        </script>
-        <div ng-controller="ExampleController">
-          <ul>
-            <li ng-repeat="color in colors">
-              <label>Name: <input ng-model="color.name"></label>
-              <label><input type="checkbox" ng-model="color.notAnOption"> Disabled?</label>
-              <button ng-click="colors.splice($index, 1)" aria-label="Remove">X</button>
-            </li>
-            <li>
-              <button ng-click="colors.push({})">add</button>
-            </li>
-          </ul>
-          <hr/>
-          <label>Color (null not allowed):
-            <select ng-model="myColor" ng-options="color.name for color in colors"></select>
-          </label><br/>
-          <label>Color (null allowed):
-          <span  class="nullable">
-            <select ng-model="myColor" ng-options="color.name for color in colors">
-              <option value="">-- choose color --</option>
-            </select>
-          </span></label><br/>
-
-          <label>Color grouped by shade:
-            <select ng-model="myColor" ng-options="color.name group by color.shade for color in colors">
-            </select>
-          </label><br/>
-
-          <label>Color grouped by shade, with some disabled:
-            <select ng-model="myColor"
-                  ng-options="color.name group by color.shade disable when color.notAnOption for color in colors">
-            </select>
-          </label><br/>
-
-
-
-          Select <button ng-click="myColor = { name:'not in list', shade: 'other' }">bogus</button>.
-          <br/>
-          <hr/>
-          Currently selected: {{ {selected_color:myColor} }}
-          <div style="border:solid 1px black; height:20px"
-               ng-style="{'background-color':myColor.name}">
-          </div>
-        </div>
-      </file>
-      <file name="protractor.js" type="protractor">
-         it('should check ng-options', function() {
-           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red');
-           element.all(by.model('myColor')).first().click();
-           element.all(by.css('select[ng-model="myColor"] option')).first().click();
-           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black');
-           element(by.css('.nullable select[ng-model="myColor"]')).click();
-           element.all(by.css('.nullable select[ng-model="myColor"] option')).first().click();
-           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('null');
-         });
-      </file>
-    </example>
- */
-
-/* eslint-disable max-len */
-//                     //00001111111111000000000002222222222000000000000000000000333333333300000000000000000000000004444444444400000000000005555555555555000000000666666666666600000007777777777777000000000000000888888888800000000000000000009999999999
-var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\s+([\s\S]+?))?\s+for\s+(?:([$\w][$\w]*)|(?:\(\s*([$\w][$\w]*)\s*,\s*([$\w][$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
-                        // 1: value expression (valueFn)
-                        // 2: label expression (displayFn)
-                        // 3: group by expression (groupByFn)
-                        // 4: disable when expression (disableWhenFn)
-                        // 5: array item variable name
-                        // 6: object item key variable name
-                        // 7: object item value variable name
-                        // 8: collection expression
-                        // 9: track by expression
-/* eslint-enable */
-
-
-var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile, $document, $parse) {
-
-  function parseOptionsExpression(optionsExp, selectElement, scope) {
-
-    var match = optionsExp.match(NG_OPTIONS_REGEXP);
-    if (!(match)) {
-      throw ngOptionsMinErr('iexp',
-        'Expected expression in form of ' +
-        '\'_select_ (as _label_)? for (_key_,)?_value_ in _collection_\'' +
-        ' but got \'{0}\'. Element: {1}',
-        optionsExp, startingTag(selectElement));
-    }
-
-    // Extract the parts from the ngOptions expression
-
-    // The variable name for the value of the item in the collection
-    var valueName = match[5] || match[7];
-    // The variable name for the key of the item in the collection
-    var keyName = match[6];
-
-    // An expression that generates the viewValue for an option if there is a label expression
-    var selectAs = / as /.test(match[0]) && match[1];
-    // An expression that is used to track the id of each object in the options collection
-    var trackBy = match[9];
-    // An expression that generates the viewValue for an option if there is no label expression
-    var valueFn = $parse(match[2] ? match[1] : valueName);
-    var selectAsFn = selectAs && $parse(selectAs);
-    var viewValueFn = selectAsFn || valueFn;
-    var trackByFn = trackBy && $parse(trackBy);
-
-    // Get the value by which we are going to track the option
-    // if we have a trackFn then use that (passing scope and locals)
-    // otherwise just hash the given viewValue
-    var getTrackByValueFn = trackBy ?
-                              function(value, locals) { return trackByFn(scope, locals); } :
-                              function getHashOfValue(value) { return hashKey(value); };
-    var getTrackByValue = function(value, key) {
-      return getTrackByValueFn(value, getLocals(value, key));
-    };
-
-    var displayFn = $parse(match[2] || match[1]);
-    var groupByFn = $parse(match[3] || '');
-    var disableWhenFn = $parse(match[4] || '');
-    var valuesFn = $parse(match[8]);
-
-    var locals = {};
-    var getLocals = keyName ? function(value, key) {
-      locals[keyName] = key;
-      locals[valueName] = value;
-      return locals;
-    } : function(value) {
-      locals[valueName] = value;
-      return locals;
-    };
-
-
-    function Option(selectValue, viewValue, label, group, disabled) {
-      this.selectValue = selectValue;
-      this.viewValue = viewValue;
-      this.label = label;
-      this.group = group;
-      this.disabled = disabled;
-    }
-
-    function getOptionValuesKeys(optionValues) {
-      var optionValuesKeys;
-
-      if (!keyName && isArrayLike(optionValues)) {
-        optionValuesKeys = optionValues;
-      } else {
-        // if object, extract keys, in enumeration order, unsorted
-        optionValuesKeys = [];
-        for (var itemKey in optionValues) {
-          if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') {
-            optionValuesKeys.push(itemKey);
-          }
-        }
-      }
-      return optionValuesKeys;
-    }
-
-    return {
-      trackBy: trackBy,
-      getTrackByValue: getTrackByValue,
-      getWatchables: $parse(valuesFn, function(optionValues) {
-        // Create a collection of things that we would like to watch (watchedArray)
-        // so that they can all be watched using a single $watchCollection
-        // that only runs the handler once if anything changes
-        var watchedArray = [];
-        optionValues = optionValues || [];
-
-        var optionValuesKeys = getOptionValuesKeys(optionValues);
-        var optionValuesLength = optionValuesKeys.length;
-        for (var index = 0; index < optionValuesLength; index++) {
-          var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
-          var value = optionValues[key];
-
-          var locals = getLocals(value, key);
-          var selectValue = getTrackByValueFn(value, locals);
-          watchedArray.push(selectValue);
-
-          // Only need to watch the displayFn if there is a specific label expression
-          if (match[2] || match[1]) {
-            var label = displayFn(scope, locals);
-            watchedArray.push(label);
-          }
-
-          // Only need to watch the disableWhenFn if there is a specific disable expression
-          if (match[4]) {
-            var disableWhen = disableWhenFn(scope, locals);
-            watchedArray.push(disableWhen);
-          }
-        }
-        return watchedArray;
-      }),
-
-      getOptions: function() {
-
-        var optionItems = [];
-        var selectValueMap = {};
-
-        // The option values were already computed in the `getWatchables` fn,
-        // which must have been called to trigger `getOptions`
-        var optionValues = valuesFn(scope) || [];
-        var optionValuesKeys = getOptionValuesKeys(optionValues);
-        var optionValuesLength = optionValuesKeys.length;
-
-        for (var index = 0; index < optionValuesLength; index++) {
-          var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
-          var value = optionValues[key];
-          var locals = getLocals(value, key);
-          var viewValue = viewValueFn(scope, locals);
-          var selectValue = getTrackByValueFn(viewValue, locals);
-          var label = displayFn(scope, locals);
-          var group = groupByFn(scope, locals);
-          var disabled = disableWhenFn(scope, locals);
-          var optionItem = new Option(selectValue, viewValue, label, group, disabled);
-
-          optionItems.push(optionItem);
-          selectValueMap[selectValue] = optionItem;
-        }
-
-        return {
-          items: optionItems,
-          selectValueMap: selectValueMap,
-          getOptionFromViewValue: function(value) {
-            return selectValueMap[getTrackByValue(value)];
-          },
-          getViewValueFromOption: function(option) {
-            // If the viewValue could be an object that may be mutated by the application,
-            // we need to make a copy and not return the reference to the value on the option.
-            return trackBy ? copy(option.viewValue) : option.viewValue;
-          }
-        };
-      }
-    };
-  }
-
-
-  // we can't just jqLite('<option>') since jqLite is not smart enough
-  // to create it in <select> and IE barfs otherwise.
-  var optionTemplate = window.document.createElement('option'),
-      optGroupTemplate = window.document.createElement('optgroup');
-
-    function ngOptionsPostLink(scope, selectElement, attr, ctrls) {
-
-      var selectCtrl = ctrls[0];
-      var ngModelCtrl = ctrls[1];
-      var multiple = attr.multiple;
-
-      // The emptyOption allows the application developer to provide their own custom "empty"
-      // option when the viewValue does not match any of the option values.
-      for (var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) {
-        if (children[i].value === '') {
-          selectCtrl.hasEmptyOption = true;
-          selectCtrl.emptyOption = children.eq(i);
-          break;
-        }
-      }
-
-      var providedEmptyOption = !!selectCtrl.emptyOption;
-
-      var unknownOption = jqLite(optionTemplate.cloneNode(false));
-      unknownOption.val('?');
-
-      var options;
-      var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope);
-      // This stores the newly created options before they are appended to the select.
-      // Since the contents are removed from the fragment when it is appended,
-      // we only need to create it once.
-      var listFragment = $document[0].createDocumentFragment();
-
-      // Overwrite the implementation. ngOptions doesn't use hashes
-      selectCtrl.generateUnknownOptionValue = function(val) {
-        return '?';
-      };
-
-      // Update the controller methods for multiple selectable options
-      if (!multiple) {
-
-        selectCtrl.writeValue = function writeNgOptionsValue(value) {
-          var selectedOption = options.selectValueMap[selectElement.val()];
-          var option = options.getOptionFromViewValue(value);
-
-          // Make sure to remove the selected attribute from the previously selected option
-          // Otherwise, screen readers might get confused
-          if (selectedOption) selectedOption.element.removeAttribute('selected');
-
-          if (option) {
-            // Don't update the option when it is already selected.
-            // For example, the browser will select the first option by default. In that case,
-            // most properties are set automatically - except the `selected` attribute, which we
-            // set always
-
-            if (selectElement[0].value !== option.selectValue) {
-              selectCtrl.removeUnknownOption();
-              selectCtrl.unselectEmptyOption();
-
-              selectElement[0].value = option.selectValue;
-              option.element.selected = true;
-            }
-
-            option.element.setAttribute('selected', 'selected');
-          } else {
-
-            if (providedEmptyOption) {
-              selectCtrl.selectEmptyOption();
-            } else if (selectCtrl.unknownOption.parent().length) {
-              selectCtrl.updateUnknownOption(value);
-            } else {
-              selectCtrl.renderUnknownOption(value);
-            }
-          }
-        };
-
-        selectCtrl.readValue = function readNgOptionsValue() {
-
-          var selectedOption = options.selectValueMap[selectElement.val()];
-
-          if (selectedOption && !selectedOption.disabled) {
-            selectCtrl.unselectEmptyOption();
-            selectCtrl.removeUnknownOption();
-            return options.getViewValueFromOption(selectedOption);
-          }
-          return null;
-        };
-
-        // If we are using `track by` then we must watch the tracked value on the model
-        // since ngModel only watches for object identity change
-        // FIXME: When a user selects an option, this watch will fire needlessly
-        if (ngOptions.trackBy) {
-          scope.$watch(
-            function() { return ngOptions.getTrackByValue(ngModelCtrl.$viewValue); },
-            function() { ngModelCtrl.$render(); }
-          );
-        }
-
-      } else {
-
-        selectCtrl.writeValue = function writeNgOptionsMultiple(values) {
-          // Only set `<option>.selected` if necessary, in order to prevent some browsers from
-          // scrolling to `<option>` elements that are outside the `<select>` element's viewport.
-
-          var selectedOptions = values && values.map(getAndUpdateSelectedOption) || [];
-
-          options.items.forEach(function(option) {
-            if (option.element.selected && !includes(selectedOptions, option)) {
-              option.element.selected = false;
-            }
-          });
-        };
-
-
-        selectCtrl.readValue = function readNgOptionsMultiple() {
-          var selectedValues = selectElement.val() || [],
-              selections = [];
-
-          forEach(selectedValues, function(value) {
-            var option = options.selectValueMap[value];
-            if (option && !option.disabled) selections.push(options.getViewValueFromOption(option));
-          });
-
-          return selections;
-        };
-
-        // If we are using `track by` then we must watch these tracked values on the model
-        // since ngModel only watches for object identity change
-        if (ngOptions.trackBy) {
-
-          scope.$watchCollection(function() {
-            if (isArray(ngModelCtrl.$viewValue)) {
-              return ngModelCtrl.$viewValue.map(function(value) {
-                return ngOptions.getTrackByValue(value);
-              });
-            }
-          }, function() {
-            ngModelCtrl.$render();
-          });
-
-        }
-      }
-
-      if (providedEmptyOption) {
-
-        // we need to remove it before calling selectElement.empty() because otherwise IE will
-        // remove the label from the element. wtf?
-        selectCtrl.emptyOption.remove();
-
-        // compile the element since there might be bindings in it
-        $compile(selectCtrl.emptyOption)(scope);
-
-        if (selectCtrl.emptyOption[0].nodeType === NODE_TYPE_COMMENT) {
-          // This means the empty option has currently no actual DOM node, probably because
-          // it has been modified by a transclusion directive.
-          selectCtrl.hasEmptyOption = false;
-
-          // Redefine the registerOption function, which will catch
-          // options that are added by ngIf etc. (rendering of the node is async because of
-          // lazy transclusion)
-          selectCtrl.registerOption = function(optionScope, optionEl) {
-            if (optionEl.val() === '') {
-              selectCtrl.hasEmptyOption = true;
-              selectCtrl.emptyOption = optionEl;
-              selectCtrl.emptyOption.removeClass('ng-scope');
-              // This ensures the new empty option is selected if previously no option was selected
-              ngModelCtrl.$render();
-
-              optionEl.on('$destroy', function() {
-                selectCtrl.hasEmptyOption = false;
-                selectCtrl.emptyOption = undefined;
-              });
-            }
-          };
-
-        } else {
-          // remove the class, which is added automatically because we recompile the element and it
-          // becomes the compilation root
-          selectCtrl.emptyOption.removeClass('ng-scope');
-        }
-
-      }
-
-      selectElement.empty();
-
-      // We need to do this here to ensure that the options object is defined
-      // when we first hit it in writeNgOptionsValue
-      updateOptions();
-
-      // We will re-render the option elements if the option values or labels change
-      scope.$watchCollection(ngOptions.getWatchables, updateOptions);
-
-      // ------------------------------------------------------------------ //
-
-      function addOptionElement(option, parent) {
-        var optionElement = optionTemplate.cloneNode(false);
-        parent.appendChild(optionElement);
-        updateOptionElement(option, optionElement);
-      }
-
-      function getAndUpdateSelectedOption(viewValue) {
-        var option = options.getOptionFromViewValue(viewValue);
-        var element = option && option.element;
-
-        if (element && !element.selected) element.selected = true;
-
-        return option;
-      }
-
-      function updateOptionElement(option, element) {
-        option.element = element;
-        element.disabled = option.disabled;
-        // NOTE: The label must be set before the value, otherwise IE10/11/EDGE create unresponsive
-        // selects in certain circumstances when multiple selects are next to each other and display
-        // the option list in listbox style, i.e. the select is [multiple], or specifies a [size].
-        // See https://github.com/angular/angular.js/issues/11314 for more info.
-        // This is unfortunately untestable with unit / e2e tests
-        if (option.label !== element.label) {
-          element.label = option.label;
-          element.textContent = option.label;
-        }
-        element.value = option.selectValue;
-      }
-
-      function updateOptions() {
-        var previousValue = options && selectCtrl.readValue();
-
-        // We must remove all current options, but cannot simply set innerHTML = null
-        // since the providedEmptyOption might have an ngIf on it that inserts comments which we
-        // must preserve.
-        // Instead, iterate over the current option elements and remove them or their optgroup
-        // parents
-        if (options) {
-
-          for (var i = options.items.length - 1; i >= 0; i--) {
-            var option = options.items[i];
-            if (isDefined(option.group)) {
-              jqLiteRemove(option.element.parentNode);
-            } else {
-              jqLiteRemove(option.element);
-            }
-          }
-        }
-
-        options = ngOptions.getOptions();
-
-        var groupElementMap = {};
-
-        // Ensure that the empty option is always there if it was explicitly provided
-        if (providedEmptyOption) {
-          selectElement.prepend(selectCtrl.emptyOption);
-        }
-
-        options.items.forEach(function addOption(option) {
-          var groupElement;
-
-          if (isDefined(option.group)) {
-
-            // This option is to live in a group
-            // See if we have already created this group
-            groupElement = groupElementMap[option.group];
-
-            if (!groupElement) {
-
-              groupElement = optGroupTemplate.cloneNode(false);
-              listFragment.appendChild(groupElement);
-
-              // Update the label on the group element
-              // "null" is special cased because of Safari
-              groupElement.label = option.group === null ? 'null' : option.group;
-
-              // Store it for use later
-              groupElementMap[option.group] = groupElement;
-            }
-
-            addOptionElement(option, groupElement);
-
-          } else {
-
-            // This option is not in a group
-            addOptionElement(option, listFragment);
-          }
-        });
-
-        selectElement[0].appendChild(listFragment);
-
-        ngModelCtrl.$render();
-
-        // Check to see if the value has changed due to the update to the options
-        if (!ngModelCtrl.$isEmpty(previousValue)) {
-          var nextValue = selectCtrl.readValue();
-          var isNotPrimitive = ngOptions.trackBy || multiple;
-          if (isNotPrimitive ? !equals(previousValue, nextValue) : previousValue !== nextValue) {
-            ngModelCtrl.$setViewValue(nextValue);
-            ngModelCtrl.$render();
-          }
-        }
-
-      }
-  }
-
-  return {
-    restrict: 'A',
-    terminal: true,
-    require: ['select', 'ngModel'],
-    link: {
-      pre: function ngOptionsPreLink(scope, selectElement, attr, ctrls) {
-        // Deactivate the SelectController.register method to prevent
-        // option directives from accidentally registering themselves
-        // (and unwanted $destroy handlers etc.)
-        ctrls[0].registerOption = noop;
-      },
-      post: ngOptionsPostLink
-    }
-  };
-}];
-
-/**
- * @ngdoc directive
- * @name ngPluralize
- * @restrict EA
- *
- * @description
- * `ngPluralize` is a directive that displays messages according to en-US localization rules.
- * These rules are bundled with angular.js, but can be overridden
- * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive
- * by specifying the mappings between
- * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)
- * and the strings to be displayed.
- *
- * # Plural categories and explicit number rules
- * There are two
- * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)
- * in Angular's default en-US locale: "one" and "other".
- *
- * While a plural category may match many numbers (for example, in en-US locale, "other" can match
- * any number that is not 1), an explicit number rule can only match one number. For example, the
- * explicit number rule for "3" matches the number 3. There are examples of plural categories
- * and explicit number rules throughout the rest of this documentation.
- *
- * # Configuring ngPluralize
- * You configure ngPluralize by providing 2 attributes: `count` and `when`.
- * You can also provide an optional attribute, `offset`.
- *
- * The value of the `count` attribute can be either a string or an {@link guide/expression
- * Angular expression}; these are evaluated on the current scope for its bound value.
- *
- * The `when` attribute specifies the mappings between plural categories and the actual
- * string to be displayed. The value of the attribute should be a JSON object.
- *
- * The following example shows how to configure ngPluralize:
- *
- * ```html
- * <ng-pluralize count="personCount"
-                 when="{'0': 'Nobody is viewing.',
- *                      'one': '1 person is viewing.',
- *                      'other': '{} people are viewing.'}">
- * </ng-pluralize>
- *```
- *
- * In the example, `"0: Nobody is viewing."` is an explicit number rule. If you did not
- * specify this rule, 0 would be matched to the "other" category and "0 people are viewing"
- * would be shown instead of "Nobody is viewing". You can specify an explicit number rule for
- * other numbers, for example 12, so that instead of showing "12 people are viewing", you can
- * show "a dozen people are viewing".
- *
- * You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted
- * into pluralized strings. In the previous example, Angular will replace `{}` with
- * <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder
- * for <span ng-non-bindable>{{numberExpression}}</span>.
- *
- * If no rule is defined for a category, then an empty string is displayed and a warning is generated.
- * Note that some locales define more categories than `one` and `other`. For example, fr-fr defines `few` and `many`.
- *
- * # Configuring ngPluralize with offset
- * The `offset` attribute allows further customization of pluralized text, which can result in
- * a better user experience. For example, instead of the message "4 people are viewing this document",
- * you might display "John, Kate and 2 others are viewing this document".
- * The offset attribute allows you to offset a number by any desired value.
- * Let's take a look at an example:
- *
- * ```html
- * <ng-pluralize count="personCount" offset=2
- *               when="{'0': 'Nobody is viewing.',
- *                      '1': '{{person1}} is viewing.',
- *                      '2': '{{person1}} and {{person2}} are viewing.',
- *                      'one': '{{person1}}, {{person2}} and one other person are viewing.',
- *                      'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
- * </ng-pluralize>
- * ```
- *
- * Notice that we are still using two plural categories(one, other), but we added
- * three explicit number rules 0, 1 and 2.
- * When one person, perhaps John, views the document, "John is viewing" will be shown.
- * When three people view the document, no explicit number rule is found, so
- * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.
- * In this case, plural category 'one' is matched and "John, Mary and one other person are viewing"
- * is shown.
- *
- * Note that when you specify offsets, you must provide explicit number rules for
- * numbers from 0 up to and including the offset. If you use an offset of 3, for example,
- * you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for
- * plural categories "one" and "other".
- *
- * @param {string|expression} count The variable to be bound to.
- * @param {string} when The mapping between plural category to its corresponding strings.
- * @param {number=} offset Offset to deduct from the total number.
- *
- * @example
-    <example module="pluralizeExample" name="ng-pluralize">
-      <file name="index.html">
-        <script>
-          angular.module('pluralizeExample', [])
-            .controller('ExampleController', ['$scope', function($scope) {
-              $scope.person1 = 'Igor';
-              $scope.person2 = 'Misko';
-              $scope.personCount = 1;
-            }]);
-        </script>
-        <div ng-controller="ExampleController">
-          <label>Person 1:<input type="text" ng-model="person1" value="Igor" /></label><br/>
-          <label>Person 2:<input type="text" ng-model="person2" value="Misko" /></label><br/>
-          <label>Number of People:<input type="text" ng-model="personCount" value="1" /></label><br/>
-
-          <!--- Example with simple pluralization rules for en locale --->
-          Without Offset:
-          <ng-pluralize count="personCount"
-                        when="{'0': 'Nobody is viewing.',
-                               'one': '1 person is viewing.',
-                               'other': '{} people are viewing.'}">
-          </ng-pluralize><br>
-
-          <!--- Example with offset --->
-          With Offset(2):
-          <ng-pluralize count="personCount" offset=2
-                        when="{'0': 'Nobody is viewing.',
-                               '1': '{{person1}} is viewing.',
-                               '2': '{{person1}} and {{person2}} are viewing.',
-                               'one': '{{person1}}, {{person2}} and one other person are viewing.',
-                               'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
-          </ng-pluralize>
-        </div>
-      </file>
-      <file name="protractor.js" type="protractor">
-        it('should show correct pluralized string', function() {
-          var withoutOffset = element.all(by.css('ng-pluralize')).get(0);
-          var withOffset = element.all(by.css('ng-pluralize')).get(1);
-          var countInput = element(by.model('personCount'));
-
-          expect(withoutOffset.getText()).toEqual('1 person is viewing.');
-          expect(withOffset.getText()).toEqual('Igor is viewing.');
-
-          countInput.clear();
-          countInput.sendKeys('0');
-
-          expect(withoutOffset.getText()).toEqual('Nobody is viewing.');
-          expect(withOffset.getText()).toEqual('Nobody is viewing.');
-
-          countInput.clear();
-          countInput.sendKeys('2');
-
-          expect(withoutOffset.getText()).toEqual('2 people are viewing.');
-          expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');
-
-          countInput.clear();
-          countInput.sendKeys('3');
-
-          expect(withoutOffset.getText()).toEqual('3 people are viewing.');
-          expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');
-
-          countInput.clear();
-          countInput.sendKeys('4');
-
-          expect(withoutOffset.getText()).toEqual('4 people are viewing.');
-          expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');
-        });
-        it('should show data-bound names', function() {
-          var withOffset = element.all(by.css('ng-pluralize')).get(1);
-          var personCount = element(by.model('personCount'));
-          var person1 = element(by.model('person1'));
-          var person2 = element(by.model('person2'));
-          personCount.clear();
-          personCount.sendKeys('4');
-          person1.clear();
-          person1.sendKeys('Di');
-          person2.clear();
-          person2.sendKeys('Vojta');
-          expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');
-        });
-      </file>
-    </example>
- */
-var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale, $interpolate, $log) {
-  var BRACE = /{}/g,
-      IS_WHEN = /^when(Minus)?(.+)$/;
-
-  return {
-    link: function(scope, element, attr) {
-      var numberExp = attr.count,
-          whenExp = attr.$attr.when && element.attr(attr.$attr.when), // we have {{}} in attrs
-          offset = attr.offset || 0,
-          whens = scope.$eval(whenExp) || {},
-          whensExpFns = {},
-          startSymbol = $interpolate.startSymbol(),
-          endSymbol = $interpolate.endSymbol(),
-          braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,
-          watchRemover = angular.noop,
-          lastCount;
-
-      forEach(attr, function(expression, attributeName) {
-        var tmpMatch = IS_WHEN.exec(attributeName);
-        if (tmpMatch) {
-          var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);
-          whens[whenKey] = element.attr(attr.$attr[attributeName]);
-        }
-      });
-      forEach(whens, function(expression, key) {
-        whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));
-
-      });
-
-      scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {
-        var count = parseFloat(newVal);
-        var countIsNaN = isNumberNaN(count);
-
-        if (!countIsNaN && !(count in whens)) {
-          // If an explicit number rule such as 1, 2, 3... is defined, just use it.
-          // Otherwise, check it against pluralization rules in $locale service.
-          count = $locale.pluralCat(count - offset);
-        }
-
-        // If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
-        // In JS `NaN !== NaN`, so we have to explicitly check.
-        if ((count !== lastCount) && !(countIsNaN && isNumberNaN(lastCount))) {
-          watchRemover();
-          var whenExpFn = whensExpFns[count];
-          if (isUndefined(whenExpFn)) {
-            if (newVal != null) {
-              $log.debug('ngPluralize: no rule defined for \'' + count + '\' in ' + whenExp);
-            }
-            watchRemover = noop;
-            updateElementText();
-          } else {
-            watchRemover = scope.$watch(whenExpFn, updateElementText);
-          }
-          lastCount = count;
-        }
-      });
-
-      function updateElementText(newText) {
-        element.text(newText || '');
-      }
-    }
-  };
-}];
-
-/* exported ngRepeatDirective */
-
-/**
- * @ngdoc directive
- * @name ngRepeat
- * @multiElement
- * @restrict A
- *
- * @description
- * The `ngRepeat` directive instantiates a template once per item from a collection. Each template
- * instance gets its own scope, where the given loop variable is set to the current collection item,
- * and `$index` is set to the item index or key.
- *
- * Special properties are exposed on the local scope of each template instance, including:
- *
- * | Variable  | Type            | Details                                                                     |
- * |-----------|-----------------|-----------------------------------------------------------------------------|
- * | `$index`  | {@type number}  | iterator offset of the repeated element (0..length-1)                       |
- * | `$first`  | {@type boolean} | true if the repeated element is first in the iterator.                      |
- * | `$middle` | {@type boolean} | true if the repeated element is between the first and last in the iterator. |
- * | `$last`   | {@type boolean} | true if the repeated element is last in the iterator.                       |
- * | `$even`   | {@type boolean} | true if the iterator position `$index` is even (otherwise false).           |
- * | `$odd`    | {@type boolean} | true if the iterator position `$index` is odd (otherwise false).            |
- *
- * <div class="alert alert-info">
- *   Creating aliases for these properties is possible with {@link ng.directive:ngInit `ngInit`}.
- *   This may be useful when, for instance, nesting ngRepeats.
- * </div>
- *
- *
- * # Iterating over object properties
- *
- * It is possible to get `ngRepeat` to iterate over the properties of an object using the following
- * syntax:
- *
- * ```js
- * <div ng-repeat="(key, value) in myObj"> ... </div>
- * ```
- *
- * However, there are a few limitations compared to array iteration:
- *
- * - The JavaScript specification does not define the order of keys
- *   returned for an object, so Angular relies on the order returned by the browser
- *   when running `for key in myObj`. Browsers generally follow the strategy of providing
- *   keys in the order in which they were defined, although there are exceptions when keys are deleted
- *   and reinstated. See the
- *   [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).
- *
- * - `ngRepeat` will silently *ignore* object keys starting with `$`, because
- *   it's a prefix used by Angular for public (`$`) and private (`$$`) properties.
- *
- * - The built-in filters {@link ng.orderBy orderBy} and {@link ng.filter filter} do not work with
- *   objects, and will throw an error if used with one.
- *
- * If you are hitting any of these limitations, the recommended workaround is to convert your object into an array
- * that is sorted into the order that you prefer before providing it to `ngRepeat`. You could
- * do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)
- * or implement a `$watch` on the object yourself.
- *
- *
- * # Tracking and Duplicates
- *
- * `ngRepeat` uses {@link $rootScope.Scope#$watchCollection $watchCollection} to detect changes in
- * the collection. When a change happens, `ngRepeat` then makes the corresponding changes to the DOM:
- *
- * * When an item is added, a new instance of the template is added to the DOM.
- * * When an item is removed, its template instance is removed from the DOM.
- * * When items are reordered, their respective templates are reordered in the DOM.
- *
- * To minimize creation of DOM elements, `ngRepeat` uses a function
- * to "keep track" of all items in the collection and their corresponding DOM elements.
- * For example, if an item is added to the collection, `ngRepeat` will know that all other items
- * already have DOM elements, and will not re-render them.
- *
- * The default tracking function (which tracks items by their identity) does not allow
- * duplicate items in arrays. This is because when there are duplicates, it is not possible
- * to maintain a one-to-one mapping between collection items and DOM elements.
- *
- * If you do need to repeat duplicate items, you can substitute the default tracking behavior
- * with your own using the `track by` expression.
- *
- * For example, you may track items by the index of each item in the collection, using the
- * special scope property `$index`:
- * ```html
- *    <div ng-repeat="n in [42, 42, 43, 43] track by $index">
- *      {{n}}
- *    </div>
- * ```
- *
- * You may also use arbitrary expressions in `track by`, including references to custom functions
- * on the scope:
- * ```html
- *    <div ng-repeat="n in [42, 42, 43, 43] track by myTrackingFunction(n)">
- *      {{n}}
- *    </div>
- * ```
- *
- * <div class="alert alert-success">
- * If you are working with objects that have a unique identifier property, you should track
- * by this identifier instead of the object instance. Should you reload your data later, `ngRepeat`
- * will not have to rebuild the DOM elements for items it has already rendered, even if the
- * JavaScript objects in the collection have been substituted for new ones. For large collections,
- * this significantly improves rendering performance. If you don't have a unique identifier,
- * `track by $index` can also provide a performance boost.
- * </div>
- *
- * ```html
- *    <div ng-repeat="model in collection track by model.id">
- *      {{model.name}}
- *    </div>
- * ```
- *
- * <br />
- * <div class="alert alert-warning">
- * Avoid using `track by $index` when the repeated template contains
- * {@link guide/expression#one-time-binding one-time bindings}. In such cases, the `nth` DOM
- * element will always be matched with the `nth` item of the array, so the bindings on that element
- * will not be updated even when the corresponding item changes, essentially causing the view to get
- * out-of-sync with the underlying data.
- * </div>
- *
- * When no `track by` expression is provided, it is equivalent to tracking by the built-in
- * `$id` function, which tracks items by their identity:
- * ```html
- *    <div ng-repeat="obj in collection track by $id(obj)">
- *      {{obj.prop}}
- *    </div>
- * ```
- *
- * <br />
- * <div class="alert alert-warning">
- * **Note:** `track by` must always be the last expression:
- * </div>
- * ```
- *    <div ng-repeat="model in collection | orderBy: 'id' as filtered_result track by model.id">
- *      {{model.name}}
- *    </div>
- * ```
- *
- *
- * # Special repeat start and end points
- * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
- * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
- * The **ng-repeat-start** directive works the same as **ng-repeat**, but will repeat all the HTML code (including the tag it's defined on)
- * up to and including the ending HTML tag where **ng-repeat-end** is placed.
- *
- * The example below makes use of this feature:
- * ```html
- *   <header ng-repeat-start="item in items">
- *     Header {{ item }}
- *   </header>
- *   <div class="body">
- *     Body {{ item }}
- *   </div>
- *   <footer ng-repeat-end>
- *     Footer {{ item }}
- *   </footer>
- * ```
- *
- * And with an input of {@type ['A','B']} for the items variable in the example above, the output will evaluate to:
- * ```html
- *   <header>
- *     Header A
- *   </header>
- *   <div class="body">
- *     Body A
- *   </div>
- *   <footer>
- *     Footer A
- *   </footer>
- *   <header>
- *     Header B
- *   </header>
- *   <div class="body">
- *     Body B
- *   </div>
- *   <footer>
- *     Footer B
- *   </footer>
- * ```
- *
- * The custom start and end points for ngRepeat also support all other HTML directive syntax flavors provided in AngularJS (such
- * as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).
- *
- * @animations
- * | Animation                        | Occurs                              |
- * |----------------------------------|-------------------------------------|
- * | {@link ng.$animate#enter enter} | when a new item is added to the list or when an item is revealed after a filter |
- * | {@link ng.$animate#leave leave} | when an item is removed from the list or when an item is filtered out |
- * | {@link ng.$animate#move move } | when an adjacent item is filtered out causing a reorder or when the item contents are reordered |
- *
- * See the example below for defining CSS animations with ngRepeat.
- *
- * @element ANY
- * @scope
- * @priority 1000
- * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. These
- *   formats are currently supported:
- *
- *   * `variable in expression` – where variable is the user defined loop variable and `expression`
- *     is a scope expression giving the collection to enumerate.
- *
- *     For example: `album in artist.albums`.
- *
- *   * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
- *     and `expression` is the scope expression giving the collection to enumerate.
- *
- *     For example: `(name, age) in {'adam':10, 'amalie':12}`.
- *
- *   * `variable in expression track by tracking_expression` – You can also provide an optional tracking expression
- *     which can be used to associate the objects in the collection with the DOM elements. If no tracking expression
- *     is specified, ng-repeat associates elements by identity. It is an error to have
- *     more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are
- *     mapped to the same DOM element, which is not possible.)
- *
- *     Note that the tracking expression must come last, after any filters, and the alias expression.
- *
- *     For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
- *     will be associated by item identity in the array.
- *
- *     For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
- *     `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements
- *     with the corresponding item in the array by identity. Moving the same object in array would move the DOM
- *     element in the same way in the DOM.
- *
- *     For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this
- *     case the object identity does not matter. Two objects are considered equivalent as long as their `id`
- *     property is same.
- *
- *     For example: `item in items | filter:searchText track by item.id` is a pattern that might be used to apply a filter
- *     to items in conjunction with a tracking expression.
- *
- *   * `variable in expression as alias_expression` – You can also provide an optional alias expression which will then store the
- *     intermediate results of the repeater after the filters have been applied. Typically this is used to render a special message
- *     when a filter is active on the repeater, but the filtered result set is empty.
- *
- *     For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
- *     the items have been processed through the filter.
- *
- *     Please note that `as [variable name] is not an operator but rather a part of ngRepeat micro-syntax so it can be used only at the end
- *     (and not as operator, inside an expression).
- *
- *     For example: `item in items | filter : x | orderBy : order | limitTo : limit as results` .
- *
- * @example
- * This example uses `ngRepeat` to display a list of people. A filter is used to restrict the displayed
- * results by name or by age. New (entering) and removed (leaving) items are animated.
-  <example module="ngRepeat" name="ngRepeat" deps="angular-animate.js" animations="true" name="ng-repeat">
-    <file name="index.html">
-      <div ng-controller="repeatController">
-        I have {{friends.length}} friends. They are:
-        <input type="search" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
-        <ul class="example-animate-container">
-          <li class="animate-repeat" ng-repeat="friend in friends | filter:q as results">
-            [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
-          </li>
-          <li class="animate-repeat" ng-if="results.length === 0">
-            <strong>No results found...</strong>
-          </li>
-        </ul>
-      </div>
-    </file>
-    <file name="script.js">
-      angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {
-        $scope.friends = [
-          {name:'John', age:25, gender:'boy'},
-          {name:'Jessie', age:30, gender:'girl'},
-          {name:'Johanna', age:28, gender:'girl'},
-          {name:'Joy', age:15, gender:'girl'},
-          {name:'Mary', age:28, gender:'girl'},
-          {name:'Peter', age:95, gender:'boy'},
-          {name:'Sebastian', age:50, gender:'boy'},
-          {name:'Erika', age:27, gender:'girl'},
-          {name:'Patrick', age:40, gender:'boy'},
-          {name:'Samantha', age:60, gender:'girl'}
-        ];
-      });
-    </file>
-    <file name="animations.css">
-      .example-animate-container {
-        background:white;
-        border:1px solid black;
-        list-style:none;
-        margin:0;
-        padding:0 10px;
-      }
-
-      .animate-repeat {
-        line-height:30px;
-        list-style:none;
-        box-sizing:border-box;
-      }
-
-      .animate-repeat.ng-move,
-      .animate-repeat.ng-enter,
-      .animate-repeat.ng-leave {
-        transition:all linear 0.5s;
-      }
-
-      .animate-repeat.ng-leave.ng-leave-active,
-      .animate-repeat.ng-move,
-      .animate-repeat.ng-enter {
-        opacity:0;
-        max-height:0;
-      }
-
-      .animate-repeat.ng-leave,
-      .animate-repeat.ng-move.ng-move-active,
-      .animate-repeat.ng-enter.ng-enter-active {
-        opacity:1;
-        max-height:30px;
-      }
-    </file>
-    <file name="protractor.js" type="protractor">
-      var friends = element.all(by.repeater('friend in friends'));
-
-      it('should render initial data set', function() {
-        expect(friends.count()).toBe(10);
-        expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');
-        expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');
-        expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');
-        expect(element(by.binding('friends.length')).getText())
-            .toMatch("I have 10 friends. They are:");
-      });
-
-       it('should update repeater when filter predicate changes', function() {
-         expect(friends.count()).toBe(10);
-
-         element(by.model('q')).sendKeys('ma');
-
-         expect(friends.count()).toBe(2);
-         expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');
-         expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');
-       });
-      </file>
-    </example>
- */
-var ngRepeatDirective = ['$parse', '$animate', '$compile', function($parse, $animate, $compile) {
-  var NG_REMOVED = '$$NG_REMOVED';
-  var ngRepeatMinErr = minErr('ngRepeat');
-
-  var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) {
-    // TODO(perf): generate setters to shave off ~40ms or 1-1.5%
-    scope[valueIdentifier] = value;
-    if (keyIdentifier) scope[keyIdentifier] = key;
-    scope.$index = index;
-    scope.$first = (index === 0);
-    scope.$last = (index === (arrayLength - 1));
-    scope.$middle = !(scope.$first || scope.$last);
-    // eslint-disable-next-line no-bitwise
-    scope.$odd = !(scope.$even = (index & 1) === 0);
-  };
-
-  var getBlockStart = function(block) {
-    return block.clone[0];
-  };
-
-  var getBlockEnd = function(block) {
-    return block.clone[block.clone.length - 1];
-  };
-
-
-  return {
-    restrict: 'A',
-    multiElement: true,
-    transclude: 'element',
-    priority: 1000,
-    terminal: true,
-    $$tlb: true,
-    compile: function ngRepeatCompile($element, $attr) {
-      var expression = $attr.ngRepeat;
-      var ngRepeatEndComment = $compile.$$createComment('end ngRepeat', expression);
-
-      var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
-
-      if (!match) {
-        throw ngRepeatMinErr('iexp', 'Expected expression in form of \'_item_ in _collection_[ track by _id_]\' but got \'{0}\'.',
-            expression);
-      }
-
-      var lhs = match[1];
-      var rhs = match[2];
-      var aliasAs = match[3];
-      var trackByExp = match[4];
-
-      match = lhs.match(/^(?:(\s*[$\w]+)|\(\s*([$\w]+)\s*,\s*([$\w]+)\s*\))$/);
-
-      if (!match) {
-        throw ngRepeatMinErr('iidexp', '\'_item_\' in \'_item_ in _collection_\' should be an identifier or \'(_key_, _value_)\' expression, but got \'{0}\'.',
-            lhs);
-      }
-      var valueIdentifier = match[3] || match[1];
-      var keyIdentifier = match[2];
-
-      if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||
-          /^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent|\$root|\$id)$/.test(aliasAs))) {
-        throw ngRepeatMinErr('badident', 'alias \'{0}\' is invalid --- must be a valid JS identifier which is not a reserved name.',
-          aliasAs);
-      }
-
-      var trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn;
-      var hashFnLocals = {$id: hashKey};
-
-      if (trackByExp) {
-        trackByExpGetter = $parse(trackByExp);
-      } else {
-        trackByIdArrayFn = function(key, value) {
-          return hashKey(value);
-        };
-        trackByIdObjFn = function(key) {
-          return key;
-        };
-      }
-
-      return function ngRepeatLink($scope, $element, $attr, ctrl, $transclude) {
-
-        if (trackByExpGetter) {
-          trackByIdExpFn = function(key, value, index) {
-            // assign key, value, and $index to the locals so that they can be used in hash functions
-            if (keyIdentifier) hashFnLocals[keyIdentifier] = key;
-            hashFnLocals[valueIdentifier] = value;
-            hashFnLocals.$index = index;
-            return trackByExpGetter($scope, hashFnLocals);
-          };
-        }
-
-        // Store a list of elements from previous run. This is a hash where key is the item from the
-        // iterator, and the value is objects with following properties.
-        //   - scope: bound scope
-        //   - element: previous element.
-        //   - index: position
-        //
-        // We are using no-proto object so that we don't need to guard against inherited props via
-        // hasOwnProperty.
-        var lastBlockMap = createMap();
-
-        //watch props
-        $scope.$watchCollection(rhs, function ngRepeatAction(collection) {
-          var index, length,
-              previousNode = $element[0],     // node that cloned nodes should be inserted after
-                                              // initialized to the comment node anchor
-              nextNode,
-              // Same as lastBlockMap but it has the current state. It will become the
-              // lastBlockMap on the next iteration.
-              nextBlockMap = createMap(),
-              collectionLength,
-              key, value, // key/value of iteration
-              trackById,
-              trackByIdFn,
-              collectionKeys,
-              block,       // last object information {scope, element, id}
-              nextBlockOrder,
-              elementsToRemove;
-
-          if (aliasAs) {
-            $scope[aliasAs] = collection;
-          }
-
-          if (isArrayLike(collection)) {
-            collectionKeys = collection;
-            trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
-          } else {
-            trackByIdFn = trackByIdExpFn || trackByIdObjFn;
-            // if object, extract keys, in enumeration order, unsorted
-            collectionKeys = [];
-            for (var itemKey in collection) {
-              if (hasOwnProperty.call(collection, itemKey) && itemKey.charAt(0) !== '$') {
-                collectionKeys.push(itemKey);
-              }
-            }
-          }
-
-          collectionLength = collectionKeys.length;
-          nextBlockOrder = new Array(collectionLength);
-
-          // locate existing items
-          for (index = 0; index < collectionLength; index++) {
-            key = (collection === collectionKeys) ? index : collectionKeys[index];
-            value = collection[key];
-            trackById = trackByIdFn(key, value, index);
-            if (lastBlockMap[trackById]) {
-              // found previously seen block
-              block = lastBlockMap[trackById];
-              delete lastBlockMap[trackById];
-              nextBlockMap[trackById] = block;
-              nextBlockOrder[index] = block;
-            } else if (nextBlockMap[trackById]) {
-              // if collision detected. restore lastBlockMap and throw an error
-              forEach(nextBlockOrder, function(block) {
-                if (block && block.scope) lastBlockMap[block.id] = block;
-              });
-              throw ngRepeatMinErr('dupes',
-                  'Duplicates in a repeater are not allowed. Use \'track by\' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}',
-                  expression, trackById, value);
-            } else {
-              // new never before seen block
-              nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined};
-              nextBlockMap[trackById] = true;
-            }
-          }
-
-          // remove leftover items
-          for (var blockKey in lastBlockMap) {
-            block = lastBlockMap[blockKey];
-            elementsToRemove = getBlockNodes(block.clone);
-            $animate.leave(elementsToRemove);
-            if (elementsToRemove[0].parentNode) {
-              // if the element was not removed yet because of pending animation, mark it as deleted
-              // so that we can ignore it later
-              for (index = 0, length = elementsToRemove.length; index < length; index++) {
-                elementsToRemove[index][NG_REMOVED] = true;
-              }
-            }
-            block.scope.$destroy();
-          }
-
-          // we are not using forEach for perf reasons (trying to avoid #call)
-          for (index = 0; index < collectionLength; index++) {
-            key = (collection === collectionKeys) ? index : collectionKeys[index];
-            value = collection[key];
-            block = nextBlockOrder[index];
-
-            if (block.scope) {
-              // if we have already seen this object, then we need to reuse the
-              // associated scope/element
-
-              nextNode = previousNode;
-
-              // skip nodes that are already pending removal via leave animation
-              do {
-                nextNode = nextNode.nextSibling;
-              } while (nextNode && nextNode[NG_REMOVED]);
-
-              if (getBlockStart(block) !== nextNode) {
-                // existing item which got moved
-                $animate.move(getBlockNodes(block.clone), null, previousNode);
-              }
-              previousNode = getBlockEnd(block);
-              updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
-            } else {
-              // new item which we don't know about
-              $transclude(function ngRepeatTransclude(clone, scope) {
-                block.scope = scope;
-                // http://jsperf.com/clone-vs-createcomment
-                var endNode = ngRepeatEndComment.cloneNode(false);
-                clone[clone.length++] = endNode;
-
-                $animate.enter(clone, null, previousNode);
-                previousNode = endNode;
-                // Note: We only need the first/last node of the cloned nodes.
-                // However, we need to keep the reference to the jqlite wrapper as it might be changed later
-                // by a directive with templateUrl when its template arrives.
-                block.clone = clone;
-                nextBlockMap[block.id] = block;
-                updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
-              });
-            }
-          }
-          lastBlockMap = nextBlockMap;
-        });
-      };
-    }
-  };
-}];
-
-var NG_HIDE_CLASS = 'ng-hide';
-var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
-/**
- * @ngdoc directive
- * @name ngShow
- * @multiElement
- *
- * @description
- * The `ngShow` directive shows or hides the given HTML element based on the expression provided to
- * the `ngShow` attribute.
- *
- * The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
- * The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an
- * `!important` flag). For CSP mode please add `angular-csp.css` to your HTML file (see
- * {@link ng.directive:ngCsp ngCsp}).
- *
- * ```html
- * <!-- when $scope.myValue is truthy (element is visible) -->
- * <div ng-show="myValue"></div>
- *
- * <!-- when $scope.myValue is falsy (element is hidden) -->
- * <div ng-show="myValue" class="ng-hide"></div>
- * ```
- *
- * When the `ngShow` expression evaluates to a falsy value then the `.ng-hide` CSS class is added
- * to the class attribute on the element causing it to become hidden. When truthy, the `.ng-hide`
- * CSS class is removed from the element causing the element not to appear hidden.
- *
- * ## Why is `!important` used?
- *
- * You may be wondering why `!important` is used for the `.ng-hide` CSS class. This is because the
- * `.ng-hide` selector can be easily overridden by heavier selectors. For example, something as
- * simple as changing the display style on a HTML list item would make hidden elements appear
- * visible. This also becomes a bigger issue when dealing with CSS frameworks.
- *
- * By using `!important`, the show and hide behavior will work as expected despite any clash between
- * CSS selector specificity (when `!important` isn't used with any conflicting styles). If a
- * developer chooses to override the styling to change how to hide an element then it is just a
- * matter of using `!important` in their own CSS code.
- *
- * ### Overriding `.ng-hide`
- *
- * By default, the `.ng-hide` class will style the element with `display: none !important`. If you
- * wish to change the hide behavior with `ngShow`/`ngHide`, you can simply overwrite the styles for
- * the `.ng-hide` CSS class. Note that the selector that needs to be used is actually
- * `.ng-hide:not(.ng-hide-animate)` to cope with extra animation classes that can be added.
- *
- * ```css
- * .ng-hide:not(.ng-hide-animate) {
- *   /&#42; These are just alternative ways of hiding an element &#42;/
- *   display: block!important;
- *   position: absolute;
- *   top: -9999px;
- *   left: -9999px;
- * }
- * ```
- *
- * By default you don't need to override anything in CSS and the animations will work around the
- * display style.
- *
- * ## A note about animations with `ngShow`
- *
- * Animations in `ngShow`/`ngHide` work with the show and hide events that are triggered when the
- * directive expression is true and false. This system works like the animation system present with
- * `ngClass` except that you must also include the `!important` flag to override the display
- * property so that the elements are not actually hidden during the animation.
- *
- * ```css
- * /&#42; A working example can be found at the bottom of this page. &#42;/
- * .my-element.ng-hide-add, .my-element.ng-hide-remove {
- *   transition: all 0.5s linear;
- * }
- *
- * .my-element.ng-hide-add { ... }
- * .my-element.ng-hide-add.ng-hide-add-active { ... }
- * .my-element.ng-hide-remove { ... }
- * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
- * ```
- *
- * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display property
- * to block during animation states - ngAnimate will automatically handle the style toggling for you.
- *
- * @animations
- * | Animation                                           | Occurs                                                                                                        |
- * |-----------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
- * | {@link $animate#addClass addClass} `.ng-hide`       | After the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden. |
- * | {@link $animate#removeClass removeClass} `.ng-hide` | After the `ngShow` expression evaluates to a truthy value and just before contents are set to visible.        |
- *
- * @element ANY
- * @param {expression} ngShow If the {@link guide/expression expression} is truthy/falsy then the
- *                            element is shown/hidden respectively.
- *
- * @example
- * A simple example, animating the element's opacity:
- *
-  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-show-simple">
-    <file name="index.html">
-      Show: <input type="checkbox" ng-model="checked" aria-label="Toggle ngShow"><br />
-      <div class="check-element animate-show-hide" ng-show="checked">
-        I show up when your checkbox is checked.
-      </div>
-    </file>
-    <file name="animations.css">
-      .animate-show-hide.ng-hide {
-        opacity: 0;
-      }
-
-      .animate-show-hide.ng-hide-add,
-      .animate-show-hide.ng-hide-remove {
-        transition: all linear 0.5s;
-      }
-
-      .check-element {
-        border: 1px solid black;
-        opacity: 1;
-        padding: 10px;
-      }
-    </file>
-    <file name="protractor.js" type="protractor">
-      it('should check ngShow', function() {
-        var checkbox = element(by.model('checked'));
-        var checkElem = element(by.css('.check-element'));
-
-        expect(checkElem.isDisplayed()).toBe(false);
-        checkbox.click();
-        expect(checkElem.isDisplayed()).toBe(true);
-      });
-    </file>
-  </example>
- *
- * <hr />
- * @example
- * A more complex example, featuring different show/hide animations:
- *
-  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-show-complex">
-    <file name="index.html">
-      Show: <input type="checkbox" ng-model="checked" aria-label="Toggle ngShow"><br />
-      <div class="check-element funky-show-hide" ng-show="checked">
-        I show up when your checkbox is checked.
-      </div>
-    </file>
-    <file name="animations.css">
-      body {
-        overflow: hidden;
-        perspective: 1000px;
-      }
-
-      .funky-show-hide.ng-hide-add {
-        transform: rotateZ(0);
-        transform-origin: right;
-        transition: all 0.5s ease-in-out;
-      }
-
-      .funky-show-hide.ng-hide-add.ng-hide-add-active {
-        transform: rotateZ(-135deg);
-      }
-
-      .funky-show-hide.ng-hide-remove {
-        transform: rotateY(90deg);
-        transform-origin: left;
-        transition: all 0.5s ease;
-      }
-
-      .funky-show-hide.ng-hide-remove.ng-hide-remove-active {
-        transform: rotateY(0);
-      }
-
-      .check-element {
-        border: 1px solid black;
-        opacity: 1;
-        padding: 10px;
-      }
-    </file>
-    <file name="protractor.js" type="protractor">
-      it('should check ngShow', function() {
-        var checkbox = element(by.model('checked'));
-        var checkElem = element(by.css('.check-element'));
-
-        expect(checkElem.isDisplayed()).toBe(false);
-        checkbox.click();
-        expect(checkElem.isDisplayed()).toBe(true);
-      });
-    </file>
-  </example>
- */
-var ngShowDirective = ['$animate', function($animate) {
-  return {
-    restrict: 'A',
-    multiElement: true,
-    link: function(scope, element, attr) {
-      scope.$watch(attr.ngShow, function ngShowWatchAction(value) {
-        // we're adding a temporary, animation-specific class for ng-hide since this way
-        // we can control when the element is actually displayed on screen without having
-        // to have a global/greedy CSS selector that breaks when other animations are run.
-        // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845
-        $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
-          tempClasses: NG_HIDE_IN_PROGRESS_CLASS
-        });
-      });
-    }
-  };
-}];
-
-
-/**
- * @ngdoc directive
- * @name ngHide
- * @multiElement
- *
- * @description
- * The `ngHide` directive shows or hides the given HTML element based on the expression provided to
- * the `ngHide` attribute.
- *
- * The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
- * The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an
- * `!important` flag). For CSP mode please add `angular-csp.css` to your HTML file (see
- * {@link ng.directive:ngCsp ngCsp}).
- *
- * ```html
- * <!-- when $scope.myValue is truthy (element is hidden) -->
- * <div ng-hide="myValue" class="ng-hide"></div>
- *
- * <!-- when $scope.myValue is falsy (element is visible) -->
- * <div ng-hide="myValue"></div>
- * ```
- *
- * When the `ngHide` expression evaluates to a truthy value then the `.ng-hide` CSS class is added
- * to the class attribute on the element causing it to become hidden. When falsy, the `.ng-hide`
- * CSS class is removed from the element causing the element not to appear hidden.
- *
- * ## Why is `!important` used?
- *
- * You may be wondering why `!important` is used for the `.ng-hide` CSS class. This is because the
- * `.ng-hide` selector can be easily overridden by heavier selectors. For example, something as
- * simple as changing the display style on a HTML list item would make hidden elements appear
- * visible. This also becomes a bigger issue when dealing with CSS frameworks.
- *
- * By using `!important`, the show and hide behavior will work as expected despite any clash between
- * CSS selector specificity (when `!important` isn't used with any conflicting styles). If a
- * developer chooses to override the styling to change how to hide an element then it is just a
- * matter of using `!important` in their own CSS code.
- *
- * ### Overriding `.ng-hide`
- *
- * By default, the `.ng-hide` class will style the element with `display: none !important`. If you
- * wish to change the hide behavior with `ngShow`/`ngHide`, you can simply overwrite the styles for
- * the `.ng-hide` CSS class. Note that the selector that needs to be used is actually
- * `.ng-hide:not(.ng-hide-animate)` to cope with extra animation classes that can be added.
- *
- * ```css
- * .ng-hide:not(.ng-hide-animate) {
- *   /&#42; These are just alternative ways of hiding an element &#42;/
- *   display: block!important;
- *   position: absolute;
- *   top: -9999px;
- *   left: -9999px;
- * }
- * ```
- *
- * By default you don't need to override in CSS anything and the animations will work around the
- * display style.
- *
- * ## A note about animations with `ngHide`
- *
- * Animations in `ngShow`/`ngHide` work with the show and hide events that are triggered when the
- * directive expression is true and false. This system works like the animation system present with
- * `ngClass` except that you must also include the `!important` flag to override the display
- * property so that the elements are not actually hidden during the animation.
- *
- * ```css
- * /&#42; A working example can be found at the bottom of this page. &#42;/
- * .my-element.ng-hide-add, .my-element.ng-hide-remove {
- *   transition: all 0.5s linear;
- * }
- *
- * .my-element.ng-hide-add { ... }
- * .my-element.ng-hide-add.ng-hide-add-active { ... }
- * .my-element.ng-hide-remove { ... }
- * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
- * ```
- *
- * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display property
- * to block during animation states - ngAnimate will automatically handle the style toggling for you.
- *
- * @animations
- * | Animation                                           | Occurs                                                                                                     |
- * |-----------------------------------------------------|------------------------------------------------------------------------------------------------------------|
- * | {@link $animate#addClass addClass} `.ng-hide`       | After the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden.  |
- * | {@link $animate#removeClass removeClass} `.ng-hide` | After the `ngHide` expression evaluates to a non truthy value and just before contents are set to visible. |
- *
- *
- * @element ANY
- * @param {expression} ngHide If the {@link guide/expression expression} is truthy/falsy then the
- *                            element is hidden/shown respectively.
- *
- * @example
- * A simple example, animating the element's opacity:
- *
-  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-hide-simple">
-    <file name="index.html">
-      Hide: <input type="checkbox" ng-model="checked" aria-label="Toggle ngHide"><br />
-      <div class="check-element animate-show-hide" ng-hide="checked">
-        I hide when your checkbox is checked.
-      </div>
-    </file>
-    <file name="animations.css">
-      .animate-show-hide.ng-hide {
-        opacity: 0;
-      }
-
-      .animate-show-hide.ng-hide-add,
-      .animate-show-hide.ng-hide-remove {
-        transition: all linear 0.5s;
-      }
-
-      .check-element {
-        border: 1px solid black;
-        opacity: 1;
-        padding: 10px;
-      }
-    </file>
-    <file name="protractor.js" type="protractor">
-      it('should check ngHide', function() {
-        var checkbox = element(by.model('checked'));
-        var checkElem = element(by.css('.check-element'));
-
-        expect(checkElem.isDisplayed()).toBe(true);
-        checkbox.click();
-        expect(checkElem.isDisplayed()).toBe(false);
-      });
-    </file>
-  </example>
- *
- * <hr />
- * @example
- * A more complex example, featuring different show/hide animations:
- *
-  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-hide-complex">
-    <file name="index.html">
-      Hide: <input type="checkbox" ng-model="checked" aria-label="Toggle ngHide"><br />
-      <div class="check-element funky-show-hide" ng-hide="checked">
-        I hide when your checkbox is checked.
-      </div>
-    </file>
-    <file name="animations.css">
-      body {
-        overflow: hidden;
-        perspective: 1000px;
-      }
-
-      .funky-show-hide.ng-hide-add {
-        transform: rotateZ(0);
-        transform-origin: right;
-        transition: all 0.5s ease-in-out;
-      }
-
-      .funky-show-hide.ng-hide-add.ng-hide-add-active {
-        transform: rotateZ(-135deg);
-      }
-
-      .funky-show-hide.ng-hide-remove {
-        transform: rotateY(90deg);
-        transform-origin: left;
-        transition: all 0.5s ease;
-      }
-
-      .funky-show-hide.ng-hide-remove.ng-hide-remove-active {
-        transform: rotateY(0);
-      }
-
-      .check-element {
-        border: 1px solid black;
-        opacity: 1;
-        padding: 10px;
-      }
-    </file>
-    <file name="protractor.js" type="protractor">
-      it('should check ngHide', function() {
-        var checkbox = element(by.model('checked'));
-        var checkElem = element(by.css('.check-element'));
-
-        expect(checkElem.isDisplayed()).toBe(true);
-        checkbox.click();
-        expect(checkElem.isDisplayed()).toBe(false);
-      });
-    </file>
-  </example>
- */
-var ngHideDirective = ['$animate', function($animate) {
-  return {
-    restrict: 'A',
-    multiElement: true,
-    link: function(scope, element, attr) {
-      scope.$watch(attr.ngHide, function ngHideWatchAction(value) {
-        // The comment inside of the ngShowDirective explains why we add and
-        // remove a temporary class for the show/hide animation
-        $animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {
-          tempClasses: NG_HIDE_IN_PROGRESS_CLASS
-        });
-      });
-    }
-  };
-}];
-
-/**
- * @ngdoc directive
- * @name ngStyle
- * @restrict AC
- *
- * @description
- * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally.
- *
- * @knownIssue
- * You should not use {@link guide/interpolation interpolation} in the value of the `style`
- * attribute, when using the `ngStyle` directive on the same element.
- * See {@link guide/interpolation#known-issues here} for more info.
- *
- * @element ANY
- * @param {expression} ngStyle
- *
- * {@link guide/expression Expression} which evals to an
- * object whose keys are CSS style names and values are corresponding values for those CSS
- * keys.
- *
- * Since some CSS style names are not valid keys for an object, they must be quoted.
- * See the 'background-color' style in the example below.
- *
- * @example
-   <example name="ng-style">
-     <file name="index.html">
-        <input type="button" value="set color" ng-click="myStyle={color:'red'}">
-        <input type="button" value="set background" ng-click="myStyle={'background-color':'blue'}">
-        <input type="button" value="clear" ng-click="myStyle={}">
-        <br/>
-        <span ng-style="myStyle">Sample Text</span>
-        <pre>myStyle={{myStyle}}</pre>
-     </file>
-     <file name="style.css">
-       span {
-         color: black;
-       }
-     </file>
-     <file name="protractor.js" type="protractor">
-       var colorSpan = element(by.css('span'));
-
-       it('should check ng-style', function() {
-         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
-         element(by.css('input[value=\'set color\']')).click();
-         expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
-         element(by.css('input[value=clear]')).click();
-         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
-       });
-     </file>
-   </example>
- */
-var ngStyleDirective = ngDirective(function(scope, element, attr) {
-  scope.$watch(attr.ngStyle, function ngStyleWatchAction(newStyles, oldStyles) {
-    if (oldStyles && (newStyles !== oldStyles)) {
-      forEach(oldStyles, function(val, style) { element.css(style, '');});
-    }
-    if (newStyles) element.css(newStyles);
-  }, true);
-});
-
-/**
- * @ngdoc directive
- * @name ngSwitch
- * @restrict EA
- *
- * @description
- * The `ngSwitch` directive is used to conditionally swap DOM structure on your template based on a scope expression.
- * Elements within `ngSwitch` but without `ngSwitchWhen` or `ngSwitchDefault` directives will be preserved at the location
- * as specified in the template.
- *
- * The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it
- * from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element
- * matches the value obtained from the evaluated expression. In other words, you define a container element
- * (where you place the directive), place an expression on the **`on="..."` attribute**
- * (or the **`ng-switch="..."` attribute**), define any inner elements inside of the directive and place
- * a when attribute per element. The when attribute is used to inform ngSwitch which element to display when the on
- * expression is evaluated. If a matching expression is not found via a when attribute then an element with the default
- * attribute is displayed.
- *
- * <div class="alert alert-info">
- * Be aware that the attribute values to match against cannot be expressions. They are interpreted
- * as literal string values to match against.
- * For example, **`ng-switch-when="someVal"`** will match against the string `"someVal"` not against the
- * value of the expression `$scope.someVal`.
- * </div>
-
- * @animations
- * | Animation                        | Occurs                              |
- * |----------------------------------|-------------------------------------|
- * | {@link ng.$animate#enter enter}  | after the ngSwitch contents change and the matched child element is placed inside the container |
- * | {@link ng.$animate#leave leave}  | after the ngSwitch contents change and just before the former contents are removed from the DOM |
- *
- * @usage
- *
- * ```
- * <ANY ng-switch="expression">
- *   <ANY ng-switch-when="matchValue1">...</ANY>
- *   <ANY ng-switch-when="matchValue2">...</ANY>
- *   <ANY ng-switch-default>...</ANY>
- * </ANY>
- * ```
- *
- *
- * @scope
- * @priority 1200
- * @param {*} ngSwitch|on expression to match against <code>ng-switch-when</code>.
- * On child elements add:
- *
- * * `ngSwitchWhen`: the case statement to match against. If match then this
- *   case will be displayed. If the same match appears multiple times, all the
- *   elements will be displayed. It is possible to associate multiple values to
- *   the same `ngSwitchWhen` by defining the optional attribute
- *   `ngSwitchWhenSeparator`. The separator will be used to split the value of
- *   the `ngSwitchWhen` attribute into multiple tokens, and the element will show
- *   if any of the `ngSwitch` evaluates to any of these tokens.
- * * `ngSwitchDefault`: the default case when no other case match. If there
- *   are multiple default cases, all of them will be displayed when no other
- *   case match.
- *
- *
- * @example
-  <example module="switchExample" deps="angular-animate.js" animations="true" name="ng-switch">
-    <file name="index.html">
-      <div ng-controller="ExampleController">
-        <select ng-model="selection" ng-options="item for item in items">
-        </select>
-        <code>selection={{selection}}</code>
-        <hr/>
-        <div class="animate-switch-container"
-          ng-switch on="selection">
-            <div class="animate-switch" ng-switch-when="settings|options" ng-switch-when-separator="|">Settings Div</div>
-            <div class="animate-switch" ng-switch-when="home">Home Span</div>
-            <div class="animate-switch" ng-switch-default>default</div>
-        </div>
-      </div>
-    </file>
-    <file name="script.js">
-      angular.module('switchExample', ['ngAnimate'])
-        .controller('ExampleController', ['$scope', function($scope) {
-          $scope.items = ['settings', 'home', 'options', 'other'];
-          $scope.selection = $scope.items[0];
-        }]);
-    </file>
-    <file name="animations.css">
-      .animate-switch-container {
-        position:relative;
-        background:white;
-        border:1px solid black;
-        height:40px;
-        overflow:hidden;
-      }
-
-      .animate-switch {
-        padding:10px;
-      }
-
-      .animate-switch.ng-animate {
-        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-
-        position:absolute;
-        top:0;
-        left:0;
-        right:0;
-        bottom:0;
-      }
-
-      .animate-switch.ng-leave.ng-leave-active,
-      .animate-switch.ng-enter {
-        top:-50px;
-      }
-      .animate-switch.ng-leave,
-      .animate-switch.ng-enter.ng-enter-active {
-        top:0;
-      }
-    </file>
-    <file name="protractor.js" type="protractor">
-      var switchElem = element(by.css('[ng-switch]'));
-      var select = element(by.model('selection'));
-
-      it('should start in settings', function() {
-        expect(switchElem.getText()).toMatch(/Settings Div/);
-      });
-      it('should change to home', function() {
-        select.all(by.css('option')).get(1).click();
-        expect(switchElem.getText()).toMatch(/Home Span/);
-      });
-      it('should change to settings via "options"', function() {
-        select.all(by.css('option')).get(2).click();
-        expect(switchElem.getText()).toMatch(/Settings Div/);
-      });
-      it('should select default', function() {
-        select.all(by.css('option')).get(3).click();
-        expect(switchElem.getText()).toMatch(/default/);
-      });
-    </file>
-  </example>
- */
-var ngSwitchDirective = ['$animate', '$compile', function($animate, $compile) {
-  return {
-    require: 'ngSwitch',
-
-    // asks for $scope to fool the BC controller module
-    controller: ['$scope', function NgSwitchController() {
-     this.cases = {};
-    }],
-    link: function(scope, element, attr, ngSwitchController) {
-      var watchExpr = attr.ngSwitch || attr.on,
-          selectedTranscludes = [],
-          selectedElements = [],
-          previousLeaveAnimations = [],
-          selectedScopes = [];
-
-      var spliceFactory = function(array, index) {
-          return function(response) {
-            if (response !== false) array.splice(index, 1);
-          };
-      };
-
-      scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
-        var i, ii;
-
-        // Start with the last, in case the array is modified during the loop
-        while (previousLeaveAnimations.length) {
-          $animate.cancel(previousLeaveAnimations.pop());
-        }
-
-        for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
-          var selected = getBlockNodes(selectedElements[i].clone);
-          selectedScopes[i].$destroy();
-          var runner = previousLeaveAnimations[i] = $animate.leave(selected);
-          runner.done(spliceFactory(previousLeaveAnimations, i));
-        }
-
-        selectedElements.length = 0;
-        selectedScopes.length = 0;
-
-        if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
-          forEach(selectedTranscludes, function(selectedTransclude) {
-            selectedTransclude.transclude(function(caseElement, selectedScope) {
-              selectedScopes.push(selectedScope);
-              var anchor = selectedTransclude.element;
-              caseElement[caseElement.length++] = $compile.$$createComment('end ngSwitchWhen');
-              var block = { clone: caseElement };
-
-              selectedElements.push(block);
-              $animate.enter(caseElement, anchor.parent(), anchor);
-            });
-          });
-        }
-      });
-    }
-  };
-}];
-
-var ngSwitchWhenDirective = ngDirective({
-  transclude: 'element',
-  priority: 1200,
-  require: '^ngSwitch',
-  multiElement: true,
-  link: function(scope, element, attrs, ctrl, $transclude) {
-
-    var cases = attrs.ngSwitchWhen.split(attrs.ngSwitchWhenSeparator).sort().filter(
-      // Filter duplicate cases
-      function(element, index, array) { return array[index - 1] !== element; }
-    );
-
-    forEach(cases, function(whenCase) {
-      ctrl.cases['!' + whenCase] = (ctrl.cases['!' + whenCase] || []);
-      ctrl.cases['!' + whenCase].push({ transclude: $transclude, element: element });
-    });
-  }
-});
-
-var ngSwitchDefaultDirective = ngDirective({
-  transclude: 'element',
-  priority: 1200,
-  require: '^ngSwitch',
-  multiElement: true,
-  link: function(scope, element, attr, ctrl, $transclude) {
-    ctrl.cases['?'] = (ctrl.cases['?'] || []);
-    ctrl.cases['?'].push({ transclude: $transclude, element: element });
-   }
-});
-
-/**
- * @ngdoc directive
- * @name ngTransclude
- * @restrict EAC
- *
- * @description
- * Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
- *
- * You can specify that you want to insert a named transclusion slot, instead of the default slot, by providing the slot name
- * as the value of the `ng-transclude` or `ng-transclude-slot` attribute.
- *
- * If the transcluded content is not empty (i.e. contains one or more DOM nodes, including whitespace text nodes), any existing
- * content of this element will be removed before the transcluded content is inserted.
- * If the transcluded content is empty (or only whitespace), the existing content is left intact. This lets you provide fallback
- * content in the case that no transcluded content is provided.
- *
- * @element ANY
- *
- * @param {string} ngTransclude|ngTranscludeSlot the name of the slot to insert at this point. If this is not provided, is empty
- *                                               or its value is the same as the name of the attribute then the default slot is used.
- *
- * @example
- * ### Basic transclusion
- * This example demonstrates basic transclusion of content into a component directive.
- * <example name="simpleTranscludeExample" module="transcludeExample">
- *   <file name="index.html">
- *     <script>
- *       angular.module('transcludeExample', [])
- *        .directive('pane', function(){
- *           return {
- *             restrict: 'E',
- *             transclude: true,
- *             scope: { title:'@' },
- *             template: '<div style="border: 1px solid black;">' +
- *                         '<div style="background-color: gray">{{title}}</div>' +
- *                         '<ng-transclude></ng-transclude>' +
- *                       '</div>'
- *           };
- *       })
- *       .controller('ExampleController', ['$scope', function($scope) {
- *         $scope.title = 'Lorem Ipsum';
- *         $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
- *       }]);
- *     </script>
- *     <div ng-controller="ExampleController">
- *       <input ng-model="title" aria-label="title"> <br/>
- *       <textarea ng-model="text" aria-label="text"></textarea> <br/>
- *       <pane title="{{title}}"><span>{{text}}</span></pane>
- *     </div>
- *   </file>
- *   <file name="protractor.js" type="protractor">
- *      it('should have transcluded', function() {
- *        var titleElement = element(by.model('title'));
- *        titleElement.clear();
- *        titleElement.sendKeys('TITLE');
- *        var textElement = element(by.model('text'));
- *        textElement.clear();
- *        textElement.sendKeys('TEXT');
- *        expect(element(by.binding('title')).getText()).toEqual('TITLE');
- *        expect(element(by.binding('text')).getText()).toEqual('TEXT');
- *      });
- *   </file>
- * </example>
- *
- * @example
- * ### Transclude fallback content
- * This example shows how to use `NgTransclude` with fallback content, that
- * is displayed if no transcluded content is provided.
- *
- * <example module="transcludeFallbackContentExample" name="ng-transclude">
- * <file name="index.html">
- * <script>
- * angular.module('transcludeFallbackContentExample', [])
- * .directive('myButton', function(){
- *             return {
- *               restrict: 'E',
- *               transclude: true,
- *               scope: true,
- *               template: '<button style="cursor: pointer;">' +
- *                           '<ng-transclude>' +
- *                             '<b style="color: red;">Button1</b>' +
- *                           '</ng-transclude>' +
- *                         '</button>'
- *             };
- *         });
- * </script>
- * <!-- fallback button content -->
- * <my-button id="fallback"></my-button>
- * <!-- modified button content -->
- * <my-button id="modified">
- *   <i style="color: green;">Button2</i>
- * </my-button>
- * </file>
- * <file name="protractor.js" type="protractor">
- * it('should have different transclude element content', function() {
- *          expect(element(by.id('fallback')).getText()).toBe('Button1');
- *          expect(element(by.id('modified')).getText()).toBe('Button2');
- *        });
- * </file>
- * </example>
- *
- * @example
- * ### Multi-slot transclusion
- * This example demonstrates using multi-slot transclusion in a component directive.
- * <example name="multiSlotTranscludeExample" module="multiSlotTranscludeExample">
- *   <file name="index.html">
- *    <style>
- *      .title, .footer {
- *        background-color: gray
- *      }
- *    </style>
- *    <div ng-controller="ExampleController">
- *      <input ng-model="title" aria-label="title"> <br/>
- *      <textarea ng-model="text" aria-label="text"></textarea> <br/>
- *      <pane>
- *        <pane-title><a ng-href="{{link}}">{{title}}</a></pane-title>
- *        <pane-body><p>{{text}}</p></pane-body>
- *      </pane>
- *    </div>
- *   </file>
- *   <file name="app.js">
- *    angular.module('multiSlotTranscludeExample', [])
- *     .directive('pane', function() {
- *        return {
- *          restrict: 'E',
- *          transclude: {
- *            'title': '?paneTitle',
- *            'body': 'paneBody',
- *            'footer': '?paneFooter'
- *          },
- *          template: '<div style="border: 1px solid black;">' +
- *                      '<div class="title" ng-transclude="title">Fallback Title</div>' +
- *                      '<div ng-transclude="body"></div>' +
- *                      '<div class="footer" ng-transclude="footer">Fallback Footer</div>' +
- *                    '</div>'
- *        };
- *    })
- *    .controller('ExampleController', ['$scope', function($scope) {
- *      $scope.title = 'Lorem Ipsum';
- *      $scope.link = 'https://google.com';
- *      $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
- *    }]);
- *   </file>
- *   <file name="protractor.js" type="protractor">
- *      it('should have transcluded the title and the body', function() {
- *        var titleElement = element(by.model('title'));
- *        titleElement.clear();
- *        titleElement.sendKeys('TITLE');
- *        var textElement = element(by.model('text'));
- *        textElement.clear();
- *        textElement.sendKeys('TEXT');
- *        expect(element(by.css('.title')).getText()).toEqual('TITLE');
- *        expect(element(by.binding('text')).getText()).toEqual('TEXT');
- *        expect(element(by.css('.footer')).getText()).toEqual('Fallback Footer');
- *      });
- *   </file>
- * </example>
- */
-var ngTranscludeMinErr = minErr('ngTransclude');
-var ngTranscludeDirective = ['$compile', function($compile) {
-  return {
-    restrict: 'EAC',
-    terminal: true,
-    compile: function ngTranscludeCompile(tElement) {
-
-      // Remove and cache any original content to act as a fallback
-      var fallbackLinkFn = $compile(tElement.contents());
-      tElement.empty();
-
-      return function ngTranscludePostLink($scope, $element, $attrs, controller, $transclude) {
-
-        if (!$transclude) {
-          throw ngTranscludeMinErr('orphan',
-          'Illegal use of ngTransclude directive in the template! ' +
-          'No parent directive that requires a transclusion found. ' +
-          'Element: {0}',
-          startingTag($element));
-        }
-
-
-        // If the attribute is of the form: `ng-transclude="ng-transclude"` then treat it like the default
-        if ($attrs.ngTransclude === $attrs.$attr.ngTransclude) {
-          $attrs.ngTransclude = '';
-        }
-        var slotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot;
-
-        // If the slot is required and no transclusion content is provided then this call will throw an error
-        $transclude(ngTranscludeCloneAttachFn, null, slotName);
-
-        // If the slot is optional and no transclusion content is provided then use the fallback content
-        if (slotName && !$transclude.isSlotFilled(slotName)) {
-          useFallbackContent();
-        }
-
-        function ngTranscludeCloneAttachFn(clone, transcludedScope) {
-          if (clone.length && notWhitespace(clone)) {
-            $element.append(clone);
-          } else {
-            useFallbackContent();
-            // There is nothing linked against the transcluded scope since no content was available,
-            // so it should be safe to clean up the generated scope.
-            transcludedScope.$destroy();
-          }
-        }
-
-        function useFallbackContent() {
-          // Since this is the fallback content rather than the transcluded content,
-          // we link against the scope of this directive rather than the transcluded scope
-          fallbackLinkFn($scope, function(clone) {
-            $element.append(clone);
-          });
-        }
-
-        function notWhitespace(nodes) {
-          for (var i = 0, ii = nodes.length; i < ii; i++) {
-            var node = nodes[i];
-            if (node.nodeType !== NODE_TYPE_TEXT || node.nodeValue.trim()) {
-              return true;
-            }
-          }
-        }
-      };
-    }
-  };
-}];
-
-/**
- * @ngdoc directive
- * @name script
- * @restrict E
- *
- * @description
- * Load the content of a `<script>` element into {@link ng.$templateCache `$templateCache`}, so that the
- * template can be used by {@link ng.directive:ngInclude `ngInclude`},
- * {@link ngRoute.directive:ngView `ngView`}, or {@link guide/directive directives}. The type of the
- * `<script>` element must be specified as `text/ng-template`, and a cache name for the template must be
- * assigned through the element's `id`, which can then be used as a directive's `templateUrl`.
- *
- * @param {string} type Must be set to `'text/ng-template'`.
- * @param {string} id Cache name of the template.
- *
- * @example
-  <example  name="script-tag">
-    <file name="index.html">
-      <script type="text/ng-template" id="/tpl.html">
-        Content of the template.
-      </script>
-
-      <a ng-click="currentTpl='/tpl.html'" id="tpl-link">Load inlined template</a>
-      <div id="tpl-content" ng-include src="currentTpl"></div>
-    </file>
-    <file name="protractor.js" type="protractor">
-      it('should load template defined inside script tag', function() {
-        element(by.css('#tpl-link')).click();
-        expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);
-      });
-    </file>
-  </example>
- */
-var scriptDirective = ['$templateCache', function($templateCache) {
-  return {
-    restrict: 'E',
-    terminal: true,
-    compile: function(element, attr) {
-      if (attr.type === 'text/ng-template') {
-        var templateUrl = attr.id,
-            text = element[0].text;
-
-        $templateCache.put(templateUrl, text);
-      }
-    }
-  };
-}];
-
-/* exported selectDirective, optionDirective */
-
-var noopNgModelController = { $setViewValue: noop, $render: noop };
-
-function setOptionSelectedStatus(optionEl, value) {
-  optionEl.prop('selected', value); // needed for IE
-  /**
-   * When unselecting an option, setting the property to null / false should be enough
-   * However, screenreaders might react to the selected attribute instead, see
-   * https://github.com/angular/angular.js/issues/14419
-   * Note: "selected" is a boolean attr and will be removed when the "value" arg in attr() is false
-   * or null
-   */
-  optionEl.attr('selected', value);
-}
-
-/**
- * @ngdoc type
- * @name  select.SelectController
- * @description
- * The controller for the `<select>` directive. This provides support for reading
- * and writing the selected value(s) of the control and also coordinates dynamically
- * added `<option>` elements, perhaps by an `ngRepeat` directive.
- */
-var SelectController =
-        ['$element', '$scope', /** @this */ function($element, $scope) {
-
-  var self = this,
-      optionsMap = new NgMap();
-
-  self.selectValueMap = {}; // Keys are the hashed values, values the original values
-
-  // If the ngModel doesn't get provided then provide a dummy noop version to prevent errors
-  self.ngModelCtrl = noopNgModelController;
-  self.multiple = false;
-
-  // The "unknown" option is one that is prepended to the list if the viewValue
-  // does not match any of the options. When it is rendered the value of the unknown
-  // option is '? XXX ?' where XXX is the hashKey of the value that is not known.
-  //
-  // We can't just jqLite('<option>') since jqLite is not smart enough
-  // to create it in <select> and IE barfs otherwise.
-  self.unknownOption = jqLite(window.document.createElement('option'));
-
-  // The empty option is an option with the value '' that te application developer can
-  // provide inside the select. When the model changes to a value that doesn't match an option,
-  // it is selected - so if an empty option is provided, no unknown option is generated.
-  // However, the empty option is not removed when the model matches an option. It is always selectable
-  // and indicates that a "null" selection has been made.
-  self.hasEmptyOption = false;
-  self.emptyOption = undefined;
-
-  self.renderUnknownOption = function(val) {
-    var unknownVal = self.generateUnknownOptionValue(val);
-    self.unknownOption.val(unknownVal);
-    $element.prepend(self.unknownOption);
-    setOptionSelectedStatus(self.unknownOption, true);
-    $element.val(unknownVal);
-  };
-
-  self.updateUnknownOption = function(val) {
-    var unknownVal = self.generateUnknownOptionValue(val);
-    self.unknownOption.val(unknownVal);
-    setOptionSelectedStatus(self.unknownOption, true);
-    $element.val(unknownVal);
-  };
-
-  self.generateUnknownOptionValue = function(val) {
-    return '? ' + hashKey(val) + ' ?';
-  };
-
-  self.removeUnknownOption = function() {
-    if (self.unknownOption.parent()) self.unknownOption.remove();
-  };
-
-  self.selectEmptyOption = function() {
-    if (self.emptyOption) {
-      $element.val('');
-      setOptionSelectedStatus(self.emptyOption, true);
-    }
-  };
-
-  self.unselectEmptyOption = function() {
-    if (self.hasEmptyOption) {
-      self.emptyOption.removeAttr('selected');
-    }
-  };
-
-  $scope.$on('$destroy', function() {
-    // disable unknown option so that we don't do work when the whole select is being destroyed
-    self.renderUnknownOption = noop;
-  });
-
-  // Read the value of the select control, the implementation of this changes depending
-  // upon whether the select can have multiple values and whether ngOptions is at work.
-  self.readValue = function readSingleValue() {
-    var val = $element.val();
-    // ngValue added option values are stored in the selectValueMap, normal interpolations are not
-    var realVal = val in self.selectValueMap ? self.selectValueMap[val] : val;
-
-    if (self.hasOption(realVal)) {
-      return realVal;
-    }
-
-    return null;
-  };
-
-
-  // Write the value to the select control, the implementation of this changes depending
-  // upon whether the select can have multiple values and whether ngOptions is at work.
-  self.writeValue = function writeSingleValue(value) {
-    // Make sure to remove the selected attribute from the previously selected option
-    // Otherwise, screen readers might get confused
-    var currentlySelectedOption = $element[0].options[$element[0].selectedIndex];
-    if (currentlySelectedOption) setOptionSelectedStatus(jqLite(currentlySelectedOption), false);
-
-    if (self.hasOption(value)) {
-      self.removeUnknownOption();
-
-      var hashedVal = hashKey(value);
-      $element.val(hashedVal in self.selectValueMap ? hashedVal : value);
-
-      // Set selected attribute and property on selected option for screen readers
-      var selectedOption = $element[0].options[$element[0].selectedIndex];
-      setOptionSelectedStatus(jqLite(selectedOption), true);
-    } else {
-      if (value == null && self.emptyOption) {
-        self.removeUnknownOption();
-        self.selectEmptyOption();
-      } else if (self.unknownOption.parent().length) {
-        self.updateUnknownOption(value);
-      } else {
-        self.renderUnknownOption(value);
-      }
-    }
-  };
-
-
-  // Tell the select control that an option, with the given value, has been added
-  self.addOption = function(value, element) {
-    // Skip comment nodes, as they only pollute the `optionsMap`
-    if (element[0].nodeType === NODE_TYPE_COMMENT) return;
-
-    assertNotHasOwnProperty(value, '"option value"');
-    if (value === '') {
-      self.hasEmptyOption = true;
-      self.emptyOption = element;
-    }
-    var count = optionsMap.get(value) || 0;
-    optionsMap.set(value, count + 1);
-    // Only render at the end of a digest. This improves render performance when many options
-    // are added during a digest and ensures all relevant options are correctly marked as selected
-    scheduleRender();
-  };
-
-  // Tell the select control that an option, with the given value, has been removed
-  self.removeOption = function(value) {
-    var count = optionsMap.get(value);
-    if (count) {
-      if (count === 1) {
-        optionsMap.delete(value);
-        if (value === '') {
-          self.hasEmptyOption = false;
-          self.emptyOption = undefined;
-        }
-      } else {
-        optionsMap.set(value, count - 1);
-      }
-    }
-  };
-
-  // Check whether the select control has an option matching the given value
-  self.hasOption = function(value) {
-    return !!optionsMap.get(value);
-  };
-
-
-  var renderScheduled = false;
-  function scheduleRender() {
-    if (renderScheduled) return;
-    renderScheduled = true;
-    $scope.$$postDigest(function() {
-      renderScheduled = false;
-      self.ngModelCtrl.$render();
-    });
-  }
-
-  var updateScheduled = false;
-  function scheduleViewValueUpdate(renderAfter) {
-    if (updateScheduled) return;
-
-    updateScheduled = true;
-
-    $scope.$$postDigest(function() {
-      if ($scope.$$destroyed) return;
-
-      updateScheduled = false;
-      self.ngModelCtrl.$setViewValue(self.readValue());
-      if (renderAfter) self.ngModelCtrl.$render();
-    });
-  }
-
-
-  self.registerOption = function(optionScope, optionElement, optionAttrs, interpolateValueFn, interpolateTextFn) {
-
-    if (optionAttrs.$attr.ngValue) {
-      // The value attribute is set by ngValue
-      var oldVal, hashedVal = NaN;
-      optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {
-
-        var removal;
-        var previouslySelected = optionElement.prop('selected');
-
-        if (isDefined(hashedVal)) {
-          self.removeOption(oldVal);
-          delete self.selectValueMap[hashedVal];
-          removal = true;
-        }
-
-        hashedVal = hashKey(newVal);
-        oldVal = newVal;
-        self.selectValueMap[hashedVal] = newVal;
-        self.addOption(newVal, optionElement);
-        // Set the attribute directly instead of using optionAttrs.$set - this stops the observer
-        // from firing a second time. Other $observers on value will also get the result of the
-        // ngValue expression, not the hashed value
-        optionElement.attr('value', hashedVal);
-
-        if (removal && previouslySelected) {
-          scheduleViewValueUpdate();
-        }
-
-      });
-    } else if (interpolateValueFn) {
-      // The value attribute is interpolated
-      optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {
-        // This method is overwritten in ngOptions and has side-effects!
-        self.readValue();
-
-        var removal;
-        var previouslySelected = optionElement.prop('selected');
-
-        if (isDefined(oldVal)) {
-          self.removeOption(oldVal);
-          removal = true;
-        }
-        oldVal = newVal;
-        self.addOption(newVal, optionElement);
-
-        if (removal && previouslySelected) {
-          scheduleViewValueUpdate();
-        }
-      });
-    } else if (interpolateTextFn) {
-      // The text content is interpolated
-      optionScope.$watch(interpolateTextFn, function interpolateWatchAction(newVal, oldVal) {
-        optionAttrs.$set('value', newVal);
-        var previouslySelected = optionElement.prop('selected');
-        if (oldVal !== newVal) {
-          self.removeOption(oldVal);
-        }
-        self.addOption(newVal, optionElement);
-
-        if (oldVal && previouslySelected) {
-          scheduleViewValueUpdate();
-        }
-      });
-    } else {
-      // The value attribute is static
-      self.addOption(optionAttrs.value, optionElement);
-    }
-
-
-    optionAttrs.$observe('disabled', function(newVal) {
-
-      // Since model updates will also select disabled options (like ngOptions),
-      // we only have to handle options becoming disabled, not enabled
-
-      if (newVal === 'true' || newVal && optionElement.prop('selected')) {
-        if (self.multiple) {
-          scheduleViewValueUpdate(true);
-        } else {
-          self.ngModelCtrl.$setViewValue(null);
-          self.ngModelCtrl.$render();
-        }
-      }
-    });
-
-    optionElement.on('$destroy', function() {
-      var currentValue = self.readValue();
-      var removeValue = optionAttrs.value;
-
-      self.removeOption(removeValue);
-      scheduleRender();
-
-      if (self.multiple && currentValue && currentValue.indexOf(removeValue) !== -1 ||
-          currentValue === removeValue
-      ) {
-        // When multiple (selected) options are destroyed at the same time, we don't want
-        // to run a model update for each of them. Instead, run a single update in the $$postDigest
-        scheduleViewValueUpdate(true);
-      }
-    });
-  };
-}];
-
-/**
- * @ngdoc directive
- * @name select
- * @restrict E
- *
- * @description
- * HTML `select` element with angular data-binding.
- *
- * The `select` directive is used together with {@link ngModel `ngModel`} to provide data-binding
- * between the scope and the `<select>` control (including setting default values).
- * It also handles dynamic `<option>` elements, which can be added using the {@link ngRepeat `ngRepeat}` or
- * {@link ngOptions `ngOptions`} directives.
- *
- * When an item in the `<select>` menu is selected, the value of the selected option will be bound
- * to the model identified by the `ngModel` directive. With static or repeated options, this is
- * the content of the `value` attribute or the textContent of the `<option>`, if the value attribute is missing.
- * Value and textContent can be interpolated.
- *
- * ## Matching model and option values
- *
- * In general, the match between the model and an option is evaluated by strictly comparing the model
- * value against the value of the available options.
- *
- * If you are setting the option value with the option's `value` attribute, or textContent, the
- * value will always be a `string` which means that the model value must also be a string.
- * Otherwise the `select` directive cannot match them correctly.
- *
- * To bind the model to a non-string value, you can use one of the following strategies:
- * - the {@link ng.ngOptions `ngOptions`} directive
- *   ({@link ng.select#using-select-with-ngoptions-and-setting-a-default-value})
- * - the {@link ng.ngValue `ngValue`} directive, which allows arbitrary expressions to be
- *   option values ({@link ng.select#using-ngvalue-to-bind-the-model-to-an-array-of-objects Example})
- * - model $parsers / $formatters to convert the string value
- *   ({@link ng.select#binding-select-to-a-non-string-value-via-ngmodel-parsing-formatting Example})
- *
- * If the viewValue of `ngModel` does not match any of the options, then the control
- * will automatically add an "unknown" option, which it then removes when the mismatch is resolved.
- *
- * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
- * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
- * option. See example below for demonstration.
- *
- * ## Choosing between `ngRepeat` and `ngOptions`
- *
- * In many cases, `ngRepeat` can be used on `<option>` elements instead of {@link ng.directive:ngOptions
- * ngOptions} to achieve a similar result. However, `ngOptions` provides some benefits:
- * - more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the
- * comprehension expression
- * - reduced memory consumption by not creating a new scope for each repeated instance
- * - increased render speed by creating the options in a documentFragment instead of individually
- *
- * Specifically, select with repeated options slows down significantly starting at 2000 options in
- * Chrome and Internet Explorer / Edge.
- *
- *
- * @param {string} ngModel Assignable angular expression to data-bind to.
- * @param {string=} name Property name of the form under which the control is published.
- * @param {string=} multiple Allows multiple options to be selected. The selected values will be
- *     bound to the model as an array.
- * @param {string=} required Sets `required` validation error key if the value is not entered.
- * @param {string=} ngRequired Adds required attribute and required validation constraint to
- * the element when the ngRequired expression evaluates to true. Use ngRequired instead of required
- * when you want to data-bind to the required attribute.
- * @param {string=} ngChange Angular expression to be executed when selected option(s) changes due to user
- *    interaction with the select element.
- * @param {string=} ngOptions sets the options that the select is populated with and defines what is
- * set on the model on selection. See {@link ngOptions `ngOptions`}.
- * @param {string=} ngAttrSize sets the size of the select element dynamically. Uses the
- * {@link guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes ngAttr} directive.
- *
- * @example
- * ### Simple `select` elements with static options
- *
- * <example name="static-select" module="staticSelect">
- * <file name="index.html">
- * <div ng-controller="ExampleController">
- *   <form name="myForm">
- *     <label for="singleSelect"> Single select: </label><br>
- *     <select name="singleSelect" ng-model="data.singleSelect">
- *       <option value="option-1">Option 1</option>
- *       <option value="option-2">Option 2</option>
- *     </select><br>
- *
- *     <label for="singleSelect"> Single select with "not selected" option and dynamic option values: </label><br>
- *     <select name="singleSelect" id="singleSelect" ng-model="data.singleSelect">
- *       <option value="">---Please select---</option> <!-- not selected / blank option -->
- *       <option value="{{data.option1}}">Option 1</option> <!-- interpolation -->
- *       <option value="option-2">Option 2</option>
- *     </select><br>
- *     <button ng-click="forceUnknownOption()">Force unknown option</button><br>
- *     <tt>singleSelect = {{data.singleSelect}}</tt>
- *
- *     <hr>
- *     <label for="multipleSelect"> Multiple select: </label><br>
- *     <select name="multipleSelect" id="multipleSelect" ng-model="data.multipleSelect" multiple>
- *       <option value="option-1">Option 1</option>
- *       <option value="option-2">Option 2</option>
- *       <option value="option-3">Option 3</option>
- *     </select><br>
- *     <tt>multipleSelect = {{data.multipleSelect}}</tt><br/>
- *   </form>
- * </div>
- * </file>
- * <file name="app.js">
- *  angular.module('staticSelect', [])
- *    .controller('ExampleController', ['$scope', function($scope) {
- *      $scope.data = {
- *       singleSelect: null,
- *       multipleSelect: [],
- *       option1: 'option-1'
- *      };
- *
- *      $scope.forceUnknownOption = function() {
- *        $scope.data.singleSelect = 'nonsense';
- *      };
- *   }]);
- * </file>
- *</example>
- *
- * ### Using `ngRepeat` to generate `select` options
- * <example name="select-ngrepeat" module="ngrepeatSelect">
- * <file name="index.html">
- * <div ng-controller="ExampleController">
- *   <form name="myForm">
- *     <label for="repeatSelect"> Repeat select: </label>
- *     <select name="repeatSelect" id="repeatSelect" ng-model="data.model">
- *       <option ng-repeat="option in data.availableOptions" value="{{option.id}}">{{option.name}}</option>
- *     </select>
- *   </form>
- *   <hr>
- *   <tt>model = {{data.model}}</tt><br/>
- * </div>
- * </file>
- * <file name="app.js">
- *  angular.module('ngrepeatSelect', [])
- *    .controller('ExampleController', ['$scope', function($scope) {
- *      $scope.data = {
- *       model: null,
- *       availableOptions: [
- *         {id: '1', name: 'Option A'},
- *         {id: '2', name: 'Option B'},
- *         {id: '3', name: 'Option C'}
- *       ]
- *      };
- *   }]);
- * </file>
- *</example>
- *
- * ### Using `ngValue` to bind the model to an array of objects
- * <example name="select-ngvalue" module="ngvalueSelect">
- * <file name="index.html">
- * <div ng-controller="ExampleController">
- *   <form name="myForm">
- *     <label for="ngvalueselect"> ngvalue select: </label>
- *     <select size="6" name="ngvalueselect" ng-model="data.model" multiple>
- *       <option ng-repeat="option in data.availableOptions" ng-value="option.value">{{option.name}}</option>
- *     </select>
- *   </form>
- *   <hr>
- *   <pre>model = {{data.model | json}}</pre><br/>
- * </div>
- * </file>
- * <file name="app.js">
- *  angular.module('ngvalueSelect', [])
- *    .controller('ExampleController', ['$scope', function($scope) {
- *      $scope.data = {
- *       model: null,
- *       availableOptions: [
-           {value: 'myString', name: 'string'},
-           {value: 1, name: 'integer'},
-           {value: true, name: 'boolean'},
-           {value: null, name: 'null'},
-           {value: {prop: 'value'}, name: 'object'},
-           {value: ['a'], name: 'array'}
- *       ]
- *      };
- *   }]);
- * </file>
- *</example>
- *
- * ### Using `select` with `ngOptions` and setting a default value
- * See the {@link ngOptions ngOptions documentation} for more `ngOptions` usage examples.
- *
- * <example name="select-with-default-values" module="defaultValueSelect">
- * <file name="index.html">
- * <div ng-controller="ExampleController">
- *   <form name="myForm">
- *     <label for="mySelect">Make a choice:</label>
- *     <select name="mySelect" id="mySelect"
- *       ng-options="option.name for option in data.availableOptions track by option.id"
- *       ng-model="data.selectedOption"></select>
- *   </form>
- *   <hr>
- *   <tt>option = {{data.selectedOption}}</tt><br/>
- * </div>
- * </file>
- * <file name="app.js">
- *  angular.module('defaultValueSelect', [])
- *    .controller('ExampleController', ['$scope', function($scope) {
- *      $scope.data = {
- *       availableOptions: [
- *         {id: '1', name: 'Option A'},
- *         {id: '2', name: 'Option B'},
- *         {id: '3', name: 'Option C'}
- *       ],
- *       selectedOption: {id: '3', name: 'Option C'} //This sets the default value of the select in the ui
- *       };
- *   }]);
- * </file>
- *</example>
- *
- *
- * ### Binding `select` to a non-string value via `ngModel` parsing / formatting
- *
- * <example name="select-with-non-string-options" module="nonStringSelect">
- *   <file name="index.html">
- *     <select ng-model="model.id" convert-to-number>
- *       <option value="0">Zero</option>
- *       <option value="1">One</option>
- *       <option value="2">Two</option>
- *     </select>
- *     {{ model }}
- *   </file>
- *   <file name="app.js">
- *     angular.module('nonStringSelect', [])
- *       .run(function($rootScope) {
- *         $rootScope.model = { id: 2 };
- *       })
- *       .directive('convertToNumber', function() {
- *         return {
- *           require: 'ngModel',
- *           link: function(scope, element, attrs, ngModel) {
- *             ngModel.$parsers.push(function(val) {
- *               return parseInt(val, 10);
- *             });
- *             ngModel.$formatters.push(function(val) {
- *               return '' + val;
- *             });
- *           }
- *         };
- *       });
- *   </file>
- *   <file name="protractor.js" type="protractor">
- *     it('should initialize to model', function() {
- *       expect(element(by.model('model.id')).$('option:checked').getText()).toEqual('Two');
- *     });
- *   </file>
- * </example>
- *
- */
-var selectDirective = function() {
-
-  return {
-    restrict: 'E',
-    require: ['select', '?ngModel'],
-    controller: SelectController,
-    priority: 1,
-    link: {
-      pre: selectPreLink,
-      post: selectPostLink
-    }
-  };
-
-  function selectPreLink(scope, element, attr, ctrls) {
-
-      var selectCtrl = ctrls[0];
-      var ngModelCtrl = ctrls[1];
-
-      // if ngModel is not defined, we don't need to do anything but set the registerOption
-      // function to noop, so options don't get added internally
-      if (!ngModelCtrl) {
-        selectCtrl.registerOption = noop;
-        return;
-      }
-
-
-      selectCtrl.ngModelCtrl = ngModelCtrl;
-
-      // When the selected item(s) changes we delegate getting the value of the select control
-      // to the `readValue` method, which can be changed if the select can have multiple
-      // selected values or if the options are being generated by `ngOptions`
-      element.on('change', function() {
-        selectCtrl.removeUnknownOption();
-        scope.$apply(function() {
-          ngModelCtrl.$setViewValue(selectCtrl.readValue());
-        });
-      });
-
-      // If the select allows multiple values then we need to modify how we read and write
-      // values from and to the control; also what it means for the value to be empty and
-      // we have to add an extra watch since ngModel doesn't work well with arrays - it
-      // doesn't trigger rendering if only an item in the array changes.
-      if (attr.multiple) {
-        selectCtrl.multiple = true;
-
-        // Read value now needs to check each option to see if it is selected
-        selectCtrl.readValue = function readMultipleValue() {
-          var array = [];
-          forEach(element.find('option'), function(option) {
-            if (option.selected && !option.disabled) {
-              var val = option.value;
-              array.push(val in selectCtrl.selectValueMap ? selectCtrl.selectValueMap[val] : val);
-            }
-          });
-          return array;
-        };
-
-        // Write value now needs to set the selected property of each matching option
-        selectCtrl.writeValue = function writeMultipleValue(value) {
-          forEach(element.find('option'), function(option) {
-            var shouldBeSelected = !!value && (includes(value, option.value) ||
-                                               includes(value, selectCtrl.selectValueMap[option.value]));
-            var currentlySelected = option.selected;
-
-            // IE and Edge, adding options to the selection via shift+click/UP/DOWN,
-            // will de-select already selected options if "selected" on those options was set
-            // more than once (i.e. when the options were already selected)
-            // So we only modify the selected property if neccessary.
-            // Note: this behavior cannot be replicated via unit tests because it only shows in the
-            // actual user interface.
-            if (shouldBeSelected !== currentlySelected) {
-              setOptionSelectedStatus(jqLite(option), shouldBeSelected);
-            }
-
-          });
-        };
-
-        // we have to do it on each watch since ngModel watches reference, but
-        // we need to work of an array, so we need to see if anything was inserted/removed
-        var lastView, lastViewRef = NaN;
-        scope.$watch(function selectMultipleWatch() {
-          if (lastViewRef === ngModelCtrl.$viewValue && !equals(lastView, ngModelCtrl.$viewValue)) {
-            lastView = shallowCopy(ngModelCtrl.$viewValue);
-            ngModelCtrl.$render();
-          }
-          lastViewRef = ngModelCtrl.$viewValue;
-        });
-
-        // If we are a multiple select then value is now a collection
-        // so the meaning of $isEmpty changes
-        ngModelCtrl.$isEmpty = function(value) {
-          return !value || value.length === 0;
-        };
-
-      }
-    }
-
-    function selectPostLink(scope, element, attrs, ctrls) {
-      // if ngModel is not defined, we don't need to do anything
-      var ngModelCtrl = ctrls[1];
-      if (!ngModelCtrl) return;
-
-      var selectCtrl = ctrls[0];
-
-      // We delegate rendering to the `writeValue` method, which can be changed
-      // if the select can have multiple selected values or if the options are being
-      // generated by `ngOptions`.
-      // This must be done in the postLink fn to prevent $render to be called before
-      // all nodes have been linked correctly.
-      ngModelCtrl.$render = function() {
-        selectCtrl.writeValue(ngModelCtrl.$viewValue);
-      };
-    }
-};
-
-
-// The option directive is purely designed to communicate the existence (or lack of)
-// of dynamically created (and destroyed) option elements to their containing select
-// directive via its controller.
-var optionDirective = ['$interpolate', function($interpolate) {
-  return {
-    restrict: 'E',
-    priority: 100,
-    compile: function(element, attr) {
-      var interpolateValueFn, interpolateTextFn;
-
-      if (isDefined(attr.ngValue)) {
-        // Will be handled by registerOption
-      } else if (isDefined(attr.value)) {
-        // If the value attribute is defined, check if it contains an interpolation
-        interpolateValueFn = $interpolate(attr.value, true);
-      } else {
-        // If the value attribute is not defined then we fall back to the
-        // text content of the option element, which may be interpolated
-        interpolateTextFn = $interpolate(element.text(), true);
-        if (!interpolateTextFn) {
-          attr.$set('value', element.text());
-        }
-      }
-
-      return function(scope, element, attr) {
-        // This is an optimization over using ^^ since we don't want to have to search
-        // all the way to the root of the DOM for every single option element
-        var selectCtrlName = '$selectController',
-            parent = element.parent(),
-            selectCtrl = parent.data(selectCtrlName) ||
-              parent.parent().data(selectCtrlName); // in case we are in optgroup
-
-        if (selectCtrl) {
-          selectCtrl.registerOption(scope, element, attr, interpolateValueFn, interpolateTextFn);
-        }
-      };
-    }
-  };
-}];
-
-/**
- * @ngdoc directive
- * @name ngRequired
- * @restrict A
- *
- * @description
- *
- * ngRequired adds the required {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
- * It is most often used for {@link input `input`} and {@link select `select`} controls, but can also be
- * applied to custom controls.
- *
- * The directive sets the `required` attribute on the element if the Angular expression inside
- * `ngRequired` evaluates to true. A special directive for setting `required` is necessary because we
- * cannot use interpolation inside `required`. See the {@link guide/interpolation interpolation guide}
- * for more info.
- *
- * The validator will set the `required` error key to true if the `required` attribute is set and
- * calling {@link ngModel.NgModelController#$isEmpty `NgModelController.$isEmpty`} with the
- * {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`} returns `true`. For example, the
- * `$isEmpty()` implementation for `input[text]` checks the length of the `$viewValue`. When developing
- * custom controls, `$isEmpty()` can be overwritten to account for a $viewValue that is not string-based.
- *
- * @example
- * <example name="ngRequiredDirective" module="ngRequiredExample">
- *   <file name="index.html">
- *     <script>
- *       angular.module('ngRequiredExample', [])
- *         .controller('ExampleController', ['$scope', function($scope) {
- *           $scope.required = true;
- *         }]);
- *     </script>
- *     <div ng-controller="ExampleController">
- *       <form name="form">
- *         <label for="required">Toggle required: </label>
- *         <input type="checkbox" ng-model="required" id="required" />
- *         <br>
- *         <label for="input">This input must be filled if `required` is true: </label>
- *         <input type="text" ng-model="model" id="input" name="input" ng-required="required" /><br>
- *         <hr>
- *         required error set? = <code>{{form.input.$error.required}}</code><br>
- *         model = <code>{{model}}</code>
- *       </form>
- *     </div>
- *   </file>
- *   <file name="protractor.js" type="protractor">
-       var required = element(by.binding('form.input.$error.required'));
-       var model = element(by.binding('model'));
-       var input = element(by.id('input'));
-
-       it('should set the required error', function() {
-         expect(required.getText()).toContain('true');
-
-         input.sendKeys('123');
-         expect(required.getText()).not.toContain('true');
-         expect(model.getText()).toContain('123');
-       });
- *   </file>
- * </example>
- */
-var requiredDirective = function() {
-  return {
-    restrict: 'A',
-    require: '?ngModel',
-    link: function(scope, elm, attr, ctrl) {
-      if (!ctrl) return;
-      attr.required = true; // force truthy in case we are on non input element
-
-      ctrl.$validators.required = function(modelValue, viewValue) {
-        return !attr.required || !ctrl.$isEmpty(viewValue);
-      };
-
-      attr.$observe('required', function() {
-        ctrl.$validate();
-      });
-    }
-  };
-};
-
-/**
- * @ngdoc directive
- * @name ngPattern
- *
- * @description
- *
- * ngPattern adds the pattern {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
- * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
- *
- * The validator sets the `pattern` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
- * does not match a RegExp which is obtained by evaluating the Angular expression given in the
- * `ngPattern` attribute value:
- * * If the expression evaluates to a RegExp object, then this is used directly.
- * * If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it
- * in `^` and `$` characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
- *
- * <div class="alert alert-info">
- * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
- * start at the index of the last search's match, thus not taking the whole input value into
- * account.
- * </div>
- *
- * <div class="alert alert-info">
- * **Note:** This directive is also added when the plain `pattern` attribute is used, with two
- * differences:
- * <ol>
- *   <li>
- *     `ngPattern` does not set the `pattern` attribute and therefore HTML5 constraint validation is
- *     not available.
- *   </li>
- *   <li>
- *     The `ngPattern` attribute must be an expression, while the `pattern` value must be
- *     interpolated.
- *   </li>
- * </ol>
- * </div>
- *
- * @example
- * <example name="ngPatternDirective" module="ngPatternExample">
- *   <file name="index.html">
- *     <script>
- *       angular.module('ngPatternExample', [])
- *         .controller('ExampleController', ['$scope', function($scope) {
- *           $scope.regex = '\\d+';
- *         }]);
- *     </script>
- *     <div ng-controller="ExampleController">
- *       <form name="form">
- *         <label for="regex">Set a pattern (regex string): </label>
- *         <input type="text" ng-model="regex" id="regex" />
- *         <br>
- *         <label for="input">This input is restricted by the current pattern: </label>
- *         <input type="text" ng-model="model" id="input" name="input" ng-pattern="regex" /><br>
- *         <hr>
- *         input valid? = <code>{{form.input.$valid}}</code><br>
- *         model = <code>{{model}}</code>
- *       </form>
- *     </div>
- *   </file>
- *   <file name="protractor.js" type="protractor">
-       var model = element(by.binding('model'));
-       var input = element(by.id('input'));
-
-       it('should validate the input with the default pattern', function() {
-         input.sendKeys('aaa');
-         expect(model.getText()).not.toContain('aaa');
-
-         input.clear().then(function() {
-           input.sendKeys('123');
-           expect(model.getText()).toContain('123');
-         });
-       });
- *   </file>
- * </example>
- */
-var patternDirective = function() {
-  return {
-    restrict: 'A',
-    require: '?ngModel',
-    link: function(scope, elm, attr, ctrl) {
-      if (!ctrl) return;
-
-      var regexp, patternExp = attr.ngPattern || attr.pattern;
-      attr.$observe('pattern', function(regex) {
-        if (isString(regex) && regex.length > 0) {
-          regex = new RegExp('^' + regex + '$');
-        }
-
-        if (regex && !regex.test) {
-          throw minErr('ngPattern')('noregexp',
-            'Expected {0} to be a RegExp but was {1}. Element: {2}', patternExp,
-            regex, startingTag(elm));
-        }
-
-        regexp = regex || undefined;
-        ctrl.$validate();
-      });
-
-      ctrl.$validators.pattern = function(modelValue, viewValue) {
-        // HTML5 pattern constraint validates the input value, so we validate the viewValue
-        return ctrl.$isEmpty(viewValue) || isUndefined(regexp) || regexp.test(viewValue);
-      };
-    }
-  };
-};
-
-/**
- * @ngdoc directive
- * @name ngMaxlength
- *
- * @description
- *
- * ngMaxlength adds the maxlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
- * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
- *
- * The validator sets the `maxlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
- * is longer than the integer obtained by evaluating the Angular expression given in the
- * `ngMaxlength` attribute value.
- *
- * <div class="alert alert-info">
- * **Note:** This directive is also added when the plain `maxlength` attribute is used, with two
- * differences:
- * <ol>
- *   <li>
- *     `ngMaxlength` does not set the `maxlength` attribute and therefore HTML5 constraint
- *     validation is not available.
- *   </li>
- *   <li>
- *     The `ngMaxlength` attribute must be an expression, while the `maxlength` value must be
- *     interpolated.
- *   </li>
- * </ol>
- * </div>
- *
- * @example
- * <example name="ngMaxlengthDirective" module="ngMaxlengthExample">
- *   <file name="index.html">
- *     <script>
- *       angular.module('ngMaxlengthExample', [])
- *         .controller('ExampleController', ['$scope', function($scope) {
- *           $scope.maxlength = 5;
- *         }]);
- *     </script>
- *     <div ng-controller="ExampleController">
- *       <form name="form">
- *         <label for="maxlength">Set a maxlength: </label>
- *         <input type="number" ng-model="maxlength" id="maxlength" />
- *         <br>
- *         <label for="input">This input is restricted by the current maxlength: </label>
- *         <input type="text" ng-model="model" id="input" name="input" ng-maxlength="maxlength" /><br>
- *         <hr>
- *         input valid? = <code>{{form.input.$valid}}</code><br>
- *         model = <code>{{model}}</code>
- *       </form>
- *     </div>
- *   </file>
- *   <file name="protractor.js" type="protractor">
-       var model = element(by.binding('model'));
-       var input = element(by.id('input'));
-
-       it('should validate the input with the default maxlength', function() {
-         input.sendKeys('abcdef');
-         expect(model.getText()).not.toContain('abcdef');
-
-         input.clear().then(function() {
-           input.sendKeys('abcde');
-           expect(model.getText()).toContain('abcde');
-         });
-       });
- *   </file>
- * </example>
- */
-var maxlengthDirective = function() {
-  return {
-    restrict: 'A',
-    require: '?ngModel',
-    link: function(scope, elm, attr, ctrl) {
-      if (!ctrl) return;
-
-      var maxlength = -1;
-      attr.$observe('maxlength', function(value) {
-        var intVal = toInt(value);
-        maxlength = isNumberNaN(intVal) ? -1 : intVal;
-        ctrl.$validate();
-      });
-      ctrl.$validators.maxlength = function(modelValue, viewValue) {
-        return (maxlength < 0) || ctrl.$isEmpty(viewValue) || (viewValue.length <= maxlength);
-      };
-    }
-  };
-};
-
-/**
- * @ngdoc directive
- * @name ngMinlength
- *
- * @description
- *
- * ngMinlength adds the minlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
- * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
- *
- * The validator sets the `minlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
- * is shorter than the integer obtained by evaluating the Angular expression given in the
- * `ngMinlength` attribute value.
- *
- * <div class="alert alert-info">
- * **Note:** This directive is also added when the plain `minlength` attribute is used, with two
- * differences:
- * <ol>
- *   <li>
- *     `ngMinlength` does not set the `minlength` attribute and therefore HTML5 constraint
- *     validation is not available.
- *   </li>
- *   <li>
- *     The `ngMinlength` value must be an expression, while the `minlength` value must be
- *     interpolated.
- *   </li>
- * </ol>
- * </div>
- *
- * @example
- * <example name="ngMinlengthDirective" module="ngMinlengthExample">
- *   <file name="index.html">
- *     <script>
- *       angular.module('ngMinlengthExample', [])
- *         .controller('ExampleController', ['$scope', function($scope) {
- *           $scope.minlength = 3;
- *         }]);
- *     </script>
- *     <div ng-controller="ExampleController">
- *       <form name="form">
- *         <label for="minlength">Set a minlength: </label>
- *         <input type="number" ng-model="minlength" id="minlength" />
- *         <br>
- *         <label for="input">This input is restricted by the current minlength: </label>
- *         <input type="text" ng-model="model" id="input" name="input" ng-minlength="minlength" /><br>
- *         <hr>
- *         input valid? = <code>{{form.input.$valid}}</code><br>
- *         model = <code>{{model}}</code>
- *       </form>
- *     </div>
- *   </file>
- *   <file name="protractor.js" type="protractor">
-       var model = element(by.binding('model'));
-       var input = element(by.id('input'));
-
-       it('should validate the input with the default minlength', function() {
-         input.sendKeys('ab');
-         expect(model.getText()).not.toContain('ab');
-
-         input.sendKeys('abc');
-         expect(model.getText()).toContain('abc');
-       });
- *   </file>
- * </example>
- */
-var minlengthDirective = function() {
-  return {
-    restrict: 'A',
-    require: '?ngModel',
-    link: function(scope, elm, attr, ctrl) {
-      if (!ctrl) return;
-
-      var minlength = 0;
-      attr.$observe('minlength', function(value) {
-        minlength = toInt(value) || 0;
-        ctrl.$validate();
-      });
-      ctrl.$validators.minlength = function(modelValue, viewValue) {
-        return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
-      };
-    }
-  };
-};
-
-if (window.angular.bootstrap) {
-  // AngularJS is already loaded, so we can return here...
-  if (window.console) {
-    console.log('WARNING: Tried to load angular more than once.');
-  }
-  return;
-}
-
-// try to bind to jquery now so that one can write jqLite(fn)
-// but we will rebind on bootstrap again.
-bindJQuery();
-
-publishExternalAPI(angular);
-
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-function getDecimals(n) {
-  n = n + '';
-  var i = n.indexOf('.');
-  return (i == -1) ? 0 : n.length - i - 1;
-}
-
-function getVF(n, opt_precision) {
-  var v = opt_precision;
-
-  if (undefined === v) {
-    v = Math.min(getDecimals(n), 3);
-  }
-
-  var base = Math.pow(10, v);
-  var f = ((n * base) | 0) % base;
-  return {v: v, f: f};
-}
-
-$provide.value("$locale", {
-  "DATETIME_FORMATS": {
-    "AMPMS": [
-      "AM",
-      "PM"
-    ],
-    "DAY": [
-      "Sunday",
-      "Monday",
-      "Tuesday",
-      "Wednesday",
-      "Thursday",
-      "Friday",
-      "Saturday"
-    ],
-    "ERANAMES": [
-      "Before Christ",
-      "Anno Domini"
-    ],
-    "ERAS": [
-      "BC",
-      "AD"
-    ],
-    "FIRSTDAYOFWEEK": 6,
-    "MONTH": [
-      "January",
-      "February",
-      "March",
-      "April",
-      "May",
-      "June",
-      "July",
-      "August",
-      "September",
-      "October",
-      "November",
-      "December"
-    ],
-    "SHORTDAY": [
-      "Sun",
-      "Mon",
-      "Tue",
-      "Wed",
-      "Thu",
-      "Fri",
-      "Sat"
-    ],
-    "SHORTMONTH": [
-      "Jan",
-      "Feb",
-      "Mar",
-      "Apr",
-      "May",
-      "Jun",
-      "Jul",
-      "Aug",
-      "Sep",
-      "Oct",
-      "Nov",
-      "Dec"
-    ],
-    "STANDALONEMONTH": [
-      "January",
-      "February",
-      "March",
-      "April",
-      "May",
-      "June",
-      "July",
-      "August",
-      "September",
-      "October",
-      "November",
-      "December"
-    ],
-    "WEEKENDRANGE": [
-      5,
-      6
-    ],
-    "fullDate": "EEEE, MMMM d, y",
-    "longDate": "MMMM d, y",
-    "medium": "MMM d, y h:mm:ss a",
-    "mediumDate": "MMM d, y",
-    "mediumTime": "h:mm:ss a",
-    "short": "M/d/yy h:mm a",
-    "shortDate": "M/d/yy",
-    "shortTime": "h:mm a"
-  },
-  "NUMBER_FORMATS": {
-    "CURRENCY_SYM": "$",
-    "DECIMAL_SEP": ".",
-    "GROUP_SEP": ",",
-    "PATTERNS": [
-      {
-        "gSize": 3,
-        "lgSize": 3,
-        "maxFrac": 3,
-        "minFrac": 0,
-        "minInt": 1,
-        "negPre": "-",
-        "negSuf": "",
-        "posPre": "",
-        "posSuf": ""
-      },
-      {
-        "gSize": 3,
-        "lgSize": 3,
-        "maxFrac": 2,
-        "minFrac": 2,
-        "minInt": 1,
-        "negPre": "-\u00a4",
-        "negSuf": "",
-        "posPre": "\u00a4",
-        "posSuf": ""
-      }
-    ]
-  },
-  "id": "en-us",
-  "localeID": "en_US",
-  "pluralCat": function(n, opt_precision) {  var i = n | 0;  var vf = getVF(n, opt_precision);  if (i == 1 && vf.v == 0) {    return PLURAL_CATEGORY.ONE;  }  return PLURAL_CATEGORY.OTHER;}
-});
-}]);
-
-  jqLite(function() {
-    angularInit(window.document, bootstrap);
-  });
-
-})(window);
-
-!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>');
-
-/***/ },
-/* 11 */
-/***/ function(module, exports) {
-
-module.exports = "\n<!--\nCopyright 2017-present Open Networking Foundation\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<div class = \"elinepanel\">\n  <h1>ELine Overview</h1>\n  <form ng-submit=\"vm.saveEline(vm.eng.eline)\">\n    <div class=\"form-group\" ng-hide=\"vm.eng.createMode\">\n      <label>ID</label><br/>\n      <p>{{vm.eng.eline.id}}</p>\n    </div>\n    <div class=\"form-group\">\n      <label for=\"name\">Name</label>\n      <input required class=\"form-control\" id=\"name\" type=\"text\" ng-value=\"vm.eng.eline.name\" ng-model=\"vm.eng.eline.name\">\n    </div>\n    <div class=\"form-group\" ng-hide=\"vm.eng.createMode\">\n      <label>Backend Status</label><br/>\n      <p>{{vm.eng.eline.backend_status}}</p>\n    </div>\n    <div class=\"form-group\">\n      <label for=\"cpi1\">Connect point 1 ID</label>\n      <input required class=\"form-control\" id=\"cpi1\" type=\"text\" ng-value=\"vm.eng.eline.connect_point_1_id\" ng-model=\"vm.eng.eline.connect_point_1_id\">\n    </div>\n    <div class=\"form-group\">\n      <label for=\"cpi2\">Connect point 2 ID</label>\n      <input required class=\"form-control\" id=\"cpi2\" type=\"text\" ng-value=\"vm.eng.eline.connect_point_2_id\" ng-model=\"vm.eng.eline.connect_point_2_id\">\n    </div>\n    <div class=\"form-group\">\n      <label for=\"bwps\">Bandwidth Profile</label>\n      <select required class=\"form-control\"\n              id=\"bwps\"\n              ng-model=\"vm.eng.eline.bwp\"\n              ng-options=\"bwp.name as bwp.name for bwp in vm.eng.bwps | orderBy:'name'\"\n      >\n      </select>\n    </div>\n    <div class=\"form-group\">\n      <label for=\"sitename\">CORD Site Name</label>\n      <input required class=\"form-control\" id=\"sitename\" type=\"text\" ng-value=\"vm.eng.eline.cord_site_name\" ng-model=\"vm.eng.eline.cord_site_name\">\n    </div>\n    <div class=\"form-group\">\n      <label for=\"vlanids\">Vlan IDs</label>\n      <input required class=\"form-control\" id=\"vlanids\" type=\"text\" ng-value=\"vm.eng.eline.vlanids\" ng-model=\"vm.eng.eline.vlanids\">\n    </div>\n    <div class=\"form-group\" style=\"text-align: center\">\n      <button type=\"submit\" class=\"btn btn-success btn-block\">Save Changes</button>\n    </div>\n  </form>\n  <button type=\"button\" class=\"btn btn-danger btn-block\" ng-click=\"vm.eng.elinePanel({}, vm.eng.eline, false)\">Close</button>\n  <button type=\"button\" class=\"btn btn-danger delete-eline\" ng-click=\"vm.deleteEline(vm.eng.eline)\">Delete Eline</button>\n</div>";
-
-/***/ },
-/* 12 */
-/***/ function(module, exports) {
-
-module.exports = "\n<!--\nCopyright 2017-present Open Networking Foundation\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n\n<div class = \"row\">\n  <div class = \"col-xs-12\">\n    <h1>Enterprise Network Map</h1>\n    <div map-lazy-load=\"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4\">\n      <ng-map\n        default-style=\"false\"\n        id=\"foobar\"\n        center=\"0,0\"\n        disable-default-u-i=\"true\"\n        map-type-id=\"ROADMAP\"\n        zoom-control=\"true\"\n        min-zoom=\"2\"\n        styles=\"{{vm.mapStyles}}\"\n      >\n        <!--Markers-->\n        <marker\n          ng-repeat=\"uni in vm.unis\"\n          id=\"marker-{{uni.id}}\"\n          position=\"{{uni.latlng.toString()}}\"\n          icon=\"{{vm.MapConfig.marker}}\"\n          on-click=\"vm.showUni(uni)\"\n        >\n        </marker>\n\n        <!--Marker Info Window-->\n\n        <info-window id = \"uni-info\">\n          <div class = \"marker-info\">\n            <h4>{{vm.current_uni.name}}</h4>\n            <p>\n              <b>LatLng: </b>{{vm.current_uni.latlng.toString()}}<br/>\n              <b>Cpe id: </b>{{vm.current_uni.cpe_id}}<br/>\n              <b>Tenant: </b>{{vm.current_uni.tenant}}<br/>\n            </p>\n            <button ng-show=\"vm.canCreateEline\" ng-click=\"vm.createConnection(vm.current_uni)()\">Create connection</button>\n            <button ng-show=\"!vm.canCreateEline && !uni.eline_start\" ng-click=\"vm.finishConnection(vm.current_uni)\">Finish connection</button>\n          </div>\n        </info-window>\n\n        <!--Connections-->\n\n        <shape\n          ng-repeat=\"eline in vm.elines\"\n          name=\"polyline\"\n          id=\"eline-{{eline.id}}\"\n          path=\"{{eline.path}}\"\n          stroke-color=\"{{vm.colorLine(eline.backend_status)}}\"\n          stroke-opacity=\"1.0\"\n          stroke-weight=\"5\"\n          on-click=\"vm.elinePanel({{eline}}, true)\"\n        >\n        </shape>\n\n      </ng-map>\n\n    </div>\n    Changes may not display until page refresh.\n  </div>\n</div>\n<!--\"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4\"-->";
-
-/***/ },
-/* 13 */
-/***/ function(module, exports, __webpack_require__) {
-
-/* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_RESULT__;/**
- * @license
- * Lodash <https://lodash.com/>
- * Copyright JS Foundation and other contributors <https://js.foundation/>
- * Released under MIT license <https://lodash.com/license>
- * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
- * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
- */
-;(function() {
-
-  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
-  var undefined;
-
-  /** Used as the semantic version number. */
-  var VERSION = '4.17.4';
-
-  /** Used as the size to enable large array optimizations. */
-  var LARGE_ARRAY_SIZE = 200;
-
-  /** Error message constants. */
-  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
-      FUNC_ERROR_TEXT = 'Expected a function';
-
-  /** Used to stand-in for `undefined` hash values. */
-  var HASH_UNDEFINED = '__lodash_hash_undefined__';
-
-  /** Used as the maximum memoize cache size. */
-  var MAX_MEMOIZE_SIZE = 500;
-
-  /** Used as the internal argument placeholder. */
-  var PLACEHOLDER = '__lodash_placeholder__';
-
-  /** Used to compose bitmasks for cloning. */
-  var CLONE_DEEP_FLAG = 1,
-      CLONE_FLAT_FLAG = 2,
-      CLONE_SYMBOLS_FLAG = 4;
-
-  /** Used to compose bitmasks for value comparisons. */
-  var COMPARE_PARTIAL_FLAG = 1,
-      COMPARE_UNORDERED_FLAG = 2;
-
-  /** Used to compose bitmasks for function metadata. */
-  var WRAP_BIND_FLAG = 1,
-      WRAP_BIND_KEY_FLAG = 2,
-      WRAP_CURRY_BOUND_FLAG = 4,
-      WRAP_CURRY_FLAG = 8,
-      WRAP_CURRY_RIGHT_FLAG = 16,
-      WRAP_PARTIAL_FLAG = 32,
-      WRAP_PARTIAL_RIGHT_FLAG = 64,
-      WRAP_ARY_FLAG = 128,
-      WRAP_REARG_FLAG = 256,
-      WRAP_FLIP_FLAG = 512;
-
-  /** Used as default options for `_.truncate`. */
-  var DEFAULT_TRUNC_LENGTH = 30,
-      DEFAULT_TRUNC_OMISSION = '...';
-
-  /** Used to detect hot functions by number of calls within a span of milliseconds. */
-  var HOT_COUNT = 800,
-      HOT_SPAN = 16;
-
-  /** Used to indicate the type of lazy iteratees. */
-  var LAZY_FILTER_FLAG = 1,
-      LAZY_MAP_FLAG = 2,
-      LAZY_WHILE_FLAG = 3;
-
-  /** Used as references for various `Number` constants. */
-  var INFINITY = 1 / 0,
-      MAX_SAFE_INTEGER = 9007199254740991,
-      MAX_INTEGER = 1.7976931348623157e+308,
-      NAN = 0 / 0;
-
-  /** Used as references for the maximum length and index of an array. */
-  var MAX_ARRAY_LENGTH = 4294967295,
-      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
-      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
-
-  /** Used to associate wrap methods with their bit flags. */
-  var wrapFlags = [
-    ['ary', WRAP_ARY_FLAG],
-    ['bind', WRAP_BIND_FLAG],
-    ['bindKey', WRAP_BIND_KEY_FLAG],
-    ['curry', WRAP_CURRY_FLAG],
-    ['curryRight', WRAP_CURRY_RIGHT_FLAG],
-    ['flip', WRAP_FLIP_FLAG],
-    ['partial', WRAP_PARTIAL_FLAG],
-    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
-    ['rearg', WRAP_REARG_FLAG]
-  ];
-
-  /** `Object#toString` result references. */
-  var argsTag = '[object Arguments]',
-      arrayTag = '[object Array]',
-      asyncTag = '[object AsyncFunction]',
-      boolTag = '[object Boolean]',
-      dateTag = '[object Date]',
-      domExcTag = '[object DOMException]',
-      errorTag = '[object Error]',
-      funcTag = '[object Function]',
-      genTag = '[object GeneratorFunction]',
-      mapTag = '[object Map]',
-      numberTag = '[object Number]',
-      nullTag = '[object Null]',
-      objectTag = '[object Object]',
-      promiseTag = '[object Promise]',
-      proxyTag = '[object Proxy]',
-      regexpTag = '[object RegExp]',
-      setTag = '[object Set]',
-      stringTag = '[object String]',
-      symbolTag = '[object Symbol]',
-      undefinedTag = '[object Undefined]',
-      weakMapTag = '[object WeakMap]',
-      weakSetTag = '[object WeakSet]';
-
-  var arrayBufferTag = '[object ArrayBuffer]',
-      dataViewTag = '[object DataView]',
-      float32Tag = '[object Float32Array]',
-      float64Tag = '[object Float64Array]',
-      int8Tag = '[object Int8Array]',
-      int16Tag = '[object Int16Array]',
-      int32Tag = '[object Int32Array]',
-      uint8Tag = '[object Uint8Array]',
-      uint8ClampedTag = '[object Uint8ClampedArray]',
-      uint16Tag = '[object Uint16Array]',
-      uint32Tag = '[object Uint32Array]';
-
-  /** Used to match empty string literals in compiled template source. */
-  var reEmptyStringLeading = /\b__p \+= '';/g,
-      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
-      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-
-  /** Used to match HTML entities and HTML characters. */
-  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
-      reUnescapedHtml = /[&<>"']/g,
-      reHasEscapedHtml = RegExp(reEscapedHtml.source),
-      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
-
-  /** Used to match template delimiters. */
-  var reEscape = /<%-([\s\S]+?)%>/g,
-      reEvaluate = /<%([\s\S]+?)%>/g,
-      reInterpolate = /<%=([\s\S]+?)%>/g;
-
-  /** Used to match property names within property paths. */
-  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
-      reIsPlainProp = /^\w*$/,
-      reLeadingDot = /^\./,
-      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
-
-  /**
-   * Used to match `RegExp`
-   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
-   */
-  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
-      reHasRegExpChar = RegExp(reRegExpChar.source);
-
-  /** Used to match leading and trailing whitespace. */
-  var reTrim = /^\s+|\s+$/g,
-      reTrimStart = /^\s+/,
-      reTrimEnd = /\s+$/;
-
-  /** Used to match wrap detail comments. */
-  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
-      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
-      reSplitDetails = /,? & /;
-
-  /** Used to match words composed of alphanumeric characters. */
-  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
-
-  /** Used to match backslashes in property paths. */
-  var reEscapeChar = /\\(\\)?/g;
-
-  /**
-   * Used to match
-   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
-   */
-  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
-
-  /** Used to match `RegExp` flags from their coerced string values. */
-  var reFlags = /\w*$/;
-
-  /** Used to detect bad signed hexadecimal string values. */
-  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
-
-  /** Used to detect binary string values. */
-  var reIsBinary = /^0b[01]+$/i;
-
-  /** Used to detect host constructors (Safari). */
-  var reIsHostCtor = /^\[object .+?Constructor\]$/;
-
-  /** Used to detect octal string values. */
-  var reIsOctal = /^0o[0-7]+$/i;
-
-  /** Used to detect unsigned integer values. */
-  var reIsUint = /^(?:0|[1-9]\d*)$/;
-
-  /** Used to match Latin Unicode letters (excluding mathematical operators). */
-  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
-
-  /** Used to ensure capturing order of template delimiters. */
-  var reNoMatch = /($^)/;
-
-  /** Used to match unescaped characters in compiled string literals. */
-  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
-
-  /** Used to compose unicode character classes. */
-  var rsAstralRange = '\\ud800-\\udfff',
-      rsComboMarksRange = '\\u0300-\\u036f',
-      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
-      rsComboSymbolsRange = '\\u20d0-\\u20ff',
-      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
-      rsDingbatRange = '\\u2700-\\u27bf',
-      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
-      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
-      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
-      rsPunctuationRange = '\\u2000-\\u206f',
-      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
-      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
-      rsVarRange = '\\ufe0e\\ufe0f',
-      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
-
-  /** Used to compose unicode capture groups. */
-  var rsApos = "['\u2019]",
-      rsAstral = '[' + rsAstralRange + ']',
-      rsBreak = '[' + rsBreakRange + ']',
-      rsCombo = '[' + rsComboRange + ']',
-      rsDigits = '\\d+',
-      rsDingbat = '[' + rsDingbatRange + ']',
-      rsLower = '[' + rsLowerRange + ']',
-      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
-      rsFitz = '\\ud83c[\\udffb-\\udfff]',
-      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
-      rsNonAstral = '[^' + rsAstralRange + ']',
-      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
-      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
-      rsUpper = '[' + rsUpperRange + ']',
-      rsZWJ = '\\u200d';
-
-  /** Used to compose unicode regexes. */
-  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
-      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
-      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
-      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
-      reOptMod = rsModifier + '?',
-      rsOptVar = '[' + rsVarRange + ']?',
-      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
-      rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
-      rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
-      rsSeq = rsOptVar + reOptMod + rsOptJoin,
-      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
-      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
-
-  /** Used to match apostrophes. */
-  var reApos = RegExp(rsApos, 'g');
-
-  /**
-   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
-   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
-   */
-  var reComboMark = RegExp(rsCombo, 'g');
-
-  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
-  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
-
-  /** Used to match complex or compound words. */
-  var reUnicodeWord = RegExp([
-    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
-    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
-    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
-    rsUpper + '+' + rsOptContrUpper,
-    rsOrdUpper,
-    rsOrdLower,
-    rsDigits,
-    rsEmoji
-  ].join('|'), 'g');
-
-  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
-  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
-
-  /** Used to detect strings that need a more robust regexp to match words. */
-  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
-
-  /** Used to assign default `context` object properties. */
-  var contextProps = [
-    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
-    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
-    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
-    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
-    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
-  ];
-
-  /** Used to make template sourceURLs easier to identify. */
-  var templateCounter = -1;
-
-  /** Used to identify `toStringTag` values of typed arrays. */
-  var typedArrayTags = {};
-  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
-  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
-  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
-  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
-  typedArrayTags[uint32Tag] = true;
-  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
-  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
-  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
-  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
-  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
-  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
-  typedArrayTags[setTag] = typedArrayTags[stringTag] =
-  typedArrayTags[weakMapTag] = false;
-
-  /** Used to identify `toStringTag` values supported by `_.clone`. */
-  var cloneableTags = {};
-  cloneableTags[argsTag] = cloneableTags[arrayTag] =
-  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
-  cloneableTags[boolTag] = cloneableTags[dateTag] =
-  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
-  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
-  cloneableTags[int32Tag] = cloneableTags[mapTag] =
-  cloneableTags[numberTag] = cloneableTags[objectTag] =
-  cloneableTags[regexpTag] = cloneableTags[setTag] =
-  cloneableTags[stringTag] = cloneableTags[symbolTag] =
-  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
-  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
-  cloneableTags[errorTag] = cloneableTags[funcTag] =
-  cloneableTags[weakMapTag] = false;
-
-  /** Used to map Latin Unicode letters to basic Latin letters. */
-  var deburredLetters = {
-    // Latin-1 Supplement block.
-    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
-    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
-    '\xc7': 'C',  '\xe7': 'c',
-    '\xd0': 'D',  '\xf0': 'd',
-    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
-    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
-    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
-    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
-    '\xd1': 'N',  '\xf1': 'n',
-    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
-    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
-    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
-    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
-    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
-    '\xc6': 'Ae', '\xe6': 'ae',
-    '\xde': 'Th', '\xfe': 'th',
-    '\xdf': 'ss',
-    // Latin Extended-A block.
-    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
-    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
-    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
-    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
-    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
-    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
-    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
-    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
-    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
-    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
-    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
-    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
-    '\u0134': 'J',  '\u0135': 'j',
-    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
-    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
-    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
-    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
-    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
-    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
-    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
-    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
-    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
-    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
-    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
-    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
-    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
-    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
-    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
-    '\u0174': 'W',  '\u0175': 'w',
-    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
-    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
-    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
-    '\u0132': 'IJ', '\u0133': 'ij',
-    '\u0152': 'Oe', '\u0153': 'oe',
-    '\u0149': "'n", '\u017f': 's'
-  };
-
-  /** Used to map characters to HTML entities. */
-  var htmlEscapes = {
-    '&': '&amp;',
-    '<': '&lt;',
-    '>': '&gt;',
-    '"': '&quot;',
-    "'": '&#39;'
-  };
-
-  /** Used to map HTML entities to characters. */
-  var htmlUnescapes = {
-    '&amp;': '&',
-    '&lt;': '<',
-    '&gt;': '>',
-    '&quot;': '"',
-    '&#39;': "'"
-  };
-
-  /** Used to escape characters for inclusion in compiled string literals. */
-  var stringEscapes = {
-    '\\': '\\',
-    "'": "'",
-    '\n': 'n',
-    '\r': 'r',
-    '\u2028': 'u2028',
-    '\u2029': 'u2029'
-  };
-
-  /** Built-in method references without a dependency on `root`. */
-  var freeParseFloat = parseFloat,
-      freeParseInt = parseInt;
-
-  /** Detect free variable `global` from Node.js. */
-  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
-
-  /** Detect free variable `self`. */
-  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
-
-  /** Used as a reference to the global object. */
-  var root = freeGlobal || freeSelf || Function('return this')();
-
-  /** Detect free variable `exports`. */
-  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
-
-  /** Detect free variable `module`. */
-  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
-
-  /** Detect the popular CommonJS extension `module.exports`. */
-  var moduleExports = freeModule && freeModule.exports === freeExports;
-
-  /** Detect free variable `process` from Node.js. */
-  var freeProcess = moduleExports && freeGlobal.process;
-
-  /** Used to access faster Node.js helpers. */
-  var nodeUtil = (function() {
-    try {
-      return freeProcess && freeProcess.binding && freeProcess.binding('util');
-    } catch (e) {}
-  }());
-
-  /* Node.js helper references. */
-  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
-      nodeIsDate = nodeUtil && nodeUtil.isDate,
-      nodeIsMap = nodeUtil && nodeUtil.isMap,
-      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
-      nodeIsSet = nodeUtil && nodeUtil.isSet,
-      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
-
-  /*--------------------------------------------------------------------------*/
-
-  /**
-   * Adds the key-value `pair` to `map`.
-   *
-   * @private
-   * @param {Object} map The map to modify.
-   * @param {Array} pair The key-value pair to add.
-   * @returns {Object} Returns `map`.
-   */
-  function addMapEntry(map, pair) {
-    // Don't return `map.set` because it's not chainable in IE 11.
-    map.set(pair[0], pair[1]);
-    return map;
-  }
-
-  /**
-   * Adds `value` to `set`.
-   *
-   * @private
-   * @param {Object} set The set to modify.
-   * @param {*} value The value to add.
-   * @returns {Object} Returns `set`.
-   */
-  function addSetEntry(set, value) {
-    // Don't return `set.add` because it's not chainable in IE 11.
-    set.add(value);
-    return set;
-  }
-
-  /**
-   * A faster alternative to `Function#apply`, this function invokes `func`
-   * with the `this` binding of `thisArg` and the arguments of `args`.
-   *
-   * @private
-   * @param {Function} func The function to invoke.
-   * @param {*} thisArg The `this` binding of `func`.
-   * @param {Array} args The arguments to invoke `func` with.
-   * @returns {*} Returns the result of `func`.
-   */
-  function apply(func, thisArg, args) {
-    switch (args.length) {
-      case 0: return func.call(thisArg);
-      case 1: return func.call(thisArg, args[0]);
-      case 2: return func.call(thisArg, args[0], args[1]);
-      case 3: return func.call(thisArg, args[0], args[1], args[2]);
-    }
-    return func.apply(thisArg, args);
-  }
-
-  /**
-   * A specialized version of `baseAggregator` for arrays.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} setter The function to set `accumulator` values.
-   * @param {Function} iteratee The iteratee to transform keys.
-   * @param {Object} accumulator The initial aggregated object.
-   * @returns {Function} Returns `accumulator`.
-   */
-  function arrayAggregator(array, setter, iteratee, accumulator) {
-    var index = -1,
-        length = array == null ? 0 : array.length;
-
-    while (++index < length) {
-      var value = array[index];
-      setter(accumulator, value, iteratee(value), array);
-    }
-    return accumulator;
-  }
-
-  /**
-   * A specialized version of `_.forEach` for arrays without support for
-   * iteratee shorthands.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @returns {Array} Returns `array`.
-   */
-  function arrayEach(array, iteratee) {
-    var index = -1,
-        length = array == null ? 0 : array.length;
-
-    while (++index < length) {
-      if (iteratee(array[index], index, array) === false) {
-        break;
-      }
-    }
-    return array;
-  }
-
-  /**
-   * A specialized version of `_.forEachRight` for arrays without support for
-   * iteratee shorthands.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @returns {Array} Returns `array`.
-   */
-  function arrayEachRight(array, iteratee) {
-    var length = array == null ? 0 : array.length;
-
-    while (length--) {
-      if (iteratee(array[length], length, array) === false) {
-        break;
-      }
-    }
-    return array;
-  }
-
-  /**
-   * A specialized version of `_.every` for arrays without support for
-   * iteratee shorthands.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} predicate The function invoked per iteration.
-   * @returns {boolean} Returns `true` if all elements pass the predicate check,
-   *  else `false`.
-   */
-  function arrayEvery(array, predicate) {
-    var index = -1,
-        length = array == null ? 0 : array.length;
-
-    while (++index < length) {
-      if (!predicate(array[index], index, array)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * A specialized version of `_.filter` for arrays without support for
-   * iteratee shorthands.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} predicate The function invoked per iteration.
-   * @returns {Array} Returns the new filtered array.
-   */
-  function arrayFilter(array, predicate) {
-    var index = -1,
-        length = array == null ? 0 : array.length,
-        resIndex = 0,
-        result = [];
-
-    while (++index < length) {
-      var value = array[index];
-      if (predicate(value, index, array)) {
-        result[resIndex++] = value;
-      }
-    }
-    return result;
-  }
-
-  /**
-   * A specialized version of `_.includes` for arrays without support for
-   * specifying an index to search from.
-   *
-   * @private
-   * @param {Array} [array] The array to inspect.
-   * @param {*} target The value to search for.
-   * @returns {boolean} Returns `true` if `target` is found, else `false`.
-   */
-  function arrayIncludes(array, value) {
-    var length = array == null ? 0 : array.length;
-    return !!length && baseIndexOf(array, value, 0) > -1;
-  }
-
-  /**
-   * This function is like `arrayIncludes` except that it accepts a comparator.
-   *
-   * @private
-   * @param {Array} [array] The array to inspect.
-   * @param {*} target The value to search for.
-   * @param {Function} comparator The comparator invoked per element.
-   * @returns {boolean} Returns `true` if `target` is found, else `false`.
-   */
-  function arrayIncludesWith(array, value, comparator) {
-    var index = -1,
-        length = array == null ? 0 : array.length;
-
-    while (++index < length) {
-      if (comparator(value, array[index])) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * A specialized version of `_.map` for arrays without support for iteratee
-   * shorthands.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @returns {Array} Returns the new mapped array.
-   */
-  function arrayMap(array, iteratee) {
-    var index = -1,
-        length = array == null ? 0 : array.length,
-        result = Array(length);
-
-    while (++index < length) {
-      result[index] = iteratee(array[index], index, array);
-    }
-    return result;
-  }
-
-  /**
-   * Appends the elements of `values` to `array`.
-   *
-   * @private
-   * @param {Array} array The array to modify.
-   * @param {Array} values The values to append.
-   * @returns {Array} Returns `array`.
-   */
-  function arrayPush(array, values) {
-    var index = -1,
-        length = values.length,
-        offset = array.length;
-
-    while (++index < length) {
-      array[offset + index] = values[index];
-    }
-    return array;
-  }
-
-  /**
-   * A specialized version of `_.reduce` for arrays without support for
-   * iteratee shorthands.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @param {*} [accumulator] The initial value.
-   * @param {boolean} [initAccum] Specify using the first element of `array` as
-   *  the initial value.
-   * @returns {*} Returns the accumulated value.
-   */
-  function arrayReduce(array, iteratee, accumulator, initAccum) {
-    var index = -1,
-        length = array == null ? 0 : array.length;
-
-    if (initAccum && length) {
-      accumulator = array[++index];
-    }
-    while (++index < length) {
-      accumulator = iteratee(accumulator, array[index], index, array);
-    }
-    return accumulator;
-  }
-
-  /**
-   * A specialized version of `_.reduceRight` for arrays without support for
-   * iteratee shorthands.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @param {*} [accumulator] The initial value.
-   * @param {boolean} [initAccum] Specify using the last element of `array` as
-   *  the initial value.
-   * @returns {*} Returns the accumulated value.
-   */
-  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
-    var length = array == null ? 0 : array.length;
-    if (initAccum && length) {
-      accumulator = array[--length];
-    }
-    while (length--) {
-      accumulator = iteratee(accumulator, array[length], length, array);
-    }
-    return accumulator;
-  }
-
-  /**
-   * A specialized version of `_.some` for arrays without support for iteratee
-   * shorthands.
-   *
-   * @private
-   * @param {Array} [array] The array to iterate over.
-   * @param {Function} predicate The function invoked per iteration.
-   * @returns {boolean} Returns `true` if any element passes the predicate check,
-   *  else `false`.
-   */
-  function arraySome(array, predicate) {
-    var index = -1,
-        length = array == null ? 0 : array.length;
-
-    while (++index < length) {
-      if (predicate(array[index], index, array)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Gets the size of an ASCII `string`.
-   *
-   * @private
-   * @param {string} string The string inspect.
-   * @returns {number} Returns the string size.
-   */
-  var asciiSize = baseProperty('length');
-
-  /**
-   * Converts an ASCII `string` to an array.
-   *
-   * @private
-   * @param {string} string The string to convert.
-   * @returns {Array} Returns the converted array.
-   */
-  function asciiToArray(string) {
-    return string.split('');
-  }
-
-  /**
-   * Splits an ASCII `string` into an array of its words.
-   *
-   * @private
-   * @param {string} The string to inspect.
-   * @returns {Array} Returns the words of `string`.
-   */
-  function asciiWords(string) {
-    return string.match(reAsciiWord) || [];
-  }
-
-  /**
-   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
-   * without support for iteratee shorthands, which iterates over `collection`
-   * using `eachFunc`.
-   *
-   * @private
-   * @param {Array|Object} collection The collection to inspect.
-   * @param {Function} predicate The function invoked per iteration.
-   * @param {Function} eachFunc The function to iterate over `collection`.
-   * @returns {*} Returns the found element or its key, else `undefined`.
-   */
-  function baseFindKey(collection, predicate, eachFunc) {
-    var result;
-    eachFunc(collection, function(value, key, collection) {
-      if (predicate(value, key, collection)) {
-        result = key;
-        return false;
-      }
-    });
-    return result;
-  }
-
-  /**
-   * The base implementation of `_.findIndex` and `_.findLastIndex` without
-   * support for iteratee shorthands.
-   *
-   * @private
-   * @param {Array} array The array to inspect.
-   * @param {Function} predicate The function invoked per iteration.
-   * @param {number} fromIndex The index to search from.
-   * @param {boolean} [fromRight] Specify iterating from right to left.
-   * @returns {number} Returns the index of the matched value, else `-1`.
-   */
-  function baseFindIndex(array, predicate, fromIndex, fromRight) {
-    var length = array.length,
-        index = fromIndex + (fromRight ? 1 : -1);
-
-    while ((fromRight ? index-- : ++index < length)) {
-      if (predicate(array[index], index, array)) {
-        return index;
-      }
-    }
-    return -1;
-  }
-
-  /**
-   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
-   *
-   * @private
-   * @param {Array} array The array to inspect.
-   * @param {*} value The value to search for.
-   * @param {number} fromIndex The index to search from.
-   * @returns {number} Returns the index of the matched value, else `-1`.
-   */
-  function baseIndexOf(array, value, fromIndex) {
-    return value === value
-      ? strictIndexOf(array, value, fromIndex)
-      : baseFindIndex(array, baseIsNaN, fromIndex);
-  }
-
-  /**
-   * This function is like `baseIndexOf` except that it accepts a comparator.
-   *
-   * @private
-   * @param {Array} array The array to inspect.
-   * @param {*} value The value to search for.
-   * @param {number} fromIndex The index to search from.
-   * @param {Function} comparator The comparator invoked per element.
-   * @returns {number} Returns the index of the matched value, else `-1`.
-   */
-  function baseIndexOfWith(array, value, fromIndex, comparator) {
-    var index = fromIndex - 1,
-        length = array.length;
-
-    while (++index < length) {
-      if (comparator(array[index], value)) {
-        return index;
-      }
-    }
-    return -1;
-  }
-
-  /**
-   * The base implementation of `_.isNaN` without support for number objects.
-   *
-   * @private
-   * @param {*} value The value to check.
-   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
-   */
-  function baseIsNaN(value) {
-    return value !== value;
-  }
-
-  /**
-   * The base implementation of `_.mean` and `_.meanBy` without support for
-   * iteratee shorthands.
-   *
-   * @private
-   * @param {Array} array The array to iterate over.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @returns {number} Returns the mean.
-   */
-  function baseMean(array, iteratee) {
-    var length = array == null ? 0 : array.length;
-    return length ? (baseSum(array, iteratee) / length) : NAN;
-  }
-
-  /**
-   * The base implementation of `_.property` without support for deep paths.
-   *
-   * @private
-   * @param {string} key The key of the property to get.
-   * @returns {Function} Returns the new accessor function.
-   */
-  function baseProperty(key) {
-    return function(object) {
-      return object == null ? undefined : object[key];
-    };
-  }
-
-  /**
-   * The base implementation of `_.propertyOf` without support for deep paths.
-   *
-   * @private
-   * @param {Object} object The object to query.
-   * @returns {Function} Returns the new accessor function.
-   */
-  function basePropertyOf(object) {
-    return function(key) {
-      return object == null ? undefined : object[key];
-    };
-  }
-
-  /**
-   * The base implementation of `_.reduce` and `_.reduceRight`, without support
-   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
-   *
-   * @private
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @param {*} accumulator The initial value.
-   * @param {boolean} initAccum Specify using the first or last element of
-   *  `collection` as the initial value.
-   * @param {Function} eachFunc The function to iterate over `collection`.
-   * @returns {*} Returns the accumulated value.
-   */
-  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
-    eachFunc(collection, function(value, index, collection) {
-      accumulator = initAccum
-        ? (initAccum = false, value)
-        : iteratee(accumulator, value, index, collection);
-    });
-    return accumulator;
-  }
-
-  /**
-   * The base implementation of `_.sortBy` which uses `comparer` to define the
-   * sort order of `array` and replaces criteria objects with their corresponding
-   * values.
-   *
-   * @private
-   * @param {Array} array The array to sort.
-   * @param {Function} comparer The function to define sort order.
-   * @returns {Array} Returns `array`.
-   */
-  function baseSortBy(array, comparer) {
-    var length = array.length;
-
-    array.sort(comparer);
-    while (length--) {
-      array[length] = array[length].value;
-    }
-    return array;
-  }
-
-  /**
-   * The base implementation of `_.sum` and `_.sumBy` without support for
-   * iteratee shorthands.
-   *
-   * @private
-   * @param {Array} array The array to iterate over.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @returns {number} Returns the sum.
-   */
-  function baseSum(array, iteratee) {
-    var result,
-        index = -1,
-        length = array.length;
-
-    while (++index < length) {
-      var current = iteratee(array[index]);
-      if (current !== undefined) {
-        result = result === undefined ? current : (result + current);
-      }
-    }
-    return result;
-  }
-
-  /**
-   * The base implementation of `_.times` without support for iteratee shorthands
-   * or max array length checks.
-   *
-   * @private
-   * @param {number} n The number of times to invoke `iteratee`.
-   * @param {Function} iteratee The function invoked per iteration.
-   * @returns {Array} Returns the array of results.
-   */
-  function baseTimes(n, iteratee) {
-    var index = -1,
-        result = Array(n);
-
-    while (++index < n) {
-      result[index] = iteratee(index);
-    }
-    return result;
-  }
-
-  /**
-   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
-   * of key-value pairs for `object` corresponding to the property names of `props`.
-   *
-   * @private
-   * @param {Object} object The object to query.
-   * @param {Array} props The property names to get values for.
-   * @returns {Object} Returns the key-value pairs.
-   */
-  function baseToPairs(object, props) {
-    return arrayMap(props, function(key) {
-      return [key, object[key]];
-    });
-  }
-
-  /**
-   * The base implementation of `_.unary` without support for storing metadata.
-   *
-   * @private
-   * @param {Function} func The function to cap arguments for.
-   * @returns {Function} Returns the new capped function.
-   */
-  function baseUnary(func) {
-    return function(value) {
-      return func(value);
-    };
-  }
-
-  /**
-   * The base implementation of `_.values` and `_.valuesIn` which creates an
-   * array of `object` property values corresponding to the property names
-   * of `props`.
-   *
-   * @private
-   * @param {Object} object The object to query.
-   * @param {Array} props The property names to get values for.
-   * @returns {Object} Returns the array of property values.
-   */
-  function baseValues(object, props) {
-    return arrayMap(props, function(key) {
-      return object[key];
-    });
-  }
-
-  /**
-   * Checks if a `cache` value for `key` exists.
-   *
-   * @private
-   * @param {Object} cache The cache to query.
-   * @param {string} key The key of the entry to check.
-   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
-   */
-  function cacheHas(cache, key) {
-    return cache.has(key);
-  }
-
-  /**
-   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
-   * that is not found in the character symbols.
-   *
-   * @private
-   * @param {Array} strSymbols The string symbols to inspect.
-   * @param {Array} chrSymbols The character symbols to find.
-   * @returns {number} Returns the index of the first unmatched string symbol.
-   */
-  function charsStartIndex(strSymbols, chrSymbols) {
-    var index = -1,
-        length = strSymbols.length;
-
-    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
-    return index;
-  }
-
-  /**
-   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
-   * that is not found in the character symbols.
-   *
-   * @private
-   * @param {Array} strSymbols The string symbols to inspect.
-   * @param {Array} chrSymbols The character symbols to find.
-   * @returns {number} Returns the index of the last unmatched string symbol.
-   */
-  function charsEndIndex(strSymbols, chrSymbols) {
-    var index = strSymbols.length;
-
-    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
-    return index;
-  }
-
-  /**
-   * Gets the number of `placeholder` occurrences in `array`.
-   *
-   * @private
-   * @param {Array} array The array to inspect.
-   * @param {*} placeholder The placeholder to search for.
-   * @returns {number} Returns the placeholder count.
-   */
-  function countHolders(array, placeholder) {
-    var length = array.length,
-        result = 0;
-
-    while (length--) {
-      if (array[length] === placeholder) {
-        ++result;
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
-   * letters to basic Latin letters.
-   *
-   * @private
-   * @param {string} letter The matched letter to deburr.
-   * @returns {string} Returns the deburred letter.
-   */
-  var deburrLetter = basePropertyOf(deburredLetters);
-
-  /**
-   * Used by `_.escape` to convert characters to HTML entities.
-   *
-   * @private
-   * @param {string} chr The matched character to escape.
-   * @returns {string} Returns the escaped character.
-   */
-  var escapeHtmlChar = basePropertyOf(htmlEscapes);
-
-  /**
-   * Used by `_.template` to escape characters for inclusion in compiled string literals.
-   *
-   * @private
-   * @param {string} chr The matched character to escape.
-   * @returns {string} Returns the escaped character.
-   */
-  function escapeStringChar(chr) {
-    return '\\' + stringEscapes[chr];
-  }
-
-  /**
-   * Gets the value at `key` of `object`.
-   *
-   * @private
-   * @param {Object} [object] The object to query.
-   * @param {string} key The key of the property to get.
-   * @returns {*} Returns the property value.
-   */
-  function getValue(object, key) {
-    return object == null ? undefined : object[key];
-  }
-
-  /**
-   * Checks if `string` contains Unicode symbols.
-   *
-   * @private
-   * @param {string} string The string to inspect.
-   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
-   */
-  function hasUnicode(string) {
-    return reHasUnicode.test(string);
-  }
-
-  /**
-   * Checks if `string` contains a word composed of Unicode symbols.
-   *
-   * @private
-   * @param {string} string The string to inspect.
-   * @returns {boolean} Returns `true` if a word is found, else `false`.
-   */
-  function hasUnicodeWord(string) {
-    return reHasUnicodeWord.test(string);
-  }
-
-  /**
-   * Converts `iterator` to an array.
-   *
-   * @private
-   * @param {Object} iterator The iterator to convert.
-   * @returns {Array} Returns the converted array.
-   */
-  function iteratorToArray(iterator) {
-    var data,
-        result = [];
-
-    while (!(data = iterator.next()).done) {
-      result.push(data.value);
-    }
-    return result;
-  }
-
-  /**
-   * Converts `map` to its key-value pairs.
-   *
-   * @private
-   * @param {Object} map The map to convert.
-   * @returns {Array} Returns the key-value pairs.
-   */
-  function mapToArray(map) {
-    var index = -1,
-        result = Array(map.size);
-
-    map.forEach(function(value, key) {
-      result[++index] = [key, value];
-    });
-    return result;
-  }
-
-  /**
-   * Creates a unary function that invokes `func` with its argument transformed.
-   *
-   * @private
-   * @param {Function} func The function to wrap.
-   * @param {Function} transform The argument transform.
-   * @returns {Function} Returns the new function.
-   */
-  function overArg(func, transform) {
-    return function(arg) {
-      return func(transform(arg));
-    };
-  }
-
-  /**
-   * Replaces all `placeholder` elements in `array` with an internal placeholder
-   * and returns an array of their indexes.
-   *
-   * @private
-   * @param {Array} array The array to modify.
-   * @param {*} placeholder The placeholder to replace.
-   * @returns {Array} Returns the new array of placeholder indexes.
-   */
-  function replaceHolders(array, placeholder) {
-    var index = -1,
-        length = array.length,
-        resIndex = 0,
-        result = [];
-
-    while (++index < length) {
-      var value = array[index];
-      if (value === placeholder || value === PLACEHOLDER) {
-        array[index] = PLACEHOLDER;
-        result[resIndex++] = index;
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Converts `set` to an array of its values.
-   *
-   * @private
-   * @param {Object} set The set to convert.
-   * @returns {Array} Returns the values.
-   */
-  function setToArray(set) {
-    var index = -1,
-        result = Array(set.size);
-
-    set.forEach(function(value) {
-      result[++index] = value;
-    });
-    return result;
-  }
-
-  /**
-   * Converts `set` to its value-value pairs.
-   *
-   * @private
-   * @param {Object} set The set to convert.
-   * @returns {Array} Returns the value-value pairs.
-   */
-  function setToPairs(set) {
-    var index = -1,
-        result = Array(set.size);
-
-    set.forEach(function(value) {
-      result[++index] = [value, value];
-    });
-    return result;
-  }
-
-  /**
-   * A specialized version of `_.indexOf` which performs strict equality
-   * comparisons of values, i.e. `===`.
-   *
-   * @private
-   * @param {Array} array The array to inspect.
-   * @param {*} value The value to search for.
-   * @param {number} fromIndex The index to search from.
-   * @returns {number} Returns the index of the matched value, else `-1`.
-   */
-  function strictIndexOf(array, value, fromIndex) {
-    var index = fromIndex - 1,
-        length = array.length;
-
-    while (++index < length) {
-      if (array[index] === value) {
-        return index;
-      }
-    }
-    return -1;
-  }
-
-  /**
-   * A specialized version of `_.lastIndexOf` which performs strict equality
-   * comparisons of values, i.e. `===`.
-   *
-   * @private
-   * @param {Array} array The array to inspect.
-   * @param {*} value The value to search for.
-   * @param {number} fromIndex The index to search from.
-   * @returns {number} Returns the index of the matched value, else `-1`.
-   */
-  function strictLastIndexOf(array, value, fromIndex) {
-    var index = fromIndex + 1;
-    while (index--) {
-      if (array[index] === value) {
-        return index;
-      }
-    }
-    return index;
-  }
-
-  /**
-   * Gets the number of symbols in `string`.
-   *
-   * @private
-   * @param {string} string The string to inspect.
-   * @returns {number} Returns the string size.
-   */
-  function stringSize(string) {
-    return hasUnicode(string)
-      ? unicodeSize(string)
-      : asciiSize(string);
-  }
-
-  /**
-   * Converts `string` to an array.
-   *
-   * @private
-   * @param {string} string The string to convert.
-   * @returns {Array} Returns the converted array.
-   */
-  function stringToArray(string) {
-    return hasUnicode(string)
-      ? unicodeToArray(string)
-      : asciiToArray(string);
-  }
-
-  /**
-   * Used by `_.unescape` to convert HTML entities to characters.
-   *
-   * @private
-   * @param {string} chr The matched character to unescape.
-   * @returns {string} Returns the unescaped character.
-   */
-  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
-
-  /**
-   * Gets the size of a Unicode `string`.
-   *
-   * @private
-   * @param {string} string The string inspect.
-   * @returns {number} Returns the string size.
-   */
-  function unicodeSize(string) {
-    var result = reUnicode.lastIndex = 0;
-    while (reUnicode.test(string)) {
-      ++result;
-    }
-    return result;
-  }
-
-  /**
-   * Converts a Unicode `string` to an array.
-   *
-   * @private
-   * @param {string} string The string to convert.
-   * @returns {Array} Returns the converted array.
-   */
-  function unicodeToArray(string) {
-    return string.match(reUnicode) || [];
-  }
-
-  /**
-   * Splits a Unicode `string` into an array of its words.
-   *
-   * @private
-   * @param {string} The string to inspect.
-   * @returns {Array} Returns the words of `string`.
-   */
-  function unicodeWords(string) {
-    return string.match(reUnicodeWord) || [];
-  }
-
-  /*--------------------------------------------------------------------------*/
-
-  /**
-   * Create a new pristine `lodash` function using the `context` object.
-   *
-   * @static
-   * @memberOf _
-   * @since 1.1.0
-   * @category Util
-   * @param {Object} [context=root] The context object.
-   * @returns {Function} Returns a new `lodash` function.
-   * @example
-   *
-   * _.mixin({ 'foo': _.constant('foo') });
-   *
-   * var lodash = _.runInContext();
-   * lodash.mixin({ 'bar': lodash.constant('bar') });
-   *
-   * _.isFunction(_.foo);
-   * // => true
-   * _.isFunction(_.bar);
-   * // => false
-   *
-   * lodash.isFunction(lodash.foo);
-   * // => false
-   * lodash.isFunction(lodash.bar);
-   * // => true
-   *
-   * // Create a suped-up `defer` in Node.js.
-   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
-   */
-  var runInContext = (function runInContext(context) {
-    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
-
-    /** Built-in constructor references. */
-    var Array = context.Array,
-        Date = context.Date,
-        Error = context.Error,
-        Function = context.Function,
-        Math = context.Math,
-        Object = context.Object,
-        RegExp = context.RegExp,
-        String = context.String,
-        TypeError = context.TypeError;
-
-    /** Used for built-in method references. */
-    var arrayProto = Array.prototype,
-        funcProto = Function.prototype,
-        objectProto = Object.prototype;
-
-    /** Used to detect overreaching core-js shims. */
-    var coreJsData = context['__core-js_shared__'];
-
-    /** Used to resolve the decompiled source of functions. */
-    var funcToString = funcProto.toString;
-
-    /** Used to check objects for own properties. */
-    var hasOwnProperty = objectProto.hasOwnProperty;
-
-    /** Used to generate unique IDs. */
-    var idCounter = 0;
-
-    /** Used to detect methods masquerading as native. */
-    var maskSrcKey = (function() {
-      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
-      return uid ? ('Symbol(src)_1.' + uid) : '';
-    }());
-
-    /**
-     * Used to resolve the
-     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
-     * of values.
-     */
-    var nativeObjectToString = objectProto.toString;
-
-    /** Used to infer the `Object` constructor. */
-    var objectCtorString = funcToString.call(Object);
-
-    /** Used to restore the original `_` reference in `_.noConflict`. */
-    var oldDash = root._;
-
-    /** Used to detect if a method is native. */
-    var reIsNative = RegExp('^' +
-      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
-      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
-    );
-
-    /** Built-in value references. */
-    var Buffer = moduleExports ? context.Buffer : undefined,
-        Symbol = context.Symbol,
-        Uint8Array = context.Uint8Array,
-        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
-        getPrototype = overArg(Object.getPrototypeOf, Object),
-        objectCreate = Object.create,
-        propertyIsEnumerable = objectProto.propertyIsEnumerable,
-        splice = arrayProto.splice,
-        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
-        symIterator = Symbol ? Symbol.iterator : undefined,
-        symToStringTag = Symbol ? Symbol.toStringTag : undefined;
-
-    var defineProperty = (function() {
-      try {
-        var func = getNative(Object, 'defineProperty');
-        func({}, '', {});
-        return func;
-      } catch (e) {}
-    }());
-
-    /** Mocked built-ins. */
-    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
-        ctxNow = Date && Date.now !== root.Date.now && Date.now,
-        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
-
-    /* Built-in method references for those with the same name as other `lodash` methods. */
-    var nativeCeil = Math.ceil,
-        nativeFloor = Math.floor,
-        nativeGetSymbols = Object.getOwnPropertySymbols,
-        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
-        nativeIsFinite = context.isFinite,
-        nativeJoin = arrayProto.join,
-        nativeKeys = overArg(Object.keys, Object),
-        nativeMax = Math.max,
-        nativeMin = Math.min,
-        nativeNow = Date.now,
-        nativeParseInt = context.parseInt,
-        nativeRandom = Math.random,
-        nativeReverse = arrayProto.reverse;
-
-    /* Built-in method references that are verified to be native. */
-    var DataView = getNative(context, 'DataView'),
-        Map = getNative(context, 'Map'),
-        Promise = getNative(context, 'Promise'),
-        Set = getNative(context, 'Set'),
-        WeakMap = getNative(context, 'WeakMap'),
-        nativeCreate = getNative(Object, 'create');
-
-    /** Used to store function metadata. */
-    var metaMap = WeakMap && new WeakMap;
-
-    /** Used to lookup unminified function names. */
-    var realNames = {};
-
-    /** Used to detect maps, sets, and weakmaps. */
-    var dataViewCtorString = toSource(DataView),
-        mapCtorString = toSource(Map),
-        promiseCtorString = toSource(Promise),
-        setCtorString = toSource(Set),
-        weakMapCtorString = toSource(WeakMap);
-
-    /** Used to convert symbols to primitives and strings. */
-    var symbolProto = Symbol ? Symbol.prototype : undefined,
-        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
-        symbolToString = symbolProto ? symbolProto.toString : undefined;
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates a `lodash` object which wraps `value` to enable implicit method
-     * chain sequences. Methods that operate on and return arrays, collections,
-     * and functions can be chained together. Methods that retrieve a single value
-     * or may return a primitive value will automatically end the chain sequence
-     * and return the unwrapped value. Otherwise, the value must be unwrapped
-     * with `_#value`.
-     *
-     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
-     * enabled using `_.chain`.
-     *
-     * The execution of chained methods is lazy, that is, it's deferred until
-     * `_#value` is implicitly or explicitly called.
-     *
-     * Lazy evaluation allows several methods to support shortcut fusion.
-     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
-     * the creation of intermediate arrays and can greatly reduce the number of
-     * iteratee executions. Sections of a chain sequence qualify for shortcut
-     * fusion if the section is applied to an array and iteratees accept only
-     * one argument. The heuristic for whether a section qualifies for shortcut
-     * fusion is subject to change.
-     *
-     * Chaining is supported in custom builds as long as the `_#value` method is
-     * directly or indirectly included in the build.
-     *
-     * In addition to lodash methods, wrappers have `Array` and `String` methods.
-     *
-     * The wrapper `Array` methods are:
-     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
-     *
-     * The wrapper `String` methods are:
-     * `replace` and `split`
-     *
-     * The wrapper methods that support shortcut fusion are:
-     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
-     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
-     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
-     *
-     * The chainable wrapper methods are:
-     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
-     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
-     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
-     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
-     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
-     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
-     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
-     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
-     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
-     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
-     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
-     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
-     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
-     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
-     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
-     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
-     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
-     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
-     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
-     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
-     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
-     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
-     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
-     * `zipObject`, `zipObjectDeep`, and `zipWith`
-     *
-     * The wrapper methods that are **not** chainable by default are:
-     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
-     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
-     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
-     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
-     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
-     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
-     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
-     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
-     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
-     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
-     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
-     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
-     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
-     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
-     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
-     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
-     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
-     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
-     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
-     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
-     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
-     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
-     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
-     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
-     * `upperFirst`, `value`, and `words`
-     *
-     * @name _
-     * @constructor
-     * @category Seq
-     * @param {*} value The value to wrap in a `lodash` instance.
-     * @returns {Object} Returns the new `lodash` wrapper instance.
-     * @example
-     *
-     * function square(n) {
-     *   return n * n;
-     * }
-     *
-     * var wrapped = _([1, 2, 3]);
-     *
-     * // Returns an unwrapped value.
-     * wrapped.reduce(_.add);
-     * // => 6
-     *
-     * // Returns a wrapped value.
-     * var squares = wrapped.map(square);
-     *
-     * _.isArray(squares);
-     * // => false
-     *
-     * _.isArray(squares.value());
-     * // => true
-     */
-    function lodash(value) {
-      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
-        if (value instanceof LodashWrapper) {
-          return value;
-        }
-        if (hasOwnProperty.call(value, '__wrapped__')) {
-          return wrapperClone(value);
-        }
-      }
-      return new LodashWrapper(value);
-    }
-
-    /**
-     * The base implementation of `_.create` without support for assigning
-     * properties to the created object.
-     *
-     * @private
-     * @param {Object} proto The object to inherit from.
-     * @returns {Object} Returns the new object.
-     */
-    var baseCreate = (function() {
-      function object() {}
-      return function(proto) {
-        if (!isObject(proto)) {
-          return {};
-        }
-        if (objectCreate) {
-          return objectCreate(proto);
-        }
-        object.prototype = proto;
-        var result = new object;
-        object.prototype = undefined;
-        return result;
-      };
-    }());
-
-    /**
-     * The function whose prototype chain sequence wrappers inherit from.
-     *
-     * @private
-     */
-    function baseLodash() {
-      // No operation performed.
-    }
-
-    /**
-     * The base constructor for creating `lodash` wrapper objects.
-     *
-     * @private
-     * @param {*} value The value to wrap.
-     * @param {boolean} [chainAll] Enable explicit method chain sequences.
-     */
-    function LodashWrapper(value, chainAll) {
-      this.__wrapped__ = value;
-      this.__actions__ = [];
-      this.__chain__ = !!chainAll;
-      this.__index__ = 0;
-      this.__values__ = undefined;
-    }
-
-    /**
-     * By default, the template delimiters used by lodash are like those in
-     * embedded Ruby (ERB) as well as ES2015 template strings. Change the
-     * following template settings to use alternative delimiters.
-     *
-     * @static
-     * @memberOf _
-     * @type {Object}
-     */
-    lodash.templateSettings = {
-
-      /**
-       * Used to detect `data` property values to be HTML-escaped.
-       *
-       * @memberOf _.templateSettings
-       * @type {RegExp}
-       */
-      'escape': reEscape,
-
-      /**
-       * Used to detect code to be evaluated.
-       *
-       * @memberOf _.templateSettings
-       * @type {RegExp}
-       */
-      'evaluate': reEvaluate,
-
-      /**
-       * Used to detect `data` property values to inject.
-       *
-       * @memberOf _.templateSettings
-       * @type {RegExp}
-       */
-      'interpolate': reInterpolate,
-
-      /**
-       * Used to reference the data object in the template text.
-       *
-       * @memberOf _.templateSettings
-       * @type {string}
-       */
-      'variable': '',
-
-      /**
-       * Used to import variables into the compiled template.
-       *
-       * @memberOf _.templateSettings
-       * @type {Object}
-       */
-      'imports': {
-
-        /**
-         * A reference to the `lodash` function.
-         *
-         * @memberOf _.templateSettings.imports
-         * @type {Function}
-         */
-        '_': lodash
-      }
-    };
-
-    // Ensure wrappers are instances of `baseLodash`.
-    lodash.prototype = baseLodash.prototype;
-    lodash.prototype.constructor = lodash;
-
-    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
-    LodashWrapper.prototype.constructor = LodashWrapper;
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
-     *
-     * @private
-     * @constructor
-     * @param {*} value The value to wrap.
-     */
-    function LazyWrapper(value) {
-      this.__wrapped__ = value;
-      this.__actions__ = [];
-      this.__dir__ = 1;
-      this.__filtered__ = false;
-      this.__iteratees__ = [];
-      this.__takeCount__ = MAX_ARRAY_LENGTH;
-      this.__views__ = [];
-    }
-
-    /**
-     * Creates a clone of the lazy wrapper object.
-     *
-     * @private
-     * @name clone
-     * @memberOf LazyWrapper
-     * @returns {Object} Returns the cloned `LazyWrapper` object.
-     */
-    function lazyClone() {
-      var result = new LazyWrapper(this.__wrapped__);
-      result.__actions__ = copyArray(this.__actions__);
-      result.__dir__ = this.__dir__;
-      result.__filtered__ = this.__filtered__;
-      result.__iteratees__ = copyArray(this.__iteratees__);
-      result.__takeCount__ = this.__takeCount__;
-      result.__views__ = copyArray(this.__views__);
-      return result;
-    }
-
-    /**
-     * Reverses the direction of lazy iteration.
-     *
-     * @private
-     * @name reverse
-     * @memberOf LazyWrapper
-     * @returns {Object} Returns the new reversed `LazyWrapper` object.
-     */
-    function lazyReverse() {
-      if (this.__filtered__) {
-        var result = new LazyWrapper(this);
-        result.__dir__ = -1;
-        result.__filtered__ = true;
-      } else {
-        result = this.clone();
-        result.__dir__ *= -1;
-      }
-      return result;
-    }
-
-    /**
-     * Extracts the unwrapped value from its lazy wrapper.
-     *
-     * @private
-     * @name value
-     * @memberOf LazyWrapper
-     * @returns {*} Returns the unwrapped value.
-     */
-    function lazyValue() {
-      var array = this.__wrapped__.value(),
-          dir = this.__dir__,
-          isArr = isArray(array),
-          isRight = dir < 0,
-          arrLength = isArr ? array.length : 0,
-          view = getView(0, arrLength, this.__views__),
-          start = view.start,
-          end = view.end,
-          length = end - start,
-          index = isRight ? end : (start - 1),
-          iteratees = this.__iteratees__,
-          iterLength = iteratees.length,
-          resIndex = 0,
-          takeCount = nativeMin(length, this.__takeCount__);
-
-      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
-        return baseWrapperValue(array, this.__actions__);
-      }
-      var result = [];
-
-      outer:
-      while (length-- && resIndex < takeCount) {
-        index += dir;
-
-        var iterIndex = -1,
-            value = array[index];
-
-        while (++iterIndex < iterLength) {
-          var data = iteratees[iterIndex],
-              iteratee = data.iteratee,
-              type = data.type,
-              computed = iteratee(value);
-
-          if (type == LAZY_MAP_FLAG) {
-            value = computed;
-          } else if (!computed) {
-            if (type == LAZY_FILTER_FLAG) {
-              continue outer;
-            } else {
-              break outer;
-            }
-          }
-        }
-        result[resIndex++] = value;
-      }
-      return result;
-    }
-
-    // Ensure `LazyWrapper` is an instance of `baseLodash`.
-    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
-    LazyWrapper.prototype.constructor = LazyWrapper;
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates a hash object.
-     *
-     * @private
-     * @constructor
-     * @param {Array} [entries] The key-value pairs to cache.
-     */
-    function Hash(entries) {
-      var index = -1,
-          length = entries == null ? 0 : entries.length;
-
-      this.clear();
-      while (++index < length) {
-        var entry = entries[index];
-        this.set(entry[0], entry[1]);
-      }
-    }
-
-    /**
-     * Removes all key-value entries from the hash.
-     *
-     * @private
-     * @name clear
-     * @memberOf Hash
-     */
-    function hashClear() {
-      this.__data__ = nativeCreate ? nativeCreate(null) : {};
-      this.size = 0;
-    }
-
-    /**
-     * Removes `key` and its value from the hash.
-     *
-     * @private
-     * @name delete
-     * @memberOf Hash
-     * @param {Object} hash The hash to modify.
-     * @param {string} key The key of the value to remove.
-     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
-     */
-    function hashDelete(key) {
-      var result = this.has(key) && delete this.__data__[key];
-      this.size -= result ? 1 : 0;
-      return result;
-    }
-
-    /**
-     * Gets the hash value for `key`.
-     *
-     * @private
-     * @name get
-     * @memberOf Hash
-     * @param {string} key The key of the value to get.
-     * @returns {*} Returns the entry value.
-     */
-    function hashGet(key) {
-      var data = this.__data__;
-      if (nativeCreate) {
-        var result = data[key];
-        return result === HASH_UNDEFINED ? undefined : result;
-      }
-      return hasOwnProperty.call(data, key) ? data[key] : undefined;
-    }
-
-    /**
-     * Checks if a hash value for `key` exists.
-     *
-     * @private
-     * @name has
-     * @memberOf Hash
-     * @param {string} key The key of the entry to check.
-     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
-     */
-    function hashHas(key) {
-      var data = this.__data__;
-      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
-    }
-
-    /**
-     * Sets the hash `key` to `value`.
-     *
-     * @private
-     * @name set
-     * @memberOf Hash
-     * @param {string} key The key of the value to set.
-     * @param {*} value The value to set.
-     * @returns {Object} Returns the hash instance.
-     */
-    function hashSet(key, value) {
-      var data = this.__data__;
-      this.size += this.has(key) ? 0 : 1;
-      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
-      return this;
-    }
-
-    // Add methods to `Hash`.
-    Hash.prototype.clear = hashClear;
-    Hash.prototype['delete'] = hashDelete;
-    Hash.prototype.get = hashGet;
-    Hash.prototype.has = hashHas;
-    Hash.prototype.set = hashSet;
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates an list cache object.
-     *
-     * @private
-     * @constructor
-     * @param {Array} [entries] The key-value pairs to cache.
-     */
-    function ListCache(entries) {
-      var index = -1,
-          length = entries == null ? 0 : entries.length;
-
-      this.clear();
-      while (++index < length) {
-        var entry = entries[index];
-        this.set(entry[0], entry[1]);
-      }
-    }
-
-    /**
-     * Removes all key-value entries from the list cache.
-     *
-     * @private
-     * @name clear
-     * @memberOf ListCache
-     */
-    function listCacheClear() {
-      this.__data__ = [];
-      this.size = 0;
-    }
-
-    /**
-     * Removes `key` and its value from the list cache.
-     *
-     * @private
-     * @name delete
-     * @memberOf ListCache
-     * @param {string} key The key of the value to remove.
-     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
-     */
-    function listCacheDelete(key) {
-      var data = this.__data__,
-          index = assocIndexOf(data, key);
-
-      if (index < 0) {
-        return false;
-      }
-      var lastIndex = data.length - 1;
-      if (index == lastIndex) {
-        data.pop();
-      } else {
-        splice.call(data, index, 1);
-      }
-      --this.size;
-      return true;
-    }
-
-    /**
-     * Gets the list cache value for `key`.
-     *
-     * @private
-     * @name get
-     * @memberOf ListCache
-     * @param {string} key The key of the value to get.
-     * @returns {*} Returns the entry value.
-     */
-    function listCacheGet(key) {
-      var data = this.__data__,
-          index = assocIndexOf(data, key);
-
-      return index < 0 ? undefined : data[index][1];
-    }
-
-    /**
-     * Checks if a list cache value for `key` exists.
-     *
-     * @private
-     * @name has
-     * @memberOf ListCache
-     * @param {string} key The key of the entry to check.
-     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
-     */
-    function listCacheHas(key) {
-      return assocIndexOf(this.__data__, key) > -1;
-    }
-
-    /**
-     * Sets the list cache `key` to `value`.
-     *
-     * @private
-     * @name set
-     * @memberOf ListCache
-     * @param {string} key The key of the value to set.
-     * @param {*} value The value to set.
-     * @returns {Object} Returns the list cache instance.
-     */
-    function listCacheSet(key, value) {
-      var data = this.__data__,
-          index = assocIndexOf(data, key);
-
-      if (index < 0) {
-        ++this.size;
-        data.push([key, value]);
-      } else {
-        data[index][1] = value;
-      }
-      return this;
-    }
-
-    // Add methods to `ListCache`.
-    ListCache.prototype.clear = listCacheClear;
-    ListCache.prototype['delete'] = listCacheDelete;
-    ListCache.prototype.get = listCacheGet;
-    ListCache.prototype.has = listCacheHas;
-    ListCache.prototype.set = listCacheSet;
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates a map cache object to store key-value pairs.
-     *
-     * @private
-     * @constructor
-     * @param {Array} [entries] The key-value pairs to cache.
-     */
-    function MapCache(entries) {
-      var index = -1,
-          length = entries == null ? 0 : entries.length;
-
-      this.clear();
-      while (++index < length) {
-        var entry = entries[index];
-        this.set(entry[0], entry[1]);
-      }
-    }
-
-    /**
-     * Removes all key-value entries from the map.
-     *
-     * @private
-     * @name clear
-     * @memberOf MapCache
-     */
-    function mapCacheClear() {
-      this.size = 0;
-      this.__data__ = {
-        'hash': new Hash,
-        'map': new (Map || ListCache),
-        'string': new Hash
-      };
-    }
-
-    /**
-     * Removes `key` and its value from the map.
-     *
-     * @private
-     * @name delete
-     * @memberOf MapCache
-     * @param {string} key The key of the value to remove.
-     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
-     */
-    function mapCacheDelete(key) {
-      var result = getMapData(this, key)['delete'](key);
-      this.size -= result ? 1 : 0;
-      return result;
-    }
-
-    /**
-     * Gets the map value for `key`.
-     *
-     * @private
-     * @name get
-     * @memberOf MapCache
-     * @param {string} key The key of the value to get.
-     * @returns {*} Returns the entry value.
-     */
-    function mapCacheGet(key) {
-      return getMapData(this, key).get(key);
-    }
-
-    /**
-     * Checks if a map value for `key` exists.
-     *
-     * @private
-     * @name has
-     * @memberOf MapCache
-     * @param {string} key The key of the entry to check.
-     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
-     */
-    function mapCacheHas(key) {
-      return getMapData(this, key).has(key);
-    }
-
-    /**
-     * Sets the map `key` to `value`.
-     *
-     * @private
-     * @name set
-     * @memberOf MapCache
-     * @param {string} key The key of the value to set.
-     * @param {*} value The value to set.
-     * @returns {Object} Returns the map cache instance.
-     */
-    function mapCacheSet(key, value) {
-      var data = getMapData(this, key),
-          size = data.size;
-
-      data.set(key, value);
-      this.size += data.size == size ? 0 : 1;
-      return this;
-    }
-
-    // Add methods to `MapCache`.
-    MapCache.prototype.clear = mapCacheClear;
-    MapCache.prototype['delete'] = mapCacheDelete;
-    MapCache.prototype.get = mapCacheGet;
-    MapCache.prototype.has = mapCacheHas;
-    MapCache.prototype.set = mapCacheSet;
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     *
-     * Creates an array cache object to store unique values.
-     *
-     * @private
-     * @constructor
-     * @param {Array} [values] The values to cache.
-     */
-    function SetCache(values) {
-      var index = -1,
-          length = values == null ? 0 : values.length;
-
-      this.__data__ = new MapCache;
-      while (++index < length) {
-        this.add(values[index]);
-      }
-    }
-
-    /**
-     * Adds `value` to the array cache.
-     *
-     * @private
-     * @name add
-     * @memberOf SetCache
-     * @alias push
-     * @param {*} value The value to cache.
-     * @returns {Object} Returns the cache instance.
-     */
-    function setCacheAdd(value) {
-      this.__data__.set(value, HASH_UNDEFINED);
-      return this;
-    }
-
-    /**
-     * Checks if `value` is in the array cache.
-     *
-     * @private
-     * @name has
-     * @memberOf SetCache
-     * @param {*} value The value to search for.
-     * @returns {number} Returns `true` if `value` is found, else `false`.
-     */
-    function setCacheHas(value) {
-      return this.__data__.has(value);
-    }
-
-    // Add methods to `SetCache`.
-    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
-    SetCache.prototype.has = setCacheHas;
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates a stack cache object to store key-value pairs.
-     *
-     * @private
-     * @constructor
-     * @param {Array} [entries] The key-value pairs to cache.
-     */
-    function Stack(entries) {
-      var data = this.__data__ = new ListCache(entries);
-      this.size = data.size;
-    }
-
-    /**
-     * Removes all key-value entries from the stack.
-     *
-     * @private
-     * @name clear
-     * @memberOf Stack
-     */
-    function stackClear() {
-      this.__data__ = new ListCache;
-      this.size = 0;
-    }
-
-    /**
-     * Removes `key` and its value from the stack.
-     *
-     * @private
-     * @name delete
-     * @memberOf Stack
-     * @param {string} key The key of the value to remove.
-     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
-     */
-    function stackDelete(key) {
-      var data = this.__data__,
-          result = data['delete'](key);
-
-      this.size = data.size;
-      return result;
-    }
-
-    /**
-     * Gets the stack value for `key`.
-     *
-     * @private
-     * @name get
-     * @memberOf Stack
-     * @param {string} key The key of the value to get.
-     * @returns {*} Returns the entry value.
-     */
-    function stackGet(key) {
-      return this.__data__.get(key);
-    }
-
-    /**
-     * Checks if a stack value for `key` exists.
-     *
-     * @private
-     * @name has
-     * @memberOf Stack
-     * @param {string} key The key of the entry to check.
-     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
-     */
-    function stackHas(key) {
-      return this.__data__.has(key);
-    }
-
-    /**
-     * Sets the stack `key` to `value`.
-     *
-     * @private
-     * @name set
-     * @memberOf Stack
-     * @param {string} key The key of the value to set.
-     * @param {*} value The value to set.
-     * @returns {Object} Returns the stack cache instance.
-     */
-    function stackSet(key, value) {
-      var data = this.__data__;
-      if (data instanceof ListCache) {
-        var pairs = data.__data__;
-        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
-          pairs.push([key, value]);
-          this.size = ++data.size;
-          return this;
-        }
-        data = this.__data__ = new MapCache(pairs);
-      }
-      data.set(key, value);
-      this.size = data.size;
-      return this;
-    }
-
-    // Add methods to `Stack`.
-    Stack.prototype.clear = stackClear;
-    Stack.prototype['delete'] = stackDelete;
-    Stack.prototype.get = stackGet;
-    Stack.prototype.has = stackHas;
-    Stack.prototype.set = stackSet;
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates an array of the enumerable property names of the array-like `value`.
-     *
-     * @private
-     * @param {*} value The value to query.
-     * @param {boolean} inherited Specify returning inherited property names.
-     * @returns {Array} Returns the array of property names.
-     */
-    function arrayLikeKeys(value, inherited) {
-      var isArr = isArray(value),
-          isArg = !isArr && isArguments(value),
-          isBuff = !isArr && !isArg && isBuffer(value),
-          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
-          skipIndexes = isArr || isArg || isBuff || isType,
-          result = skipIndexes ? baseTimes(value.length, String) : [],
-          length = result.length;
-
-      for (var key in value) {
-        if ((inherited || hasOwnProperty.call(value, key)) &&
-            !(skipIndexes && (
-               // Safari 9 has enumerable `arguments.length` in strict mode.
-               key == 'length' ||
-               // Node.js 0.10 has enumerable non-index properties on buffers.
-               (isBuff && (key == 'offset' || key == 'parent')) ||
-               // PhantomJS 2 has enumerable non-index properties on typed arrays.
-               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
-               // Skip index properties.
-               isIndex(key, length)
-            ))) {
-          result.push(key);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * A specialized version of `_.sample` for arrays.
-     *
-     * @private
-     * @param {Array} array The array to sample.
-     * @returns {*} Returns the random element.
-     */
-    function arraySample(array) {
-      var length = array.length;
-      return length ? array[baseRandom(0, length - 1)] : undefined;
-    }
-
-    /**
-     * A specialized version of `_.sampleSize` for arrays.
-     *
-     * @private
-     * @param {Array} array The array to sample.
-     * @param {number} n The number of elements to sample.
-     * @returns {Array} Returns the random elements.
-     */
-    function arraySampleSize(array, n) {
-      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
-    }
-
-    /**
-     * A specialized version of `_.shuffle` for arrays.
-     *
-     * @private
-     * @param {Array} array The array to shuffle.
-     * @returns {Array} Returns the new shuffled array.
-     */
-    function arrayShuffle(array) {
-      return shuffleSelf(copyArray(array));
-    }
-
-    /**
-     * This function is like `assignValue` except that it doesn't assign
-     * `undefined` values.
-     *
-     * @private
-     * @param {Object} object The object to modify.
-     * @param {string} key The key of the property to assign.
-     * @param {*} value The value to assign.
-     */
-    function assignMergeValue(object, key, value) {
-      if ((value !== undefined && !eq(object[key], value)) ||
-          (value === undefined && !(key in object))) {
-        baseAssignValue(object, key, value);
-      }
-    }
-
-    /**
-     * Assigns `value` to `key` of `object` if the existing value is not equivalent
-     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * for equality comparisons.
-     *
-     * @private
-     * @param {Object} object The object to modify.
-     * @param {string} key The key of the property to assign.
-     * @param {*} value The value to assign.
-     */
-    function assignValue(object, key, value) {
-      var objValue = object[key];
-      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
-          (value === undefined && !(key in object))) {
-        baseAssignValue(object, key, value);
-      }
-    }
-
-    /**
-     * Gets the index at which the `key` is found in `array` of key-value pairs.
-     *
-     * @private
-     * @param {Array} array The array to inspect.
-     * @param {*} key The key to search for.
-     * @returns {number} Returns the index of the matched value, else `-1`.
-     */
-    function assocIndexOf(array, key) {
-      var length = array.length;
-      while (length--) {
-        if (eq(array[length][0], key)) {
-          return length;
-        }
-      }
-      return -1;
-    }
-
-    /**
-     * Aggregates elements of `collection` on `accumulator` with keys transformed
-     * by `iteratee` and values set by `setter`.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} setter The function to set `accumulator` values.
-     * @param {Function} iteratee The iteratee to transform keys.
-     * @param {Object} accumulator The initial aggregated object.
-     * @returns {Function} Returns `accumulator`.
-     */
-    function baseAggregator(collection, setter, iteratee, accumulator) {
-      baseEach(collection, function(value, key, collection) {
-        setter(accumulator, value, iteratee(value), collection);
-      });
-      return accumulator;
-    }
-
-    /**
-     * The base implementation of `_.assign` without support for multiple sources
-     * or `customizer` functions.
-     *
-     * @private
-     * @param {Object} object The destination object.
-     * @param {Object} source The source object.
-     * @returns {Object} Returns `object`.
-     */
-    function baseAssign(object, source) {
-      return object && copyObject(source, keys(source), object);
-    }
-
-    /**
-     * The base implementation of `_.assignIn` without support for multiple sources
-     * or `customizer` functions.
-     *
-     * @private
-     * @param {Object} object The destination object.
-     * @param {Object} source The source object.
-     * @returns {Object} Returns `object`.
-     */
-    function baseAssignIn(object, source) {
-      return object && copyObject(source, keysIn(source), object);
-    }
-
-    /**
-     * The base implementation of `assignValue` and `assignMergeValue` without
-     * value checks.
-     *
-     * @private
-     * @param {Object} object The object to modify.
-     * @param {string} key The key of the property to assign.
-     * @param {*} value The value to assign.
-     */
-    function baseAssignValue(object, key, value) {
-      if (key == '__proto__' && defineProperty) {
-        defineProperty(object, key, {
-          'configurable': true,
-          'enumerable': true,
-          'value': value,
-          'writable': true
-        });
-      } else {
-        object[key] = value;
-      }
-    }
-
-    /**
-     * The base implementation of `_.at` without support for individual paths.
-     *
-     * @private
-     * @param {Object} object The object to iterate over.
-     * @param {string[]} paths The property paths to pick.
-     * @returns {Array} Returns the picked elements.
-     */
-    function baseAt(object, paths) {
-      var index = -1,
-          length = paths.length,
-          result = Array(length),
-          skip = object == null;
-
-      while (++index < length) {
-        result[index] = skip ? undefined : get(object, paths[index]);
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.clamp` which doesn't coerce arguments.
-     *
-     * @private
-     * @param {number} number The number to clamp.
-     * @param {number} [lower] The lower bound.
-     * @param {number} upper The upper bound.
-     * @returns {number} Returns the clamped number.
-     */
-    function baseClamp(number, lower, upper) {
-      if (number === number) {
-        if (upper !== undefined) {
-          number = number <= upper ? number : upper;
-        }
-        if (lower !== undefined) {
-          number = number >= lower ? number : lower;
-        }
-      }
-      return number;
-    }
-
-    /**
-     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
-     * traversed objects.
-     *
-     * @private
-     * @param {*} value The value to clone.
-     * @param {boolean} bitmask The bitmask flags.
-     *  1 - Deep clone
-     *  2 - Flatten inherited properties
-     *  4 - Clone symbols
-     * @param {Function} [customizer] The function to customize cloning.
-     * @param {string} [key] The key of `value`.
-     * @param {Object} [object] The parent object of `value`.
-     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
-     * @returns {*} Returns the cloned value.
-     */
-    function baseClone(value, bitmask, customizer, key, object, stack) {
-      var result,
-          isDeep = bitmask & CLONE_DEEP_FLAG,
-          isFlat = bitmask & CLONE_FLAT_FLAG,
-          isFull = bitmask & CLONE_SYMBOLS_FLAG;
-
-      if (customizer) {
-        result = object ? customizer(value, key, object, stack) : customizer(value);
-      }
-      if (result !== undefined) {
-        return result;
-      }
-      if (!isObject(value)) {
-        return value;
-      }
-      var isArr = isArray(value);
-      if (isArr) {
-        result = initCloneArray(value);
-        if (!isDeep) {
-          return copyArray(value, result);
-        }
-      } else {
-        var tag = getTag(value),
-            isFunc = tag == funcTag || tag == genTag;
-
-        if (isBuffer(value)) {
-          return cloneBuffer(value, isDeep);
-        }
-        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
-          result = (isFlat || isFunc) ? {} : initCloneObject(value);
-          if (!isDeep) {
-            return isFlat
-              ? copySymbolsIn(value, baseAssignIn(result, value))
-              : copySymbols(value, baseAssign(result, value));
-          }
-        } else {
-          if (!cloneableTags[tag]) {
-            return object ? value : {};
-          }
-          result = initCloneByTag(value, tag, baseClone, isDeep);
-        }
-      }
-      // Check for circular references and return its corresponding clone.
-      stack || (stack = new Stack);
-      var stacked = stack.get(value);
-      if (stacked) {
-        return stacked;
-      }
-      stack.set(value, result);
-
-      var keysFunc = isFull
-        ? (isFlat ? getAllKeysIn : getAllKeys)
-        : (isFlat ? keysIn : keys);
-
-      var props = isArr ? undefined : keysFunc(value);
-      arrayEach(props || value, function(subValue, key) {
-        if (props) {
-          key = subValue;
-          subValue = value[key];
-        }
-        // Recursively populate clone (susceptible to call stack limits).
-        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
-      });
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.conforms` which doesn't clone `source`.
-     *
-     * @private
-     * @param {Object} source The object of property predicates to conform to.
-     * @returns {Function} Returns the new spec function.
-     */
-    function baseConforms(source) {
-      var props = keys(source);
-      return function(object) {
-        return baseConformsTo(object, source, props);
-      };
-    }
-
-    /**
-     * The base implementation of `_.conformsTo` which accepts `props` to check.
-     *
-     * @private
-     * @param {Object} object The object to inspect.
-     * @param {Object} source The object of property predicates to conform to.
-     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
-     */
-    function baseConformsTo(object, source, props) {
-      var length = props.length;
-      if (object == null) {
-        return !length;
-      }
-      object = Object(object);
-      while (length--) {
-        var key = props[length],
-            predicate = source[key],
-            value = object[key];
-
-        if ((value === undefined && !(key in object)) || !predicate(value)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /**
-     * The base implementation of `_.delay` and `_.defer` which accepts `args`
-     * to provide to `func`.
-     *
-     * @private
-     * @param {Function} func The function to delay.
-     * @param {number} wait The number of milliseconds to delay invocation.
-     * @param {Array} args The arguments to provide to `func`.
-     * @returns {number|Object} Returns the timer id or timeout object.
-     */
-    function baseDelay(func, wait, args) {
-      if (typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      return setTimeout(function() { func.apply(undefined, args); }, wait);
-    }
-
-    /**
-     * The base implementation of methods like `_.difference` without support
-     * for excluding multiple arrays or iteratee shorthands.
-     *
-     * @private
-     * @param {Array} array The array to inspect.
-     * @param {Array} values The values to exclude.
-     * @param {Function} [iteratee] The iteratee invoked per element.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new array of filtered values.
-     */
-    function baseDifference(array, values, iteratee, comparator) {
-      var index = -1,
-          includes = arrayIncludes,
-          isCommon = true,
-          length = array.length,
-          result = [],
-          valuesLength = values.length;
-
-      if (!length) {
-        return result;
-      }
-      if (iteratee) {
-        values = arrayMap(values, baseUnary(iteratee));
-      }
-      if (comparator) {
-        includes = arrayIncludesWith;
-        isCommon = false;
-      }
-      else if (values.length >= LARGE_ARRAY_SIZE) {
-        includes = cacheHas;
-        isCommon = false;
-        values = new SetCache(values);
-      }
-      outer:
-      while (++index < length) {
-        var value = array[index],
-            computed = iteratee == null ? value : iteratee(value);
-
-        value = (comparator || value !== 0) ? value : 0;
-        if (isCommon && computed === computed) {
-          var valuesIndex = valuesLength;
-          while (valuesIndex--) {
-            if (values[valuesIndex] === computed) {
-              continue outer;
-            }
-          }
-          result.push(value);
-        }
-        else if (!includes(values, computed, comparator)) {
-          result.push(value);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.forEach` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} iteratee The function invoked per iteration.
-     * @returns {Array|Object} Returns `collection`.
-     */
-    var baseEach = createBaseEach(baseForOwn);
-
-    /**
-     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} iteratee The function invoked per iteration.
-     * @returns {Array|Object} Returns `collection`.
-     */
-    var baseEachRight = createBaseEach(baseForOwnRight, true);
-
-    /**
-     * The base implementation of `_.every` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} predicate The function invoked per iteration.
-     * @returns {boolean} Returns `true` if all elements pass the predicate check,
-     *  else `false`
-     */
-    function baseEvery(collection, predicate) {
-      var result = true;
-      baseEach(collection, function(value, index, collection) {
-        result = !!predicate(value, index, collection);
-        return result;
-      });
-      return result;
-    }
-
-    /**
-     * The base implementation of methods like `_.max` and `_.min` which accepts a
-     * `comparator` to determine the extremum value.
-     *
-     * @private
-     * @param {Array} array The array to iterate over.
-     * @param {Function} iteratee The iteratee invoked per iteration.
-     * @param {Function} comparator The comparator used to compare values.
-     * @returns {*} Returns the extremum value.
-     */
-    function baseExtremum(array, iteratee, comparator) {
-      var index = -1,
-          length = array.length;
-
-      while (++index < length) {
-        var value = array[index],
-            current = iteratee(value);
-
-        if (current != null && (computed === undefined
-              ? (current === current && !isSymbol(current))
-              : comparator(current, computed)
-            )) {
-          var computed = current,
-              result = value;
-        }
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.fill` without an iteratee call guard.
-     *
-     * @private
-     * @param {Array} array The array to fill.
-     * @param {*} value The value to fill `array` with.
-     * @param {number} [start=0] The start position.
-     * @param {number} [end=array.length] The end position.
-     * @returns {Array} Returns `array`.
-     */
-    function baseFill(array, value, start, end) {
-      var length = array.length;
-
-      start = toInteger(start);
-      if (start < 0) {
-        start = -start > length ? 0 : (length + start);
-      }
-      end = (end === undefined || end > length) ? length : toInteger(end);
-      if (end < 0) {
-        end += length;
-      }
-      end = start > end ? 0 : toLength(end);
-      while (start < end) {
-        array[start++] = value;
-      }
-      return array;
-    }
-
-    /**
-     * The base implementation of `_.filter` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} predicate The function invoked per iteration.
-     * @returns {Array} Returns the new filtered array.
-     */
-    function baseFilter(collection, predicate) {
-      var result = [];
-      baseEach(collection, function(value, index, collection) {
-        if (predicate(value, index, collection)) {
-          result.push(value);
-        }
-      });
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.flatten` with support for restricting flattening.
-     *
-     * @private
-     * @param {Array} array The array to flatten.
-     * @param {number} depth The maximum recursion depth.
-     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
-     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
-     * @param {Array} [result=[]] The initial result value.
-     * @returns {Array} Returns the new flattened array.
-     */
-    function baseFlatten(array, depth, predicate, isStrict, result) {
-      var index = -1,
-          length = array.length;
-
-      predicate || (predicate = isFlattenable);
-      result || (result = []);
-
-      while (++index < length) {
-        var value = array[index];
-        if (depth > 0 && predicate(value)) {
-          if (depth > 1) {
-            // Recursively flatten arrays (susceptible to call stack limits).
-            baseFlatten(value, depth - 1, predicate, isStrict, result);
-          } else {
-            arrayPush(result, value);
-          }
-        } else if (!isStrict) {
-          result[result.length] = value;
-        }
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `baseForOwn` which iterates over `object`
-     * properties returned by `keysFunc` and invokes `iteratee` for each property.
-     * Iteratee functions may exit iteration early by explicitly returning `false`.
-     *
-     * @private
-     * @param {Object} object The object to iterate over.
-     * @param {Function} iteratee The function invoked per iteration.
-     * @param {Function} keysFunc The function to get the keys of `object`.
-     * @returns {Object} Returns `object`.
-     */
-    var baseFor = createBaseFor();
-
-    /**
-     * This function is like `baseFor` except that it iterates over properties
-     * in the opposite order.
-     *
-     * @private
-     * @param {Object} object The object to iterate over.
-     * @param {Function} iteratee The function invoked per iteration.
-     * @param {Function} keysFunc The function to get the keys of `object`.
-     * @returns {Object} Returns `object`.
-     */
-    var baseForRight = createBaseFor(true);
-
-    /**
-     * The base implementation of `_.forOwn` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Object} object The object to iterate over.
-     * @param {Function} iteratee The function invoked per iteration.
-     * @returns {Object} Returns `object`.
-     */
-    function baseForOwn(object, iteratee) {
-      return object && baseFor(object, iteratee, keys);
-    }
-
-    /**
-     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Object} object The object to iterate over.
-     * @param {Function} iteratee The function invoked per iteration.
-     * @returns {Object} Returns `object`.
-     */
-    function baseForOwnRight(object, iteratee) {
-      return object && baseForRight(object, iteratee, keys);
-    }
-
-    /**
-     * The base implementation of `_.functions` which creates an array of
-     * `object` function property names filtered from `props`.
-     *
-     * @private
-     * @param {Object} object The object to inspect.
-     * @param {Array} props The property names to filter.
-     * @returns {Array} Returns the function names.
-     */
-    function baseFunctions(object, props) {
-      return arrayFilter(props, function(key) {
-        return isFunction(object[key]);
-      });
-    }
-
-    /**
-     * The base implementation of `_.get` without support for default values.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @param {Array|string} path The path of the property to get.
-     * @returns {*} Returns the resolved value.
-     */
-    function baseGet(object, path) {
-      path = castPath(path, object);
-
-      var index = 0,
-          length = path.length;
-
-      while (object != null && index < length) {
-        object = object[toKey(path[index++])];
-      }
-      return (index && index == length) ? object : undefined;
-    }
-
-    /**
-     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
-     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
-     * symbols of `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @param {Function} keysFunc The function to get the keys of `object`.
-     * @param {Function} symbolsFunc The function to get the symbols of `object`.
-     * @returns {Array} Returns the array of property names and symbols.
-     */
-    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
-      var result = keysFunc(object);
-      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
-    }
-
-    /**
-     * The base implementation of `getTag` without fallbacks for buggy environments.
-     *
-     * @private
-     * @param {*} value The value to query.
-     * @returns {string} Returns the `toStringTag`.
-     */
-    function baseGetTag(value) {
-      if (value == null) {
-        return value === undefined ? undefinedTag : nullTag;
-      }
-      return (symToStringTag && symToStringTag in Object(value))
-        ? getRawTag(value)
-        : objectToString(value);
-    }
-
-    /**
-     * The base implementation of `_.gt` which doesn't coerce arguments.
-     *
-     * @private
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {boolean} Returns `true` if `value` is greater than `other`,
-     *  else `false`.
-     */
-    function baseGt(value, other) {
-      return value > other;
-    }
-
-    /**
-     * The base implementation of `_.has` without support for deep paths.
-     *
-     * @private
-     * @param {Object} [object] The object to query.
-     * @param {Array|string} key The key to check.
-     * @returns {boolean} Returns `true` if `key` exists, else `false`.
-     */
-    function baseHas(object, key) {
-      return object != null && hasOwnProperty.call(object, key);
-    }
-
-    /**
-     * The base implementation of `_.hasIn` without support for deep paths.
-     *
-     * @private
-     * @param {Object} [object] The object to query.
-     * @param {Array|string} key The key to check.
-     * @returns {boolean} Returns `true` if `key` exists, else `false`.
-     */
-    function baseHasIn(object, key) {
-      return object != null && key in Object(object);
-    }
-
-    /**
-     * The base implementation of `_.inRange` which doesn't coerce arguments.
-     *
-     * @private
-     * @param {number} number The number to check.
-     * @param {number} start The start of the range.
-     * @param {number} end The end of the range.
-     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
-     */
-    function baseInRange(number, start, end) {
-      return number >= nativeMin(start, end) && number < nativeMax(start, end);
-    }
-
-    /**
-     * The base implementation of methods like `_.intersection`, without support
-     * for iteratee shorthands, that accepts an array of arrays to inspect.
-     *
-     * @private
-     * @param {Array} arrays The arrays to inspect.
-     * @param {Function} [iteratee] The iteratee invoked per element.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new array of shared values.
-     */
-    function baseIntersection(arrays, iteratee, comparator) {
-      var includes = comparator ? arrayIncludesWith : arrayIncludes,
-          length = arrays[0].length,
-          othLength = arrays.length,
-          othIndex = othLength,
-          caches = Array(othLength),
-          maxLength = Infinity,
-          result = [];
-
-      while (othIndex--) {
-        var array = arrays[othIndex];
-        if (othIndex && iteratee) {
-          array = arrayMap(array, baseUnary(iteratee));
-        }
-        maxLength = nativeMin(array.length, maxLength);
-        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
-          ? new SetCache(othIndex && array)
-          : undefined;
-      }
-      array = arrays[0];
-
-      var index = -1,
-          seen = caches[0];
-
-      outer:
-      while (++index < length && result.length < maxLength) {
-        var value = array[index],
-            computed = iteratee ? iteratee(value) : value;
-
-        value = (comparator || value !== 0) ? value : 0;
-        if (!(seen
-              ? cacheHas(seen, computed)
-              : includes(result, computed, comparator)
-            )) {
-          othIndex = othLength;
-          while (--othIndex) {
-            var cache = caches[othIndex];
-            if (!(cache
-                  ? cacheHas(cache, computed)
-                  : includes(arrays[othIndex], computed, comparator))
-                ) {
-              continue outer;
-            }
-          }
-          if (seen) {
-            seen.push(computed);
-          }
-          result.push(value);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.invert` and `_.invertBy` which inverts
-     * `object` with values transformed by `iteratee` and set by `setter`.
-     *
-     * @private
-     * @param {Object} object The object to iterate over.
-     * @param {Function} setter The function to set `accumulator` values.
-     * @param {Function} iteratee The iteratee to transform values.
-     * @param {Object} accumulator The initial inverted object.
-     * @returns {Function} Returns `accumulator`.
-     */
-    function baseInverter(object, setter, iteratee, accumulator) {
-      baseForOwn(object, function(value, key, object) {
-        setter(accumulator, iteratee(value), key, object);
-      });
-      return accumulator;
-    }
-
-    /**
-     * The base implementation of `_.invoke` without support for individual
-     * method arguments.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @param {Array|string} path The path of the method to invoke.
-     * @param {Array} args The arguments to invoke the method with.
-     * @returns {*} Returns the result of the invoked method.
-     */
-    function baseInvoke(object, path, args) {
-      path = castPath(path, object);
-      object = parent(object, path);
-      var func = object == null ? object : object[toKey(last(path))];
-      return func == null ? undefined : apply(func, object, args);
-    }
-
-    /**
-     * The base implementation of `_.isArguments`.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
-     */
-    function baseIsArguments(value) {
-      return isObjectLike(value) && baseGetTag(value) == argsTag;
-    }
-
-    /**
-     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
-     */
-    function baseIsArrayBuffer(value) {
-      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
-    }
-
-    /**
-     * The base implementation of `_.isDate` without Node.js optimizations.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
-     */
-    function baseIsDate(value) {
-      return isObjectLike(value) && baseGetTag(value) == dateTag;
-    }
-
-    /**
-     * The base implementation of `_.isEqual` which supports partial comparisons
-     * and tracks traversed objects.
-     *
-     * @private
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @param {boolean} bitmask The bitmask flags.
-     *  1 - Unordered comparison
-     *  2 - Partial comparison
-     * @param {Function} [customizer] The function to customize comparisons.
-     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
-     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-     */
-    function baseIsEqual(value, other, bitmask, customizer, stack) {
-      if (value === other) {
-        return true;
-      }
-      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
-        return value !== value && other !== other;
-      }
-      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
-    }
-
-    /**
-     * A specialized version of `baseIsEqual` for arrays and objects which performs
-     * deep comparisons and tracks traversed objects enabling objects with circular
-     * references to be compared.
-     *
-     * @private
-     * @param {Object} object The object to compare.
-     * @param {Object} other The other object to compare.
-     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
-     * @param {Function} customizer The function to customize comparisons.
-     * @param {Function} equalFunc The function to determine equivalents of values.
-     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
-     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
-     */
-    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
-      var objIsArr = isArray(object),
-          othIsArr = isArray(other),
-          objTag = objIsArr ? arrayTag : getTag(object),
-          othTag = othIsArr ? arrayTag : getTag(other);
-
-      objTag = objTag == argsTag ? objectTag : objTag;
-      othTag = othTag == argsTag ? objectTag : othTag;
-
-      var objIsObj = objTag == objectTag,
-          othIsObj = othTag == objectTag,
-          isSameTag = objTag == othTag;
-
-      if (isSameTag && isBuffer(object)) {
-        if (!isBuffer(other)) {
-          return false;
-        }
-        objIsArr = true;
-        objIsObj = false;
-      }
-      if (isSameTag && !objIsObj) {
-        stack || (stack = new Stack);
-        return (objIsArr || isTypedArray(object))
-          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
-          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
-      }
-      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
-        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
-            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
-
-        if (objIsWrapped || othIsWrapped) {
-          var objUnwrapped = objIsWrapped ? object.value() : object,
-              othUnwrapped = othIsWrapped ? other.value() : other;
-
-          stack || (stack = new Stack);
-          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
-        }
-      }
-      if (!isSameTag) {
-        return false;
-      }
-      stack || (stack = new Stack);
-      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
-    }
-
-    /**
-     * The base implementation of `_.isMap` without Node.js optimizations.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
-     */
-    function baseIsMap(value) {
-      return isObjectLike(value) && getTag(value) == mapTag;
-    }
-
-    /**
-     * The base implementation of `_.isMatch` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Object} object The object to inspect.
-     * @param {Object} source The object of property values to match.
-     * @param {Array} matchData The property names, values, and compare flags to match.
-     * @param {Function} [customizer] The function to customize comparisons.
-     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
-     */
-    function baseIsMatch(object, source, matchData, customizer) {
-      var index = matchData.length,
-          length = index,
-          noCustomizer = !customizer;
-
-      if (object == null) {
-        return !length;
-      }
-      object = Object(object);
-      while (index--) {
-        var data = matchData[index];
-        if ((noCustomizer && data[2])
-              ? data[1] !== object[data[0]]
-              : !(data[0] in object)
-            ) {
-          return false;
-        }
-      }
-      while (++index < length) {
-        data = matchData[index];
-        var key = data[0],
-            objValue = object[key],
-            srcValue = data[1];
-
-        if (noCustomizer && data[2]) {
-          if (objValue === undefined && !(key in object)) {
-            return false;
-          }
-        } else {
-          var stack = new Stack;
-          if (customizer) {
-            var result = customizer(objValue, srcValue, key, object, source, stack);
-          }
-          if (!(result === undefined
-                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
-                : result
-              )) {
-            return false;
-          }
-        }
-      }
-      return true;
-    }
-
-    /**
-     * The base implementation of `_.isNative` without bad shim checks.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a native function,
-     *  else `false`.
-     */
-    function baseIsNative(value) {
-      if (!isObject(value) || isMasked(value)) {
-        return false;
-      }
-      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
-      return pattern.test(toSource(value));
-    }
-
-    /**
-     * The base implementation of `_.isRegExp` without Node.js optimizations.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
-     */
-    function baseIsRegExp(value) {
-      return isObjectLike(value) && baseGetTag(value) == regexpTag;
-    }
-
-    /**
-     * The base implementation of `_.isSet` without Node.js optimizations.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
-     */
-    function baseIsSet(value) {
-      return isObjectLike(value) && getTag(value) == setTag;
-    }
-
-    /**
-     * The base implementation of `_.isTypedArray` without Node.js optimizations.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
-     */
-    function baseIsTypedArray(value) {
-      return isObjectLike(value) &&
-        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
-    }
-
-    /**
-     * The base implementation of `_.iteratee`.
-     *
-     * @private
-     * @param {*} [value=_.identity] The value to convert to an iteratee.
-     * @returns {Function} Returns the iteratee.
-     */
-    function baseIteratee(value) {
-      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
-      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
-      if (typeof value == 'function') {
-        return value;
-      }
-      if (value == null) {
-        return identity;
-      }
-      if (typeof value == 'object') {
-        return isArray(value)
-          ? baseMatchesProperty(value[0], value[1])
-          : baseMatches(value);
-      }
-      return property(value);
-    }
-
-    /**
-     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property names.
-     */
-    function baseKeys(object) {
-      if (!isPrototype(object)) {
-        return nativeKeys(object);
-      }
-      var result = [];
-      for (var key in Object(object)) {
-        if (hasOwnProperty.call(object, key) && key != 'constructor') {
-          result.push(key);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property names.
-     */
-    function baseKeysIn(object) {
-      if (!isObject(object)) {
-        return nativeKeysIn(object);
-      }
-      var isProto = isPrototype(object),
-          result = [];
-
-      for (var key in object) {
-        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
-          result.push(key);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.lt` which doesn't coerce arguments.
-     *
-     * @private
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {boolean} Returns `true` if `value` is less than `other`,
-     *  else `false`.
-     */
-    function baseLt(value, other) {
-      return value < other;
-    }
-
-    /**
-     * The base implementation of `_.map` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} iteratee The function invoked per iteration.
-     * @returns {Array} Returns the new mapped array.
-     */
-    function baseMap(collection, iteratee) {
-      var index = -1,
-          result = isArrayLike(collection) ? Array(collection.length) : [];
-
-      baseEach(collection, function(value, key, collection) {
-        result[++index] = iteratee(value, key, collection);
-      });
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.matches` which doesn't clone `source`.
-     *
-     * @private
-     * @param {Object} source The object of property values to match.
-     * @returns {Function} Returns the new spec function.
-     */
-    function baseMatches(source) {
-      var matchData = getMatchData(source);
-      if (matchData.length == 1 && matchData[0][2]) {
-        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
-      }
-      return function(object) {
-        return object === source || baseIsMatch(object, source, matchData);
-      };
-    }
-
-    /**
-     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
-     *
-     * @private
-     * @param {string} path The path of the property to get.
-     * @param {*} srcValue The value to match.
-     * @returns {Function} Returns the new spec function.
-     */
-    function baseMatchesProperty(path, srcValue) {
-      if (isKey(path) && isStrictComparable(srcValue)) {
-        return matchesStrictComparable(toKey(path), srcValue);
-      }
-      return function(object) {
-        var objValue = get(object, path);
-        return (objValue === undefined && objValue === srcValue)
-          ? hasIn(object, path)
-          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
-      };
-    }
-
-    /**
-     * The base implementation of `_.merge` without support for multiple sources.
-     *
-     * @private
-     * @param {Object} object The destination object.
-     * @param {Object} source The source object.
-     * @param {number} srcIndex The index of `source`.
-     * @param {Function} [customizer] The function to customize merged values.
-     * @param {Object} [stack] Tracks traversed source values and their merged
-     *  counterparts.
-     */
-    function baseMerge(object, source, srcIndex, customizer, stack) {
-      if (object === source) {
-        return;
-      }
-      baseFor(source, function(srcValue, key) {
-        if (isObject(srcValue)) {
-          stack || (stack = new Stack);
-          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
-        }
-        else {
-          var newValue = customizer
-            ? customizer(object[key], srcValue, (key + ''), object, source, stack)
-            : undefined;
-
-          if (newValue === undefined) {
-            newValue = srcValue;
-          }
-          assignMergeValue(object, key, newValue);
-        }
-      }, keysIn);
-    }
-
-    /**
-     * A specialized version of `baseMerge` for arrays and objects which performs
-     * deep merges and tracks traversed objects enabling objects with circular
-     * references to be merged.
-     *
-     * @private
-     * @param {Object} object The destination object.
-     * @param {Object} source The source object.
-     * @param {string} key The key of the value to merge.
-     * @param {number} srcIndex The index of `source`.
-     * @param {Function} mergeFunc The function to merge values.
-     * @param {Function} [customizer] The function to customize assigned values.
-     * @param {Object} [stack] Tracks traversed source values and their merged
-     *  counterparts.
-     */
-    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
-      var objValue = object[key],
-          srcValue = source[key],
-          stacked = stack.get(srcValue);
-
-      if (stacked) {
-        assignMergeValue(object, key, stacked);
-        return;
-      }
-      var newValue = customizer
-        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
-        : undefined;
-
-      var isCommon = newValue === undefined;
-
-      if (isCommon) {
-        var isArr = isArray(srcValue),
-            isBuff = !isArr && isBuffer(srcValue),
-            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
-
-        newValue = srcValue;
-        if (isArr || isBuff || isTyped) {
-          if (isArray(objValue)) {
-            newValue = objValue;
-          }
-          else if (isArrayLikeObject(objValue)) {
-            newValue = copyArray(objValue);
-          }
-          else if (isBuff) {
-            isCommon = false;
-            newValue = cloneBuffer(srcValue, true);
-          }
-          else if (isTyped) {
-            isCommon = false;
-            newValue = cloneTypedArray(srcValue, true);
-          }
-          else {
-            newValue = [];
-          }
-        }
-        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
-          newValue = objValue;
-          if (isArguments(objValue)) {
-            newValue = toPlainObject(objValue);
-          }
-          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
-            newValue = initCloneObject(srcValue);
-          }
-        }
-        else {
-          isCommon = false;
-        }
-      }
-      if (isCommon) {
-        // Recursively merge objects and arrays (susceptible to call stack limits).
-        stack.set(srcValue, newValue);
-        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
-        stack['delete'](srcValue);
-      }
-      assignMergeValue(object, key, newValue);
-    }
-
-    /**
-     * The base implementation of `_.nth` which doesn't coerce arguments.
-     *
-     * @private
-     * @param {Array} array The array to query.
-     * @param {number} n The index of the element to return.
-     * @returns {*} Returns the nth element of `array`.
-     */
-    function baseNth(array, n) {
-      var length = array.length;
-      if (!length) {
-        return;
-      }
-      n += n < 0 ? length : 0;
-      return isIndex(n, length) ? array[n] : undefined;
-    }
-
-    /**
-     * The base implementation of `_.orderBy` without param guards.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
-     * @param {string[]} orders The sort orders of `iteratees`.
-     * @returns {Array} Returns the new sorted array.
-     */
-    function baseOrderBy(collection, iteratees, orders) {
-      var index = -1;
-      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
-
-      var result = baseMap(collection, function(value, key, collection) {
-        var criteria = arrayMap(iteratees, function(iteratee) {
-          return iteratee(value);
-        });
-        return { 'criteria': criteria, 'index': ++index, 'value': value };
-      });
-
-      return baseSortBy(result, function(object, other) {
-        return compareMultiple(object, other, orders);
-      });
-    }
-
-    /**
-     * The base implementation of `_.pick` without support for individual
-     * property identifiers.
-     *
-     * @private
-     * @param {Object} object The source object.
-     * @param {string[]} paths The property paths to pick.
-     * @returns {Object} Returns the new object.
-     */
-    function basePick(object, paths) {
-      return basePickBy(object, paths, function(value, path) {
-        return hasIn(object, path);
-      });
-    }
-
-    /**
-     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Object} object The source object.
-     * @param {string[]} paths The property paths to pick.
-     * @param {Function} predicate The function invoked per property.
-     * @returns {Object} Returns the new object.
-     */
-    function basePickBy(object, paths, predicate) {
-      var index = -1,
-          length = paths.length,
-          result = {};
-
-      while (++index < length) {
-        var path = paths[index],
-            value = baseGet(object, path);
-
-        if (predicate(value, path)) {
-          baseSet(result, castPath(path, object), value);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * A specialized version of `baseProperty` which supports deep paths.
-     *
-     * @private
-     * @param {Array|string} path The path of the property to get.
-     * @returns {Function} Returns the new accessor function.
-     */
-    function basePropertyDeep(path) {
-      return function(object) {
-        return baseGet(object, path);
-      };
-    }
-
-    /**
-     * The base implementation of `_.pullAllBy` without support for iteratee
-     * shorthands.
-     *
-     * @private
-     * @param {Array} array The array to modify.
-     * @param {Array} values The values to remove.
-     * @param {Function} [iteratee] The iteratee invoked per element.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns `array`.
-     */
-    function basePullAll(array, values, iteratee, comparator) {
-      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
-          index = -1,
-          length = values.length,
-          seen = array;
-
-      if (array === values) {
-        values = copyArray(values);
-      }
-      if (iteratee) {
-        seen = arrayMap(array, baseUnary(iteratee));
-      }
-      while (++index < length) {
-        var fromIndex = 0,
-            value = values[index],
-            computed = iteratee ? iteratee(value) : value;
-
-        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
-          if (seen !== array) {
-            splice.call(seen, fromIndex, 1);
-          }
-          splice.call(array, fromIndex, 1);
-        }
-      }
-      return array;
-    }
-
-    /**
-     * The base implementation of `_.pullAt` without support for individual
-     * indexes or capturing the removed elements.
-     *
-     * @private
-     * @param {Array} array The array to modify.
-     * @param {number[]} indexes The indexes of elements to remove.
-     * @returns {Array} Returns `array`.
-     */
-    function basePullAt(array, indexes) {
-      var length = array ? indexes.length : 0,
-          lastIndex = length - 1;
-
-      while (length--) {
-        var index = indexes[length];
-        if (length == lastIndex || index !== previous) {
-          var previous = index;
-          if (isIndex(index)) {
-            splice.call(array, index, 1);
-          } else {
-            baseUnset(array, index);
-          }
-        }
-      }
-      return array;
-    }
-
-    /**
-     * The base implementation of `_.random` without support for returning
-     * floating-point numbers.
-     *
-     * @private
-     * @param {number} lower The lower bound.
-     * @param {number} upper The upper bound.
-     * @returns {number} Returns the random number.
-     */
-    function baseRandom(lower, upper) {
-      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
-    }
-
-    /**
-     * The base implementation of `_.range` and `_.rangeRight` which doesn't
-     * coerce arguments.
-     *
-     * @private
-     * @param {number} start The start of the range.
-     * @param {number} end The end of the range.
-     * @param {number} step The value to increment or decrement by.
-     * @param {boolean} [fromRight] Specify iterating from right to left.
-     * @returns {Array} Returns the range of numbers.
-     */
-    function baseRange(start, end, step, fromRight) {
-      var index = -1,
-          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
-          result = Array(length);
-
-      while (length--) {
-        result[fromRight ? length : ++index] = start;
-        start += step;
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.repeat` which doesn't coerce arguments.
-     *
-     * @private
-     * @param {string} string The string to repeat.
-     * @param {number} n The number of times to repeat the string.
-     * @returns {string} Returns the repeated string.
-     */
-    function baseRepeat(string, n) {
-      var result = '';
-      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
-        return result;
-      }
-      // Leverage the exponentiation by squaring algorithm for a faster repeat.
-      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
-      do {
-        if (n % 2) {
-          result += string;
-        }
-        n = nativeFloor(n / 2);
-        if (n) {
-          string += string;
-        }
-      } while (n);
-
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
-     *
-     * @private
-     * @param {Function} func The function to apply a rest parameter to.
-     * @param {number} [start=func.length-1] The start position of the rest parameter.
-     * @returns {Function} Returns the new function.
-     */
-    function baseRest(func, start) {
-      return setToString(overRest(func, start, identity), func + '');
-    }
-
-    /**
-     * The base implementation of `_.sample`.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to sample.
-     * @returns {*} Returns the random element.
-     */
-    function baseSample(collection) {
-      return arraySample(values(collection));
-    }
-
-    /**
-     * The base implementation of `_.sampleSize` without param guards.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to sample.
-     * @param {number} n The number of elements to sample.
-     * @returns {Array} Returns the random elements.
-     */
-    function baseSampleSize(collection, n) {
-      var array = values(collection);
-      return shuffleSelf(array, baseClamp(n, 0, array.length));
-    }
-
-    /**
-     * The base implementation of `_.set`.
-     *
-     * @private
-     * @param {Object} object The object to modify.
-     * @param {Array|string} path The path of the property to set.
-     * @param {*} value The value to set.
-     * @param {Function} [customizer] The function to customize path creation.
-     * @returns {Object} Returns `object`.
-     */
-    function baseSet(object, path, value, customizer) {
-      if (!isObject(object)) {
-        return object;
-      }
-      path = castPath(path, object);
-
-      var index = -1,
-          length = path.length,
-          lastIndex = length - 1,
-          nested = object;
-
-      while (nested != null && ++index < length) {
-        var key = toKey(path[index]),
-            newValue = value;
-
-        if (index != lastIndex) {
-          var objValue = nested[key];
-          newValue = customizer ? customizer(objValue, key, nested) : undefined;
-          if (newValue === undefined) {
-            newValue = isObject(objValue)
-              ? objValue
-              : (isIndex(path[index + 1]) ? [] : {});
-          }
-        }
-        assignValue(nested, key, newValue);
-        nested = nested[key];
-      }
-      return object;
-    }
-
-    /**
-     * The base implementation of `setData` without support for hot loop shorting.
-     *
-     * @private
-     * @param {Function} func The function to associate metadata with.
-     * @param {*} data The metadata.
-     * @returns {Function} Returns `func`.
-     */
-    var baseSetData = !metaMap ? identity : function(func, data) {
-      metaMap.set(func, data);
-      return func;
-    };
-
-    /**
-     * The base implementation of `setToString` without support for hot loop shorting.
-     *
-     * @private
-     * @param {Function} func The function to modify.
-     * @param {Function} string The `toString` result.
-     * @returns {Function} Returns `func`.
-     */
-    var baseSetToString = !defineProperty ? identity : function(func, string) {
-      return defineProperty(func, 'toString', {
-        'configurable': true,
-        'enumerable': false,
-        'value': constant(string),
-        'writable': true
-      });
-    };
-
-    /**
-     * The base implementation of `_.shuffle`.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to shuffle.
-     * @returns {Array} Returns the new shuffled array.
-     */
-    function baseShuffle(collection) {
-      return shuffleSelf(values(collection));
-    }
-
-    /**
-     * The base implementation of `_.slice` without an iteratee call guard.
-     *
-     * @private
-     * @param {Array} array The array to slice.
-     * @param {number} [start=0] The start position.
-     * @param {number} [end=array.length] The end position.
-     * @returns {Array} Returns the slice of `array`.
-     */
-    function baseSlice(array, start, end) {
-      var index = -1,
-          length = array.length;
-
-      if (start < 0) {
-        start = -start > length ? 0 : (length + start);
-      }
-      end = end > length ? length : end;
-      if (end < 0) {
-        end += length;
-      }
-      length = start > end ? 0 : ((end - start) >>> 0);
-      start >>>= 0;
-
-      var result = Array(length);
-      while (++index < length) {
-        result[index] = array[index + start];
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.some` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} predicate The function invoked per iteration.
-     * @returns {boolean} Returns `true` if any element passes the predicate check,
-     *  else `false`.
-     */
-    function baseSome(collection, predicate) {
-      var result;
-
-      baseEach(collection, function(value, index, collection) {
-        result = predicate(value, index, collection);
-        return !result;
-      });
-      return !!result;
-    }
-
-    /**
-     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
-     * performs a binary search of `array` to determine the index at which `value`
-     * should be inserted into `array` in order to maintain its sort order.
-     *
-     * @private
-     * @param {Array} array The sorted array to inspect.
-     * @param {*} value The value to evaluate.
-     * @param {boolean} [retHighest] Specify returning the highest qualified index.
-     * @returns {number} Returns the index at which `value` should be inserted
-     *  into `array`.
-     */
-    function baseSortedIndex(array, value, retHighest) {
-      var low = 0,
-          high = array == null ? low : array.length;
-
-      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
-        while (low < high) {
-          var mid = (low + high) >>> 1,
-              computed = array[mid];
-
-          if (computed !== null && !isSymbol(computed) &&
-              (retHighest ? (computed <= value) : (computed < value))) {
-            low = mid + 1;
-          } else {
-            high = mid;
-          }
-        }
-        return high;
-      }
-      return baseSortedIndexBy(array, value, identity, retHighest);
-    }
-
-    /**
-     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
-     * which invokes `iteratee` for `value` and each element of `array` to compute
-     * their sort ranking. The iteratee is invoked with one argument; (value).
-     *
-     * @private
-     * @param {Array} array The sorted array to inspect.
-     * @param {*} value The value to evaluate.
-     * @param {Function} iteratee The iteratee invoked per element.
-     * @param {boolean} [retHighest] Specify returning the highest qualified index.
-     * @returns {number} Returns the index at which `value` should be inserted
-     *  into `array`.
-     */
-    function baseSortedIndexBy(array, value, iteratee, retHighest) {
-      value = iteratee(value);
-
-      var low = 0,
-          high = array == null ? 0 : array.length,
-          valIsNaN = value !== value,
-          valIsNull = value === null,
-          valIsSymbol = isSymbol(value),
-          valIsUndefined = value === undefined;
-
-      while (low < high) {
-        var mid = nativeFloor((low + high) / 2),
-            computed = iteratee(array[mid]),
-            othIsDefined = computed !== undefined,
-            othIsNull = computed === null,
-            othIsReflexive = computed === computed,
-            othIsSymbol = isSymbol(computed);
-
-        if (valIsNaN) {
-          var setLow = retHighest || othIsReflexive;
-        } else if (valIsUndefined) {
-          setLow = othIsReflexive && (retHighest || othIsDefined);
-        } else if (valIsNull) {
-          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
-        } else if (valIsSymbol) {
-          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
-        } else if (othIsNull || othIsSymbol) {
-          setLow = false;
-        } else {
-          setLow = retHighest ? (computed <= value) : (computed < value);
-        }
-        if (setLow) {
-          low = mid + 1;
-        } else {
-          high = mid;
-        }
-      }
-      return nativeMin(high, MAX_ARRAY_INDEX);
-    }
-
-    /**
-     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
-     * support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array} array The array to inspect.
-     * @param {Function} [iteratee] The iteratee invoked per element.
-     * @returns {Array} Returns the new duplicate free array.
-     */
-    function baseSortedUniq(array, iteratee) {
-      var index = -1,
-          length = array.length,
-          resIndex = 0,
-          result = [];
-
-      while (++index < length) {
-        var value = array[index],
-            computed = iteratee ? iteratee(value) : value;
-
-        if (!index || !eq(computed, seen)) {
-          var seen = computed;
-          result[resIndex++] = value === 0 ? 0 : value;
-        }
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.toNumber` which doesn't ensure correct
-     * conversions of binary, hexadecimal, or octal string values.
-     *
-     * @private
-     * @param {*} value The value to process.
-     * @returns {number} Returns the number.
-     */
-    function baseToNumber(value) {
-      if (typeof value == 'number') {
-        return value;
-      }
-      if (isSymbol(value)) {
-        return NAN;
-      }
-      return +value;
-    }
-
-    /**
-     * The base implementation of `_.toString` which doesn't convert nullish
-     * values to empty strings.
-     *
-     * @private
-     * @param {*} value The value to process.
-     * @returns {string} Returns the string.
-     */
-    function baseToString(value) {
-      // Exit early for strings to avoid a performance hit in some environments.
-      if (typeof value == 'string') {
-        return value;
-      }
-      if (isArray(value)) {
-        // Recursively convert values (susceptible to call stack limits).
-        return arrayMap(value, baseToString) + '';
-      }
-      if (isSymbol(value)) {
-        return symbolToString ? symbolToString.call(value) : '';
-      }
-      var result = (value + '');
-      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-    }
-
-    /**
-     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array} array The array to inspect.
-     * @param {Function} [iteratee] The iteratee invoked per element.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new duplicate free array.
-     */
-    function baseUniq(array, iteratee, comparator) {
-      var index = -1,
-          includes = arrayIncludes,
-          length = array.length,
-          isCommon = true,
-          result = [],
-          seen = result;
-
-      if (comparator) {
-        isCommon = false;
-        includes = arrayIncludesWith;
-      }
-      else if (length >= LARGE_ARRAY_SIZE) {
-        var set = iteratee ? null : createSet(array);
-        if (set) {
-          return setToArray(set);
-        }
-        isCommon = false;
-        includes = cacheHas;
-        seen = new SetCache;
-      }
-      else {
-        seen = iteratee ? [] : result;
-      }
-      outer:
-      while (++index < length) {
-        var value = array[index],
-            computed = iteratee ? iteratee(value) : value;
-
-        value = (comparator || value !== 0) ? value : 0;
-        if (isCommon && computed === computed) {
-          var seenIndex = seen.length;
-          while (seenIndex--) {
-            if (seen[seenIndex] === computed) {
-              continue outer;
-            }
-          }
-          if (iteratee) {
-            seen.push(computed);
-          }
-          result.push(value);
-        }
-        else if (!includes(seen, computed, comparator)) {
-          if (seen !== result) {
-            seen.push(computed);
-          }
-          result.push(value);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * The base implementation of `_.unset`.
-     *
-     * @private
-     * @param {Object} object The object to modify.
-     * @param {Array|string} path The property path to unset.
-     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
-     */
-    function baseUnset(object, path) {
-      path = castPath(path, object);
-      object = parent(object, path);
-      return object == null || delete object[toKey(last(path))];
-    }
-
-    /**
-     * The base implementation of `_.update`.
-     *
-     * @private
-     * @param {Object} object The object to modify.
-     * @param {Array|string} path The path of the property to update.
-     * @param {Function} updater The function to produce the updated value.
-     * @param {Function} [customizer] The function to customize path creation.
-     * @returns {Object} Returns `object`.
-     */
-    function baseUpdate(object, path, updater, customizer) {
-      return baseSet(object, path, updater(baseGet(object, path)), customizer);
-    }
-
-    /**
-     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
-     * without support for iteratee shorthands.
-     *
-     * @private
-     * @param {Array} array The array to query.
-     * @param {Function} predicate The function invoked per iteration.
-     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
-     * @param {boolean} [fromRight] Specify iterating from right to left.
-     * @returns {Array} Returns the slice of `array`.
-     */
-    function baseWhile(array, predicate, isDrop, fromRight) {
-      var length = array.length,
-          index = fromRight ? length : -1;
-
-      while ((fromRight ? index-- : ++index < length) &&
-        predicate(array[index], index, array)) {}
-
-      return isDrop
-        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
-        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
-    }
-
-    /**
-     * The base implementation of `wrapperValue` which returns the result of
-     * performing a sequence of actions on the unwrapped `value`, where each
-     * successive action is supplied the return value of the previous.
-     *
-     * @private
-     * @param {*} value The unwrapped value.
-     * @param {Array} actions Actions to perform to resolve the unwrapped value.
-     * @returns {*} Returns the resolved value.
-     */
-    function baseWrapperValue(value, actions) {
-      var result = value;
-      if (result instanceof LazyWrapper) {
-        result = result.value();
-      }
-      return arrayReduce(actions, function(result, action) {
-        return action.func.apply(action.thisArg, arrayPush([result], action.args));
-      }, result);
-    }
-
-    /**
-     * The base implementation of methods like `_.xor`, without support for
-     * iteratee shorthands, that accepts an array of arrays to inspect.
-     *
-     * @private
-     * @param {Array} arrays The arrays to inspect.
-     * @param {Function} [iteratee] The iteratee invoked per element.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new array of values.
-     */
-    function baseXor(arrays, iteratee, comparator) {
-      var length = arrays.length;
-      if (length < 2) {
-        return length ? baseUniq(arrays[0]) : [];
-      }
-      var index = -1,
-          result = Array(length);
-
-      while (++index < length) {
-        var array = arrays[index],
-            othIndex = -1;
-
-        while (++othIndex < length) {
-          if (othIndex != index) {
-            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
-          }
-        }
-      }
-      return baseUniq(baseFlatten(result, 1), iteratee, comparator);
-    }
-
-    /**
-     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
-     *
-     * @private
-     * @param {Array} props The property identifiers.
-     * @param {Array} values The property values.
-     * @param {Function} assignFunc The function to assign values.
-     * @returns {Object} Returns the new object.
-     */
-    function baseZipObject(props, values, assignFunc) {
-      var index = -1,
-          length = props.length,
-          valsLength = values.length,
-          result = {};
-
-      while (++index < length) {
-        var value = index < valsLength ? values[index] : undefined;
-        assignFunc(result, props[index], value);
-      }
-      return result;
-    }
-
-    /**
-     * Casts `value` to an empty array if it's not an array like object.
-     *
-     * @private
-     * @param {*} value The value to inspect.
-     * @returns {Array|Object} Returns the cast array-like object.
-     */
-    function castArrayLikeObject(value) {
-      return isArrayLikeObject(value) ? value : [];
-    }
-
-    /**
-     * Casts `value` to `identity` if it's not a function.
-     *
-     * @private
-     * @param {*} value The value to inspect.
-     * @returns {Function} Returns cast function.
-     */
-    function castFunction(value) {
-      return typeof value == 'function' ? value : identity;
-    }
-
-    /**
-     * Casts `value` to a path array if it's not one.
-     *
-     * @private
-     * @param {*} value The value to inspect.
-     * @param {Object} [object] The object to query keys on.
-     * @returns {Array} Returns the cast property path array.
-     */
-    function castPath(value, object) {
-      if (isArray(value)) {
-        return value;
-      }
-      return isKey(value, object) ? [value] : stringToPath(toString(value));
-    }
-
-    /**
-     * A `baseRest` alias which can be replaced with `identity` by module
-     * replacement plugins.
-     *
-     * @private
-     * @type {Function}
-     * @param {Function} func The function to apply a rest parameter to.
-     * @returns {Function} Returns the new function.
-     */
-    var castRest = baseRest;
-
-    /**
-     * Casts `array` to a slice if it's needed.
-     *
-     * @private
-     * @param {Array} array The array to inspect.
-     * @param {number} start The start position.
-     * @param {number} [end=array.length] The end position.
-     * @returns {Array} Returns the cast slice.
-     */
-    function castSlice(array, start, end) {
-      var length = array.length;
-      end = end === undefined ? length : end;
-      return (!start && end >= length) ? array : baseSlice(array, start, end);
-    }
-
-    /**
-     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
-     *
-     * @private
-     * @param {number|Object} id The timer id or timeout object of the timer to clear.
-     */
-    var clearTimeout = ctxClearTimeout || function(id) {
-      return root.clearTimeout(id);
-    };
-
-    /**
-     * Creates a clone of  `buffer`.
-     *
-     * @private
-     * @param {Buffer} buffer The buffer to clone.
-     * @param {boolean} [isDeep] Specify a deep clone.
-     * @returns {Buffer} Returns the cloned buffer.
-     */
-    function cloneBuffer(buffer, isDeep) {
-      if (isDeep) {
-        return buffer.slice();
-      }
-      var length = buffer.length,
-          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
-
-      buffer.copy(result);
-      return result;
-    }
-
-    /**
-     * Creates a clone of `arrayBuffer`.
-     *
-     * @private
-     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
-     * @returns {ArrayBuffer} Returns the cloned array buffer.
-     */
-    function cloneArrayBuffer(arrayBuffer) {
-      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
-      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
-      return result;
-    }
-
-    /**
-     * Creates a clone of `dataView`.
-     *
-     * @private
-     * @param {Object} dataView The data view to clone.
-     * @param {boolean} [isDeep] Specify a deep clone.
-     * @returns {Object} Returns the cloned data view.
-     */
-    function cloneDataView(dataView, isDeep) {
-      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
-      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
-    }
-
-    /**
-     * Creates a clone of `map`.
-     *
-     * @private
-     * @param {Object} map The map to clone.
-     * @param {Function} cloneFunc The function to clone values.
-     * @param {boolean} [isDeep] Specify a deep clone.
-     * @returns {Object} Returns the cloned map.
-     */
-    function cloneMap(map, isDeep, cloneFunc) {
-      var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
-      return arrayReduce(array, addMapEntry, new map.constructor);
-    }
-
-    /**
-     * Creates a clone of `regexp`.
-     *
-     * @private
-     * @param {Object} regexp The regexp to clone.
-     * @returns {Object} Returns the cloned regexp.
-     */
-    function cloneRegExp(regexp) {
-      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
-      result.lastIndex = regexp.lastIndex;
-      return result;
-    }
-
-    /**
-     * Creates a clone of `set`.
-     *
-     * @private
-     * @param {Object} set The set to clone.
-     * @param {Function} cloneFunc The function to clone values.
-     * @param {boolean} [isDeep] Specify a deep clone.
-     * @returns {Object} Returns the cloned set.
-     */
-    function cloneSet(set, isDeep, cloneFunc) {
-      var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
-      return arrayReduce(array, addSetEntry, new set.constructor);
-    }
-
-    /**
-     * Creates a clone of the `symbol` object.
-     *
-     * @private
-     * @param {Object} symbol The symbol object to clone.
-     * @returns {Object} Returns the cloned symbol object.
-     */
-    function cloneSymbol(symbol) {
-      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
-    }
-
-    /**
-     * Creates a clone of `typedArray`.
-     *
-     * @private
-     * @param {Object} typedArray The typed array to clone.
-     * @param {boolean} [isDeep] Specify a deep clone.
-     * @returns {Object} Returns the cloned typed array.
-     */
-    function cloneTypedArray(typedArray, isDeep) {
-      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
-      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
-    }
-
-    /**
-     * Compares values to sort them in ascending order.
-     *
-     * @private
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {number} Returns the sort order indicator for `value`.
-     */
-    function compareAscending(value, other) {
-      if (value !== other) {
-        var valIsDefined = value !== undefined,
-            valIsNull = value === null,
-            valIsReflexive = value === value,
-            valIsSymbol = isSymbol(value);
-
-        var othIsDefined = other !== undefined,
-            othIsNull = other === null,
-            othIsReflexive = other === other,
-            othIsSymbol = isSymbol(other);
-
-        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
-            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
-            (valIsNull && othIsDefined && othIsReflexive) ||
-            (!valIsDefined && othIsReflexive) ||
-            !valIsReflexive) {
-          return 1;
-        }
-        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
-            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
-            (othIsNull && valIsDefined && valIsReflexive) ||
-            (!othIsDefined && valIsReflexive) ||
-            !othIsReflexive) {
-          return -1;
-        }
-      }
-      return 0;
-    }
-
-    /**
-     * Used by `_.orderBy` to compare multiple properties of a value to another
-     * and stable sort them.
-     *
-     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
-     * specify an order of "desc" for descending or "asc" for ascending sort order
-     * of corresponding values.
-     *
-     * @private
-     * @param {Object} object The object to compare.
-     * @param {Object} other The other object to compare.
-     * @param {boolean[]|string[]} orders The order to sort by for each property.
-     * @returns {number} Returns the sort order indicator for `object`.
-     */
-    function compareMultiple(object, other, orders) {
-      var index = -1,
-          objCriteria = object.criteria,
-          othCriteria = other.criteria,
-          length = objCriteria.length,
-          ordersLength = orders.length;
-
-      while (++index < length) {
-        var result = compareAscending(objCriteria[index], othCriteria[index]);
-        if (result) {
-          if (index >= ordersLength) {
-            return result;
-          }
-          var order = orders[index];
-          return result * (order == 'desc' ? -1 : 1);
-        }
-      }
-      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
-      // that causes it, under certain circumstances, to provide the same value for
-      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
-      // for more details.
-      //
-      // This also ensures a stable sort in V8 and other engines.
-      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
-      return object.index - other.index;
-    }
-
-    /**
-     * Creates an array that is the composition of partially applied arguments,
-     * placeholders, and provided arguments into a single array of arguments.
-     *
-     * @private
-     * @param {Array} args The provided arguments.
-     * @param {Array} partials The arguments to prepend to those provided.
-     * @param {Array} holders The `partials` placeholder indexes.
-     * @params {boolean} [isCurried] Specify composing for a curried function.
-     * @returns {Array} Returns the new array of composed arguments.
-     */
-    function composeArgs(args, partials, holders, isCurried) {
-      var argsIndex = -1,
-          argsLength = args.length,
-          holdersLength = holders.length,
-          leftIndex = -1,
-          leftLength = partials.length,
-          rangeLength = nativeMax(argsLength - holdersLength, 0),
-          result = Array(leftLength + rangeLength),
-          isUncurried = !isCurried;
-
-      while (++leftIndex < leftLength) {
-        result[leftIndex] = partials[leftIndex];
-      }
-      while (++argsIndex < holdersLength) {
-        if (isUncurried || argsIndex < argsLength) {
-          result[holders[argsIndex]] = args[argsIndex];
-        }
-      }
-      while (rangeLength--) {
-        result[leftIndex++] = args[argsIndex++];
-      }
-      return result;
-    }
-
-    /**
-     * This function is like `composeArgs` except that the arguments composition
-     * is tailored for `_.partialRight`.
-     *
-     * @private
-     * @param {Array} args The provided arguments.
-     * @param {Array} partials The arguments to append to those provided.
-     * @param {Array} holders The `partials` placeholder indexes.
-     * @params {boolean} [isCurried] Specify composing for a curried function.
-     * @returns {Array} Returns the new array of composed arguments.
-     */
-    function composeArgsRight(args, partials, holders, isCurried) {
-      var argsIndex = -1,
-          argsLength = args.length,
-          holdersIndex = -1,
-          holdersLength = holders.length,
-          rightIndex = -1,
-          rightLength = partials.length,
-          rangeLength = nativeMax(argsLength - holdersLength, 0),
-          result = Array(rangeLength + rightLength),
-          isUncurried = !isCurried;
-
-      while (++argsIndex < rangeLength) {
-        result[argsIndex] = args[argsIndex];
-      }
-      var offset = argsIndex;
-      while (++rightIndex < rightLength) {
-        result[offset + rightIndex] = partials[rightIndex];
-      }
-      while (++holdersIndex < holdersLength) {
-        if (isUncurried || argsIndex < argsLength) {
-          result[offset + holders[holdersIndex]] = args[argsIndex++];
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Copies the values of `source` to `array`.
-     *
-     * @private
-     * @param {Array} source The array to copy values from.
-     * @param {Array} [array=[]] The array to copy values to.
-     * @returns {Array} Returns `array`.
-     */
-    function copyArray(source, array) {
-      var index = -1,
-          length = source.length;
-
-      array || (array = Array(length));
-      while (++index < length) {
-        array[index] = source[index];
-      }
-      return array;
-    }
-
-    /**
-     * Copies properties of `source` to `object`.
-     *
-     * @private
-     * @param {Object} source The object to copy properties from.
-     * @param {Array} props The property identifiers to copy.
-     * @param {Object} [object={}] The object to copy properties to.
-     * @param {Function} [customizer] The function to customize copied values.
-     * @returns {Object} Returns `object`.
-     */
-    function copyObject(source, props, object, customizer) {
-      var isNew = !object;
-      object || (object = {});
-
-      var index = -1,
-          length = props.length;
-
-      while (++index < length) {
-        var key = props[index];
-
-        var newValue = customizer
-          ? customizer(object[key], source[key], key, object, source)
-          : undefined;
-
-        if (newValue === undefined) {
-          newValue = source[key];
-        }
-        if (isNew) {
-          baseAssignValue(object, key, newValue);
-        } else {
-          assignValue(object, key, newValue);
-        }
-      }
-      return object;
-    }
-
-    /**
-     * Copies own symbols of `source` to `object`.
-     *
-     * @private
-     * @param {Object} source The object to copy symbols from.
-     * @param {Object} [object={}] The object to copy symbols to.
-     * @returns {Object} Returns `object`.
-     */
-    function copySymbols(source, object) {
-      return copyObject(source, getSymbols(source), object);
-    }
-
-    /**
-     * Copies own and inherited symbols of `source` to `object`.
-     *
-     * @private
-     * @param {Object} source The object to copy symbols from.
-     * @param {Object} [object={}] The object to copy symbols to.
-     * @returns {Object} Returns `object`.
-     */
-    function copySymbolsIn(source, object) {
-      return copyObject(source, getSymbolsIn(source), object);
-    }
-
-    /**
-     * Creates a function like `_.groupBy`.
-     *
-     * @private
-     * @param {Function} setter The function to set accumulator values.
-     * @param {Function} [initializer] The accumulator object initializer.
-     * @returns {Function} Returns the new aggregator function.
-     */
-    function createAggregator(setter, initializer) {
-      return function(collection, iteratee) {
-        var func = isArray(collection) ? arrayAggregator : baseAggregator,
-            accumulator = initializer ? initializer() : {};
-
-        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
-      };
-    }
-
-    /**
-     * Creates a function like `_.assign`.
-     *
-     * @private
-     * @param {Function} assigner The function to assign values.
-     * @returns {Function} Returns the new assigner function.
-     */
-    function createAssigner(assigner) {
-      return baseRest(function(object, sources) {
-        var index = -1,
-            length = sources.length,
-            customizer = length > 1 ? sources[length - 1] : undefined,
-            guard = length > 2 ? sources[2] : undefined;
-
-        customizer = (assigner.length > 3 && typeof customizer == 'function')
-          ? (length--, customizer)
-          : undefined;
-
-        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
-          customizer = length < 3 ? undefined : customizer;
-          length = 1;
-        }
-        object = Object(object);
-        while (++index < length) {
-          var source = sources[index];
-          if (source) {
-            assigner(object, source, index, customizer);
-          }
-        }
-        return object;
-      });
-    }
-
-    /**
-     * Creates a `baseEach` or `baseEachRight` function.
-     *
-     * @private
-     * @param {Function} eachFunc The function to iterate over a collection.
-     * @param {boolean} [fromRight] Specify iterating from right to left.
-     * @returns {Function} Returns the new base function.
-     */
-    function createBaseEach(eachFunc, fromRight) {
-      return function(collection, iteratee) {
-        if (collection == null) {
-          return collection;
-        }
-        if (!isArrayLike(collection)) {
-          return eachFunc(collection, iteratee);
-        }
-        var length = collection.length,
-            index = fromRight ? length : -1,
-            iterable = Object(collection);
-
-        while ((fromRight ? index-- : ++index < length)) {
-          if (iteratee(iterable[index], index, iterable) === false) {
-            break;
-          }
-        }
-        return collection;
-      };
-    }
-
-    /**
-     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
-     *
-     * @private
-     * @param {boolean} [fromRight] Specify iterating from right to left.
-     * @returns {Function} Returns the new base function.
-     */
-    function createBaseFor(fromRight) {
-      return function(object, iteratee, keysFunc) {
-        var index = -1,
-            iterable = Object(object),
-            props = keysFunc(object),
-            length = props.length;
-
-        while (length--) {
-          var key = props[fromRight ? length : ++index];
-          if (iteratee(iterable[key], key, iterable) === false) {
-            break;
-          }
-        }
-        return object;
-      };
-    }
-
-    /**
-     * Creates a function that wraps `func` to invoke it with the optional `this`
-     * binding of `thisArg`.
-     *
-     * @private
-     * @param {Function} func The function to wrap.
-     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
-     * @param {*} [thisArg] The `this` binding of `func`.
-     * @returns {Function} Returns the new wrapped function.
-     */
-    function createBind(func, bitmask, thisArg) {
-      var isBind = bitmask & WRAP_BIND_FLAG,
-          Ctor = createCtor(func);
-
-      function wrapper() {
-        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
-        return fn.apply(isBind ? thisArg : this, arguments);
-      }
-      return wrapper;
-    }
-
-    /**
-     * Creates a function like `_.lowerFirst`.
-     *
-     * @private
-     * @param {string} methodName The name of the `String` case method to use.
-     * @returns {Function} Returns the new case function.
-     */
-    function createCaseFirst(methodName) {
-      return function(string) {
-        string = toString(string);
-
-        var strSymbols = hasUnicode(string)
-          ? stringToArray(string)
-          : undefined;
-
-        var chr = strSymbols
-          ? strSymbols[0]
-          : string.charAt(0);
-
-        var trailing = strSymbols
-          ? castSlice(strSymbols, 1).join('')
-          : string.slice(1);
-
-        return chr[methodName]() + trailing;
-      };
-    }
-
-    /**
-     * Creates a function like `_.camelCase`.
-     *
-     * @private
-     * @param {Function} callback The function to combine each word.
-     * @returns {Function} Returns the new compounder function.
-     */
-    function createCompounder(callback) {
-      return function(string) {
-        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
-      };
-    }
-
-    /**
-     * Creates a function that produces an instance of `Ctor` regardless of
-     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
-     *
-     * @private
-     * @param {Function} Ctor The constructor to wrap.
-     * @returns {Function} Returns the new wrapped function.
-     */
-    function createCtor(Ctor) {
-      return function() {
-        // Use a `switch` statement to work with class constructors. See
-        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
-        // for more details.
-        var args = arguments;
-        switch (args.length) {
-          case 0: return new Ctor;
-          case 1: return new Ctor(args[0]);
-          case 2: return new Ctor(args[0], args[1]);
-          case 3: return new Ctor(args[0], args[1], args[2]);
-          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
-          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
-          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
-          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
-        }
-        var thisBinding = baseCreate(Ctor.prototype),
-            result = Ctor.apply(thisBinding, args);
-
-        // Mimic the constructor's `return` behavior.
-        // See https://es5.github.io/#x13.2.2 for more details.
-        return isObject(result) ? result : thisBinding;
-      };
-    }
-
-    /**
-     * Creates a function that wraps `func` to enable currying.
-     *
-     * @private
-     * @param {Function} func The function to wrap.
-     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
-     * @param {number} arity The arity of `func`.
-     * @returns {Function} Returns the new wrapped function.
-     */
-    function createCurry(func, bitmask, arity) {
-      var Ctor = createCtor(func);
-
-      function wrapper() {
-        var length = arguments.length,
-            args = Array(length),
-            index = length,
-            placeholder = getHolder(wrapper);
-
-        while (index--) {
-          args[index] = arguments[index];
-        }
-        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
-          ? []
-          : replaceHolders(args, placeholder);
-
-        length -= holders.length;
-        if (length < arity) {
-          return createRecurry(
-            func, bitmask, createHybrid, wrapper.placeholder, undefined,
-            args, holders, undefined, undefined, arity - length);
-        }
-        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
-        return apply(fn, this, args);
-      }
-      return wrapper;
-    }
-
-    /**
-     * Creates a `_.find` or `_.findLast` function.
-     *
-     * @private
-     * @param {Function} findIndexFunc The function to find the collection index.
-     * @returns {Function} Returns the new find function.
-     */
-    function createFind(findIndexFunc) {
-      return function(collection, predicate, fromIndex) {
-        var iterable = Object(collection);
-        if (!isArrayLike(collection)) {
-          var iteratee = getIteratee(predicate, 3);
-          collection = keys(collection);
-          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
-        }
-        var index = findIndexFunc(collection, predicate, fromIndex);
-        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
-      };
-    }
-
-    /**
-     * Creates a `_.flow` or `_.flowRight` function.
-     *
-     * @private
-     * @param {boolean} [fromRight] Specify iterating from right to left.
-     * @returns {Function} Returns the new flow function.
-     */
-    function createFlow(fromRight) {
-      return flatRest(function(funcs) {
-        var length = funcs.length,
-            index = length,
-            prereq = LodashWrapper.prototype.thru;
-
-        if (fromRight) {
-          funcs.reverse();
-        }
-        while (index--) {
-          var func = funcs[index];
-          if (typeof func != 'function') {
-            throw new TypeError(FUNC_ERROR_TEXT);
-          }
-          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
-            var wrapper = new LodashWrapper([], true);
-          }
-        }
-        index = wrapper ? index : length;
-        while (++index < length) {
-          func = funcs[index];
-
-          var funcName = getFuncName(func),
-              data = funcName == 'wrapper' ? getData(func) : undefined;
-
-          if (data && isLaziable(data[0]) &&
-                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
-                !data[4].length && data[9] == 1
-              ) {
-            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
-          } else {
-            wrapper = (func.length == 1 && isLaziable(func))
-              ? wrapper[funcName]()
-              : wrapper.thru(func);
-          }
-        }
-        return function() {
-          var args = arguments,
-              value = args[0];
-
-          if (wrapper && args.length == 1 && isArray(value)) {
-            return wrapper.plant(value).value();
-          }
-          var index = 0,
-              result = length ? funcs[index].apply(this, args) : value;
-
-          while (++index < length) {
-            result = funcs[index].call(this, result);
-          }
-          return result;
-        };
-      });
-    }
-
-    /**
-     * Creates a function that wraps `func` to invoke it with optional `this`
-     * binding of `thisArg`, partial application, and currying.
-     *
-     * @private
-     * @param {Function|string} func The function or method name to wrap.
-     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
-     * @param {*} [thisArg] The `this` binding of `func`.
-     * @param {Array} [partials] The arguments to prepend to those provided to
-     *  the new function.
-     * @param {Array} [holders] The `partials` placeholder indexes.
-     * @param {Array} [partialsRight] The arguments to append to those provided
-     *  to the new function.
-     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
-     * @param {Array} [argPos] The argument positions of the new function.
-     * @param {number} [ary] The arity cap of `func`.
-     * @param {number} [arity] The arity of `func`.
-     * @returns {Function} Returns the new wrapped function.
-     */
-    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
-      var isAry = bitmask & WRAP_ARY_FLAG,
-          isBind = bitmask & WRAP_BIND_FLAG,
-          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
-          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
-          isFlip = bitmask & WRAP_FLIP_FLAG,
-          Ctor = isBindKey ? undefined : createCtor(func);
-
-      function wrapper() {
-        var length = arguments.length,
-            args = Array(length),
-            index = length;
-
-        while (index--) {
-          args[index] = arguments[index];
-        }
-        if (isCurried) {
-          var placeholder = getHolder(wrapper),
-              holdersCount = countHolders(args, placeholder);
-        }
-        if (partials) {
-          args = composeArgs(args, partials, holders, isCurried);
-        }
-        if (partialsRight) {
-          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
-        }
-        length -= holdersCount;
-        if (isCurried && length < arity) {
-          var newHolders = replaceHolders(args, placeholder);
-          return createRecurry(
-            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
-            args, newHolders, argPos, ary, arity - length
-          );
-        }
-        var thisBinding = isBind ? thisArg : this,
-            fn = isBindKey ? thisBinding[func] : func;
-
-        length = args.length;
-        if (argPos) {
-          args = reorder(args, argPos);
-        } else if (isFlip && length > 1) {
-          args.reverse();
-        }
-        if (isAry && ary < length) {
-          args.length = ary;
-        }
-        if (this && this !== root && this instanceof wrapper) {
-          fn = Ctor || createCtor(fn);
-        }
-        return fn.apply(thisBinding, args);
-      }
-      return wrapper;
-    }
-
-    /**
-     * Creates a function like `_.invertBy`.
-     *
-     * @private
-     * @param {Function} setter The function to set accumulator values.
-     * @param {Function} toIteratee The function to resolve iteratees.
-     * @returns {Function} Returns the new inverter function.
-     */
-    function createInverter(setter, toIteratee) {
-      return function(object, iteratee) {
-        return baseInverter(object, setter, toIteratee(iteratee), {});
-      };
-    }
-
-    /**
-     * Creates a function that performs a mathematical operation on two values.
-     *
-     * @private
-     * @param {Function} operator The function to perform the operation.
-     * @param {number} [defaultValue] The value used for `undefined` arguments.
-     * @returns {Function} Returns the new mathematical operation function.
-     */
-    function createMathOperation(operator, defaultValue) {
-      return function(value, other) {
-        var result;
-        if (value === undefined && other === undefined) {
-          return defaultValue;
-        }
-        if (value !== undefined) {
-          result = value;
-        }
-        if (other !== undefined) {
-          if (result === undefined) {
-            return other;
-          }
-          if (typeof value == 'string' || typeof other == 'string') {
-            value = baseToString(value);
-            other = baseToString(other);
-          } else {
-            value = baseToNumber(value);
-            other = baseToNumber(other);
-          }
-          result = operator(value, other);
-        }
-        return result;
-      };
-    }
-
-    /**
-     * Creates a function like `_.over`.
-     *
-     * @private
-     * @param {Function} arrayFunc The function to iterate over iteratees.
-     * @returns {Function} Returns the new over function.
-     */
-    function createOver(arrayFunc) {
-      return flatRest(function(iteratees) {
-        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
-        return baseRest(function(args) {
-          var thisArg = this;
-          return arrayFunc(iteratees, function(iteratee) {
-            return apply(iteratee, thisArg, args);
-          });
-        });
-      });
-    }
-
-    /**
-     * Creates the padding for `string` based on `length`. The `chars` string
-     * is truncated if the number of characters exceeds `length`.
-     *
-     * @private
-     * @param {number} length The padding length.
-     * @param {string} [chars=' '] The string used as padding.
-     * @returns {string} Returns the padding for `string`.
-     */
-    function createPadding(length, chars) {
-      chars = chars === undefined ? ' ' : baseToString(chars);
-
-      var charsLength = chars.length;
-      if (charsLength < 2) {
-        return charsLength ? baseRepeat(chars, length) : chars;
-      }
-      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
-      return hasUnicode(chars)
-        ? castSlice(stringToArray(result), 0, length).join('')
-        : result.slice(0, length);
-    }
-
-    /**
-     * Creates a function that wraps `func` to invoke it with the `this` binding
-     * of `thisArg` and `partials` prepended to the arguments it receives.
-     *
-     * @private
-     * @param {Function} func The function to wrap.
-     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
-     * @param {*} thisArg The `this` binding of `func`.
-     * @param {Array} partials The arguments to prepend to those provided to
-     *  the new function.
-     * @returns {Function} Returns the new wrapped function.
-     */
-    function createPartial(func, bitmask, thisArg, partials) {
-      var isBind = bitmask & WRAP_BIND_FLAG,
-          Ctor = createCtor(func);
-
-      function wrapper() {
-        var argsIndex = -1,
-            argsLength = arguments.length,
-            leftIndex = -1,
-            leftLength = partials.length,
-            args = Array(leftLength + argsLength),
-            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
-
-        while (++leftIndex < leftLength) {
-          args[leftIndex] = partials[leftIndex];
-        }
-        while (argsLength--) {
-          args[leftIndex++] = arguments[++argsIndex];
-        }
-        return apply(fn, isBind ? thisArg : this, args);
-      }
-      return wrapper;
-    }
-
-    /**
-     * Creates a `_.range` or `_.rangeRight` function.
-     *
-     * @private
-     * @param {boolean} [fromRight] Specify iterating from right to left.
-     * @returns {Function} Returns the new range function.
-     */
-    function createRange(fromRight) {
-      return function(start, end, step) {
-        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
-          end = step = undefined;
-        }
-        // Ensure the sign of `-0` is preserved.
-        start = toFinite(start);
-        if (end === undefined) {
-          end = start;
-          start = 0;
-        } else {
-          end = toFinite(end);
-        }
-        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
-        return baseRange(start, end, step, fromRight);
-      };
-    }
-
-    /**
-     * Creates a function that performs a relational operation on two values.
-     *
-     * @private
-     * @param {Function} operator The function to perform the operation.
-     * @returns {Function} Returns the new relational operation function.
-     */
-    function createRelationalOperation(operator) {
-      return function(value, other) {
-        if (!(typeof value == 'string' && typeof other == 'string')) {
-          value = toNumber(value);
-          other = toNumber(other);
-        }
-        return operator(value, other);
-      };
-    }
-
-    /**
-     * Creates a function that wraps `func` to continue currying.
-     *
-     * @private
-     * @param {Function} func The function to wrap.
-     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
-     * @param {Function} wrapFunc The function to create the `func` wrapper.
-     * @param {*} placeholder The placeholder value.
-     * @param {*} [thisArg] The `this` binding of `func`.
-     * @param {Array} [partials] The arguments to prepend to those provided to
-     *  the new function.
-     * @param {Array} [holders] The `partials` placeholder indexes.
-     * @param {Array} [argPos] The argument positions of the new function.
-     * @param {number} [ary] The arity cap of `func`.
-     * @param {number} [arity] The arity of `func`.
-     * @returns {Function} Returns the new wrapped function.
-     */
-    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
-      var isCurry = bitmask & WRAP_CURRY_FLAG,
-          newHolders = isCurry ? holders : undefined,
-          newHoldersRight = isCurry ? undefined : holders,
-          newPartials = isCurry ? partials : undefined,
-          newPartialsRight = isCurry ? undefined : partials;
-
-      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
-      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
-
-      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
-        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
-      }
-      var newData = [
-        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
-        newHoldersRight, argPos, ary, arity
-      ];
-
-      var result = wrapFunc.apply(undefined, newData);
-      if (isLaziable(func)) {
-        setData(result, newData);
-      }
-      result.placeholder = placeholder;
-      return setWrapToString(result, func, bitmask);
-    }
-
-    /**
-     * Creates a function like `_.round`.
-     *
-     * @private
-     * @param {string} methodName The name of the `Math` method to use when rounding.
-     * @returns {Function} Returns the new round function.
-     */
-    function createRound(methodName) {
-      var func = Math[methodName];
-      return function(number, precision) {
-        number = toNumber(number);
-        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
-        if (precision) {
-          // Shift with exponential notation to avoid floating-point issues.
-          // See [MDN](https://mdn.io/round#Examples) for more details.
-          var pair = (toString(number) + 'e').split('e'),
-              value = func(pair[0] + 'e' + (+pair[1] + precision));
-
-          pair = (toString(value) + 'e').split('e');
-          return +(pair[0] + 'e' + (+pair[1] - precision));
-        }
-        return func(number);
-      };
-    }
-
-    /**
-     * Creates a set object of `values`.
-     *
-     * @private
-     * @param {Array} values The values to add to the set.
-     * @returns {Object} Returns the new set.
-     */
-    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
-      return new Set(values);
-    };
-
-    /**
-     * Creates a `_.toPairs` or `_.toPairsIn` function.
-     *
-     * @private
-     * @param {Function} keysFunc The function to get the keys of a given object.
-     * @returns {Function} Returns the new pairs function.
-     */
-    function createToPairs(keysFunc) {
-      return function(object) {
-        var tag = getTag(object);
-        if (tag == mapTag) {
-          return mapToArray(object);
-        }
-        if (tag == setTag) {
-          return setToPairs(object);
-        }
-        return baseToPairs(object, keysFunc(object));
-      };
-    }
-
-    /**
-     * Creates a function that either curries or invokes `func` with optional
-     * `this` binding and partially applied arguments.
-     *
-     * @private
-     * @param {Function|string} func The function or method name to wrap.
-     * @param {number} bitmask The bitmask flags.
-     *    1 - `_.bind`
-     *    2 - `_.bindKey`
-     *    4 - `_.curry` or `_.curryRight` of a bound function
-     *    8 - `_.curry`
-     *   16 - `_.curryRight`
-     *   32 - `_.partial`
-     *   64 - `_.partialRight`
-     *  128 - `_.rearg`
-     *  256 - `_.ary`
-     *  512 - `_.flip`
-     * @param {*} [thisArg] The `this` binding of `func`.
-     * @param {Array} [partials] The arguments to be partially applied.
-     * @param {Array} [holders] The `partials` placeholder indexes.
-     * @param {Array} [argPos] The argument positions of the new function.
-     * @param {number} [ary] The arity cap of `func`.
-     * @param {number} [arity] The arity of `func`.
-     * @returns {Function} Returns the new wrapped function.
-     */
-    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
-      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
-      if (!isBindKey && typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      var length = partials ? partials.length : 0;
-      if (!length) {
-        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
-        partials = holders = undefined;
-      }
-      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
-      arity = arity === undefined ? arity : toInteger(arity);
-      length -= holders ? holders.length : 0;
-
-      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
-        var partialsRight = partials,
-            holdersRight = holders;
-
-        partials = holders = undefined;
-      }
-      var data = isBindKey ? undefined : getData(func);
-
-      var newData = [
-        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
-        argPos, ary, arity
-      ];
-
-      if (data) {
-        mergeData(newData, data);
-      }
-      func = newData[0];
-      bitmask = newData[1];
-      thisArg = newData[2];
-      partials = newData[3];
-      holders = newData[4];
-      arity = newData[9] = newData[9] === undefined
-        ? (isBindKey ? 0 : func.length)
-        : nativeMax(newData[9] - length, 0);
-
-      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
-        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
-      }
-      if (!bitmask || bitmask == WRAP_BIND_FLAG) {
-        var result = createBind(func, bitmask, thisArg);
-      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
-        result = createCurry(func, bitmask, arity);
-      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
-        result = createPartial(func, bitmask, thisArg, partials);
-      } else {
-        result = createHybrid.apply(undefined, newData);
-      }
-      var setter = data ? baseSetData : setData;
-      return setWrapToString(setter(result, newData), func, bitmask);
-    }
-
-    /**
-     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
-     * of source objects to the destination object for all destination properties
-     * that resolve to `undefined`.
-     *
-     * @private
-     * @param {*} objValue The destination value.
-     * @param {*} srcValue The source value.
-     * @param {string} key The key of the property to assign.
-     * @param {Object} object The parent object of `objValue`.
-     * @returns {*} Returns the value to assign.
-     */
-    function customDefaultsAssignIn(objValue, srcValue, key, object) {
-      if (objValue === undefined ||
-          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
-        return srcValue;
-      }
-      return objValue;
-    }
-
-    /**
-     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
-     * objects into destination objects that are passed thru.
-     *
-     * @private
-     * @param {*} objValue The destination value.
-     * @param {*} srcValue The source value.
-     * @param {string} key The key of the property to merge.
-     * @param {Object} object The parent object of `objValue`.
-     * @param {Object} source The parent object of `srcValue`.
-     * @param {Object} [stack] Tracks traversed source values and their merged
-     *  counterparts.
-     * @returns {*} Returns the value to assign.
-     */
-    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
-      if (isObject(objValue) && isObject(srcValue)) {
-        // Recursively merge objects and arrays (susceptible to call stack limits).
-        stack.set(srcValue, objValue);
-        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
-        stack['delete'](srcValue);
-      }
-      return objValue;
-    }
-
-    /**
-     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
-     * objects.
-     *
-     * @private
-     * @param {*} value The value to inspect.
-     * @param {string} key The key of the property to inspect.
-     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
-     */
-    function customOmitClone(value) {
-      return isPlainObject(value) ? undefined : value;
-    }
-
-    /**
-     * A specialized version of `baseIsEqualDeep` for arrays with support for
-     * partial deep comparisons.
-     *
-     * @private
-     * @param {Array} array The array to compare.
-     * @param {Array} other The other array to compare.
-     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
-     * @param {Function} customizer The function to customize comparisons.
-     * @param {Function} equalFunc The function to determine equivalents of values.
-     * @param {Object} stack Tracks traversed `array` and `other` objects.
-     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
-     */
-    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
-      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
-          arrLength = array.length,
-          othLength = other.length;
-
-      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
-        return false;
-      }
-      // Assume cyclic values are equal.
-      var stacked = stack.get(array);
-      if (stacked && stack.get(other)) {
-        return stacked == other;
-      }
-      var index = -1,
-          result = true,
-          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
-
-      stack.set(array, other);
-      stack.set(other, array);
-
-      // Ignore non-index properties.
-      while (++index < arrLength) {
-        var arrValue = array[index],
-            othValue = other[index];
-
-        if (customizer) {
-          var compared = isPartial
-            ? customizer(othValue, arrValue, index, other, array, stack)
-            : customizer(arrValue, othValue, index, array, other, stack);
-        }
-        if (compared !== undefined) {
-          if (compared) {
-            continue;
-          }
-          result = false;
-          break;
-        }
-        // Recursively compare arrays (susceptible to call stack limits).
-        if (seen) {
-          if (!arraySome(other, function(othValue, othIndex) {
-                if (!cacheHas(seen, othIndex) &&
-                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
-                  return seen.push(othIndex);
-                }
-              })) {
-            result = false;
-            break;
-          }
-        } else if (!(
-              arrValue === othValue ||
-                equalFunc(arrValue, othValue, bitmask, customizer, stack)
-            )) {
-          result = false;
-          break;
-        }
-      }
-      stack['delete'](array);
-      stack['delete'](other);
-      return result;
-    }
-
-    /**
-     * A specialized version of `baseIsEqualDeep` for comparing objects of
-     * the same `toStringTag`.
-     *
-     * **Note:** This function only supports comparing values with tags of
-     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
-     *
-     * @private
-     * @param {Object} object The object to compare.
-     * @param {Object} other The other object to compare.
-     * @param {string} tag The `toStringTag` of the objects to compare.
-     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
-     * @param {Function} customizer The function to customize comparisons.
-     * @param {Function} equalFunc The function to determine equivalents of values.
-     * @param {Object} stack Tracks traversed `object` and `other` objects.
-     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
-     */
-    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
-      switch (tag) {
-        case dataViewTag:
-          if ((object.byteLength != other.byteLength) ||
-              (object.byteOffset != other.byteOffset)) {
-            return false;
-          }
-          object = object.buffer;
-          other = other.buffer;
-
-        case arrayBufferTag:
-          if ((object.byteLength != other.byteLength) ||
-              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
-            return false;
-          }
-          return true;
-
-        case boolTag:
-        case dateTag:
-        case numberTag:
-          // Coerce booleans to `1` or `0` and dates to milliseconds.
-          // Invalid dates are coerced to `NaN`.
-          return eq(+object, +other);
-
-        case errorTag:
-          return object.name == other.name && object.message == other.message;
-
-        case regexpTag:
-        case stringTag:
-          // Coerce regexes to strings and treat strings, primitives and objects,
-          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
-          // for more details.
-          return object == (other + '');
-
-        case mapTag:
-          var convert = mapToArray;
-
-        case setTag:
-          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
-          convert || (convert = setToArray);
-
-          if (object.size != other.size && !isPartial) {
-            return false;
-          }
-          // Assume cyclic values are equal.
-          var stacked = stack.get(object);
-          if (stacked) {
-            return stacked == other;
-          }
-          bitmask |= COMPARE_UNORDERED_FLAG;
-
-          // Recursively compare objects (susceptible to call stack limits).
-          stack.set(object, other);
-          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
-          stack['delete'](object);
-          return result;
-
-        case symbolTag:
-          if (symbolValueOf) {
-            return symbolValueOf.call(object) == symbolValueOf.call(other);
-          }
-      }
-      return false;
-    }
-
-    /**
-     * A specialized version of `baseIsEqualDeep` for objects with support for
-     * partial deep comparisons.
-     *
-     * @private
-     * @param {Object} object The object to compare.
-     * @param {Object} other The other object to compare.
-     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
-     * @param {Function} customizer The function to customize comparisons.
-     * @param {Function} equalFunc The function to determine equivalents of values.
-     * @param {Object} stack Tracks traversed `object` and `other` objects.
-     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
-     */
-    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
-      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
-          objProps = getAllKeys(object),
-          objLength = objProps.length,
-          othProps = getAllKeys(other),
-          othLength = othProps.length;
-
-      if (objLength != othLength && !isPartial) {
-        return false;
-      }
-      var index = objLength;
-      while (index--) {
-        var key = objProps[index];
-        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
-          return false;
-        }
-      }
-      // Assume cyclic values are equal.
-      var stacked = stack.get(object);
-      if (stacked && stack.get(other)) {
-        return stacked == other;
-      }
-      var result = true;
-      stack.set(object, other);
-      stack.set(other, object);
-
-      var skipCtor = isPartial;
-      while (++index < objLength) {
-        key = objProps[index];
-        var objValue = object[key],
-            othValue = other[key];
-
-        if (customizer) {
-          var compared = isPartial
-            ? customizer(othValue, objValue, key, other, object, stack)
-            : customizer(objValue, othValue, key, object, other, stack);
-        }
-        // Recursively compare objects (susceptible to call stack limits).
-        if (!(compared === undefined
-              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
-              : compared
-            )) {
-          result = false;
-          break;
-        }
-        skipCtor || (skipCtor = key == 'constructor');
-      }
-      if (result && !skipCtor) {
-        var objCtor = object.constructor,
-            othCtor = other.constructor;
-
-        // Non `Object` object instances with different constructors are not equal.
-        if (objCtor != othCtor &&
-            ('constructor' in object && 'constructor' in other) &&
-            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
-              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
-          result = false;
-        }
-      }
-      stack['delete'](object);
-      stack['delete'](other);
-      return result;
-    }
-
-    /**
-     * A specialized version of `baseRest` which flattens the rest array.
-     *
-     * @private
-     * @param {Function} func The function to apply a rest parameter to.
-     * @returns {Function} Returns the new function.
-     */
-    function flatRest(func) {
-      return setToString(overRest(func, undefined, flatten), func + '');
-    }
-
-    /**
-     * Creates an array of own enumerable property names and symbols of `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property names and symbols.
-     */
-    function getAllKeys(object) {
-      return baseGetAllKeys(object, keys, getSymbols);
-    }
-
-    /**
-     * Creates an array of own and inherited enumerable property names and
-     * symbols of `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property names and symbols.
-     */
-    function getAllKeysIn(object) {
-      return baseGetAllKeys(object, keysIn, getSymbolsIn);
-    }
-
-    /**
-     * Gets metadata for `func`.
-     *
-     * @private
-     * @param {Function} func The function to query.
-     * @returns {*} Returns the metadata for `func`.
-     */
-    var getData = !metaMap ? noop : function(func) {
-      return metaMap.get(func);
-    };
-
-    /**
-     * Gets the name of `func`.
-     *
-     * @private
-     * @param {Function} func The function to query.
-     * @returns {string} Returns the function name.
-     */
-    function getFuncName(func) {
-      var result = (func.name + ''),
-          array = realNames[result],
-          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
-
-      while (length--) {
-        var data = array[length],
-            otherFunc = data.func;
-        if (otherFunc == null || otherFunc == func) {
-          return data.name;
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Gets the argument placeholder value for `func`.
-     *
-     * @private
-     * @param {Function} func The function to inspect.
-     * @returns {*} Returns the placeholder value.
-     */
-    function getHolder(func) {
-      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
-      return object.placeholder;
-    }
-
-    /**
-     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
-     * this function returns the custom method, otherwise it returns `baseIteratee`.
-     * If arguments are provided, the chosen function is invoked with them and
-     * its result is returned.
-     *
-     * @private
-     * @param {*} [value] The value to convert to an iteratee.
-     * @param {number} [arity] The arity of the created iteratee.
-     * @returns {Function} Returns the chosen function or its result.
-     */
-    function getIteratee() {
-      var result = lodash.iteratee || iteratee;
-      result = result === iteratee ? baseIteratee : result;
-      return arguments.length ? result(arguments[0], arguments[1]) : result;
-    }
-
-    /**
-     * Gets the data for `map`.
-     *
-     * @private
-     * @param {Object} map The map to query.
-     * @param {string} key The reference key.
-     * @returns {*} Returns the map data.
-     */
-    function getMapData(map, key) {
-      var data = map.__data__;
-      return isKeyable(key)
-        ? data[typeof key == 'string' ? 'string' : 'hash']
-        : data.map;
-    }
-
-    /**
-     * Gets the property names, values, and compare flags of `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the match data of `object`.
-     */
-    function getMatchData(object) {
-      var result = keys(object),
-          length = result.length;
-
-      while (length--) {
-        var key = result[length],
-            value = object[key];
-
-        result[length] = [key, value, isStrictComparable(value)];
-      }
-      return result;
-    }
-
-    /**
-     * Gets the native function at `key` of `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @param {string} key The key of the method to get.
-     * @returns {*} Returns the function if it's native, else `undefined`.
-     */
-    function getNative(object, key) {
-      var value = getValue(object, key);
-      return baseIsNative(value) ? value : undefined;
-    }
-
-    /**
-     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
-     *
-     * @private
-     * @param {*} value The value to query.
-     * @returns {string} Returns the raw `toStringTag`.
-     */
-    function getRawTag(value) {
-      var isOwn = hasOwnProperty.call(value, symToStringTag),
-          tag = value[symToStringTag];
-
-      try {
-        value[symToStringTag] = undefined;
-        var unmasked = true;
-      } catch (e) {}
-
-      var result = nativeObjectToString.call(value);
-      if (unmasked) {
-        if (isOwn) {
-          value[symToStringTag] = tag;
-        } else {
-          delete value[symToStringTag];
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Creates an array of the own enumerable symbols of `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of symbols.
-     */
-    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
-      if (object == null) {
-        return [];
-      }
-      object = Object(object);
-      return arrayFilter(nativeGetSymbols(object), function(symbol) {
-        return propertyIsEnumerable.call(object, symbol);
-      });
-    };
-
-    /**
-     * Creates an array of the own and inherited enumerable symbols of `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of symbols.
-     */
-    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
-      var result = [];
-      while (object) {
-        arrayPush(result, getSymbols(object));
-        object = getPrototype(object);
-      }
-      return result;
-    };
-
-    /**
-     * Gets the `toStringTag` of `value`.
-     *
-     * @private
-     * @param {*} value The value to query.
-     * @returns {string} Returns the `toStringTag`.
-     */
-    var getTag = baseGetTag;
-
-    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
-    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
-        (Map && getTag(new Map) != mapTag) ||
-        (Promise && getTag(Promise.resolve()) != promiseTag) ||
-        (Set && getTag(new Set) != setTag) ||
-        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
-      getTag = function(value) {
-        var result = baseGetTag(value),
-            Ctor = result == objectTag ? value.constructor : undefined,
-            ctorString = Ctor ? toSource(Ctor) : '';
-
-        if (ctorString) {
-          switch (ctorString) {
-            case dataViewCtorString: return dataViewTag;
-            case mapCtorString: return mapTag;
-            case promiseCtorString: return promiseTag;
-            case setCtorString: return setTag;
-            case weakMapCtorString: return weakMapTag;
-          }
-        }
-        return result;
-      };
-    }
-
-    /**
-     * Gets the view, applying any `transforms` to the `start` and `end` positions.
-     *
-     * @private
-     * @param {number} start The start of the view.
-     * @param {number} end The end of the view.
-     * @param {Array} transforms The transformations to apply to the view.
-     * @returns {Object} Returns an object containing the `start` and `end`
-     *  positions of the view.
-     */
-    function getView(start, end, transforms) {
-      var index = -1,
-          length = transforms.length;
-
-      while (++index < length) {
-        var data = transforms[index],
-            size = data.size;
-
-        switch (data.type) {
-          case 'drop':      start += size; break;
-          case 'dropRight': end -= size; break;
-          case 'take':      end = nativeMin(end, start + size); break;
-          case 'takeRight': start = nativeMax(start, end - size); break;
-        }
-      }
-      return { 'start': start, 'end': end };
-    }
-
-    /**
-     * Extracts wrapper details from the `source` body comment.
-     *
-     * @private
-     * @param {string} source The source to inspect.
-     * @returns {Array} Returns the wrapper details.
-     */
-    function getWrapDetails(source) {
-      var match = source.match(reWrapDetails);
-      return match ? match[1].split(reSplitDetails) : [];
-    }
-
-    /**
-     * Checks if `path` exists on `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @param {Array|string} path The path to check.
-     * @param {Function} hasFunc The function to check properties.
-     * @returns {boolean} Returns `true` if `path` exists, else `false`.
-     */
-    function hasPath(object, path, hasFunc) {
-      path = castPath(path, object);
-
-      var index = -1,
-          length = path.length,
-          result = false;
-
-      while (++index < length) {
-        var key = toKey(path[index]);
-        if (!(result = object != null && hasFunc(object, key))) {
-          break;
-        }
-        object = object[key];
-      }
-      if (result || ++index != length) {
-        return result;
-      }
-      length = object == null ? 0 : object.length;
-      return !!length && isLength(length) && isIndex(key, length) &&
-        (isArray(object) || isArguments(object));
-    }
-
-    /**
-     * Initializes an array clone.
-     *
-     * @private
-     * @param {Array} array The array to clone.
-     * @returns {Array} Returns the initialized clone.
-     */
-    function initCloneArray(array) {
-      var length = array.length,
-          result = array.constructor(length);
-
-      // Add properties assigned by `RegExp#exec`.
-      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
-        result.index = array.index;
-        result.input = array.input;
-      }
-      return result;
-    }
-
-    /**
-     * Initializes an object clone.
-     *
-     * @private
-     * @param {Object} object The object to clone.
-     * @returns {Object} Returns the initialized clone.
-     */
-    function initCloneObject(object) {
-      return (typeof object.constructor == 'function' && !isPrototype(object))
-        ? baseCreate(getPrototype(object))
-        : {};
-    }
-
-    /**
-     * Initializes an object clone based on its `toStringTag`.
-     *
-     * **Note:** This function only supports cloning values with tags of
-     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
-     *
-     * @private
-     * @param {Object} object The object to clone.
-     * @param {string} tag The `toStringTag` of the object to clone.
-     * @param {Function} cloneFunc The function to clone values.
-     * @param {boolean} [isDeep] Specify a deep clone.
-     * @returns {Object} Returns the initialized clone.
-     */
-    function initCloneByTag(object, tag, cloneFunc, isDeep) {
-      var Ctor = object.constructor;
-      switch (tag) {
-        case arrayBufferTag:
-          return cloneArrayBuffer(object);
-
-        case boolTag:
-        case dateTag:
-          return new Ctor(+object);
-
-        case dataViewTag:
-          return cloneDataView(object, isDeep);
-
-        case float32Tag: case float64Tag:
-        case int8Tag: case int16Tag: case int32Tag:
-        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
-          return cloneTypedArray(object, isDeep);
-
-        case mapTag:
-          return cloneMap(object, isDeep, cloneFunc);
-
-        case numberTag:
-        case stringTag:
-          return new Ctor(object);
-
-        case regexpTag:
-          return cloneRegExp(object);
-
-        case setTag:
-          return cloneSet(object, isDeep, cloneFunc);
-
-        case symbolTag:
-          return cloneSymbol(object);
-      }
-    }
-
-    /**
-     * Inserts wrapper `details` in a comment at the top of the `source` body.
-     *
-     * @private
-     * @param {string} source The source to modify.
-     * @returns {Array} details The details to insert.
-     * @returns {string} Returns the modified source.
-     */
-    function insertWrapDetails(source, details) {
-      var length = details.length;
-      if (!length) {
-        return source;
-      }
-      var lastIndex = length - 1;
-      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
-      details = details.join(length > 2 ? ', ' : ' ');
-      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
-    }
-
-    /**
-     * Checks if `value` is a flattenable `arguments` object or array.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
-     */
-    function isFlattenable(value) {
-      return isArray(value) || isArguments(value) ||
-        !!(spreadableSymbol && value && value[spreadableSymbol]);
-    }
-
-    /**
-     * Checks if `value` is a valid array-like index.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
-     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
-     */
-    function isIndex(value, length) {
-      length = length == null ? MAX_SAFE_INTEGER : length;
-      return !!length &&
-        (typeof value == 'number' || reIsUint.test(value)) &&
-        (value > -1 && value % 1 == 0 && value < length);
-    }
-
-    /**
-     * Checks if the given arguments are from an iteratee call.
-     *
-     * @private
-     * @param {*} value The potential iteratee value argument.
-     * @param {*} index The potential iteratee index or key argument.
-     * @param {*} object The potential iteratee object argument.
-     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
-     *  else `false`.
-     */
-    function isIterateeCall(value, index, object) {
-      if (!isObject(object)) {
-        return false;
-      }
-      var type = typeof index;
-      if (type == 'number'
-            ? (isArrayLike(object) && isIndex(index, object.length))
-            : (type == 'string' && index in object)
-          ) {
-        return eq(object[index], value);
-      }
-      return false;
-    }
-
-    /**
-     * Checks if `value` is a property name and not a property path.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @param {Object} [object] The object to query keys on.
-     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
-     */
-    function isKey(value, object) {
-      if (isArray(value)) {
-        return false;
-      }
-      var type = typeof value;
-      if (type == 'number' || type == 'symbol' || type == 'boolean' ||
-          value == null || isSymbol(value)) {
-        return true;
-      }
-      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
-        (object != null && value in Object(object));
-    }
-
-    /**
-     * Checks if `value` is suitable for use as unique object key.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
-     */
-    function isKeyable(value) {
-      var type = typeof value;
-      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
-        ? (value !== '__proto__')
-        : (value === null);
-    }
-
-    /**
-     * Checks if `func` has a lazy counterpart.
-     *
-     * @private
-     * @param {Function} func The function to check.
-     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
-     *  else `false`.
-     */
-    function isLaziable(func) {
-      var funcName = getFuncName(func),
-          other = lodash[funcName];
-
-      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
-        return false;
-      }
-      if (func === other) {
-        return true;
-      }
-      var data = getData(other);
-      return !!data && func === data[0];
-    }
-
-    /**
-     * Checks if `func` has its source masked.
-     *
-     * @private
-     * @param {Function} func The function to check.
-     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
-     */
-    function isMasked(func) {
-      return !!maskSrcKey && (maskSrcKey in func);
-    }
-
-    /**
-     * Checks if `func` is capable of being masked.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
-     */
-    var isMaskable = coreJsData ? isFunction : stubFalse;
-
-    /**
-     * Checks if `value` is likely a prototype object.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
-     */
-    function isPrototype(value) {
-      var Ctor = value && value.constructor,
-          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
-
-      return value === proto;
-    }
-
-    /**
-     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
-     *
-     * @private
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` if suitable for strict
-     *  equality comparisons, else `false`.
-     */
-    function isStrictComparable(value) {
-      return value === value && !isObject(value);
-    }
-
-    /**
-     * A specialized version of `matchesProperty` for source values suitable
-     * for strict equality comparisons, i.e. `===`.
-     *
-     * @private
-     * @param {string} key The key of the property to get.
-     * @param {*} srcValue The value to match.
-     * @returns {Function} Returns the new spec function.
-     */
-    function matchesStrictComparable(key, srcValue) {
-      return function(object) {
-        if (object == null) {
-          return false;
-        }
-        return object[key] === srcValue &&
-          (srcValue !== undefined || (key in Object(object)));
-      };
-    }
-
-    /**
-     * A specialized version of `_.memoize` which clears the memoized function's
-     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
-     *
-     * @private
-     * @param {Function} func The function to have its output memoized.
-     * @returns {Function} Returns the new memoized function.
-     */
-    function memoizeCapped(func) {
-      var result = memoize(func, function(key) {
-        if (cache.size === MAX_MEMOIZE_SIZE) {
-          cache.clear();
-        }
-        return key;
-      });
-
-      var cache = result.cache;
-      return result;
-    }
-
-    /**
-     * Merges the function metadata of `source` into `data`.
-     *
-     * Merging metadata reduces the number of wrappers used to invoke a function.
-     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
-     * may be applied regardless of execution order. Methods like `_.ary` and
-     * `_.rearg` modify function arguments, making the order in which they are
-     * executed important, preventing the merging of metadata. However, we make
-     * an exception for a safe combined case where curried functions have `_.ary`
-     * and or `_.rearg` applied.
-     *
-     * @private
-     * @param {Array} data The destination metadata.
-     * @param {Array} source The source metadata.
-     * @returns {Array} Returns `data`.
-     */
-    function mergeData(data, source) {
-      var bitmask = data[1],
-          srcBitmask = source[1],
-          newBitmask = bitmask | srcBitmask,
-          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
-
-      var isCombo =
-        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
-        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
-        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
-
-      // Exit early if metadata can't be merged.
-      if (!(isCommon || isCombo)) {
-        return data;
-      }
-      // Use source `thisArg` if available.
-      if (srcBitmask & WRAP_BIND_FLAG) {
-        data[2] = source[2];
-        // Set when currying a bound function.
-        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
-      }
-      // Compose partial arguments.
-      var value = source[3];
-      if (value) {
-        var partials = data[3];
-        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
-        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
-      }
-      // Compose partial right arguments.
-      value = source[5];
-      if (value) {
-        partials = data[5];
-        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
-        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
-      }
-      // Use source `argPos` if available.
-      value = source[7];
-      if (value) {
-        data[7] = value;
-      }
-      // Use source `ary` if it's smaller.
-      if (srcBitmask & WRAP_ARY_FLAG) {
-        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
-      }
-      // Use source `arity` if one is not provided.
-      if (data[9] == null) {
-        data[9] = source[9];
-      }
-      // Use source `func` and merge bitmasks.
-      data[0] = source[0];
-      data[1] = newBitmask;
-
-      return data;
-    }
-
-    /**
-     * This function is like
-     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
-     * except that it includes inherited enumerable properties.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property names.
-     */
-    function nativeKeysIn(object) {
-      var result = [];
-      if (object != null) {
-        for (var key in Object(object)) {
-          result.push(key);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Converts `value` to a string using `Object.prototype.toString`.
-     *
-     * @private
-     * @param {*} value The value to convert.
-     * @returns {string} Returns the converted string.
-     */
-    function objectToString(value) {
-      return nativeObjectToString.call(value);
-    }
-
-    /**
-     * A specialized version of `baseRest` which transforms the rest array.
-     *
-     * @private
-     * @param {Function} func The function to apply a rest parameter to.
-     * @param {number} [start=func.length-1] The start position of the rest parameter.
-     * @param {Function} transform The rest array transform.
-     * @returns {Function} Returns the new function.
-     */
-    function overRest(func, start, transform) {
-      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
-      return function() {
-        var args = arguments,
-            index = -1,
-            length = nativeMax(args.length - start, 0),
-            array = Array(length);
-
-        while (++index < length) {
-          array[index] = args[start + index];
-        }
-        index = -1;
-        var otherArgs = Array(start + 1);
-        while (++index < start) {
-          otherArgs[index] = args[index];
-        }
-        otherArgs[start] = transform(array);
-        return apply(func, this, otherArgs);
-      };
-    }
-
-    /**
-     * Gets the parent value at `path` of `object`.
-     *
-     * @private
-     * @param {Object} object The object to query.
-     * @param {Array} path The path to get the parent value of.
-     * @returns {*} Returns the parent value.
-     */
-    function parent(object, path) {
-      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
-    }
-
-    /**
-     * Reorder `array` according to the specified indexes where the element at
-     * the first index is assigned as the first element, the element at
-     * the second index is assigned as the second element, and so on.
-     *
-     * @private
-     * @param {Array} array The array to reorder.
-     * @param {Array} indexes The arranged array indexes.
-     * @returns {Array} Returns `array`.
-     */
-    function reorder(array, indexes) {
-      var arrLength = array.length,
-          length = nativeMin(indexes.length, arrLength),
-          oldArray = copyArray(array);
-
-      while (length--) {
-        var index = indexes[length];
-        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
-      }
-      return array;
-    }
-
-    /**
-     * Sets metadata for `func`.
-     *
-     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
-     * period of time, it will trip its breaker and transition to an identity
-     * function to avoid garbage collection pauses in V8. See
-     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
-     * for more details.
-     *
-     * @private
-     * @param {Function} func The function to associate metadata with.
-     * @param {*} data The metadata.
-     * @returns {Function} Returns `func`.
-     */
-    var setData = shortOut(baseSetData);
-
-    /**
-     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
-     *
-     * @private
-     * @param {Function} func The function to delay.
-     * @param {number} wait The number of milliseconds to delay invocation.
-     * @returns {number|Object} Returns the timer id or timeout object.
-     */
-    var setTimeout = ctxSetTimeout || function(func, wait) {
-      return root.setTimeout(func, wait);
-    };
-
-    /**
-     * Sets the `toString` method of `func` to return `string`.
-     *
-     * @private
-     * @param {Function} func The function to modify.
-     * @param {Function} string The `toString` result.
-     * @returns {Function} Returns `func`.
-     */
-    var setToString = shortOut(baseSetToString);
-
-    /**
-     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
-     * with wrapper details in a comment at the top of the source body.
-     *
-     * @private
-     * @param {Function} wrapper The function to modify.
-     * @param {Function} reference The reference function.
-     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
-     * @returns {Function} Returns `wrapper`.
-     */
-    function setWrapToString(wrapper, reference, bitmask) {
-      var source = (reference + '');
-      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
-    }
-
-    /**
-     * Creates a function that'll short out and invoke `identity` instead
-     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
-     * milliseconds.
-     *
-     * @private
-     * @param {Function} func The function to restrict.
-     * @returns {Function} Returns the new shortable function.
-     */
-    function shortOut(func) {
-      var count = 0,
-          lastCalled = 0;
-
-      return function() {
-        var stamp = nativeNow(),
-            remaining = HOT_SPAN - (stamp - lastCalled);
-
-        lastCalled = stamp;
-        if (remaining > 0) {
-          if (++count >= HOT_COUNT) {
-            return arguments[0];
-          }
-        } else {
-          count = 0;
-        }
-        return func.apply(undefined, arguments);
-      };
-    }
-
-    /**
-     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
-     *
-     * @private
-     * @param {Array} array The array to shuffle.
-     * @param {number} [size=array.length] The size of `array`.
-     * @returns {Array} Returns `array`.
-     */
-    function shuffleSelf(array, size) {
-      var index = -1,
-          length = array.length,
-          lastIndex = length - 1;
-
-      size = size === undefined ? length : size;
-      while (++index < size) {
-        var rand = baseRandom(index, lastIndex),
-            value = array[rand];
-
-        array[rand] = array[index];
-        array[index] = value;
-      }
-      array.length = size;
-      return array;
-    }
-
-    /**
-     * Converts `string` to a property path array.
-     *
-     * @private
-     * @param {string} string The string to convert.
-     * @returns {Array} Returns the property path array.
-     */
-    var stringToPath = memoizeCapped(function(string) {
-      var result = [];
-      if (reLeadingDot.test(string)) {
-        result.push('');
-      }
-      string.replace(rePropName, function(match, number, quote, string) {
-        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
-      });
-      return result;
-    });
-
-    /**
-     * Converts `value` to a string key if it's not a string or symbol.
-     *
-     * @private
-     * @param {*} value The value to inspect.
-     * @returns {string|symbol} Returns the key.
-     */
-    function toKey(value) {
-      if (typeof value == 'string' || isSymbol(value)) {
-        return value;
-      }
-      var result = (value + '');
-      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-    }
-
-    /**
-     * Converts `func` to its source code.
-     *
-     * @private
-     * @param {Function} func The function to convert.
-     * @returns {string} Returns the source code.
-     */
-    function toSource(func) {
-      if (func != null) {
-        try {
-          return funcToString.call(func);
-        } catch (e) {}
-        try {
-          return (func + '');
-        } catch (e) {}
-      }
-      return '';
-    }
-
-    /**
-     * Updates wrapper `details` based on `bitmask` flags.
-     *
-     * @private
-     * @returns {Array} details The details to modify.
-     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
-     * @returns {Array} Returns `details`.
-     */
-    function updateWrapDetails(details, bitmask) {
-      arrayEach(wrapFlags, function(pair) {
-        var value = '_.' + pair[0];
-        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
-          details.push(value);
-        }
-      });
-      return details.sort();
-    }
-
-    /**
-     * Creates a clone of `wrapper`.
-     *
-     * @private
-     * @param {Object} wrapper The wrapper to clone.
-     * @returns {Object} Returns the cloned wrapper.
-     */
-    function wrapperClone(wrapper) {
-      if (wrapper instanceof LazyWrapper) {
-        return wrapper.clone();
-      }
-      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
-      result.__actions__ = copyArray(wrapper.__actions__);
-      result.__index__  = wrapper.__index__;
-      result.__values__ = wrapper.__values__;
-      return result;
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates an array of elements split into groups the length of `size`.
-     * If `array` can't be split evenly, the final chunk will be the remaining
-     * elements.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to process.
-     * @param {number} [size=1] The length of each chunk
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Array} Returns the new array of chunks.
-     * @example
-     *
-     * _.chunk(['a', 'b', 'c', 'd'], 2);
-     * // => [['a', 'b'], ['c', 'd']]
-     *
-     * _.chunk(['a', 'b', 'c', 'd'], 3);
-     * // => [['a', 'b', 'c'], ['d']]
-     */
-    function chunk(array, size, guard) {
-      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
-        size = 1;
-      } else {
-        size = nativeMax(toInteger(size), 0);
-      }
-      var length = array == null ? 0 : array.length;
-      if (!length || size < 1) {
-        return [];
-      }
-      var index = 0,
-          resIndex = 0,
-          result = Array(nativeCeil(length / size));
-
-      while (index < length) {
-        result[resIndex++] = baseSlice(array, index, (index += size));
-      }
-      return result;
-    }
-
-    /**
-     * Creates an array with all falsey values removed. The values `false`, `null`,
-     * `0`, `""`, `undefined`, and `NaN` are falsey.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to compact.
-     * @returns {Array} Returns the new array of filtered values.
-     * @example
-     *
-     * _.compact([0, 1, false, 2, '', 3]);
-     * // => [1, 2, 3]
-     */
-    function compact(array) {
-      var index = -1,
-          length = array == null ? 0 : array.length,
-          resIndex = 0,
-          result = [];
-
-      while (++index < length) {
-        var value = array[index];
-        if (value) {
-          result[resIndex++] = value;
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Creates a new array concatenating `array` with any additional arrays
-     * and/or values.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to concatenate.
-     * @param {...*} [values] The values to concatenate.
-     * @returns {Array} Returns the new concatenated array.
-     * @example
-     *
-     * var array = [1];
-     * var other = _.concat(array, 2, [3], [[4]]);
-     *
-     * console.log(other);
-     * // => [1, 2, 3, [4]]
-     *
-     * console.log(array);
-     * // => [1]
-     */
-    function concat() {
-      var length = arguments.length;
-      if (!length) {
-        return [];
-      }
-      var args = Array(length - 1),
-          array = arguments[0],
-          index = length;
-
-      while (index--) {
-        args[index - 1] = arguments[index];
-      }
-      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
-    }
-
-    /**
-     * Creates an array of `array` values not included in the other given arrays
-     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * for equality comparisons. The order and references of result values are
-     * determined by the first array.
-     *
-     * **Note:** Unlike `_.pullAll`, this method returns a new array.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {...Array} [values] The values to exclude.
-     * @returns {Array} Returns the new array of filtered values.
-     * @see _.without, _.xor
-     * @example
-     *
-     * _.difference([2, 1], [2, 3]);
-     * // => [1]
-     */
-    var difference = baseRest(function(array, values) {
-      return isArrayLikeObject(array)
-        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
-        : [];
-    });
-
-    /**
-     * This method is like `_.difference` except that it accepts `iteratee` which
-     * is invoked for each element of `array` and `values` to generate the criterion
-     * by which they're compared. The order and references of result values are
-     * determined by the first array. The iteratee is invoked with one argument:
-     * (value).
-     *
-     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {...Array} [values] The values to exclude.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {Array} Returns the new array of filtered values.
-     * @example
-     *
-     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
-     * // => [1.2]
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
-     * // => [{ 'x': 2 }]
-     */
-    var differenceBy = baseRest(function(array, values) {
-      var iteratee = last(values);
-      if (isArrayLikeObject(iteratee)) {
-        iteratee = undefined;
-      }
-      return isArrayLikeObject(array)
-        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
-        : [];
-    });
-
-    /**
-     * This method is like `_.difference` except that it accepts `comparator`
-     * which is invoked to compare elements of `array` to `values`. The order and
-     * references of result values are determined by the first array. The comparator
-     * is invoked with two arguments: (arrVal, othVal).
-     *
-     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {...Array} [values] The values to exclude.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new array of filtered values.
-     * @example
-     *
-     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
-     *
-     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
-     * // => [{ 'x': 2, 'y': 1 }]
-     */
-    var differenceWith = baseRest(function(array, values) {
-      var comparator = last(values);
-      if (isArrayLikeObject(comparator)) {
-        comparator = undefined;
-      }
-      return isArrayLikeObject(array)
-        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
-        : [];
-    });
-
-    /**
-     * Creates a slice of `array` with `n` elements dropped from the beginning.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.5.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {number} [n=1] The number of elements to drop.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * _.drop([1, 2, 3]);
-     * // => [2, 3]
-     *
-     * _.drop([1, 2, 3], 2);
-     * // => [3]
-     *
-     * _.drop([1, 2, 3], 5);
-     * // => []
-     *
-     * _.drop([1, 2, 3], 0);
-     * // => [1, 2, 3]
-     */
-    function drop(array, n, guard) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return [];
-      }
-      n = (guard || n === undefined) ? 1 : toInteger(n);
-      return baseSlice(array, n < 0 ? 0 : n, length);
-    }
-
-    /**
-     * Creates a slice of `array` with `n` elements dropped from the end.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {number} [n=1] The number of elements to drop.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * _.dropRight([1, 2, 3]);
-     * // => [1, 2]
-     *
-     * _.dropRight([1, 2, 3], 2);
-     * // => [1]
-     *
-     * _.dropRight([1, 2, 3], 5);
-     * // => []
-     *
-     * _.dropRight([1, 2, 3], 0);
-     * // => [1, 2, 3]
-     */
-    function dropRight(array, n, guard) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return [];
-      }
-      n = (guard || n === undefined) ? 1 : toInteger(n);
-      n = length - n;
-      return baseSlice(array, 0, n < 0 ? 0 : n);
-    }
-
-    /**
-     * Creates a slice of `array` excluding elements dropped from the end.
-     * Elements are dropped until `predicate` returns falsey. The predicate is
-     * invoked with three arguments: (value, index, array).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'active': true },
-     *   { 'user': 'fred',    'active': false },
-     *   { 'user': 'pebbles', 'active': false }
-     * ];
-     *
-     * _.dropRightWhile(users, function(o) { return !o.active; });
-     * // => objects for ['barney']
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
-     * // => objects for ['barney', 'fred']
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.dropRightWhile(users, ['active', false]);
-     * // => objects for ['barney']
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.dropRightWhile(users, 'active');
-     * // => objects for ['barney', 'fred', 'pebbles']
-     */
-    function dropRightWhile(array, predicate) {
-      return (array && array.length)
-        ? baseWhile(array, getIteratee(predicate, 3), true, true)
-        : [];
-    }
-
-    /**
-     * Creates a slice of `array` excluding elements dropped from the beginning.
-     * Elements are dropped until `predicate` returns falsey. The predicate is
-     * invoked with three arguments: (value, index, array).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'active': false },
-     *   { 'user': 'fred',    'active': false },
-     *   { 'user': 'pebbles', 'active': true }
-     * ];
-     *
-     * _.dropWhile(users, function(o) { return !o.active; });
-     * // => objects for ['pebbles']
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.dropWhile(users, { 'user': 'barney', 'active': false });
-     * // => objects for ['fred', 'pebbles']
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.dropWhile(users, ['active', false]);
-     * // => objects for ['pebbles']
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.dropWhile(users, 'active');
-     * // => objects for ['barney', 'fred', 'pebbles']
-     */
-    function dropWhile(array, predicate) {
-      return (array && array.length)
-        ? baseWhile(array, getIteratee(predicate, 3), true)
-        : [];
-    }
-
-    /**
-     * Fills elements of `array` with `value` from `start` up to, but not
-     * including, `end`.
-     *
-     * **Note:** This method mutates `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.2.0
-     * @category Array
-     * @param {Array} array The array to fill.
-     * @param {*} value The value to fill `array` with.
-     * @param {number} [start=0] The start position.
-     * @param {number} [end=array.length] The end position.
-     * @returns {Array} Returns `array`.
-     * @example
-     *
-     * var array = [1, 2, 3];
-     *
-     * _.fill(array, 'a');
-     * console.log(array);
-     * // => ['a', 'a', 'a']
-     *
-     * _.fill(Array(3), 2);
-     * // => [2, 2, 2]
-     *
-     * _.fill([4, 6, 8, 10], '*', 1, 3);
-     * // => [4, '*', '*', 10]
-     */
-    function fill(array, value, start, end) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return [];
-      }
-      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
-        start = 0;
-        end = length;
-      }
-      return baseFill(array, value, start, end);
-    }
-
-    /**
-     * This method is like `_.find` except that it returns the index of the first
-     * element `predicate` returns truthy for instead of the element itself.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.1.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @param {number} [fromIndex=0] The index to search from.
-     * @returns {number} Returns the index of the found element, else `-1`.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'active': false },
-     *   { 'user': 'fred',    'active': false },
-     *   { 'user': 'pebbles', 'active': true }
-     * ];
-     *
-     * _.findIndex(users, function(o) { return o.user == 'barney'; });
-     * // => 0
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.findIndex(users, { 'user': 'fred', 'active': false });
-     * // => 1
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.findIndex(users, ['active', false]);
-     * // => 0
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.findIndex(users, 'active');
-     * // => 2
-     */
-    function findIndex(array, predicate, fromIndex) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return -1;
-      }
-      var index = fromIndex == null ? 0 : toInteger(fromIndex);
-      if (index < 0) {
-        index = nativeMax(length + index, 0);
-      }
-      return baseFindIndex(array, getIteratee(predicate, 3), index);
-    }
-
-    /**
-     * This method is like `_.findIndex` except that it iterates over elements
-     * of `collection` from right to left.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @param {number} [fromIndex=array.length-1] The index to search from.
-     * @returns {number} Returns the index of the found element, else `-1`.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'active': true },
-     *   { 'user': 'fred',    'active': false },
-     *   { 'user': 'pebbles', 'active': false }
-     * ];
-     *
-     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
-     * // => 2
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
-     * // => 0
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.findLastIndex(users, ['active', false]);
-     * // => 2
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.findLastIndex(users, 'active');
-     * // => 0
-     */
-    function findLastIndex(array, predicate, fromIndex) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return -1;
-      }
-      var index = length - 1;
-      if (fromIndex !== undefined) {
-        index = toInteger(fromIndex);
-        index = fromIndex < 0
-          ? nativeMax(length + index, 0)
-          : nativeMin(index, length - 1);
-      }
-      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
-    }
-
-    /**
-     * Flattens `array` a single level deep.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to flatten.
-     * @returns {Array} Returns the new flattened array.
-     * @example
-     *
-     * _.flatten([1, [2, [3, [4]], 5]]);
-     * // => [1, 2, [3, [4]], 5]
-     */
-    function flatten(array) {
-      var length = array == null ? 0 : array.length;
-      return length ? baseFlatten(array, 1) : [];
-    }
-
-    /**
-     * Recursively flattens `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to flatten.
-     * @returns {Array} Returns the new flattened array.
-     * @example
-     *
-     * _.flattenDeep([1, [2, [3, [4]], 5]]);
-     * // => [1, 2, 3, 4, 5]
-     */
-    function flattenDeep(array) {
-      var length = array == null ? 0 : array.length;
-      return length ? baseFlatten(array, INFINITY) : [];
-    }
-
-    /**
-     * Recursively flatten `array` up to `depth` times.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.4.0
-     * @category Array
-     * @param {Array} array The array to flatten.
-     * @param {number} [depth=1] The maximum recursion depth.
-     * @returns {Array} Returns the new flattened array.
-     * @example
-     *
-     * var array = [1, [2, [3, [4]], 5]];
-     *
-     * _.flattenDepth(array, 1);
-     * // => [1, 2, [3, [4]], 5]
-     *
-     * _.flattenDepth(array, 2);
-     * // => [1, 2, 3, [4], 5]
-     */
-    function flattenDepth(array, depth) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return [];
-      }
-      depth = depth === undefined ? 1 : toInteger(depth);
-      return baseFlatten(array, depth);
-    }
-
-    /**
-     * The inverse of `_.toPairs`; this method returns an object composed
-     * from key-value `pairs`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} pairs The key-value pairs.
-     * @returns {Object} Returns the new object.
-     * @example
-     *
-     * _.fromPairs([['a', 1], ['b', 2]]);
-     * // => { 'a': 1, 'b': 2 }
-     */
-    function fromPairs(pairs) {
-      var index = -1,
-          length = pairs == null ? 0 : pairs.length,
-          result = {};
-
-      while (++index < length) {
-        var pair = pairs[index];
-        result[pair[0]] = pair[1];
-      }
-      return result;
-    }
-
-    /**
-     * Gets the first element of `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @alias first
-     * @category Array
-     * @param {Array} array The array to query.
-     * @returns {*} Returns the first element of `array`.
-     * @example
-     *
-     * _.head([1, 2, 3]);
-     * // => 1
-     *
-     * _.head([]);
-     * // => undefined
-     */
-    function head(array) {
-      return (array && array.length) ? array[0] : undefined;
-    }
-
-    /**
-     * Gets the index at which the first occurrence of `value` is found in `array`
-     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * for equality comparisons. If `fromIndex` is negative, it's used as the
-     * offset from the end of `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {*} value The value to search for.
-     * @param {number} [fromIndex=0] The index to search from.
-     * @returns {number} Returns the index of the matched value, else `-1`.
-     * @example
-     *
-     * _.indexOf([1, 2, 1, 2], 2);
-     * // => 1
-     *
-     * // Search from the `fromIndex`.
-     * _.indexOf([1, 2, 1, 2], 2, 2);
-     * // => 3
-     */
-    function indexOf(array, value, fromIndex) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return -1;
-      }
-      var index = fromIndex == null ? 0 : toInteger(fromIndex);
-      if (index < 0) {
-        index = nativeMax(length + index, 0);
-      }
-      return baseIndexOf(array, value, index);
-    }
-
-    /**
-     * Gets all but the last element of `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * _.initial([1, 2, 3]);
-     * // => [1, 2]
-     */
-    function initial(array) {
-      var length = array == null ? 0 : array.length;
-      return length ? baseSlice(array, 0, -1) : [];
-    }
-
-    /**
-     * Creates an array of unique values that are included in all given arrays
-     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * for equality comparisons. The order and references of result values are
-     * determined by the first array.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @returns {Array} Returns the new array of intersecting values.
-     * @example
-     *
-     * _.intersection([2, 1], [2, 3]);
-     * // => [2]
-     */
-    var intersection = baseRest(function(arrays) {
-      var mapped = arrayMap(arrays, castArrayLikeObject);
-      return (mapped.length && mapped[0] === arrays[0])
-        ? baseIntersection(mapped)
-        : [];
-    });
-
-    /**
-     * This method is like `_.intersection` except that it accepts `iteratee`
-     * which is invoked for each element of each `arrays` to generate the criterion
-     * by which they're compared. The order and references of result values are
-     * determined by the first array. The iteratee is invoked with one argument:
-     * (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {Array} Returns the new array of intersecting values.
-     * @example
-     *
-     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
-     * // => [2.1]
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
-     * // => [{ 'x': 1 }]
-     */
-    var intersectionBy = baseRest(function(arrays) {
-      var iteratee = last(arrays),
-          mapped = arrayMap(arrays, castArrayLikeObject);
-
-      if (iteratee === last(mapped)) {
-        iteratee = undefined;
-      } else {
-        mapped.pop();
-      }
-      return (mapped.length && mapped[0] === arrays[0])
-        ? baseIntersection(mapped, getIteratee(iteratee, 2))
-        : [];
-    });
-
-    /**
-     * This method is like `_.intersection` except that it accepts `comparator`
-     * which is invoked to compare elements of `arrays`. The order and references
-     * of result values are determined by the first array. The comparator is
-     * invoked with two arguments: (arrVal, othVal).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new array of intersecting values.
-     * @example
-     *
-     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
-     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
-     *
-     * _.intersectionWith(objects, others, _.isEqual);
-     * // => [{ 'x': 1, 'y': 2 }]
-     */
-    var intersectionWith = baseRest(function(arrays) {
-      var comparator = last(arrays),
-          mapped = arrayMap(arrays, castArrayLikeObject);
-
-      comparator = typeof comparator == 'function' ? comparator : undefined;
-      if (comparator) {
-        mapped.pop();
-      }
-      return (mapped.length && mapped[0] === arrays[0])
-        ? baseIntersection(mapped, undefined, comparator)
-        : [];
-    });
-
-    /**
-     * Converts all elements in `array` into a string separated by `separator`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to convert.
-     * @param {string} [separator=','] The element separator.
-     * @returns {string} Returns the joined string.
-     * @example
-     *
-     * _.join(['a', 'b', 'c'], '~');
-     * // => 'a~b~c'
-     */
-    function join(array, separator) {
-      return array == null ? '' : nativeJoin.call(array, separator);
-    }
-
-    /**
-     * Gets the last element of `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @returns {*} Returns the last element of `array`.
-     * @example
-     *
-     * _.last([1, 2, 3]);
-     * // => 3
-     */
-    function last(array) {
-      var length = array == null ? 0 : array.length;
-      return length ? array[length - 1] : undefined;
-    }
-
-    /**
-     * This method is like `_.indexOf` except that it iterates over elements of
-     * `array` from right to left.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {*} value The value to search for.
-     * @param {number} [fromIndex=array.length-1] The index to search from.
-     * @returns {number} Returns the index of the matched value, else `-1`.
-     * @example
-     *
-     * _.lastIndexOf([1, 2, 1, 2], 2);
-     * // => 3
-     *
-     * // Search from the `fromIndex`.
-     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
-     * // => 1
-     */
-    function lastIndexOf(array, value, fromIndex) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return -1;
-      }
-      var index = length;
-      if (fromIndex !== undefined) {
-        index = toInteger(fromIndex);
-        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
-      }
-      return value === value
-        ? strictLastIndexOf(array, value, index)
-        : baseFindIndex(array, baseIsNaN, index, true);
-    }
-
-    /**
-     * Gets the element at index `n` of `array`. If `n` is negative, the nth
-     * element from the end is returned.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.11.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {number} [n=0] The index of the element to return.
-     * @returns {*} Returns the nth element of `array`.
-     * @example
-     *
-     * var array = ['a', 'b', 'c', 'd'];
-     *
-     * _.nth(array, 1);
-     * // => 'b'
-     *
-     * _.nth(array, -2);
-     * // => 'c';
-     */
-    function nth(array, n) {
-      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
-    }
-
-    /**
-     * Removes all given values from `array` using
-     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * for equality comparisons.
-     *
-     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
-     * to remove elements from an array by predicate.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Array
-     * @param {Array} array The array to modify.
-     * @param {...*} [values] The values to remove.
-     * @returns {Array} Returns `array`.
-     * @example
-     *
-     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
-     *
-     * _.pull(array, 'a', 'c');
-     * console.log(array);
-     * // => ['b', 'b']
-     */
-    var pull = baseRest(pullAll);
-
-    /**
-     * This method is like `_.pull` except that it accepts an array of values to remove.
-     *
-     * **Note:** Unlike `_.difference`, this method mutates `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to modify.
-     * @param {Array} values The values to remove.
-     * @returns {Array} Returns `array`.
-     * @example
-     *
-     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
-     *
-     * _.pullAll(array, ['a', 'c']);
-     * console.log(array);
-     * // => ['b', 'b']
-     */
-    function pullAll(array, values) {
-      return (array && array.length && values && values.length)
-        ? basePullAll(array, values)
-        : array;
-    }
-
-    /**
-     * This method is like `_.pullAll` except that it accepts `iteratee` which is
-     * invoked for each element of `array` and `values` to generate the criterion
-     * by which they're compared. The iteratee is invoked with one argument: (value).
-     *
-     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to modify.
-     * @param {Array} values The values to remove.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {Array} Returns `array`.
-     * @example
-     *
-     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
-     *
-     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
-     * console.log(array);
-     * // => [{ 'x': 2 }]
-     */
-    function pullAllBy(array, values, iteratee) {
-      return (array && array.length && values && values.length)
-        ? basePullAll(array, values, getIteratee(iteratee, 2))
-        : array;
-    }
-
-    /**
-     * This method is like `_.pullAll` except that it accepts `comparator` which
-     * is invoked to compare elements of `array` to `values`. The comparator is
-     * invoked with two arguments: (arrVal, othVal).
-     *
-     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.6.0
-     * @category Array
-     * @param {Array} array The array to modify.
-     * @param {Array} values The values to remove.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns `array`.
-     * @example
-     *
-     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
-     *
-     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
-     * console.log(array);
-     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
-     */
-    function pullAllWith(array, values, comparator) {
-      return (array && array.length && values && values.length)
-        ? basePullAll(array, values, undefined, comparator)
-        : array;
-    }
-
-    /**
-     * Removes elements from `array` corresponding to `indexes` and returns an
-     * array of removed elements.
-     *
-     * **Note:** Unlike `_.at`, this method mutates `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to modify.
-     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
-     * @returns {Array} Returns the new array of removed elements.
-     * @example
-     *
-     * var array = ['a', 'b', 'c', 'd'];
-     * var pulled = _.pullAt(array, [1, 3]);
-     *
-     * console.log(array);
-     * // => ['a', 'c']
-     *
-     * console.log(pulled);
-     * // => ['b', 'd']
-     */
-    var pullAt = flatRest(function(array, indexes) {
-      var length = array == null ? 0 : array.length,
-          result = baseAt(array, indexes);
-
-      basePullAt(array, arrayMap(indexes, function(index) {
-        return isIndex(index, length) ? +index : index;
-      }).sort(compareAscending));
-
-      return result;
-    });
-
-    /**
-     * Removes all elements from `array` that `predicate` returns truthy for
-     * and returns an array of the removed elements. The predicate is invoked
-     * with three arguments: (value, index, array).
-     *
-     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
-     * to pull elements from an array by value.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Array
-     * @param {Array} array The array to modify.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the new array of removed elements.
-     * @example
-     *
-     * var array = [1, 2, 3, 4];
-     * var evens = _.remove(array, function(n) {
-     *   return n % 2 == 0;
-     * });
-     *
-     * console.log(array);
-     * // => [1, 3]
-     *
-     * console.log(evens);
-     * // => [2, 4]
-     */
-    function remove(array, predicate) {
-      var result = [];
-      if (!(array && array.length)) {
-        return result;
-      }
-      var index = -1,
-          indexes = [],
-          length = array.length;
-
-      predicate = getIteratee(predicate, 3);
-      while (++index < length) {
-        var value = array[index];
-        if (predicate(value, index, array)) {
-          result.push(value);
-          indexes.push(index);
-        }
-      }
-      basePullAt(array, indexes);
-      return result;
-    }
-
-    /**
-     * Reverses `array` so that the first element becomes the last, the second
-     * element becomes the second to last, and so on.
-     *
-     * **Note:** This method mutates `array` and is based on
-     * [`Array#reverse`](https://mdn.io/Array/reverse).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to modify.
-     * @returns {Array} Returns `array`.
-     * @example
-     *
-     * var array = [1, 2, 3];
-     *
-     * _.reverse(array);
-     * // => [3, 2, 1]
-     *
-     * console.log(array);
-     * // => [3, 2, 1]
-     */
-    function reverse(array) {
-      return array == null ? array : nativeReverse.call(array);
-    }
-
-    /**
-     * Creates a slice of `array` from `start` up to, but not including, `end`.
-     *
-     * **Note:** This method is used instead of
-     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
-     * returned.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to slice.
-     * @param {number} [start=0] The start position.
-     * @param {number} [end=array.length] The end position.
-     * @returns {Array} Returns the slice of `array`.
-     */
-    function slice(array, start, end) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return [];
-      }
-      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
-        start = 0;
-        end = length;
-      }
-      else {
-        start = start == null ? 0 : toInteger(start);
-        end = end === undefined ? length : toInteger(end);
-      }
-      return baseSlice(array, start, end);
-    }
-
-    /**
-     * Uses a binary search to determine the lowest index at which `value`
-     * should be inserted into `array` in order to maintain its sort order.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The sorted array to inspect.
-     * @param {*} value The value to evaluate.
-     * @returns {number} Returns the index at which `value` should be inserted
-     *  into `array`.
-     * @example
-     *
-     * _.sortedIndex([30, 50], 40);
-     * // => 1
-     */
-    function sortedIndex(array, value) {
-      return baseSortedIndex(array, value);
-    }
-
-    /**
-     * This method is like `_.sortedIndex` except that it accepts `iteratee`
-     * which is invoked for `value` and each element of `array` to compute their
-     * sort ranking. The iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The sorted array to inspect.
-     * @param {*} value The value to evaluate.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {number} Returns the index at which `value` should be inserted
-     *  into `array`.
-     * @example
-     *
-     * var objects = [{ 'x': 4 }, { 'x': 5 }];
-     *
-     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
-     * // => 0
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
-     * // => 0
-     */
-    function sortedIndexBy(array, value, iteratee) {
-      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
-    }
-
-    /**
-     * This method is like `_.indexOf` except that it performs a binary
-     * search on a sorted `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {*} value The value to search for.
-     * @returns {number} Returns the index of the matched value, else `-1`.
-     * @example
-     *
-     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
-     * // => 1
-     */
-    function sortedIndexOf(array, value) {
-      var length = array == null ? 0 : array.length;
-      if (length) {
-        var index = baseSortedIndex(array, value);
-        if (index < length && eq(array[index], value)) {
-          return index;
-        }
-      }
-      return -1;
-    }
-
-    /**
-     * This method is like `_.sortedIndex` except that it returns the highest
-     * index at which `value` should be inserted into `array` in order to
-     * maintain its sort order.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The sorted array to inspect.
-     * @param {*} value The value to evaluate.
-     * @returns {number} Returns the index at which `value` should be inserted
-     *  into `array`.
-     * @example
-     *
-     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
-     * // => 4
-     */
-    function sortedLastIndex(array, value) {
-      return baseSortedIndex(array, value, true);
-    }
-
-    /**
-     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
-     * which is invoked for `value` and each element of `array` to compute their
-     * sort ranking. The iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The sorted array to inspect.
-     * @param {*} value The value to evaluate.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {number} Returns the index at which `value` should be inserted
-     *  into `array`.
-     * @example
-     *
-     * var objects = [{ 'x': 4 }, { 'x': 5 }];
-     *
-     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
-     * // => 1
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
-     * // => 1
-     */
-    function sortedLastIndexBy(array, value, iteratee) {
-      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
-    }
-
-    /**
-     * This method is like `_.lastIndexOf` except that it performs a binary
-     * search on a sorted `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {*} value The value to search for.
-     * @returns {number} Returns the index of the matched value, else `-1`.
-     * @example
-     *
-     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
-     * // => 3
-     */
-    function sortedLastIndexOf(array, value) {
-      var length = array == null ? 0 : array.length;
-      if (length) {
-        var index = baseSortedIndex(array, value, true) - 1;
-        if (eq(array[index], value)) {
-          return index;
-        }
-      }
-      return -1;
-    }
-
-    /**
-     * This method is like `_.uniq` except that it's designed and optimized
-     * for sorted arrays.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @returns {Array} Returns the new duplicate free array.
-     * @example
-     *
-     * _.sortedUniq([1, 1, 2]);
-     * // => [1, 2]
-     */
-    function sortedUniq(array) {
-      return (array && array.length)
-        ? baseSortedUniq(array)
-        : [];
-    }
-
-    /**
-     * This method is like `_.uniqBy` except that it's designed and optimized
-     * for sorted arrays.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {Function} [iteratee] The iteratee invoked per element.
-     * @returns {Array} Returns the new duplicate free array.
-     * @example
-     *
-     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
-     * // => [1.1, 2.3]
-     */
-    function sortedUniqBy(array, iteratee) {
-      return (array && array.length)
-        ? baseSortedUniq(array, getIteratee(iteratee, 2))
-        : [];
-    }
-
-    /**
-     * Gets all but the first element of `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * _.tail([1, 2, 3]);
-     * // => [2, 3]
-     */
-    function tail(array) {
-      var length = array == null ? 0 : array.length;
-      return length ? baseSlice(array, 1, length) : [];
-    }
-
-    /**
-     * Creates a slice of `array` with `n` elements taken from the beginning.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {number} [n=1] The number of elements to take.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * _.take([1, 2, 3]);
-     * // => [1]
-     *
-     * _.take([1, 2, 3], 2);
-     * // => [1, 2]
-     *
-     * _.take([1, 2, 3], 5);
-     * // => [1, 2, 3]
-     *
-     * _.take([1, 2, 3], 0);
-     * // => []
-     */
-    function take(array, n, guard) {
-      if (!(array && array.length)) {
-        return [];
-      }
-      n = (guard || n === undefined) ? 1 : toInteger(n);
-      return baseSlice(array, 0, n < 0 ? 0 : n);
-    }
-
-    /**
-     * Creates a slice of `array` with `n` elements taken from the end.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {number} [n=1] The number of elements to take.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * _.takeRight([1, 2, 3]);
-     * // => [3]
-     *
-     * _.takeRight([1, 2, 3], 2);
-     * // => [2, 3]
-     *
-     * _.takeRight([1, 2, 3], 5);
-     * // => [1, 2, 3]
-     *
-     * _.takeRight([1, 2, 3], 0);
-     * // => []
-     */
-    function takeRight(array, n, guard) {
-      var length = array == null ? 0 : array.length;
-      if (!length) {
-        return [];
-      }
-      n = (guard || n === undefined) ? 1 : toInteger(n);
-      n = length - n;
-      return baseSlice(array, n < 0 ? 0 : n, length);
-    }
-
-    /**
-     * Creates a slice of `array` with elements taken from the end. Elements are
-     * taken until `predicate` returns falsey. The predicate is invoked with
-     * three arguments: (value, index, array).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'active': true },
-     *   { 'user': 'fred',    'active': false },
-     *   { 'user': 'pebbles', 'active': false }
-     * ];
-     *
-     * _.takeRightWhile(users, function(o) { return !o.active; });
-     * // => objects for ['fred', 'pebbles']
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
-     * // => objects for ['pebbles']
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.takeRightWhile(users, ['active', false]);
-     * // => objects for ['fred', 'pebbles']
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.takeRightWhile(users, 'active');
-     * // => []
-     */
-    function takeRightWhile(array, predicate) {
-      return (array && array.length)
-        ? baseWhile(array, getIteratee(predicate, 3), false, true)
-        : [];
-    }
-
-    /**
-     * Creates a slice of `array` with elements taken from the beginning. Elements
-     * are taken until `predicate` returns falsey. The predicate is invoked with
-     * three arguments: (value, index, array).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Array
-     * @param {Array} array The array to query.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the slice of `array`.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'active': false },
-     *   { 'user': 'fred',    'active': false },
-     *   { 'user': 'pebbles', 'active': true }
-     * ];
-     *
-     * _.takeWhile(users, function(o) { return !o.active; });
-     * // => objects for ['barney', 'fred']
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.takeWhile(users, { 'user': 'barney', 'active': false });
-     * // => objects for ['barney']
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.takeWhile(users, ['active', false]);
-     * // => objects for ['barney', 'fred']
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.takeWhile(users, 'active');
-     * // => []
-     */
-    function takeWhile(array, predicate) {
-      return (array && array.length)
-        ? baseWhile(array, getIteratee(predicate, 3))
-        : [];
-    }
-
-    /**
-     * Creates an array of unique values, in order, from all given arrays using
-     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * for equality comparisons.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @returns {Array} Returns the new array of combined values.
-     * @example
-     *
-     * _.union([2], [1, 2]);
-     * // => [2, 1]
-     */
-    var union = baseRest(function(arrays) {
-      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
-    });
-
-    /**
-     * This method is like `_.union` except that it accepts `iteratee` which is
-     * invoked for each element of each `arrays` to generate the criterion by
-     * which uniqueness is computed. Result values are chosen from the first
-     * array in which the value occurs. The iteratee is invoked with one argument:
-     * (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {Array} Returns the new array of combined values.
-     * @example
-     *
-     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
-     * // => [2.1, 1.2]
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
-     * // => [{ 'x': 1 }, { 'x': 2 }]
-     */
-    var unionBy = baseRest(function(arrays) {
-      var iteratee = last(arrays);
-      if (isArrayLikeObject(iteratee)) {
-        iteratee = undefined;
-      }
-      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
-    });
-
-    /**
-     * This method is like `_.union` except that it accepts `comparator` which
-     * is invoked to compare elements of `arrays`. Result values are chosen from
-     * the first array in which the value occurs. The comparator is invoked
-     * with two arguments: (arrVal, othVal).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new array of combined values.
-     * @example
-     *
-     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
-     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
-     *
-     * _.unionWith(objects, others, _.isEqual);
-     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
-     */
-    var unionWith = baseRest(function(arrays) {
-      var comparator = last(arrays);
-      comparator = typeof comparator == 'function' ? comparator : undefined;
-      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
-    });
-
-    /**
-     * Creates a duplicate-free version of an array, using
-     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * for equality comparisons, in which only the first occurrence of each element
-     * is kept. The order of result values is determined by the order they occur
-     * in the array.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @returns {Array} Returns the new duplicate free array.
-     * @example
-     *
-     * _.uniq([2, 1, 2]);
-     * // => [2, 1]
-     */
-    function uniq(array) {
-      return (array && array.length) ? baseUniq(array) : [];
-    }
-
-    /**
-     * This method is like `_.uniq` except that it accepts `iteratee` which is
-     * invoked for each element in `array` to generate the criterion by which
-     * uniqueness is computed. The order of result values is determined by the
-     * order they occur in the array. The iteratee is invoked with one argument:
-     * (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {Array} Returns the new duplicate free array.
-     * @example
-     *
-     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
-     * // => [2.1, 1.2]
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
-     * // => [{ 'x': 1 }, { 'x': 2 }]
-     */
-    function uniqBy(array, iteratee) {
-      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
-    }
-
-    /**
-     * This method is like `_.uniq` except that it accepts `comparator` which
-     * is invoked to compare elements of `array`. The order of result values is
-     * determined by the order they occur in the array.The comparator is invoked
-     * with two arguments: (arrVal, othVal).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new duplicate free array.
-     * @example
-     *
-     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
-     *
-     * _.uniqWith(objects, _.isEqual);
-     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
-     */
-    function uniqWith(array, comparator) {
-      comparator = typeof comparator == 'function' ? comparator : undefined;
-      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
-    }
-
-    /**
-     * This method is like `_.zip` except that it accepts an array of grouped
-     * elements and creates an array regrouping the elements to their pre-zip
-     * configuration.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.2.0
-     * @category Array
-     * @param {Array} array The array of grouped elements to process.
-     * @returns {Array} Returns the new array of regrouped elements.
-     * @example
-     *
-     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
-     * // => [['a', 1, true], ['b', 2, false]]
-     *
-     * _.unzip(zipped);
-     * // => [['a', 'b'], [1, 2], [true, false]]
-     */
-    function unzip(array) {
-      if (!(array && array.length)) {
-        return [];
-      }
-      var length = 0;
-      array = arrayFilter(array, function(group) {
-        if (isArrayLikeObject(group)) {
-          length = nativeMax(group.length, length);
-          return true;
-        }
-      });
-      return baseTimes(length, function(index) {
-        return arrayMap(array, baseProperty(index));
-      });
-    }
-
-    /**
-     * This method is like `_.unzip` except that it accepts `iteratee` to specify
-     * how regrouped values should be combined. The iteratee is invoked with the
-     * elements of each group: (...group).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.8.0
-     * @category Array
-     * @param {Array} array The array of grouped elements to process.
-     * @param {Function} [iteratee=_.identity] The function to combine
-     *  regrouped values.
-     * @returns {Array} Returns the new array of regrouped elements.
-     * @example
-     *
-     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
-     * // => [[1, 10, 100], [2, 20, 200]]
-     *
-     * _.unzipWith(zipped, _.add);
-     * // => [3, 30, 300]
-     */
-    function unzipWith(array, iteratee) {
-      if (!(array && array.length)) {
-        return [];
-      }
-      var result = unzip(array);
-      if (iteratee == null) {
-        return result;
-      }
-      return arrayMap(result, function(group) {
-        return apply(iteratee, undefined, group);
-      });
-    }
-
-    /**
-     * Creates an array excluding all given values using
-     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * for equality comparisons.
-     *
-     * **Note:** Unlike `_.pull`, this method returns a new array.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {Array} array The array to inspect.
-     * @param {...*} [values] The values to exclude.
-     * @returns {Array} Returns the new array of filtered values.
-     * @see _.difference, _.xor
-     * @example
-     *
-     * _.without([2, 1, 2, 3], 1, 2);
-     * // => [3]
-     */
-    var without = baseRest(function(array, values) {
-      return isArrayLikeObject(array)
-        ? baseDifference(array, values)
-        : [];
-    });
-
-    /**
-     * Creates an array of unique values that is the
-     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
-     * of the given arrays. The order of result values is determined by the order
-     * they occur in the arrays.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.4.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @returns {Array} Returns the new array of filtered values.
-     * @see _.difference, _.without
-     * @example
-     *
-     * _.xor([2, 1], [2, 3]);
-     * // => [1, 3]
-     */
-    var xor = baseRest(function(arrays) {
-      return baseXor(arrayFilter(arrays, isArrayLikeObject));
-    });
-
-    /**
-     * This method is like `_.xor` except that it accepts `iteratee` which is
-     * invoked for each element of each `arrays` to generate the criterion by
-     * which by which they're compared. The order of result values is determined
-     * by the order they occur in the arrays. The iteratee is invoked with one
-     * argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {Array} Returns the new array of filtered values.
-     * @example
-     *
-     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
-     * // => [1.2, 3.4]
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
-     * // => [{ 'x': 2 }]
-     */
-    var xorBy = baseRest(function(arrays) {
-      var iteratee = last(arrays);
-      if (isArrayLikeObject(iteratee)) {
-        iteratee = undefined;
-      }
-      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
-    });
-
-    /**
-     * This method is like `_.xor` except that it accepts `comparator` which is
-     * invoked to compare elements of `arrays`. The order of result values is
-     * determined by the order they occur in the arrays. The comparator is invoked
-     * with two arguments: (arrVal, othVal).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to inspect.
-     * @param {Function} [comparator] The comparator invoked per element.
-     * @returns {Array} Returns the new array of filtered values.
-     * @example
-     *
-     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
-     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
-     *
-     * _.xorWith(objects, others, _.isEqual);
-     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
-     */
-    var xorWith = baseRest(function(arrays) {
-      var comparator = last(arrays);
-      comparator = typeof comparator == 'function' ? comparator : undefined;
-      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
-    });
-
-    /**
-     * Creates an array of grouped elements, the first of which contains the
-     * first elements of the given arrays, the second of which contains the
-     * second elements of the given arrays, and so on.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to process.
-     * @returns {Array} Returns the new array of grouped elements.
-     * @example
-     *
-     * _.zip(['a', 'b'], [1, 2], [true, false]);
-     * // => [['a', 1, true], ['b', 2, false]]
-     */
-    var zip = baseRest(unzip);
-
-    /**
-     * This method is like `_.fromPairs` except that it accepts two arrays,
-     * one of property identifiers and one of corresponding values.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.4.0
-     * @category Array
-     * @param {Array} [props=[]] The property identifiers.
-     * @param {Array} [values=[]] The property values.
-     * @returns {Object} Returns the new object.
-     * @example
-     *
-     * _.zipObject(['a', 'b'], [1, 2]);
-     * // => { 'a': 1, 'b': 2 }
-     */
-    function zipObject(props, values) {
-      return baseZipObject(props || [], values || [], assignValue);
-    }
-
-    /**
-     * This method is like `_.zipObject` except that it supports property paths.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.1.0
-     * @category Array
-     * @param {Array} [props=[]] The property identifiers.
-     * @param {Array} [values=[]] The property values.
-     * @returns {Object} Returns the new object.
-     * @example
-     *
-     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
-     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
-     */
-    function zipObjectDeep(props, values) {
-      return baseZipObject(props || [], values || [], baseSet);
-    }
-
-    /**
-     * This method is like `_.zip` except that it accepts `iteratee` to specify
-     * how grouped values should be combined. The iteratee is invoked with the
-     * elements of each group: (...group).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.8.0
-     * @category Array
-     * @param {...Array} [arrays] The arrays to process.
-     * @param {Function} [iteratee=_.identity] The function to combine
-     *  grouped values.
-     * @returns {Array} Returns the new array of grouped elements.
-     * @example
-     *
-     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
-     *   return a + b + c;
-     * });
-     * // => [111, 222]
-     */
-    var zipWith = baseRest(function(arrays) {
-      var length = arrays.length,
-          iteratee = length > 1 ? arrays[length - 1] : undefined;
-
-      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
-      return unzipWith(arrays, iteratee);
-    });
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
-     * chain sequences enabled. The result of such sequences must be unwrapped
-     * with `_#value`.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.3.0
-     * @category Seq
-     * @param {*} value The value to wrap.
-     * @returns {Object} Returns the new `lodash` wrapper instance.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'age': 36 },
-     *   { 'user': 'fred',    'age': 40 },
-     *   { 'user': 'pebbles', 'age': 1 }
-     * ];
-     *
-     * var youngest = _
-     *   .chain(users)
-     *   .sortBy('age')
-     *   .map(function(o) {
-     *     return o.user + ' is ' + o.age;
-     *   })
-     *   .head()
-     *   .value();
-     * // => 'pebbles is 1'
-     */
-    function chain(value) {
-      var result = lodash(value);
-      result.__chain__ = true;
-      return result;
-    }
-
-    /**
-     * This method invokes `interceptor` and returns `value`. The interceptor
-     * is invoked with one argument; (value). The purpose of this method is to
-     * "tap into" a method chain sequence in order to modify intermediate results.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Seq
-     * @param {*} value The value to provide to `interceptor`.
-     * @param {Function} interceptor The function to invoke.
-     * @returns {*} Returns `value`.
-     * @example
-     *
-     * _([1, 2, 3])
-     *  .tap(function(array) {
-     *    // Mutate input array.
-     *    array.pop();
-     *  })
-     *  .reverse()
-     *  .value();
-     * // => [2, 1]
-     */
-    function tap(value, interceptor) {
-      interceptor(value);
-      return value;
-    }
-
-    /**
-     * This method is like `_.tap` except that it returns the result of `interceptor`.
-     * The purpose of this method is to "pass thru" values replacing intermediate
-     * results in a method chain sequence.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Seq
-     * @param {*} value The value to provide to `interceptor`.
-     * @param {Function} interceptor The function to invoke.
-     * @returns {*} Returns the result of `interceptor`.
-     * @example
-     *
-     * _('  abc  ')
-     *  .chain()
-     *  .trim()
-     *  .thru(function(value) {
-     *    return [value];
-     *  })
-     *  .value();
-     * // => ['abc']
-     */
-    function thru(value, interceptor) {
-      return interceptor(value);
-    }
-
-    /**
-     * This method is the wrapper version of `_.at`.
-     *
-     * @name at
-     * @memberOf _
-     * @since 1.0.0
-     * @category Seq
-     * @param {...(string|string[])} [paths] The property paths to pick.
-     * @returns {Object} Returns the new `lodash` wrapper instance.
-     * @example
-     *
-     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
-     *
-     * _(object).at(['a[0].b.c', 'a[1]']).value();
-     * // => [3, 4]
-     */
-    var wrapperAt = flatRest(function(paths) {
-      var length = paths.length,
-          start = length ? paths[0] : 0,
-          value = this.__wrapped__,
-          interceptor = function(object) { return baseAt(object, paths); };
-
-      if (length > 1 || this.__actions__.length ||
-          !(value instanceof LazyWrapper) || !isIndex(start)) {
-        return this.thru(interceptor);
-      }
-      value = value.slice(start, +start + (length ? 1 : 0));
-      value.__actions__.push({
-        'func': thru,
-        'args': [interceptor],
-        'thisArg': undefined
-      });
-      return new LodashWrapper(value, this.__chain__).thru(function(array) {
-        if (length && !array.length) {
-          array.push(undefined);
-        }
-        return array;
-      });
-    });
-
-    /**
-     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
-     *
-     * @name chain
-     * @memberOf _
-     * @since 0.1.0
-     * @category Seq
-     * @returns {Object} Returns the new `lodash` wrapper instance.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney', 'age': 36 },
-     *   { 'user': 'fred',   'age': 40 }
-     * ];
-     *
-     * // A sequence without explicit chaining.
-     * _(users).head();
-     * // => { 'user': 'barney', 'age': 36 }
-     *
-     * // A sequence with explicit chaining.
-     * _(users)
-     *   .chain()
-     *   .head()
-     *   .pick('user')
-     *   .value();
-     * // => { 'user': 'barney' }
-     */
-    function wrapperChain() {
-      return chain(this);
-    }
-
-    /**
-     * Executes the chain sequence and returns the wrapped result.
-     *
-     * @name commit
-     * @memberOf _
-     * @since 3.2.0
-     * @category Seq
-     * @returns {Object} Returns the new `lodash` wrapper instance.
-     * @example
-     *
-     * var array = [1, 2];
-     * var wrapped = _(array).push(3);
-     *
-     * console.log(array);
-     * // => [1, 2]
-     *
-     * wrapped = wrapped.commit();
-     * console.log(array);
-     * // => [1, 2, 3]
-     *
-     * wrapped.last();
-     * // => 3
-     *
-     * console.log(array);
-     * // => [1, 2, 3]
-     */
-    function wrapperCommit() {
-      return new LodashWrapper(this.value(), this.__chain__);
-    }
-
-    /**
-     * Gets the next value on a wrapped object following the
-     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
-     *
-     * @name next
-     * @memberOf _
-     * @since 4.0.0
-     * @category Seq
-     * @returns {Object} Returns the next iterator value.
-     * @example
-     *
-     * var wrapped = _([1, 2]);
-     *
-     * wrapped.next();
-     * // => { 'done': false, 'value': 1 }
-     *
-     * wrapped.next();
-     * // => { 'done': false, 'value': 2 }
-     *
-     * wrapped.next();
-     * // => { 'done': true, 'value': undefined }
-     */
-    function wrapperNext() {
-      if (this.__values__ === undefined) {
-        this.__values__ = toArray(this.value());
-      }
-      var done = this.__index__ >= this.__values__.length,
-          value = done ? undefined : this.__values__[this.__index__++];
-
-      return { 'done': done, 'value': value };
-    }
-
-    /**
-     * Enables the wrapper to be iterable.
-     *
-     * @name Symbol.iterator
-     * @memberOf _
-     * @since 4.0.0
-     * @category Seq
-     * @returns {Object} Returns the wrapper object.
-     * @example
-     *
-     * var wrapped = _([1, 2]);
-     *
-     * wrapped[Symbol.iterator]() === wrapped;
-     * // => true
-     *
-     * Array.from(wrapped);
-     * // => [1, 2]
-     */
-    function wrapperToIterator() {
-      return this;
-    }
-
-    /**
-     * Creates a clone of the chain sequence planting `value` as the wrapped value.
-     *
-     * @name plant
-     * @memberOf _
-     * @since 3.2.0
-     * @category Seq
-     * @param {*} value The value to plant.
-     * @returns {Object} Returns the new `lodash` wrapper instance.
-     * @example
-     *
-     * function square(n) {
-     *   return n * n;
-     * }
-     *
-     * var wrapped = _([1, 2]).map(square);
-     * var other = wrapped.plant([3, 4]);
-     *
-     * other.value();
-     * // => [9, 16]
-     *
-     * wrapped.value();
-     * // => [1, 4]
-     */
-    function wrapperPlant(value) {
-      var result,
-          parent = this;
-
-      while (parent instanceof baseLodash) {
-        var clone = wrapperClone(parent);
-        clone.__index__ = 0;
-        clone.__values__ = undefined;
-        if (result) {
-          previous.__wrapped__ = clone;
-        } else {
-          result = clone;
-        }
-        var previous = clone;
-        parent = parent.__wrapped__;
-      }
-      previous.__wrapped__ = value;
-      return result;
-    }
-
-    /**
-     * This method is the wrapper version of `_.reverse`.
-     *
-     * **Note:** This method mutates the wrapped array.
-     *
-     * @name reverse
-     * @memberOf _
-     * @since 0.1.0
-     * @category Seq
-     * @returns {Object} Returns the new `lodash` wrapper instance.
-     * @example
-     *
-     * var array = [1, 2, 3];
-     *
-     * _(array).reverse().value()
-     * // => [3, 2, 1]
-     *
-     * console.log(array);
-     * // => [3, 2, 1]
-     */
-    function wrapperReverse() {
-      var value = this.__wrapped__;
-      if (value instanceof LazyWrapper) {
-        var wrapped = value;
-        if (this.__actions__.length) {
-          wrapped = new LazyWrapper(this);
-        }
-        wrapped = wrapped.reverse();
-        wrapped.__actions__.push({
-          'func': thru,
-          'args': [reverse],
-          'thisArg': undefined
-        });
-        return new LodashWrapper(wrapped, this.__chain__);
-      }
-      return this.thru(reverse);
-    }
-
-    /**
-     * Executes the chain sequence to resolve the unwrapped value.
-     *
-     * @name value
-     * @memberOf _
-     * @since 0.1.0
-     * @alias toJSON, valueOf
-     * @category Seq
-     * @returns {*} Returns the resolved unwrapped value.
-     * @example
-     *
-     * _([1, 2, 3]).value();
-     * // => [1, 2, 3]
-     */
-    function wrapperValue() {
-      return baseWrapperValue(this.__wrapped__, this.__actions__);
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Creates an object composed of keys generated from the results of running
-     * each element of `collection` thru `iteratee`. The corresponding value of
-     * each key is the number of times the key was returned by `iteratee`. The
-     * iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.5.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
-     * @returns {Object} Returns the composed aggregate object.
-     * @example
-     *
-     * _.countBy([6.1, 4.2, 6.3], Math.floor);
-     * // => { '4': 1, '6': 2 }
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.countBy(['one', 'two', 'three'], 'length');
-     * // => { '3': 2, '5': 1 }
-     */
-    var countBy = createAggregator(function(result, value, key) {
-      if (hasOwnProperty.call(result, key)) {
-        ++result[key];
-      } else {
-        baseAssignValue(result, key, 1);
-      }
-    });
-
-    /**
-     * Checks if `predicate` returns truthy for **all** elements of `collection`.
-     * Iteration is stopped once `predicate` returns falsey. The predicate is
-     * invoked with three arguments: (value, index|key, collection).
-     *
-     * **Note:** This method returns `true` for
-     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
-     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
-     * elements of empty collections.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {boolean} Returns `true` if all elements pass the predicate check,
-     *  else `false`.
-     * @example
-     *
-     * _.every([true, 1, null, 'yes'], Boolean);
-     * // => false
-     *
-     * var users = [
-     *   { 'user': 'barney', 'age': 36, 'active': false },
-     *   { 'user': 'fred',   'age': 40, 'active': false }
-     * ];
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.every(users, { 'user': 'barney', 'active': false });
-     * // => false
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.every(users, ['active', false]);
-     * // => true
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.every(users, 'active');
-     * // => false
-     */
-    function every(collection, predicate, guard) {
-      var func = isArray(collection) ? arrayEvery : baseEvery;
-      if (guard && isIterateeCall(collection, predicate, guard)) {
-        predicate = undefined;
-      }
-      return func(collection, getIteratee(predicate, 3));
-    }
-
-    /**
-     * Iterates over elements of `collection`, returning an array of all elements
-     * `predicate` returns truthy for. The predicate is invoked with three
-     * arguments: (value, index|key, collection).
-     *
-     * **Note:** Unlike `_.remove`, this method returns a new array.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the new filtered array.
-     * @see _.reject
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney', 'age': 36, 'active': true },
-     *   { 'user': 'fred',   'age': 40, 'active': false }
-     * ];
-     *
-     * _.filter(users, function(o) { return !o.active; });
-     * // => objects for ['fred']
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.filter(users, { 'age': 36, 'active': true });
-     * // => objects for ['barney']
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.filter(users, ['active', false]);
-     * // => objects for ['fred']
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.filter(users, 'active');
-     * // => objects for ['barney']
-     */
-    function filter(collection, predicate) {
-      var func = isArray(collection) ? arrayFilter : baseFilter;
-      return func(collection, getIteratee(predicate, 3));
-    }
-
-    /**
-     * Iterates over elements of `collection`, returning the first element
-     * `predicate` returns truthy for. The predicate is invoked with three
-     * arguments: (value, index|key, collection).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to inspect.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @param {number} [fromIndex=0] The index to search from.
-     * @returns {*} Returns the matched element, else `undefined`.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'age': 36, 'active': true },
-     *   { 'user': 'fred',    'age': 40, 'active': false },
-     *   { 'user': 'pebbles', 'age': 1,  'active': true }
-     * ];
-     *
-     * _.find(users, function(o) { return o.age < 40; });
-     * // => object for 'barney'
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.find(users, { 'age': 1, 'active': true });
-     * // => object for 'pebbles'
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.find(users, ['active', false]);
-     * // => object for 'fred'
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.find(users, 'active');
-     * // => object for 'barney'
-     */
-    var find = createFind(findIndex);
-
-    /**
-     * This method is like `_.find` except that it iterates over elements of
-     * `collection` from right to left.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to inspect.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @param {number} [fromIndex=collection.length-1] The index to search from.
-     * @returns {*} Returns the matched element, else `undefined`.
-     * @example
-     *
-     * _.findLast([1, 2, 3, 4], function(n) {
-     *   return n % 2 == 1;
-     * });
-     * // => 3
-     */
-    var findLast = createFind(findLastIndex);
-
-    /**
-     * Creates a flattened array of values by running each element in `collection`
-     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
-     * with three arguments: (value, index|key, collection).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the new flattened array.
-     * @example
-     *
-     * function duplicate(n) {
-     *   return [n, n];
-     * }
-     *
-     * _.flatMap([1, 2], duplicate);
-     * // => [1, 1, 2, 2]
-     */
-    function flatMap(collection, iteratee) {
-      return baseFlatten(map(collection, iteratee), 1);
-    }
-
-    /**
-     * This method is like `_.flatMap` except that it recursively flattens the
-     * mapped results.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.7.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the new flattened array.
-     * @example
-     *
-     * function duplicate(n) {
-     *   return [[[n, n]]];
-     * }
-     *
-     * _.flatMapDeep([1, 2], duplicate);
-     * // => [1, 1, 2, 2]
-     */
-    function flatMapDeep(collection, iteratee) {
-      return baseFlatten(map(collection, iteratee), INFINITY);
-    }
-
-    /**
-     * This method is like `_.flatMap` except that it recursively flattens the
-     * mapped results up to `depth` times.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.7.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @param {number} [depth=1] The maximum recursion depth.
-     * @returns {Array} Returns the new flattened array.
-     * @example
-     *
-     * function duplicate(n) {
-     *   return [[[n, n]]];
-     * }
-     *
-     * _.flatMapDepth([1, 2], duplicate, 2);
-     * // => [[1, 1], [2, 2]]
-     */
-    function flatMapDepth(collection, iteratee, depth) {
-      depth = depth === undefined ? 1 : toInteger(depth);
-      return baseFlatten(map(collection, iteratee), depth);
-    }
-
-    /**
-     * Iterates over elements of `collection` and invokes `iteratee` for each element.
-     * The iteratee is invoked with three arguments: (value, index|key, collection).
-     * Iteratee functions may exit iteration early by explicitly returning `false`.
-     *
-     * **Note:** As with other "Collections" methods, objects with a "length"
-     * property are iterated like arrays. To avoid this behavior use `_.forIn`
-     * or `_.forOwn` for object iteration.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @alias each
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Array|Object} Returns `collection`.
-     * @see _.forEachRight
-     * @example
-     *
-     * _.forEach([1, 2], function(value) {
-     *   console.log(value);
-     * });
-     * // => Logs `1` then `2`.
-     *
-     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
-     *   console.log(key);
-     * });
-     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
-     */
-    function forEach(collection, iteratee) {
-      var func = isArray(collection) ? arrayEach : baseEach;
-      return func(collection, getIteratee(iteratee, 3));
-    }
-
-    /**
-     * This method is like `_.forEach` except that it iterates over elements of
-     * `collection` from right to left.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @alias eachRight
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Array|Object} Returns `collection`.
-     * @see _.forEach
-     * @example
-     *
-     * _.forEachRight([1, 2], function(value) {
-     *   console.log(value);
-     * });
-     * // => Logs `2` then `1`.
-     */
-    function forEachRight(collection, iteratee) {
-      var func = isArray(collection) ? arrayEachRight : baseEachRight;
-      return func(collection, getIteratee(iteratee, 3));
-    }
-
-    /**
-     * Creates an object composed of keys generated from the results of running
-     * each element of `collection` thru `iteratee`. The order of grouped values
-     * is determined by the order they occur in `collection`. The corresponding
-     * value of each key is an array of elements responsible for generating the
-     * key. The iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
-     * @returns {Object} Returns the composed aggregate object.
-     * @example
-     *
-     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
-     * // => { '4': [4.2], '6': [6.1, 6.3] }
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.groupBy(['one', 'two', 'three'], 'length');
-     * // => { '3': ['one', 'two'], '5': ['three'] }
-     */
-    var groupBy = createAggregator(function(result, value, key) {
-      if (hasOwnProperty.call(result, key)) {
-        result[key].push(value);
-      } else {
-        baseAssignValue(result, key, [value]);
-      }
-    });
-
-    /**
-     * Checks if `value` is in `collection`. If `collection` is a string, it's
-     * checked for a substring of `value`, otherwise
-     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * is used for equality comparisons. If `fromIndex` is negative, it's used as
-     * the offset from the end of `collection`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object|string} collection The collection to inspect.
-     * @param {*} value The value to search for.
-     * @param {number} [fromIndex=0] The index to search from.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
-     * @returns {boolean} Returns `true` if `value` is found, else `false`.
-     * @example
-     *
-     * _.includes([1, 2, 3], 1);
-     * // => true
-     *
-     * _.includes([1, 2, 3], 1, 2);
-     * // => false
-     *
-     * _.includes({ 'a': 1, 'b': 2 }, 1);
-     * // => true
-     *
-     * _.includes('abcd', 'bc');
-     * // => true
-     */
-    function includes(collection, value, fromIndex, guard) {
-      collection = isArrayLike(collection) ? collection : values(collection);
-      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
-
-      var length = collection.length;
-      if (fromIndex < 0) {
-        fromIndex = nativeMax(length + fromIndex, 0);
-      }
-      return isString(collection)
-        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
-        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
-    }
-
-    /**
-     * Invokes the method at `path` of each element in `collection`, returning
-     * an array of the results of each invoked method. Any additional arguments
-     * are provided to each invoked method. If `path` is a function, it's invoked
-     * for, and `this` bound to, each element in `collection`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Array|Function|string} path The path of the method to invoke or
-     *  the function invoked per iteration.
-     * @param {...*} [args] The arguments to invoke each method with.
-     * @returns {Array} Returns the array of results.
-     * @example
-     *
-     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
-     * // => [[1, 5, 7], [1, 2, 3]]
-     *
-     * _.invokeMap([123, 456], String.prototype.split, '');
-     * // => [['1', '2', '3'], ['4', '5', '6']]
-     */
-    var invokeMap = baseRest(function(collection, path, args) {
-      var index = -1,
-          isFunc = typeof path == 'function',
-          result = isArrayLike(collection) ? Array(collection.length) : [];
-
-      baseEach(collection, function(value) {
-        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
-      });
-      return result;
-    });
-
-    /**
-     * Creates an object composed of keys generated from the results of running
-     * each element of `collection` thru `iteratee`. The corresponding value of
-     * each key is the last element responsible for generating the key. The
-     * iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
-     * @returns {Object} Returns the composed aggregate object.
-     * @example
-     *
-     * var array = [
-     *   { 'dir': 'left', 'code': 97 },
-     *   { 'dir': 'right', 'code': 100 }
-     * ];
-     *
-     * _.keyBy(array, function(o) {
-     *   return String.fromCharCode(o.code);
-     * });
-     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
-     *
-     * _.keyBy(array, 'dir');
-     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
-     */
-    var keyBy = createAggregator(function(result, value, key) {
-      baseAssignValue(result, key, value);
-    });
-
-    /**
-     * Creates an array of values by running each element in `collection` thru
-     * `iteratee`. The iteratee is invoked with three arguments:
-     * (value, index|key, collection).
-     *
-     * Many lodash methods are guarded to work as iteratees for methods like
-     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
-     *
-     * The guarded methods are:
-     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
-     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
-     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
-     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the new mapped array.
-     * @example
-     *
-     * function square(n) {
-     *   return n * n;
-     * }
-     *
-     * _.map([4, 8], square);
-     * // => [16, 64]
-     *
-     * _.map({ 'a': 4, 'b': 8 }, square);
-     * // => [16, 64] (iteration order is not guaranteed)
-     *
-     * var users = [
-     *   { 'user': 'barney' },
-     *   { 'user': 'fred' }
-     * ];
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.map(users, 'user');
-     * // => ['barney', 'fred']
-     */
-    function map(collection, iteratee) {
-      var func = isArray(collection) ? arrayMap : baseMap;
-      return func(collection, getIteratee(iteratee, 3));
-    }
-
-    /**
-     * This method is like `_.sortBy` except that it allows specifying the sort
-     * orders of the iteratees to sort by. If `orders` is unspecified, all values
-     * are sorted in ascending order. Otherwise, specify an order of "desc" for
-     * descending or "asc" for ascending sort order of corresponding values.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
-     *  The iteratees to sort by.
-     * @param {string[]} [orders] The sort orders of `iteratees`.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
-     * @returns {Array} Returns the new sorted array.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'fred',   'age': 48 },
-     *   { 'user': 'barney', 'age': 34 },
-     *   { 'user': 'fred',   'age': 40 },
-     *   { 'user': 'barney', 'age': 36 }
-     * ];
-     *
-     * // Sort by `user` in ascending order and by `age` in descending order.
-     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
-     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
-     */
-    function orderBy(collection, iteratees, orders, guard) {
-      if (collection == null) {
-        return [];
-      }
-      if (!isArray(iteratees)) {
-        iteratees = iteratees == null ? [] : [iteratees];
-      }
-      orders = guard ? undefined : orders;
-      if (!isArray(orders)) {
-        orders = orders == null ? [] : [orders];
-      }
-      return baseOrderBy(collection, iteratees, orders);
-    }
-
-    /**
-     * Creates an array of elements split into two groups, the first of which
-     * contains elements `predicate` returns truthy for, the second of which
-     * contains elements `predicate` returns falsey for. The predicate is
-     * invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the array of grouped elements.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney',  'age': 36, 'active': false },
-     *   { 'user': 'fred',    'age': 40, 'active': true },
-     *   { 'user': 'pebbles', 'age': 1,  'active': false }
-     * ];
-     *
-     * _.partition(users, function(o) { return o.active; });
-     * // => objects for [['fred'], ['barney', 'pebbles']]
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.partition(users, { 'age': 1, 'active': false });
-     * // => objects for [['pebbles'], ['barney', 'fred']]
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.partition(users, ['active', false]);
-     * // => objects for [['barney', 'pebbles'], ['fred']]
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.partition(users, 'active');
-     * // => objects for [['fred'], ['barney', 'pebbles']]
-     */
-    var partition = createAggregator(function(result, value, key) {
-      result[key ? 0 : 1].push(value);
-    }, function() { return [[], []]; });
-
-    /**
-     * Reduces `collection` to a value which is the accumulated result of running
-     * each element in `collection` thru `iteratee`, where each successive
-     * invocation is supplied the return value of the previous. If `accumulator`
-     * is not given, the first element of `collection` is used as the initial
-     * value. The iteratee is invoked with four arguments:
-     * (accumulator, value, index|key, collection).
-     *
-     * Many lodash methods are guarded to work as iteratees for methods like
-     * `_.reduce`, `_.reduceRight`, and `_.transform`.
-     *
-     * The guarded methods are:
-     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
-     * and `sortBy`
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @param {*} [accumulator] The initial value.
-     * @returns {*} Returns the accumulated value.
-     * @see _.reduceRight
-     * @example
-     *
-     * _.reduce([1, 2], function(sum, n) {
-     *   return sum + n;
-     * }, 0);
-     * // => 3
-     *
-     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
-     *   (result[value] || (result[value] = [])).push(key);
-     *   return result;
-     * }, {});
-     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
-     */
-    function reduce(collection, iteratee, accumulator) {
-      var func = isArray(collection) ? arrayReduce : baseReduce,
-          initAccum = arguments.length < 3;
-
-      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
-    }
-
-    /**
-     * This method is like `_.reduce` except that it iterates over elements of
-     * `collection` from right to left.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @param {*} [accumulator] The initial value.
-     * @returns {*} Returns the accumulated value.
-     * @see _.reduce
-     * @example
-     *
-     * var array = [[0, 1], [2, 3], [4, 5]];
-     *
-     * _.reduceRight(array, function(flattened, other) {
-     *   return flattened.concat(other);
-     * }, []);
-     * // => [4, 5, 2, 3, 0, 1]
-     */
-    function reduceRight(collection, iteratee, accumulator) {
-      var func = isArray(collection) ? arrayReduceRight : baseReduce,
-          initAccum = arguments.length < 3;
-
-      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
-    }
-
-    /**
-     * The opposite of `_.filter`; this method returns the elements of `collection`
-     * that `predicate` does **not** return truthy for.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the new filtered array.
-     * @see _.filter
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney', 'age': 36, 'active': false },
-     *   { 'user': 'fred',   'age': 40, 'active': true }
-     * ];
-     *
-     * _.reject(users, function(o) { return !o.active; });
-     * // => objects for ['fred']
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.reject(users, { 'age': 40, 'active': true });
-     * // => objects for ['barney']
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.reject(users, ['active', false]);
-     * // => objects for ['fred']
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.reject(users, 'active');
-     * // => objects for ['barney']
-     */
-    function reject(collection, predicate) {
-      var func = isArray(collection) ? arrayFilter : baseFilter;
-      return func(collection, negate(getIteratee(predicate, 3)));
-    }
-
-    /**
-     * Gets a random element from `collection`.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to sample.
-     * @returns {*} Returns the random element.
-     * @example
-     *
-     * _.sample([1, 2, 3, 4]);
-     * // => 2
-     */
-    function sample(collection) {
-      var func = isArray(collection) ? arraySample : baseSample;
-      return func(collection);
-    }
-
-    /**
-     * Gets `n` random elements at unique keys from `collection` up to the
-     * size of `collection`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to sample.
-     * @param {number} [n=1] The number of elements to sample.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Array} Returns the random elements.
-     * @example
-     *
-     * _.sampleSize([1, 2, 3], 2);
-     * // => [3, 1]
-     *
-     * _.sampleSize([1, 2, 3], 4);
-     * // => [2, 3, 1]
-     */
-    function sampleSize(collection, n, guard) {
-      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
-        n = 1;
-      } else {
-        n = toInteger(n);
-      }
-      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
-      return func(collection, n);
-    }
-
-    /**
-     * Creates an array of shuffled values, using a version of the
-     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to shuffle.
-     * @returns {Array} Returns the new shuffled array.
-     * @example
-     *
-     * _.shuffle([1, 2, 3, 4]);
-     * // => [4, 1, 3, 2]
-     */
-    function shuffle(collection) {
-      var func = isArray(collection) ? arrayShuffle : baseShuffle;
-      return func(collection);
-    }
-
-    /**
-     * Gets the size of `collection` by returning its length for array-like
-     * values or the number of own enumerable string keyed properties for objects.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object|string} collection The collection to inspect.
-     * @returns {number} Returns the collection size.
-     * @example
-     *
-     * _.size([1, 2, 3]);
-     * // => 3
-     *
-     * _.size({ 'a': 1, 'b': 2 });
-     * // => 2
-     *
-     * _.size('pebbles');
-     * // => 7
-     */
-    function size(collection) {
-      if (collection == null) {
-        return 0;
-      }
-      if (isArrayLike(collection)) {
-        return isString(collection) ? stringSize(collection) : collection.length;
-      }
-      var tag = getTag(collection);
-      if (tag == mapTag || tag == setTag) {
-        return collection.size;
-      }
-      return baseKeys(collection).length;
-    }
-
-    /**
-     * Checks if `predicate` returns truthy for **any** element of `collection`.
-     * Iteration is stopped once `predicate` returns truthy. The predicate is
-     * invoked with three arguments: (value, index|key, collection).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {boolean} Returns `true` if any element passes the predicate check,
-     *  else `false`.
-     * @example
-     *
-     * _.some([null, 0, 'yes', false], Boolean);
-     * // => true
-     *
-     * var users = [
-     *   { 'user': 'barney', 'active': true },
-     *   { 'user': 'fred',   'active': false }
-     * ];
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.some(users, { 'user': 'barney', 'active': false });
-     * // => false
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.some(users, ['active', false]);
-     * // => true
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.some(users, 'active');
-     * // => true
-     */
-    function some(collection, predicate, guard) {
-      var func = isArray(collection) ? arraySome : baseSome;
-      if (guard && isIterateeCall(collection, predicate, guard)) {
-        predicate = undefined;
-      }
-      return func(collection, getIteratee(predicate, 3));
-    }
-
-    /**
-     * Creates an array of elements, sorted in ascending order by the results of
-     * running each element in a collection thru each iteratee. This method
-     * performs a stable sort, that is, it preserves the original sort order of
-     * equal elements. The iteratees are invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Collection
-     * @param {Array|Object} collection The collection to iterate over.
-     * @param {...(Function|Function[])} [iteratees=[_.identity]]
-     *  The iteratees to sort by.
-     * @returns {Array} Returns the new sorted array.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'fred',   'age': 48 },
-     *   { 'user': 'barney', 'age': 36 },
-     *   { 'user': 'fred',   'age': 40 },
-     *   { 'user': 'barney', 'age': 34 }
-     * ];
-     *
-     * _.sortBy(users, [function(o) { return o.user; }]);
-     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
-     *
-     * _.sortBy(users, ['user', 'age']);
-     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
-     */
-    var sortBy = baseRest(function(collection, iteratees) {
-      if (collection == null) {
-        return [];
-      }
-      var length = iteratees.length;
-      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
-        iteratees = [];
-      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
-        iteratees = [iteratees[0]];
-      }
-      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
-    });
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Gets the timestamp of the number of milliseconds that have elapsed since
-     * the Unix epoch (1 January 1970 00:00:00 UTC).
-     *
-     * @static
-     * @memberOf _
-     * @since 2.4.0
-     * @category Date
-     * @returns {number} Returns the timestamp.
-     * @example
-     *
-     * _.defer(function(stamp) {
-     *   console.log(_.now() - stamp);
-     * }, _.now());
-     * // => Logs the number of milliseconds it took for the deferred invocation.
-     */
-    var now = ctxNow || function() {
-      return root.Date.now();
-    };
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * The opposite of `_.before`; this method creates a function that invokes
-     * `func` once it's called `n` or more times.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {number} n The number of calls before `func` is invoked.
-     * @param {Function} func The function to restrict.
-     * @returns {Function} Returns the new restricted function.
-     * @example
-     *
-     * var saves = ['profile', 'settings'];
-     *
-     * var done = _.after(saves.length, function() {
-     *   console.log('done saving!');
-     * });
-     *
-     * _.forEach(saves, function(type) {
-     *   asyncSave({ 'type': type, 'complete': done });
-     * });
-     * // => Logs 'done saving!' after the two async saves have completed.
-     */
-    function after(n, func) {
-      if (typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      n = toInteger(n);
-      return function() {
-        if (--n < 1) {
-          return func.apply(this, arguments);
-        }
-      };
-    }
-
-    /**
-     * Creates a function that invokes `func`, with up to `n` arguments,
-     * ignoring any additional arguments.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Function
-     * @param {Function} func The function to cap arguments for.
-     * @param {number} [n=func.length] The arity cap.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Function} Returns the new capped function.
-     * @example
-     *
-     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
-     * // => [6, 8, 10]
-     */
-    function ary(func, n, guard) {
-      n = guard ? undefined : n;
-      n = (func && n == null) ? func.length : n;
-      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
-    }
-
-    /**
-     * Creates a function that invokes `func`, with the `this` binding and arguments
-     * of the created function, while it's called less than `n` times. Subsequent
-     * calls to the created function return the result of the last `func` invocation.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Function
-     * @param {number} n The number of calls at which `func` is no longer invoked.
-     * @param {Function} func The function to restrict.
-     * @returns {Function} Returns the new restricted function.
-     * @example
-     *
-     * jQuery(element).on('click', _.before(5, addContactToList));
-     * // => Allows adding up to 4 contacts to the list.
-     */
-    function before(n, func) {
-      var result;
-      if (typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      n = toInteger(n);
-      return function() {
-        if (--n > 0) {
-          result = func.apply(this, arguments);
-        }
-        if (n <= 1) {
-          func = undefined;
-        }
-        return result;
-      };
-    }
-
-    /**
-     * Creates a function that invokes `func` with the `this` binding of `thisArg`
-     * and `partials` prepended to the arguments it receives.
-     *
-     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
-     * may be used as a placeholder for partially applied arguments.
-     *
-     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
-     * property of bound functions.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {Function} func The function to bind.
-     * @param {*} thisArg The `this` binding of `func`.
-     * @param {...*} [partials] The arguments to be partially applied.
-     * @returns {Function} Returns the new bound function.
-     * @example
-     *
-     * function greet(greeting, punctuation) {
-     *   return greeting + ' ' + this.user + punctuation;
-     * }
-     *
-     * var object = { 'user': 'fred' };
-     *
-     * var bound = _.bind(greet, object, 'hi');
-     * bound('!');
-     * // => 'hi fred!'
-     *
-     * // Bound with placeholders.
-     * var bound = _.bind(greet, object, _, '!');
-     * bound('hi');
-     * // => 'hi fred!'
-     */
-    var bind = baseRest(function(func, thisArg, partials) {
-      var bitmask = WRAP_BIND_FLAG;
-      if (partials.length) {
-        var holders = replaceHolders(partials, getHolder(bind));
-        bitmask |= WRAP_PARTIAL_FLAG;
-      }
-      return createWrap(func, bitmask, thisArg, partials, holders);
-    });
-
-    /**
-     * Creates a function that invokes the method at `object[key]` with `partials`
-     * prepended to the arguments it receives.
-     *
-     * This method differs from `_.bind` by allowing bound functions to reference
-     * methods that may be redefined or don't yet exist. See
-     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
-     * for more details.
-     *
-     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
-     * builds, may be used as a placeholder for partially applied arguments.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.10.0
-     * @category Function
-     * @param {Object} object The object to invoke the method on.
-     * @param {string} key The key of the method.
-     * @param {...*} [partials] The arguments to be partially applied.
-     * @returns {Function} Returns the new bound function.
-     * @example
-     *
-     * var object = {
-     *   'user': 'fred',
-     *   'greet': function(greeting, punctuation) {
-     *     return greeting + ' ' + this.user + punctuation;
-     *   }
-     * };
-     *
-     * var bound = _.bindKey(object, 'greet', 'hi');
-     * bound('!');
-     * // => 'hi fred!'
-     *
-     * object.greet = function(greeting, punctuation) {
-     *   return greeting + 'ya ' + this.user + punctuation;
-     * };
-     *
-     * bound('!');
-     * // => 'hiya fred!'
-     *
-     * // Bound with placeholders.
-     * var bound = _.bindKey(object, 'greet', _, '!');
-     * bound('hi');
-     * // => 'hiya fred!'
-     */
-    var bindKey = baseRest(function(object, key, partials) {
-      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
-      if (partials.length) {
-        var holders = replaceHolders(partials, getHolder(bindKey));
-        bitmask |= WRAP_PARTIAL_FLAG;
-      }
-      return createWrap(key, bitmask, object, partials, holders);
-    });
-
-    /**
-     * Creates a function that accepts arguments of `func` and either invokes
-     * `func` returning its result, if at least `arity` number of arguments have
-     * been provided, or returns a function that accepts the remaining `func`
-     * arguments, and so on. The arity of `func` may be specified if `func.length`
-     * is not sufficient.
-     *
-     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
-     * may be used as a placeholder for provided arguments.
-     *
-     * **Note:** This method doesn't set the "length" property of curried functions.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Function
-     * @param {Function} func The function to curry.
-     * @param {number} [arity=func.length] The arity of `func`.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Function} Returns the new curried function.
-     * @example
-     *
-     * var abc = function(a, b, c) {
-     *   return [a, b, c];
-     * };
-     *
-     * var curried = _.curry(abc);
-     *
-     * curried(1)(2)(3);
-     * // => [1, 2, 3]
-     *
-     * curried(1, 2)(3);
-     * // => [1, 2, 3]
-     *
-     * curried(1, 2, 3);
-     * // => [1, 2, 3]
-     *
-     * // Curried with placeholders.
-     * curried(1)(_, 3)(2);
-     * // => [1, 2, 3]
-     */
-    function curry(func, arity, guard) {
-      arity = guard ? undefined : arity;
-      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
-      result.placeholder = curry.placeholder;
-      return result;
-    }
-
-    /**
-     * This method is like `_.curry` except that arguments are applied to `func`
-     * in the manner of `_.partialRight` instead of `_.partial`.
-     *
-     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
-     * builds, may be used as a placeholder for provided arguments.
-     *
-     * **Note:** This method doesn't set the "length" property of curried functions.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Function
-     * @param {Function} func The function to curry.
-     * @param {number} [arity=func.length] The arity of `func`.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Function} Returns the new curried function.
-     * @example
-     *
-     * var abc = function(a, b, c) {
-     *   return [a, b, c];
-     * };
-     *
-     * var curried = _.curryRight(abc);
-     *
-     * curried(3)(2)(1);
-     * // => [1, 2, 3]
-     *
-     * curried(2, 3)(1);
-     * // => [1, 2, 3]
-     *
-     * curried(1, 2, 3);
-     * // => [1, 2, 3]
-     *
-     * // Curried with placeholders.
-     * curried(3)(1, _)(2);
-     * // => [1, 2, 3]
-     */
-    function curryRight(func, arity, guard) {
-      arity = guard ? undefined : arity;
-      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
-      result.placeholder = curryRight.placeholder;
-      return result;
-    }
-
-    /**
-     * Creates a debounced function that delays invoking `func` until after `wait`
-     * milliseconds have elapsed since the last time the debounced function was
-     * invoked. The debounced function comes with a `cancel` method to cancel
-     * delayed `func` invocations and a `flush` method to immediately invoke them.
-     * Provide `options` to indicate whether `func` should be invoked on the
-     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
-     * with the last arguments provided to the debounced function. Subsequent
-     * calls to the debounced function return the result of the last `func`
-     * invocation.
-     *
-     * **Note:** If `leading` and `trailing` options are `true`, `func` is
-     * invoked on the trailing edge of the timeout only if the debounced function
-     * is invoked more than once during the `wait` timeout.
-     *
-     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
-     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
-     *
-     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
-     * for details over the differences between `_.debounce` and `_.throttle`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {Function} func The function to debounce.
-     * @param {number} [wait=0] The number of milliseconds to delay.
-     * @param {Object} [options={}] The options object.
-     * @param {boolean} [options.leading=false]
-     *  Specify invoking on the leading edge of the timeout.
-     * @param {number} [options.maxWait]
-     *  The maximum time `func` is allowed to be delayed before it's invoked.
-     * @param {boolean} [options.trailing=true]
-     *  Specify invoking on the trailing edge of the timeout.
-     * @returns {Function} Returns the new debounced function.
-     * @example
-     *
-     * // Avoid costly calculations while the window size is in flux.
-     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
-     *
-     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
-     * jQuery(element).on('click', _.debounce(sendMail, 300, {
-     *   'leading': true,
-     *   'trailing': false
-     * }));
-     *
-     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
-     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
-     * var source = new EventSource('/stream');
-     * jQuery(source).on('message', debounced);
-     *
-     * // Cancel the trailing debounced invocation.
-     * jQuery(window).on('popstate', debounced.cancel);
-     */
-    function debounce(func, wait, options) {
-      var lastArgs,
-          lastThis,
-          maxWait,
-          result,
-          timerId,
-          lastCallTime,
-          lastInvokeTime = 0,
-          leading = false,
-          maxing = false,
-          trailing = true;
-
-      if (typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      wait = toNumber(wait) || 0;
-      if (isObject(options)) {
-        leading = !!options.leading;
-        maxing = 'maxWait' in options;
-        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
-        trailing = 'trailing' in options ? !!options.trailing : trailing;
-      }
-
-      function invokeFunc(time) {
-        var args = lastArgs,
-            thisArg = lastThis;
-
-        lastArgs = lastThis = undefined;
-        lastInvokeTime = time;
-        result = func.apply(thisArg, args);
-        return result;
-      }
-
-      function leadingEdge(time) {
-        // Reset any `maxWait` timer.
-        lastInvokeTime = time;
-        // Start the timer for the trailing edge.
-        timerId = setTimeout(timerExpired, wait);
-        // Invoke the leading edge.
-        return leading ? invokeFunc(time) : result;
-      }
-
-      function remainingWait(time) {
-        var timeSinceLastCall = time - lastCallTime,
-            timeSinceLastInvoke = time - lastInvokeTime,
-            result = wait - timeSinceLastCall;
-
-        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
-      }
-
-      function shouldInvoke(time) {
-        var timeSinceLastCall = time - lastCallTime,
-            timeSinceLastInvoke = time - lastInvokeTime;
-
-        // Either this is the first call, activity has stopped and we're at the
-        // trailing edge, the system time has gone backwards and we're treating
-        // it as the trailing edge, or we've hit the `maxWait` limit.
-        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
-          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
-      }
-
-      function timerExpired() {
-        var time = now();
-        if (shouldInvoke(time)) {
-          return trailingEdge(time);
-        }
-        // Restart the timer.
-        timerId = setTimeout(timerExpired, remainingWait(time));
-      }
-
-      function trailingEdge(time) {
-        timerId = undefined;
-
-        // Only invoke if we have `lastArgs` which means `func` has been
-        // debounced at least once.
-        if (trailing && lastArgs) {
-          return invokeFunc(time);
-        }
-        lastArgs = lastThis = undefined;
-        return result;
-      }
-
-      function cancel() {
-        if (timerId !== undefined) {
-          clearTimeout(timerId);
-        }
-        lastInvokeTime = 0;
-        lastArgs = lastCallTime = lastThis = timerId = undefined;
-      }
-
-      function flush() {
-        return timerId === undefined ? result : trailingEdge(now());
-      }
-
-      function debounced() {
-        var time = now(),
-            isInvoking = shouldInvoke(time);
-
-        lastArgs = arguments;
-        lastThis = this;
-        lastCallTime = time;
-
-        if (isInvoking) {
-          if (timerId === undefined) {
-            return leadingEdge(lastCallTime);
-          }
-          if (maxing) {
-            // Handle invocations in a tight loop.
-            timerId = setTimeout(timerExpired, wait);
-            return invokeFunc(lastCallTime);
-          }
-        }
-        if (timerId === undefined) {
-          timerId = setTimeout(timerExpired, wait);
-        }
-        return result;
-      }
-      debounced.cancel = cancel;
-      debounced.flush = flush;
-      return debounced;
-    }
-
-    /**
-     * Defers invoking the `func` until the current call stack has cleared. Any
-     * additional arguments are provided to `func` when it's invoked.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {Function} func The function to defer.
-     * @param {...*} [args] The arguments to invoke `func` with.
-     * @returns {number} Returns the timer id.
-     * @example
-     *
-     * _.defer(function(text) {
-     *   console.log(text);
-     * }, 'deferred');
-     * // => Logs 'deferred' after one millisecond.
-     */
-    var defer = baseRest(function(func, args) {
-      return baseDelay(func, 1, args);
-    });
-
-    /**
-     * Invokes `func` after `wait` milliseconds. Any additional arguments are
-     * provided to `func` when it's invoked.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {Function} func The function to delay.
-     * @param {number} wait The number of milliseconds to delay invocation.
-     * @param {...*} [args] The arguments to invoke `func` with.
-     * @returns {number} Returns the timer id.
-     * @example
-     *
-     * _.delay(function(text) {
-     *   console.log(text);
-     * }, 1000, 'later');
-     * // => Logs 'later' after one second.
-     */
-    var delay = baseRest(function(func, wait, args) {
-      return baseDelay(func, toNumber(wait) || 0, args);
-    });
-
-    /**
-     * Creates a function that invokes `func` with arguments reversed.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Function
-     * @param {Function} func The function to flip arguments for.
-     * @returns {Function} Returns the new flipped function.
-     * @example
-     *
-     * var flipped = _.flip(function() {
-     *   return _.toArray(arguments);
-     * });
-     *
-     * flipped('a', 'b', 'c', 'd');
-     * // => ['d', 'c', 'b', 'a']
-     */
-    function flip(func) {
-      return createWrap(func, WRAP_FLIP_FLAG);
-    }
-
-    /**
-     * Creates a function that memoizes the result of `func`. If `resolver` is
-     * provided, it determines the cache key for storing the result based on the
-     * arguments provided to the memoized function. By default, the first argument
-     * provided to the memoized function is used as the map cache key. The `func`
-     * is invoked with the `this` binding of the memoized function.
-     *
-     * **Note:** The cache is exposed as the `cache` property on the memoized
-     * function. Its creation may be customized by replacing the `_.memoize.Cache`
-     * constructor with one whose instances implement the
-     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
-     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {Function} func The function to have its output memoized.
-     * @param {Function} [resolver] The function to resolve the cache key.
-     * @returns {Function} Returns the new memoized function.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': 2 };
-     * var other = { 'c': 3, 'd': 4 };
-     *
-     * var values = _.memoize(_.values);
-     * values(object);
-     * // => [1, 2]
-     *
-     * values(other);
-     * // => [3, 4]
-     *
-     * object.a = 2;
-     * values(object);
-     * // => [1, 2]
-     *
-     * // Modify the result cache.
-     * values.cache.set(object, ['a', 'b']);
-     * values(object);
-     * // => ['a', 'b']
-     *
-     * // Replace `_.memoize.Cache`.
-     * _.memoize.Cache = WeakMap;
-     */
-    function memoize(func, resolver) {
-      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      var memoized = function() {
-        var args = arguments,
-            key = resolver ? resolver.apply(this, args) : args[0],
-            cache = memoized.cache;
-
-        if (cache.has(key)) {
-          return cache.get(key);
-        }
-        var result = func.apply(this, args);
-        memoized.cache = cache.set(key, result) || cache;
-        return result;
-      };
-      memoized.cache = new (memoize.Cache || MapCache);
-      return memoized;
-    }
-
-    // Expose `MapCache`.
-    memoize.Cache = MapCache;
-
-    /**
-     * Creates a function that negates the result of the predicate `func`. The
-     * `func` predicate is invoked with the `this` binding and arguments of the
-     * created function.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Function
-     * @param {Function} predicate The predicate to negate.
-     * @returns {Function} Returns the new negated function.
-     * @example
-     *
-     * function isEven(n) {
-     *   return n % 2 == 0;
-     * }
-     *
-     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
-     * // => [1, 3, 5]
-     */
-    function negate(predicate) {
-      if (typeof predicate != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      return function() {
-        var args = arguments;
-        switch (args.length) {
-          case 0: return !predicate.call(this);
-          case 1: return !predicate.call(this, args[0]);
-          case 2: return !predicate.call(this, args[0], args[1]);
-          case 3: return !predicate.call(this, args[0], args[1], args[2]);
-        }
-        return !predicate.apply(this, args);
-      };
-    }
-
-    /**
-     * Creates a function that is restricted to invoking `func` once. Repeat calls
-     * to the function return the value of the first invocation. The `func` is
-     * invoked with the `this` binding and arguments of the created function.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {Function} func The function to restrict.
-     * @returns {Function} Returns the new restricted function.
-     * @example
-     *
-     * var initialize = _.once(createApplication);
-     * initialize();
-     * initialize();
-     * // => `createApplication` is invoked once
-     */
-    function once(func) {
-      return before(2, func);
-    }
-
-    /**
-     * Creates a function that invokes `func` with its arguments transformed.
-     *
-     * @static
-     * @since 4.0.0
-     * @memberOf _
-     * @category Function
-     * @param {Function} func The function to wrap.
-     * @param {...(Function|Function[])} [transforms=[_.identity]]
-     *  The argument transforms.
-     * @returns {Function} Returns the new function.
-     * @example
-     *
-     * function doubled(n) {
-     *   return n * 2;
-     * }
-     *
-     * function square(n) {
-     *   return n * n;
-     * }
-     *
-     * var func = _.overArgs(function(x, y) {
-     *   return [x, y];
-     * }, [square, doubled]);
-     *
-     * func(9, 3);
-     * // => [81, 6]
-     *
-     * func(10, 5);
-     * // => [100, 10]
-     */
-    var overArgs = castRest(function(func, transforms) {
-      transforms = (transforms.length == 1 && isArray(transforms[0]))
-        ? arrayMap(transforms[0], baseUnary(getIteratee()))
-        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
-
-      var funcsLength = transforms.length;
-      return baseRest(function(args) {
-        var index = -1,
-            length = nativeMin(args.length, funcsLength);
-
-        while (++index < length) {
-          args[index] = transforms[index].call(this, args[index]);
-        }
-        return apply(func, this, args);
-      });
-    });
-
-    /**
-     * Creates a function that invokes `func` with `partials` prepended to the
-     * arguments it receives. This method is like `_.bind` except it does **not**
-     * alter the `this` binding.
-     *
-     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
-     * builds, may be used as a placeholder for partially applied arguments.
-     *
-     * **Note:** This method doesn't set the "length" property of partially
-     * applied functions.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.2.0
-     * @category Function
-     * @param {Function} func The function to partially apply arguments to.
-     * @param {...*} [partials] The arguments to be partially applied.
-     * @returns {Function} Returns the new partially applied function.
-     * @example
-     *
-     * function greet(greeting, name) {
-     *   return greeting + ' ' + name;
-     * }
-     *
-     * var sayHelloTo = _.partial(greet, 'hello');
-     * sayHelloTo('fred');
-     * // => 'hello fred'
-     *
-     * // Partially applied with placeholders.
-     * var greetFred = _.partial(greet, _, 'fred');
-     * greetFred('hi');
-     * // => 'hi fred'
-     */
-    var partial = baseRest(function(func, partials) {
-      var holders = replaceHolders(partials, getHolder(partial));
-      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
-    });
-
-    /**
-     * This method is like `_.partial` except that partially applied arguments
-     * are appended to the arguments it receives.
-     *
-     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
-     * builds, may be used as a placeholder for partially applied arguments.
-     *
-     * **Note:** This method doesn't set the "length" property of partially
-     * applied functions.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.0.0
-     * @category Function
-     * @param {Function} func The function to partially apply arguments to.
-     * @param {...*} [partials] The arguments to be partially applied.
-     * @returns {Function} Returns the new partially applied function.
-     * @example
-     *
-     * function greet(greeting, name) {
-     *   return greeting + ' ' + name;
-     * }
-     *
-     * var greetFred = _.partialRight(greet, 'fred');
-     * greetFred('hi');
-     * // => 'hi fred'
-     *
-     * // Partially applied with placeholders.
-     * var sayHelloTo = _.partialRight(greet, 'hello', _);
-     * sayHelloTo('fred');
-     * // => 'hello fred'
-     */
-    var partialRight = baseRest(function(func, partials) {
-      var holders = replaceHolders(partials, getHolder(partialRight));
-      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
-    });
-
-    /**
-     * Creates a function that invokes `func` with arguments arranged according
-     * to the specified `indexes` where the argument value at the first index is
-     * provided as the first argument, the argument value at the second index is
-     * provided as the second argument, and so on.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Function
-     * @param {Function} func The function to rearrange arguments for.
-     * @param {...(number|number[])} indexes The arranged argument indexes.
-     * @returns {Function} Returns the new function.
-     * @example
-     *
-     * var rearged = _.rearg(function(a, b, c) {
-     *   return [a, b, c];
-     * }, [2, 0, 1]);
-     *
-     * rearged('b', 'c', 'a')
-     * // => ['a', 'b', 'c']
-     */
-    var rearg = flatRest(function(func, indexes) {
-      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
-    });
-
-    /**
-     * Creates a function that invokes `func` with the `this` binding of the
-     * created function and arguments from `start` and beyond provided as
-     * an array.
-     *
-     * **Note:** This method is based on the
-     * [rest parameter](https://mdn.io/rest_parameters).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Function
-     * @param {Function} func The function to apply a rest parameter to.
-     * @param {number} [start=func.length-1] The start position of the rest parameter.
-     * @returns {Function} Returns the new function.
-     * @example
-     *
-     * var say = _.rest(function(what, names) {
-     *   return what + ' ' + _.initial(names).join(', ') +
-     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
-     * });
-     *
-     * say('hello', 'fred', 'barney', 'pebbles');
-     * // => 'hello fred, barney, & pebbles'
-     */
-    function rest(func, start) {
-      if (typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      start = start === undefined ? start : toInteger(start);
-      return baseRest(func, start);
-    }
-
-    /**
-     * Creates a function that invokes `func` with the `this` binding of the
-     * create function and an array of arguments much like
-     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
-     *
-     * **Note:** This method is based on the
-     * [spread operator](https://mdn.io/spread_operator).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.2.0
-     * @category Function
-     * @param {Function} func The function to spread arguments over.
-     * @param {number} [start=0] The start position of the spread.
-     * @returns {Function} Returns the new function.
-     * @example
-     *
-     * var say = _.spread(function(who, what) {
-     *   return who + ' says ' + what;
-     * });
-     *
-     * say(['fred', 'hello']);
-     * // => 'fred says hello'
-     *
-     * var numbers = Promise.all([
-     *   Promise.resolve(40),
-     *   Promise.resolve(36)
-     * ]);
-     *
-     * numbers.then(_.spread(function(x, y) {
-     *   return x + y;
-     * }));
-     * // => a Promise of 76
-     */
-    function spread(func, start) {
-      if (typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      start = start == null ? 0 : nativeMax(toInteger(start), 0);
-      return baseRest(function(args) {
-        var array = args[start],
-            otherArgs = castSlice(args, 0, start);
-
-        if (array) {
-          arrayPush(otherArgs, array);
-        }
-        return apply(func, this, otherArgs);
-      });
-    }
-
-    /**
-     * Creates a throttled function that only invokes `func` at most once per
-     * every `wait` milliseconds. The throttled function comes with a `cancel`
-     * method to cancel delayed `func` invocations and a `flush` method to
-     * immediately invoke them. Provide `options` to indicate whether `func`
-     * should be invoked on the leading and/or trailing edge of the `wait`
-     * timeout. The `func` is invoked with the last arguments provided to the
-     * throttled function. Subsequent calls to the throttled function return the
-     * result of the last `func` invocation.
-     *
-     * **Note:** If `leading` and `trailing` options are `true`, `func` is
-     * invoked on the trailing edge of the timeout only if the throttled function
-     * is invoked more than once during the `wait` timeout.
-     *
-     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
-     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
-     *
-     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
-     * for details over the differences between `_.throttle` and `_.debounce`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {Function} func The function to throttle.
-     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
-     * @param {Object} [options={}] The options object.
-     * @param {boolean} [options.leading=true]
-     *  Specify invoking on the leading edge of the timeout.
-     * @param {boolean} [options.trailing=true]
-     *  Specify invoking on the trailing edge of the timeout.
-     * @returns {Function} Returns the new throttled function.
-     * @example
-     *
-     * // Avoid excessively updating the position while scrolling.
-     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
-     *
-     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
-     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
-     * jQuery(element).on('click', throttled);
-     *
-     * // Cancel the trailing throttled invocation.
-     * jQuery(window).on('popstate', throttled.cancel);
-     */
-    function throttle(func, wait, options) {
-      var leading = true,
-          trailing = true;
-
-      if (typeof func != 'function') {
-        throw new TypeError(FUNC_ERROR_TEXT);
-      }
-      if (isObject(options)) {
-        leading = 'leading' in options ? !!options.leading : leading;
-        trailing = 'trailing' in options ? !!options.trailing : trailing;
-      }
-      return debounce(func, wait, {
-        'leading': leading,
-        'maxWait': wait,
-        'trailing': trailing
-      });
-    }
-
-    /**
-     * Creates a function that accepts up to one argument, ignoring any
-     * additional arguments.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Function
-     * @param {Function} func The function to cap arguments for.
-     * @returns {Function} Returns the new capped function.
-     * @example
-     *
-     * _.map(['6', '8', '10'], _.unary(parseInt));
-     * // => [6, 8, 10]
-     */
-    function unary(func) {
-      return ary(func, 1);
-    }
-
-    /**
-     * Creates a function that provides `value` to `wrapper` as its first
-     * argument. Any additional arguments provided to the function are appended
-     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
-     * binding of the created function.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Function
-     * @param {*} value The value to wrap.
-     * @param {Function} [wrapper=identity] The wrapper function.
-     * @returns {Function} Returns the new function.
-     * @example
-     *
-     * var p = _.wrap(_.escape, function(func, text) {
-     *   return '<p>' + func(text) + '</p>';
-     * });
-     *
-     * p('fred, barney, & pebbles');
-     * // => '<p>fred, barney, &amp; pebbles</p>'
-     */
-    function wrap(value, wrapper) {
-      return partial(castFunction(wrapper), value);
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Casts `value` as an array if it's not one.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.4.0
-     * @category Lang
-     * @param {*} value The value to inspect.
-     * @returns {Array} Returns the cast array.
-     * @example
-     *
-     * _.castArray(1);
-     * // => [1]
-     *
-     * _.castArray({ 'a': 1 });
-     * // => [{ 'a': 1 }]
-     *
-     * _.castArray('abc');
-     * // => ['abc']
-     *
-     * _.castArray(null);
-     * // => [null]
-     *
-     * _.castArray(undefined);
-     * // => [undefined]
-     *
-     * _.castArray();
-     * // => []
-     *
-     * var array = [1, 2, 3];
-     * console.log(_.castArray(array) === array);
-     * // => true
-     */
-    function castArray() {
-      if (!arguments.length) {
-        return [];
-      }
-      var value = arguments[0];
-      return isArray(value) ? value : [value];
-    }
-
-    /**
-     * Creates a shallow clone of `value`.
-     *
-     * **Note:** This method is loosely based on the
-     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
-     * and supports cloning arrays, array buffers, booleans, date objects, maps,
-     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
-     * arrays. The own enumerable properties of `arguments` objects are cloned
-     * as plain objects. An empty object is returned for uncloneable values such
-     * as error objects, functions, DOM nodes, and WeakMaps.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to clone.
-     * @returns {*} Returns the cloned value.
-     * @see _.cloneDeep
-     * @example
-     *
-     * var objects = [{ 'a': 1 }, { 'b': 2 }];
-     *
-     * var shallow = _.clone(objects);
-     * console.log(shallow[0] === objects[0]);
-     * // => true
-     */
-    function clone(value) {
-      return baseClone(value, CLONE_SYMBOLS_FLAG);
-    }
-
-    /**
-     * This method is like `_.clone` except that it accepts `customizer` which
-     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
-     * cloning is handled by the method instead. The `customizer` is invoked with
-     * up to four arguments; (value [, index|key, object, stack]).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to clone.
-     * @param {Function} [customizer] The function to customize cloning.
-     * @returns {*} Returns the cloned value.
-     * @see _.cloneDeepWith
-     * @example
-     *
-     * function customizer(value) {
-     *   if (_.isElement(value)) {
-     *     return value.cloneNode(false);
-     *   }
-     * }
-     *
-     * var el = _.cloneWith(document.body, customizer);
-     *
-     * console.log(el === document.body);
-     * // => false
-     * console.log(el.nodeName);
-     * // => 'BODY'
-     * console.log(el.childNodes.length);
-     * // => 0
-     */
-    function cloneWith(value, customizer) {
-      customizer = typeof customizer == 'function' ? customizer : undefined;
-      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
-    }
-
-    /**
-     * This method is like `_.clone` except that it recursively clones `value`.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.0.0
-     * @category Lang
-     * @param {*} value The value to recursively clone.
-     * @returns {*} Returns the deep cloned value.
-     * @see _.clone
-     * @example
-     *
-     * var objects = [{ 'a': 1 }, { 'b': 2 }];
-     *
-     * var deep = _.cloneDeep(objects);
-     * console.log(deep[0] === objects[0]);
-     * // => false
-     */
-    function cloneDeep(value) {
-      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
-    }
-
-    /**
-     * This method is like `_.cloneWith` except that it recursively clones `value`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to recursively clone.
-     * @param {Function} [customizer] The function to customize cloning.
-     * @returns {*} Returns the deep cloned value.
-     * @see _.cloneWith
-     * @example
-     *
-     * function customizer(value) {
-     *   if (_.isElement(value)) {
-     *     return value.cloneNode(true);
-     *   }
-     * }
-     *
-     * var el = _.cloneDeepWith(document.body, customizer);
-     *
-     * console.log(el === document.body);
-     * // => false
-     * console.log(el.nodeName);
-     * // => 'BODY'
-     * console.log(el.childNodes.length);
-     * // => 20
-     */
-    function cloneDeepWith(value, customizer) {
-      customizer = typeof customizer == 'function' ? customizer : undefined;
-      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
-    }
-
-    /**
-     * Checks if `object` conforms to `source` by invoking the predicate
-     * properties of `source` with the corresponding property values of `object`.
-     *
-     * **Note:** This method is equivalent to `_.conforms` when `source` is
-     * partially applied.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.14.0
-     * @category Lang
-     * @param {Object} object The object to inspect.
-     * @param {Object} source The object of property predicates to conform to.
-     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': 2 };
-     *
-     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
-     * // => true
-     *
-     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
-     * // => false
-     */
-    function conformsTo(object, source) {
-      return source == null || baseConformsTo(object, source, keys(source));
-    }
-
-    /**
-     * Performs a
-     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-     * comparison between two values to determine if they are equivalent.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-     * @example
-     *
-     * var object = { 'a': 1 };
-     * var other = { 'a': 1 };
-     *
-     * _.eq(object, object);
-     * // => true
-     *
-     * _.eq(object, other);
-     * // => false
-     *
-     * _.eq('a', 'a');
-     * // => true
-     *
-     * _.eq('a', Object('a'));
-     * // => false
-     *
-     * _.eq(NaN, NaN);
-     * // => true
-     */
-    function eq(value, other) {
-      return value === other || (value !== value && other !== other);
-    }
-
-    /**
-     * Checks if `value` is greater than `other`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.9.0
-     * @category Lang
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {boolean} Returns `true` if `value` is greater than `other`,
-     *  else `false`.
-     * @see _.lt
-     * @example
-     *
-     * _.gt(3, 1);
-     * // => true
-     *
-     * _.gt(3, 3);
-     * // => false
-     *
-     * _.gt(1, 3);
-     * // => false
-     */
-    var gt = createRelationalOperation(baseGt);
-
-    /**
-     * Checks if `value` is greater than or equal to `other`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.9.0
-     * @category Lang
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {boolean} Returns `true` if `value` is greater than or equal to
-     *  `other`, else `false`.
-     * @see _.lte
-     * @example
-     *
-     * _.gte(3, 1);
-     * // => true
-     *
-     * _.gte(3, 3);
-     * // => true
-     *
-     * _.gte(1, 3);
-     * // => false
-     */
-    var gte = createRelationalOperation(function(value, other) {
-      return value >= other;
-    });
-
-    /**
-     * Checks if `value` is likely an `arguments` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
-     *  else `false`.
-     * @example
-     *
-     * _.isArguments(function() { return arguments; }());
-     * // => true
-     *
-     * _.isArguments([1, 2, 3]);
-     * // => false
-     */
-    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
-      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
-        !propertyIsEnumerable.call(value, 'callee');
-    };
-
-    /**
-     * Checks if `value` is classified as an `Array` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an array, else `false`.
-     * @example
-     *
-     * _.isArray([1, 2, 3]);
-     * // => true
-     *
-     * _.isArray(document.body.children);
-     * // => false
-     *
-     * _.isArray('abc');
-     * // => false
-     *
-     * _.isArray(_.noop);
-     * // => false
-     */
-    var isArray = Array.isArray;
-
-    /**
-     * Checks if `value` is classified as an `ArrayBuffer` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.3.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
-     * @example
-     *
-     * _.isArrayBuffer(new ArrayBuffer(2));
-     * // => true
-     *
-     * _.isArrayBuffer(new Array(2));
-     * // => false
-     */
-    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
-
-    /**
-     * Checks if `value` is array-like. A value is considered array-like if it's
-     * not a function and has a `value.length` that's an integer greater than or
-     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
-     * @example
-     *
-     * _.isArrayLike([1, 2, 3]);
-     * // => true
-     *
-     * _.isArrayLike(document.body.children);
-     * // => true
-     *
-     * _.isArrayLike('abc');
-     * // => true
-     *
-     * _.isArrayLike(_.noop);
-     * // => false
-     */
-    function isArrayLike(value) {
-      return value != null && isLength(value.length) && !isFunction(value);
-    }
-
-    /**
-     * This method is like `_.isArrayLike` except that it also checks if `value`
-     * is an object.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an array-like object,
-     *  else `false`.
-     * @example
-     *
-     * _.isArrayLikeObject([1, 2, 3]);
-     * // => true
-     *
-     * _.isArrayLikeObject(document.body.children);
-     * // => true
-     *
-     * _.isArrayLikeObject('abc');
-     * // => false
-     *
-     * _.isArrayLikeObject(_.noop);
-     * // => false
-     */
-    function isArrayLikeObject(value) {
-      return isObjectLike(value) && isArrayLike(value);
-    }
-
-    /**
-     * Checks if `value` is classified as a boolean primitive or object.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
-     * @example
-     *
-     * _.isBoolean(false);
-     * // => true
-     *
-     * _.isBoolean(null);
-     * // => false
-     */
-    function isBoolean(value) {
-      return value === true || value === false ||
-        (isObjectLike(value) && baseGetTag(value) == boolTag);
-    }
-
-    /**
-     * Checks if `value` is a buffer.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.3.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
-     * @example
-     *
-     * _.isBuffer(new Buffer(2));
-     * // => true
-     *
-     * _.isBuffer(new Uint8Array(2));
-     * // => false
-     */
-    var isBuffer = nativeIsBuffer || stubFalse;
-
-    /**
-     * Checks if `value` is classified as a `Date` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
-     * @example
-     *
-     * _.isDate(new Date);
-     * // => true
-     *
-     * _.isDate('Mon April 23 2012');
-     * // => false
-     */
-    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
-
-    /**
-     * Checks if `value` is likely a DOM element.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
-     * @example
-     *
-     * _.isElement(document.body);
-     * // => true
-     *
-     * _.isElement('<body>');
-     * // => false
-     */
-    function isElement(value) {
-      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
-    }
-
-    /**
-     * Checks if `value` is an empty object, collection, map, or set.
-     *
-     * Objects are considered empty if they have no own enumerable string keyed
-     * properties.
-     *
-     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
-     * jQuery-like collections are considered empty if they have a `length` of `0`.
-     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
-     * @example
-     *
-     * _.isEmpty(null);
-     * // => true
-     *
-     * _.isEmpty(true);
-     * // => true
-     *
-     * _.isEmpty(1);
-     * // => true
-     *
-     * _.isEmpty([1, 2, 3]);
-     * // => false
-     *
-     * _.isEmpty({ 'a': 1 });
-     * // => false
-     */
-    function isEmpty(value) {
-      if (value == null) {
-        return true;
-      }
-      if (isArrayLike(value) &&
-          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
-            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
-        return !value.length;
-      }
-      var tag = getTag(value);
-      if (tag == mapTag || tag == setTag) {
-        return !value.size;
-      }
-      if (isPrototype(value)) {
-        return !baseKeys(value).length;
-      }
-      for (var key in value) {
-        if (hasOwnProperty.call(value, key)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    /**
-     * Performs a deep comparison between two values to determine if they are
-     * equivalent.
-     *
-     * **Note:** This method supports comparing arrays, array buffers, booleans,
-     * date objects, error objects, maps, numbers, `Object` objects, regexes,
-     * sets, strings, symbols, and typed arrays. `Object` objects are compared
-     * by their own, not inherited, enumerable properties. Functions and DOM
-     * nodes are compared by strict equality, i.e. `===`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-     * @example
-     *
-     * var object = { 'a': 1 };
-     * var other = { 'a': 1 };
-     *
-     * _.isEqual(object, other);
-     * // => true
-     *
-     * object === other;
-     * // => false
-     */
-    function isEqual(value, other) {
-      return baseIsEqual(value, other);
-    }
-
-    /**
-     * This method is like `_.isEqual` except that it accepts `customizer` which
-     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
-     * are handled by the method instead. The `customizer` is invoked with up to
-     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @param {Function} [customizer] The function to customize comparisons.
-     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-     * @example
-     *
-     * function isGreeting(value) {
-     *   return /^h(?:i|ello)$/.test(value);
-     * }
-     *
-     * function customizer(objValue, othValue) {
-     *   if (isGreeting(objValue) && isGreeting(othValue)) {
-     *     return true;
-     *   }
-     * }
-     *
-     * var array = ['hello', 'goodbye'];
-     * var other = ['hi', 'goodbye'];
-     *
-     * _.isEqualWith(array, other, customizer);
-     * // => true
-     */
-    function isEqualWith(value, other, customizer) {
-      customizer = typeof customizer == 'function' ? customizer : undefined;
-      var result = customizer ? customizer(value, other) : undefined;
-      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
-    }
-
-    /**
-     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
-     * `SyntaxError`, `TypeError`, or `URIError` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
-     * @example
-     *
-     * _.isError(new Error);
-     * // => true
-     *
-     * _.isError(Error);
-     * // => false
-     */
-    function isError(value) {
-      if (!isObjectLike(value)) {
-        return false;
-      }
-      var tag = baseGetTag(value);
-      return tag == errorTag || tag == domExcTag ||
-        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
-    }
-
-    /**
-     * Checks if `value` is a finite primitive number.
-     *
-     * **Note:** This method is based on
-     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
-     * @example
-     *
-     * _.isFinite(3);
-     * // => true
-     *
-     * _.isFinite(Number.MIN_VALUE);
-     * // => true
-     *
-     * _.isFinite(Infinity);
-     * // => false
-     *
-     * _.isFinite('3');
-     * // => false
-     */
-    function isFinite(value) {
-      return typeof value == 'number' && nativeIsFinite(value);
-    }
-
-    /**
-     * Checks if `value` is classified as a `Function` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
-     * @example
-     *
-     * _.isFunction(_);
-     * // => true
-     *
-     * _.isFunction(/abc/);
-     * // => false
-     */
-    function isFunction(value) {
-      if (!isObject(value)) {
-        return false;
-      }
-      // The use of `Object#toString` avoids issues with the `typeof` operator
-      // in Safari 9 which returns 'object' for typed arrays and other constructors.
-      var tag = baseGetTag(value);
-      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
-    }
-
-    /**
-     * Checks if `value` is an integer.
-     *
-     * **Note:** This method is based on
-     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
-     * @example
-     *
-     * _.isInteger(3);
-     * // => true
-     *
-     * _.isInteger(Number.MIN_VALUE);
-     * // => false
-     *
-     * _.isInteger(Infinity);
-     * // => false
-     *
-     * _.isInteger('3');
-     * // => false
-     */
-    function isInteger(value) {
-      return typeof value == 'number' && value == toInteger(value);
-    }
-
-    /**
-     * Checks if `value` is a valid array-like length.
-     *
-     * **Note:** This method is loosely based on
-     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
-     * @example
-     *
-     * _.isLength(3);
-     * // => true
-     *
-     * _.isLength(Number.MIN_VALUE);
-     * // => false
-     *
-     * _.isLength(Infinity);
-     * // => false
-     *
-     * _.isLength('3');
-     * // => false
-     */
-    function isLength(value) {
-      return typeof value == 'number' &&
-        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
-    }
-
-    /**
-     * Checks if `value` is the
-     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
-     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
-     * @example
-     *
-     * _.isObject({});
-     * // => true
-     *
-     * _.isObject([1, 2, 3]);
-     * // => true
-     *
-     * _.isObject(_.noop);
-     * // => true
-     *
-     * _.isObject(null);
-     * // => false
-     */
-    function isObject(value) {
-      var type = typeof value;
-      return value != null && (type == 'object' || type == 'function');
-    }
-
-    /**
-     * Checks if `value` is object-like. A value is object-like if it's not `null`
-     * and has a `typeof` result of "object".
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
-     * @example
-     *
-     * _.isObjectLike({});
-     * // => true
-     *
-     * _.isObjectLike([1, 2, 3]);
-     * // => true
-     *
-     * _.isObjectLike(_.noop);
-     * // => false
-     *
-     * _.isObjectLike(null);
-     * // => false
-     */
-    function isObjectLike(value) {
-      return value != null && typeof value == 'object';
-    }
-
-    /**
-     * Checks if `value` is classified as a `Map` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.3.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
-     * @example
-     *
-     * _.isMap(new Map);
-     * // => true
-     *
-     * _.isMap(new WeakMap);
-     * // => false
-     */
-    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
-
-    /**
-     * Performs a partial deep comparison between `object` and `source` to
-     * determine if `object` contains equivalent property values.
-     *
-     * **Note:** This method is equivalent to `_.matches` when `source` is
-     * partially applied.
-     *
-     * Partial comparisons will match empty array and empty object `source`
-     * values against any array or object value, respectively. See `_.isEqual`
-     * for a list of supported value comparisons.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Lang
-     * @param {Object} object The object to inspect.
-     * @param {Object} source The object of property values to match.
-     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': 2 };
-     *
-     * _.isMatch(object, { 'b': 2 });
-     * // => true
-     *
-     * _.isMatch(object, { 'b': 1 });
-     * // => false
-     */
-    function isMatch(object, source) {
-      return object === source || baseIsMatch(object, source, getMatchData(source));
-    }
-
-    /**
-     * This method is like `_.isMatch` except that it accepts `customizer` which
-     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
-     * are handled by the method instead. The `customizer` is invoked with five
-     * arguments: (objValue, srcValue, index|key, object, source).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {Object} object The object to inspect.
-     * @param {Object} source The object of property values to match.
-     * @param {Function} [customizer] The function to customize comparisons.
-     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
-     * @example
-     *
-     * function isGreeting(value) {
-     *   return /^h(?:i|ello)$/.test(value);
-     * }
-     *
-     * function customizer(objValue, srcValue) {
-     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
-     *     return true;
-     *   }
-     * }
-     *
-     * var object = { 'greeting': 'hello' };
-     * var source = { 'greeting': 'hi' };
-     *
-     * _.isMatchWith(object, source, customizer);
-     * // => true
-     */
-    function isMatchWith(object, source, customizer) {
-      customizer = typeof customizer == 'function' ? customizer : undefined;
-      return baseIsMatch(object, source, getMatchData(source), customizer);
-    }
-
-    /**
-     * Checks if `value` is `NaN`.
-     *
-     * **Note:** This method is based on
-     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
-     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
-     * `undefined` and other non-number values.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
-     * @example
-     *
-     * _.isNaN(NaN);
-     * // => true
-     *
-     * _.isNaN(new Number(NaN));
-     * // => true
-     *
-     * isNaN(undefined);
-     * // => true
-     *
-     * _.isNaN(undefined);
-     * // => false
-     */
-    function isNaN(value) {
-      // An `NaN` primitive is the only value that is not equal to itself.
-      // Perform the `toStringTag` check first to avoid errors with some
-      // ActiveX objects in IE.
-      return isNumber(value) && value != +value;
-    }
-
-    /**
-     * Checks if `value` is a pristine native function.
-     *
-     * **Note:** This method can't reliably detect native functions in the presence
-     * of the core-js package because core-js circumvents this kind of detection.
-     * Despite multiple requests, the core-js maintainer has made it clear: any
-     * attempt to fix the detection will be obstructed. As a result, we're left
-     * with little choice but to throw an error. Unfortunately, this also affects
-     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
-     * which rely on core-js.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a native function,
-     *  else `false`.
-     * @example
-     *
-     * _.isNative(Array.prototype.push);
-     * // => true
-     *
-     * _.isNative(_);
-     * // => false
-     */
-    function isNative(value) {
-      if (isMaskable(value)) {
-        throw new Error(CORE_ERROR_TEXT);
-      }
-      return baseIsNative(value);
-    }
-
-    /**
-     * Checks if `value` is `null`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
-     * @example
-     *
-     * _.isNull(null);
-     * // => true
-     *
-     * _.isNull(void 0);
-     * // => false
-     */
-    function isNull(value) {
-      return value === null;
-    }
-
-    /**
-     * Checks if `value` is `null` or `undefined`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
-     * @example
-     *
-     * _.isNil(null);
-     * // => true
-     *
-     * _.isNil(void 0);
-     * // => true
-     *
-     * _.isNil(NaN);
-     * // => false
-     */
-    function isNil(value) {
-      return value == null;
-    }
-
-    /**
-     * Checks if `value` is classified as a `Number` primitive or object.
-     *
-     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
-     * classified as numbers, use the `_.isFinite` method.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a number, else `false`.
-     * @example
-     *
-     * _.isNumber(3);
-     * // => true
-     *
-     * _.isNumber(Number.MIN_VALUE);
-     * // => true
-     *
-     * _.isNumber(Infinity);
-     * // => true
-     *
-     * _.isNumber('3');
-     * // => false
-     */
-    function isNumber(value) {
-      return typeof value == 'number' ||
-        (isObjectLike(value) && baseGetTag(value) == numberTag);
-    }
-
-    /**
-     * Checks if `value` is a plain object, that is, an object created by the
-     * `Object` constructor or one with a `[[Prototype]]` of `null`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.8.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     * }
-     *
-     * _.isPlainObject(new Foo);
-     * // => false
-     *
-     * _.isPlainObject([1, 2, 3]);
-     * // => false
-     *
-     * _.isPlainObject({ 'x': 0, 'y': 0 });
-     * // => true
-     *
-     * _.isPlainObject(Object.create(null));
-     * // => true
-     */
-    function isPlainObject(value) {
-      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
-        return false;
-      }
-      var proto = getPrototype(value);
-      if (proto === null) {
-        return true;
-      }
-      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
-      return typeof Ctor == 'function' && Ctor instanceof Ctor &&
-        funcToString.call(Ctor) == objectCtorString;
-    }
-
-    /**
-     * Checks if `value` is classified as a `RegExp` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.1.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
-     * @example
-     *
-     * _.isRegExp(/abc/);
-     * // => true
-     *
-     * _.isRegExp('/abc/');
-     * // => false
-     */
-    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
-
-    /**
-     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
-     * double precision number which isn't the result of a rounded unsafe integer.
-     *
-     * **Note:** This method is based on
-     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
-     * @example
-     *
-     * _.isSafeInteger(3);
-     * // => true
-     *
-     * _.isSafeInteger(Number.MIN_VALUE);
-     * // => false
-     *
-     * _.isSafeInteger(Infinity);
-     * // => false
-     *
-     * _.isSafeInteger('3');
-     * // => false
-     */
-    function isSafeInteger(value) {
-      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
-    }
-
-    /**
-     * Checks if `value` is classified as a `Set` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.3.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
-     * @example
-     *
-     * _.isSet(new Set);
-     * // => true
-     *
-     * _.isSet(new WeakSet);
-     * // => false
-     */
-    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
-
-    /**
-     * Checks if `value` is classified as a `String` primitive or object.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a string, else `false`.
-     * @example
-     *
-     * _.isString('abc');
-     * // => true
-     *
-     * _.isString(1);
-     * // => false
-     */
-    function isString(value) {
-      return typeof value == 'string' ||
-        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
-    }
-
-    /**
-     * Checks if `value` is classified as a `Symbol` primitive or object.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
-     * @example
-     *
-     * _.isSymbol(Symbol.iterator);
-     * // => true
-     *
-     * _.isSymbol('abc');
-     * // => false
-     */
-    function isSymbol(value) {
-      return typeof value == 'symbol' ||
-        (isObjectLike(value) && baseGetTag(value) == symbolTag);
-    }
-
-    /**
-     * Checks if `value` is classified as a typed array.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
-     * @example
-     *
-     * _.isTypedArray(new Uint8Array);
-     * // => true
-     *
-     * _.isTypedArray([]);
-     * // => false
-     */
-    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
-
-    /**
-     * Checks if `value` is `undefined`.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
-     * @example
-     *
-     * _.isUndefined(void 0);
-     * // => true
-     *
-     * _.isUndefined(null);
-     * // => false
-     */
-    function isUndefined(value) {
-      return value === undefined;
-    }
-
-    /**
-     * Checks if `value` is classified as a `WeakMap` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.3.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
-     * @example
-     *
-     * _.isWeakMap(new WeakMap);
-     * // => true
-     *
-     * _.isWeakMap(new Map);
-     * // => false
-     */
-    function isWeakMap(value) {
-      return isObjectLike(value) && getTag(value) == weakMapTag;
-    }
-
-    /**
-     * Checks if `value` is classified as a `WeakSet` object.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.3.0
-     * @category Lang
-     * @param {*} value The value to check.
-     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
-     * @example
-     *
-     * _.isWeakSet(new WeakSet);
-     * // => true
-     *
-     * _.isWeakSet(new Set);
-     * // => false
-     */
-    function isWeakSet(value) {
-      return isObjectLike(value) && baseGetTag(value) == weakSetTag;
-    }
-
-    /**
-     * Checks if `value` is less than `other`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.9.0
-     * @category Lang
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {boolean} Returns `true` if `value` is less than `other`,
-     *  else `false`.
-     * @see _.gt
-     * @example
-     *
-     * _.lt(1, 3);
-     * // => true
-     *
-     * _.lt(3, 3);
-     * // => false
-     *
-     * _.lt(3, 1);
-     * // => false
-     */
-    var lt = createRelationalOperation(baseLt);
-
-    /**
-     * Checks if `value` is less than or equal to `other`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.9.0
-     * @category Lang
-     * @param {*} value The value to compare.
-     * @param {*} other The other value to compare.
-     * @returns {boolean} Returns `true` if `value` is less than or equal to
-     *  `other`, else `false`.
-     * @see _.gte
-     * @example
-     *
-     * _.lte(1, 3);
-     * // => true
-     *
-     * _.lte(3, 3);
-     * // => true
-     *
-     * _.lte(3, 1);
-     * // => false
-     */
-    var lte = createRelationalOperation(function(value, other) {
-      return value <= other;
-    });
-
-    /**
-     * Converts `value` to an array.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Lang
-     * @param {*} value The value to convert.
-     * @returns {Array} Returns the converted array.
-     * @example
-     *
-     * _.toArray({ 'a': 1, 'b': 2 });
-     * // => [1, 2]
-     *
-     * _.toArray('abc');
-     * // => ['a', 'b', 'c']
-     *
-     * _.toArray(1);
-     * // => []
-     *
-     * _.toArray(null);
-     * // => []
-     */
-    function toArray(value) {
-      if (!value) {
-        return [];
-      }
-      if (isArrayLike(value)) {
-        return isString(value) ? stringToArray(value) : copyArray(value);
-      }
-      if (symIterator && value[symIterator]) {
-        return iteratorToArray(value[symIterator]());
-      }
-      var tag = getTag(value),
-          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
-
-      return func(value);
-    }
-
-    /**
-     * Converts `value` to a finite number.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.12.0
-     * @category Lang
-     * @param {*} value The value to convert.
-     * @returns {number} Returns the converted number.
-     * @example
-     *
-     * _.toFinite(3.2);
-     * // => 3.2
-     *
-     * _.toFinite(Number.MIN_VALUE);
-     * // => 5e-324
-     *
-     * _.toFinite(Infinity);
-     * // => 1.7976931348623157e+308
-     *
-     * _.toFinite('3.2');
-     * // => 3.2
-     */
-    function toFinite(value) {
-      if (!value) {
-        return value === 0 ? value : 0;
-      }
-      value = toNumber(value);
-      if (value === INFINITY || value === -INFINITY) {
-        var sign = (value < 0 ? -1 : 1);
-        return sign * MAX_INTEGER;
-      }
-      return value === value ? value : 0;
-    }
-
-    /**
-     * Converts `value` to an integer.
-     *
-     * **Note:** This method is loosely based on
-     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to convert.
-     * @returns {number} Returns the converted integer.
-     * @example
-     *
-     * _.toInteger(3.2);
-     * // => 3
-     *
-     * _.toInteger(Number.MIN_VALUE);
-     * // => 0
-     *
-     * _.toInteger(Infinity);
-     * // => 1.7976931348623157e+308
-     *
-     * _.toInteger('3.2');
-     * // => 3
-     */
-    function toInteger(value) {
-      var result = toFinite(value),
-          remainder = result % 1;
-
-      return result === result ? (remainder ? result - remainder : result) : 0;
-    }
-
-    /**
-     * Converts `value` to an integer suitable for use as the length of an
-     * array-like object.
-     *
-     * **Note:** This method is based on
-     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to convert.
-     * @returns {number} Returns the converted integer.
-     * @example
-     *
-     * _.toLength(3.2);
-     * // => 3
-     *
-     * _.toLength(Number.MIN_VALUE);
-     * // => 0
-     *
-     * _.toLength(Infinity);
-     * // => 4294967295
-     *
-     * _.toLength('3.2');
-     * // => 3
-     */
-    function toLength(value) {
-      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
-    }
-
-    /**
-     * Converts `value` to a number.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to process.
-     * @returns {number} Returns the number.
-     * @example
-     *
-     * _.toNumber(3.2);
-     * // => 3.2
-     *
-     * _.toNumber(Number.MIN_VALUE);
-     * // => 5e-324
-     *
-     * _.toNumber(Infinity);
-     * // => Infinity
-     *
-     * _.toNumber('3.2');
-     * // => 3.2
-     */
-    function toNumber(value) {
-      if (typeof value == 'number') {
-        return value;
-      }
-      if (isSymbol(value)) {
-        return NAN;
-      }
-      if (isObject(value)) {
-        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
-        value = isObject(other) ? (other + '') : other;
-      }
-      if (typeof value != 'string') {
-        return value === 0 ? value : +value;
-      }
-      value = value.replace(reTrim, '');
-      var isBinary = reIsBinary.test(value);
-      return (isBinary || reIsOctal.test(value))
-        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
-        : (reIsBadHex.test(value) ? NAN : +value);
-    }
-
-    /**
-     * Converts `value` to a plain object flattening inherited enumerable string
-     * keyed properties of `value` to own properties of the plain object.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Lang
-     * @param {*} value The value to convert.
-     * @returns {Object} Returns the converted plain object.
-     * @example
-     *
-     * function Foo() {
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.assign({ 'a': 1 }, new Foo);
-     * // => { 'a': 1, 'b': 2 }
-     *
-     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
-     * // => { 'a': 1, 'b': 2, 'c': 3 }
-     */
-    function toPlainObject(value) {
-      return copyObject(value, keysIn(value));
-    }
-
-    /**
-     * Converts `value` to a safe integer. A safe integer can be compared and
-     * represented correctly.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to convert.
-     * @returns {number} Returns the converted integer.
-     * @example
-     *
-     * _.toSafeInteger(3.2);
-     * // => 3
-     *
-     * _.toSafeInteger(Number.MIN_VALUE);
-     * // => 0
-     *
-     * _.toSafeInteger(Infinity);
-     * // => 9007199254740991
-     *
-     * _.toSafeInteger('3.2');
-     * // => 3
-     */
-    function toSafeInteger(value) {
-      return value
-        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
-        : (value === 0 ? value : 0);
-    }
-
-    /**
-     * Converts `value` to a string. An empty string is returned for `null`
-     * and `undefined` values. The sign of `-0` is preserved.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Lang
-     * @param {*} value The value to convert.
-     * @returns {string} Returns the converted string.
-     * @example
-     *
-     * _.toString(null);
-     * // => ''
-     *
-     * _.toString(-0);
-     * // => '-0'
-     *
-     * _.toString([1, 2, 3]);
-     * // => '1,2,3'
-     */
-    function toString(value) {
-      return value == null ? '' : baseToString(value);
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Assigns own enumerable string keyed properties of source objects to the
-     * destination object. Source objects are applied from left to right.
-     * Subsequent sources overwrite property assignments of previous sources.
-     *
-     * **Note:** This method mutates `object` and is loosely based on
-     * [`Object.assign`](https://mdn.io/Object/assign).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.10.0
-     * @category Object
-     * @param {Object} object The destination object.
-     * @param {...Object} [sources] The source objects.
-     * @returns {Object} Returns `object`.
-     * @see _.assignIn
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     * }
-     *
-     * function Bar() {
-     *   this.c = 3;
-     * }
-     *
-     * Foo.prototype.b = 2;
-     * Bar.prototype.d = 4;
-     *
-     * _.assign({ 'a': 0 }, new Foo, new Bar);
-     * // => { 'a': 1, 'c': 3 }
-     */
-    var assign = createAssigner(function(object, source) {
-      if (isPrototype(source) || isArrayLike(source)) {
-        copyObject(source, keys(source), object);
-        return;
-      }
-      for (var key in source) {
-        if (hasOwnProperty.call(source, key)) {
-          assignValue(object, key, source[key]);
-        }
-      }
-    });
-
-    /**
-     * This method is like `_.assign` except that it iterates over own and
-     * inherited source properties.
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @alias extend
-     * @category Object
-     * @param {Object} object The destination object.
-     * @param {...Object} [sources] The source objects.
-     * @returns {Object} Returns `object`.
-     * @see _.assign
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     * }
-     *
-     * function Bar() {
-     *   this.c = 3;
-     * }
-     *
-     * Foo.prototype.b = 2;
-     * Bar.prototype.d = 4;
-     *
-     * _.assignIn({ 'a': 0 }, new Foo, new Bar);
-     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
-     */
-    var assignIn = createAssigner(function(object, source) {
-      copyObject(source, keysIn(source), object);
-    });
-
-    /**
-     * This method is like `_.assignIn` except that it accepts `customizer`
-     * which is invoked to produce the assigned values. If `customizer` returns
-     * `undefined`, assignment is handled by the method instead. The `customizer`
-     * is invoked with five arguments: (objValue, srcValue, key, object, source).
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @alias extendWith
-     * @category Object
-     * @param {Object} object The destination object.
-     * @param {...Object} sources The source objects.
-     * @param {Function} [customizer] The function to customize assigned values.
-     * @returns {Object} Returns `object`.
-     * @see _.assignWith
-     * @example
-     *
-     * function customizer(objValue, srcValue) {
-     *   return _.isUndefined(objValue) ? srcValue : objValue;
-     * }
-     *
-     * var defaults = _.partialRight(_.assignInWith, customizer);
-     *
-     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
-     * // => { 'a': 1, 'b': 2 }
-     */
-    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
-      copyObject(source, keysIn(source), object, customizer);
-    });
-
-    /**
-     * This method is like `_.assign` except that it accepts `customizer`
-     * which is invoked to produce the assigned values. If `customizer` returns
-     * `undefined`, assignment is handled by the method instead. The `customizer`
-     * is invoked with five arguments: (objValue, srcValue, key, object, source).
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The destination object.
-     * @param {...Object} sources The source objects.
-     * @param {Function} [customizer] The function to customize assigned values.
-     * @returns {Object} Returns `object`.
-     * @see _.assignInWith
-     * @example
-     *
-     * function customizer(objValue, srcValue) {
-     *   return _.isUndefined(objValue) ? srcValue : objValue;
-     * }
-     *
-     * var defaults = _.partialRight(_.assignWith, customizer);
-     *
-     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
-     * // => { 'a': 1, 'b': 2 }
-     */
-    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
-      copyObject(source, keys(source), object, customizer);
-    });
-
-    /**
-     * Creates an array of values corresponding to `paths` of `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.0.0
-     * @category Object
-     * @param {Object} object The object to iterate over.
-     * @param {...(string|string[])} [paths] The property paths to pick.
-     * @returns {Array} Returns the picked values.
-     * @example
-     *
-     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
-     *
-     * _.at(object, ['a[0].b.c', 'a[1]']);
-     * // => [3, 4]
-     */
-    var at = flatRest(baseAt);
-
-    /**
-     * Creates an object that inherits from the `prototype` object. If a
-     * `properties` object is given, its own enumerable string keyed properties
-     * are assigned to the created object.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.3.0
-     * @category Object
-     * @param {Object} prototype The object to inherit from.
-     * @param {Object} [properties] The properties to assign to the object.
-     * @returns {Object} Returns the new object.
-     * @example
-     *
-     * function Shape() {
-     *   this.x = 0;
-     *   this.y = 0;
-     * }
-     *
-     * function Circle() {
-     *   Shape.call(this);
-     * }
-     *
-     * Circle.prototype = _.create(Shape.prototype, {
-     *   'constructor': Circle
-     * });
-     *
-     * var circle = new Circle;
-     * circle instanceof Circle;
-     * // => true
-     *
-     * circle instanceof Shape;
-     * // => true
-     */
-    function create(prototype, properties) {
-      var result = baseCreate(prototype);
-      return properties == null ? result : baseAssign(result, properties);
-    }
-
-    /**
-     * Assigns own and inherited enumerable string keyed properties of source
-     * objects to the destination object for all destination properties that
-     * resolve to `undefined`. Source objects are applied from left to right.
-     * Once a property is set, additional values of the same property are ignored.
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Object
-     * @param {Object} object The destination object.
-     * @param {...Object} [sources] The source objects.
-     * @returns {Object} Returns `object`.
-     * @see _.defaultsDeep
-     * @example
-     *
-     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
-     * // => { 'a': 1, 'b': 2 }
-     */
-    var defaults = baseRest(function(args) {
-      args.push(undefined, customDefaultsAssignIn);
-      return apply(assignInWith, undefined, args);
-    });
-
-    /**
-     * This method is like `_.defaults` except that it recursively assigns
-     * default properties.
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.10.0
-     * @category Object
-     * @param {Object} object The destination object.
-     * @param {...Object} [sources] The source objects.
-     * @returns {Object} Returns `object`.
-     * @see _.defaults
-     * @example
-     *
-     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
-     * // => { 'a': { 'b': 2, 'c': 3 } }
-     */
-    var defaultsDeep = baseRest(function(args) {
-      args.push(undefined, customDefaultsMerge);
-      return apply(mergeWith, undefined, args);
-    });
-
-    /**
-     * This method is like `_.find` except that it returns the key of the first
-     * element `predicate` returns truthy for instead of the element itself.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.1.0
-     * @category Object
-     * @param {Object} object The object to inspect.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {string|undefined} Returns the key of the matched element,
-     *  else `undefined`.
-     * @example
-     *
-     * var users = {
-     *   'barney':  { 'age': 36, 'active': true },
-     *   'fred':    { 'age': 40, 'active': false },
-     *   'pebbles': { 'age': 1,  'active': true }
-     * };
-     *
-     * _.findKey(users, function(o) { return o.age < 40; });
-     * // => 'barney' (iteration order is not guaranteed)
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.findKey(users, { 'age': 1, 'active': true });
-     * // => 'pebbles'
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.findKey(users, ['active', false]);
-     * // => 'fred'
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.findKey(users, 'active');
-     * // => 'barney'
-     */
-    function findKey(object, predicate) {
-      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
-    }
-
-    /**
-     * This method is like `_.findKey` except that it iterates over elements of
-     * a collection in the opposite order.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Object
-     * @param {Object} object The object to inspect.
-     * @param {Function} [predicate=_.identity] The function invoked per iteration.
-     * @returns {string|undefined} Returns the key of the matched element,
-     *  else `undefined`.
-     * @example
-     *
-     * var users = {
-     *   'barney':  { 'age': 36, 'active': true },
-     *   'fred':    { 'age': 40, 'active': false },
-     *   'pebbles': { 'age': 1,  'active': true }
-     * };
-     *
-     * _.findLastKey(users, function(o) { return o.age < 40; });
-     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.findLastKey(users, { 'age': 36, 'active': true });
-     * // => 'barney'
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.findLastKey(users, ['active', false]);
-     * // => 'fred'
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.findLastKey(users, 'active');
-     * // => 'pebbles'
-     */
-    function findLastKey(object, predicate) {
-      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
-    }
-
-    /**
-     * Iterates over own and inherited enumerable string keyed properties of an
-     * object and invokes `iteratee` for each property. The iteratee is invoked
-     * with three arguments: (value, key, object). Iteratee functions may exit
-     * iteration early by explicitly returning `false`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.3.0
-     * @category Object
-     * @param {Object} object The object to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Object} Returns `object`.
-     * @see _.forInRight
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.forIn(new Foo, function(value, key) {
-     *   console.log(key);
-     * });
-     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
-     */
-    function forIn(object, iteratee) {
-      return object == null
-        ? object
-        : baseFor(object, getIteratee(iteratee, 3), keysIn);
-    }
-
-    /**
-     * This method is like `_.forIn` except that it iterates over properties of
-     * `object` in the opposite order.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Object
-     * @param {Object} object The object to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Object} Returns `object`.
-     * @see _.forIn
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.forInRight(new Foo, function(value, key) {
-     *   console.log(key);
-     * });
-     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
-     */
-    function forInRight(object, iteratee) {
-      return object == null
-        ? object
-        : baseForRight(object, getIteratee(iteratee, 3), keysIn);
-    }
-
-    /**
-     * Iterates over own enumerable string keyed properties of an object and
-     * invokes `iteratee` for each property. The iteratee is invoked with three
-     * arguments: (value, key, object). Iteratee functions may exit iteration
-     * early by explicitly returning `false`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.3.0
-     * @category Object
-     * @param {Object} object The object to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Object} Returns `object`.
-     * @see _.forOwnRight
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.forOwn(new Foo, function(value, key) {
-     *   console.log(key);
-     * });
-     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
-     */
-    function forOwn(object, iteratee) {
-      return object && baseForOwn(object, getIteratee(iteratee, 3));
-    }
-
-    /**
-     * This method is like `_.forOwn` except that it iterates over properties of
-     * `object` in the opposite order.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.0.0
-     * @category Object
-     * @param {Object} object The object to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Object} Returns `object`.
-     * @see _.forOwn
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.forOwnRight(new Foo, function(value, key) {
-     *   console.log(key);
-     * });
-     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
-     */
-    function forOwnRight(object, iteratee) {
-      return object && baseForOwnRight(object, getIteratee(iteratee, 3));
-    }
-
-    /**
-     * Creates an array of function property names from own enumerable properties
-     * of `object`.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Object
-     * @param {Object} object The object to inspect.
-     * @returns {Array} Returns the function names.
-     * @see _.functionsIn
-     * @example
-     *
-     * function Foo() {
-     *   this.a = _.constant('a');
-     *   this.b = _.constant('b');
-     * }
-     *
-     * Foo.prototype.c = _.constant('c');
-     *
-     * _.functions(new Foo);
-     * // => ['a', 'b']
-     */
-    function functions(object) {
-      return object == null ? [] : baseFunctions(object, keys(object));
-    }
-
-    /**
-     * Creates an array of function property names from own and inherited
-     * enumerable properties of `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The object to inspect.
-     * @returns {Array} Returns the function names.
-     * @see _.functions
-     * @example
-     *
-     * function Foo() {
-     *   this.a = _.constant('a');
-     *   this.b = _.constant('b');
-     * }
-     *
-     * Foo.prototype.c = _.constant('c');
-     *
-     * _.functionsIn(new Foo);
-     * // => ['a', 'b', 'c']
-     */
-    function functionsIn(object) {
-      return object == null ? [] : baseFunctions(object, keysIn(object));
-    }
-
-    /**
-     * Gets the value at `path` of `object`. If the resolved value is
-     * `undefined`, the `defaultValue` is returned in its place.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.7.0
-     * @category Object
-     * @param {Object} object The object to query.
-     * @param {Array|string} path The path of the property to get.
-     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
-     * @returns {*} Returns the resolved value.
-     * @example
-     *
-     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
-     *
-     * _.get(object, 'a[0].b.c');
-     * // => 3
-     *
-     * _.get(object, ['a', '0', 'b', 'c']);
-     * // => 3
-     *
-     * _.get(object, 'a.b.c', 'default');
-     * // => 'default'
-     */
-    function get(object, path, defaultValue) {
-      var result = object == null ? undefined : baseGet(object, path);
-      return result === undefined ? defaultValue : result;
-    }
-
-    /**
-     * Checks if `path` is a direct property of `object`.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Object
-     * @param {Object} object The object to query.
-     * @param {Array|string} path The path to check.
-     * @returns {boolean} Returns `true` if `path` exists, else `false`.
-     * @example
-     *
-     * var object = { 'a': { 'b': 2 } };
-     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
-     *
-     * _.has(object, 'a');
-     * // => true
-     *
-     * _.has(object, 'a.b');
-     * // => true
-     *
-     * _.has(object, ['a', 'b']);
-     * // => true
-     *
-     * _.has(other, 'a');
-     * // => false
-     */
-    function has(object, path) {
-      return object != null && hasPath(object, path, baseHas);
-    }
-
-    /**
-     * Checks if `path` is a direct or inherited property of `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The object to query.
-     * @param {Array|string} path The path to check.
-     * @returns {boolean} Returns `true` if `path` exists, else `false`.
-     * @example
-     *
-     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
-     *
-     * _.hasIn(object, 'a');
-     * // => true
-     *
-     * _.hasIn(object, 'a.b');
-     * // => true
-     *
-     * _.hasIn(object, ['a', 'b']);
-     * // => true
-     *
-     * _.hasIn(object, 'b');
-     * // => false
-     */
-    function hasIn(object, path) {
-      return object != null && hasPath(object, path, baseHasIn);
-    }
-
-    /**
-     * Creates an object composed of the inverted keys and values of `object`.
-     * If `object` contains duplicate values, subsequent values overwrite
-     * property assignments of previous values.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.7.0
-     * @category Object
-     * @param {Object} object The object to invert.
-     * @returns {Object} Returns the new inverted object.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': 2, 'c': 1 };
-     *
-     * _.invert(object);
-     * // => { '1': 'c', '2': 'b' }
-     */
-    var invert = createInverter(function(result, value, key) {
-      result[value] = key;
-    }, constant(identity));
-
-    /**
-     * This method is like `_.invert` except that the inverted object is generated
-     * from the results of running each element of `object` thru `iteratee`. The
-     * corresponding inverted value of each inverted key is an array of keys
-     * responsible for generating the inverted value. The iteratee is invoked
-     * with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.1.0
-     * @category Object
-     * @param {Object} object The object to invert.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {Object} Returns the new inverted object.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': 2, 'c': 1 };
-     *
-     * _.invertBy(object);
-     * // => { '1': ['a', 'c'], '2': ['b'] }
-     *
-     * _.invertBy(object, function(value) {
-     *   return 'group' + value;
-     * });
-     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
-     */
-    var invertBy = createInverter(function(result, value, key) {
-      if (hasOwnProperty.call(result, value)) {
-        result[value].push(key);
-      } else {
-        result[value] = [key];
-      }
-    }, getIteratee);
-
-    /**
-     * Invokes the method at `path` of `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The object to query.
-     * @param {Array|string} path The path of the method to invoke.
-     * @param {...*} [args] The arguments to invoke the method with.
-     * @returns {*} Returns the result of the invoked method.
-     * @example
-     *
-     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
-     *
-     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
-     * // => [2, 3]
-     */
-    var invoke = baseRest(baseInvoke);
-
-    /**
-     * Creates an array of the own enumerable property names of `object`.
-     *
-     * **Note:** Non-object values are coerced to objects. See the
-     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
-     * for more details.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Object
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property names.
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.keys(new Foo);
-     * // => ['a', 'b'] (iteration order is not guaranteed)
-     *
-     * _.keys('hi');
-     * // => ['0', '1']
-     */
-    function keys(object) {
-      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
-    }
-
-    /**
-     * Creates an array of the own and inherited enumerable property names of `object`.
-     *
-     * **Note:** Non-object values are coerced to objects.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Object
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property names.
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.keysIn(new Foo);
-     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
-     */
-    function keysIn(object) {
-      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
-    }
-
-    /**
-     * The opposite of `_.mapValues`; this method creates an object with the
-     * same values as `object` and keys generated by running each own enumerable
-     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
-     * with three arguments: (value, key, object).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.8.0
-     * @category Object
-     * @param {Object} object The object to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Object} Returns the new mapped object.
-     * @see _.mapValues
-     * @example
-     *
-     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
-     *   return key + value;
-     * });
-     * // => { 'a1': 1, 'b2': 2 }
-     */
-    function mapKeys(object, iteratee) {
-      var result = {};
-      iteratee = getIteratee(iteratee, 3);
-
-      baseForOwn(object, function(value, key, object) {
-        baseAssignValue(result, iteratee(value, key, object), value);
-      });
-      return result;
-    }
-
-    /**
-     * Creates an object with the same keys as `object` and values generated
-     * by running each own enumerable string keyed property of `object` thru
-     * `iteratee`. The iteratee is invoked with three arguments:
-     * (value, key, object).
-     *
-     * @static
-     * @memberOf _
-     * @since 2.4.0
-     * @category Object
-     * @param {Object} object The object to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Object} Returns the new mapped object.
-     * @see _.mapKeys
-     * @example
-     *
-     * var users = {
-     *   'fred':    { 'user': 'fred',    'age': 40 },
-     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
-     * };
-     *
-     * _.mapValues(users, function(o) { return o.age; });
-     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.mapValues(users, 'age');
-     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
-     */
-    function mapValues(object, iteratee) {
-      var result = {};
-      iteratee = getIteratee(iteratee, 3);
-
-      baseForOwn(object, function(value, key, object) {
-        baseAssignValue(result, key, iteratee(value, key, object));
-      });
-      return result;
-    }
-
-    /**
-     * This method is like `_.assign` except that it recursively merges own and
-     * inherited enumerable string keyed properties of source objects into the
-     * destination object. Source properties that resolve to `undefined` are
-     * skipped if a destination value exists. Array and plain object properties
-     * are merged recursively. Other objects and value types are overridden by
-     * assignment. Source objects are applied from left to right. Subsequent
-     * sources overwrite property assignments of previous sources.
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.5.0
-     * @category Object
-     * @param {Object} object The destination object.
-     * @param {...Object} [sources] The source objects.
-     * @returns {Object} Returns `object`.
-     * @example
-     *
-     * var object = {
-     *   'a': [{ 'b': 2 }, { 'd': 4 }]
-     * };
-     *
-     * var other = {
-     *   'a': [{ 'c': 3 }, { 'e': 5 }]
-     * };
-     *
-     * _.merge(object, other);
-     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
-     */
-    var merge = createAssigner(function(object, source, srcIndex) {
-      baseMerge(object, source, srcIndex);
-    });
-
-    /**
-     * This method is like `_.merge` except that it accepts `customizer` which
-     * is invoked to produce the merged values of the destination and source
-     * properties. If `customizer` returns `undefined`, merging is handled by the
-     * method instead. The `customizer` is invoked with six arguments:
-     * (objValue, srcValue, key, object, source, stack).
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The destination object.
-     * @param {...Object} sources The source objects.
-     * @param {Function} customizer The function to customize assigned values.
-     * @returns {Object} Returns `object`.
-     * @example
-     *
-     * function customizer(objValue, srcValue) {
-     *   if (_.isArray(objValue)) {
-     *     return objValue.concat(srcValue);
-     *   }
-     * }
-     *
-     * var object = { 'a': [1], 'b': [2] };
-     * var other = { 'a': [3], 'b': [4] };
-     *
-     * _.mergeWith(object, other, customizer);
-     * // => { 'a': [1, 3], 'b': [2, 4] }
-     */
-    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
-      baseMerge(object, source, srcIndex, customizer);
-    });
-
-    /**
-     * The opposite of `_.pick`; this method creates an object composed of the
-     * own and inherited enumerable property paths of `object` that are not omitted.
-     *
-     * **Note:** This method is considerably slower than `_.pick`.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Object
-     * @param {Object} object The source object.
-     * @param {...(string|string[])} [paths] The property paths to omit.
-     * @returns {Object} Returns the new object.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': '2', 'c': 3 };
-     *
-     * _.omit(object, ['a', 'c']);
-     * // => { 'b': '2' }
-     */
-    var omit = flatRest(function(object, paths) {
-      var result = {};
-      if (object == null) {
-        return result;
-      }
-      var isDeep = false;
-      paths = arrayMap(paths, function(path) {
-        path = castPath(path, object);
-        isDeep || (isDeep = path.length > 1);
-        return path;
-      });
-      copyObject(object, getAllKeysIn(object), result);
-      if (isDeep) {
-        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
-      }
-      var length = paths.length;
-      while (length--) {
-        baseUnset(result, paths[length]);
-      }
-      return result;
-    });
-
-    /**
-     * The opposite of `_.pickBy`; this method creates an object composed of
-     * the own and inherited enumerable string keyed properties of `object` that
-     * `predicate` doesn't return truthy for. The predicate is invoked with two
-     * arguments: (value, key).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The source object.
-     * @param {Function} [predicate=_.identity] The function invoked per property.
-     * @returns {Object} Returns the new object.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': '2', 'c': 3 };
-     *
-     * _.omitBy(object, _.isNumber);
-     * // => { 'b': '2' }
-     */
-    function omitBy(object, predicate) {
-      return pickBy(object, negate(getIteratee(predicate)));
-    }
-
-    /**
-     * Creates an object composed of the picked `object` properties.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Object
-     * @param {Object} object The source object.
-     * @param {...(string|string[])} [paths] The property paths to pick.
-     * @returns {Object} Returns the new object.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': '2', 'c': 3 };
-     *
-     * _.pick(object, ['a', 'c']);
-     * // => { 'a': 1, 'c': 3 }
-     */
-    var pick = flatRest(function(object, paths) {
-      return object == null ? {} : basePick(object, paths);
-    });
-
-    /**
-     * Creates an object composed of the `object` properties `predicate` returns
-     * truthy for. The predicate is invoked with two arguments: (value, key).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The source object.
-     * @param {Function} [predicate=_.identity] The function invoked per property.
-     * @returns {Object} Returns the new object.
-     * @example
-     *
-     * var object = { 'a': 1, 'b': '2', 'c': 3 };
-     *
-     * _.pickBy(object, _.isNumber);
-     * // => { 'a': 1, 'c': 3 }
-     */
-    function pickBy(object, predicate) {
-      if (object == null) {
-        return {};
-      }
-      var props = arrayMap(getAllKeysIn(object), function(prop) {
-        return [prop];
-      });
-      predicate = getIteratee(predicate);
-      return basePickBy(object, props, function(value, path) {
-        return predicate(value, path[0]);
-      });
-    }
-
-    /**
-     * This method is like `_.get` except that if the resolved value is a
-     * function it's invoked with the `this` binding of its parent object and
-     * its result is returned.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Object
-     * @param {Object} object The object to query.
-     * @param {Array|string} path The path of the property to resolve.
-     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
-     * @returns {*} Returns the resolved value.
-     * @example
-     *
-     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
-     *
-     * _.result(object, 'a[0].b.c1');
-     * // => 3
-     *
-     * _.result(object, 'a[0].b.c2');
-     * // => 4
-     *
-     * _.result(object, 'a[0].b.c3', 'default');
-     * // => 'default'
-     *
-     * _.result(object, 'a[0].b.c3', _.constant('default'));
-     * // => 'default'
-     */
-    function result(object, path, defaultValue) {
-      path = castPath(path, object);
-
-      var index = -1,
-          length = path.length;
-
-      // Ensure the loop is entered when path is empty.
-      if (!length) {
-        length = 1;
-        object = undefined;
-      }
-      while (++index < length) {
-        var value = object == null ? undefined : object[toKey(path[index])];
-        if (value === undefined) {
-          index = length;
-          value = defaultValue;
-        }
-        object = isFunction(value) ? value.call(object) : value;
-      }
-      return object;
-    }
-
-    /**
-     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
-     * it's created. Arrays are created for missing index properties while objects
-     * are created for all other missing properties. Use `_.setWith` to customize
-     * `path` creation.
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.7.0
-     * @category Object
-     * @param {Object} object The object to modify.
-     * @param {Array|string} path The path of the property to set.
-     * @param {*} value The value to set.
-     * @returns {Object} Returns `object`.
-     * @example
-     *
-     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
-     *
-     * _.set(object, 'a[0].b.c', 4);
-     * console.log(object.a[0].b.c);
-     * // => 4
-     *
-     * _.set(object, ['x', '0', 'y', 'z'], 5);
-     * console.log(object.x[0].y.z);
-     * // => 5
-     */
-    function set(object, path, value) {
-      return object == null ? object : baseSet(object, path, value);
-    }
-
-    /**
-     * This method is like `_.set` except that it accepts `customizer` which is
-     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
-     * path creation is handled by the method instead. The `customizer` is invoked
-     * with three arguments: (nsValue, key, nsObject).
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The object to modify.
-     * @param {Array|string} path The path of the property to set.
-     * @param {*} value The value to set.
-     * @param {Function} [customizer] The function to customize assigned values.
-     * @returns {Object} Returns `object`.
-     * @example
-     *
-     * var object = {};
-     *
-     * _.setWith(object, '[0][1]', 'a', Object);
-     * // => { '0': { '1': 'a' } }
-     */
-    function setWith(object, path, value, customizer) {
-      customizer = typeof customizer == 'function' ? customizer : undefined;
-      return object == null ? object : baseSet(object, path, value, customizer);
-    }
-
-    /**
-     * Creates an array of own enumerable string keyed-value pairs for `object`
-     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
-     * entries are returned.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @alias entries
-     * @category Object
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the key-value pairs.
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.toPairs(new Foo);
-     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
-     */
-    var toPairs = createToPairs(keys);
-
-    /**
-     * Creates an array of own and inherited enumerable string keyed-value pairs
-     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
-     * or set, its entries are returned.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @alias entriesIn
-     * @category Object
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the key-value pairs.
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.toPairsIn(new Foo);
-     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
-     */
-    var toPairsIn = createToPairs(keysIn);
-
-    /**
-     * An alternative to `_.reduce`; this method transforms `object` to a new
-     * `accumulator` object which is the result of running each of its own
-     * enumerable string keyed properties thru `iteratee`, with each invocation
-     * potentially mutating the `accumulator` object. If `accumulator` is not
-     * provided, a new object with the same `[[Prototype]]` will be used. The
-     * iteratee is invoked with four arguments: (accumulator, value, key, object).
-     * Iteratee functions may exit iteration early by explicitly returning `false`.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.3.0
-     * @category Object
-     * @param {Object} object The object to iterate over.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @param {*} [accumulator] The custom accumulator value.
-     * @returns {*} Returns the accumulated value.
-     * @example
-     *
-     * _.transform([2, 3, 4], function(result, n) {
-     *   result.push(n *= n);
-     *   return n % 2 == 0;
-     * }, []);
-     * // => [4, 9]
-     *
-     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
-     *   (result[value] || (result[value] = [])).push(key);
-     * }, {});
-     * // => { '1': ['a', 'c'], '2': ['b'] }
-     */
-    function transform(object, iteratee, accumulator) {
-      var isArr = isArray(object),
-          isArrLike = isArr || isBuffer(object) || isTypedArray(object);
-
-      iteratee = getIteratee(iteratee, 4);
-      if (accumulator == null) {
-        var Ctor = object && object.constructor;
-        if (isArrLike) {
-          accumulator = isArr ? new Ctor : [];
-        }
-        else if (isObject(object)) {
-          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
-        }
-        else {
-          accumulator = {};
-        }
-      }
-      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
-        return iteratee(accumulator, value, index, object);
-      });
-      return accumulator;
-    }
-
-    /**
-     * Removes the property at `path` of `object`.
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Object
-     * @param {Object} object The object to modify.
-     * @param {Array|string} path The path of the property to unset.
-     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
-     * @example
-     *
-     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
-     * _.unset(object, 'a[0].b.c');
-     * // => true
-     *
-     * console.log(object);
-     * // => { 'a': [{ 'b': {} }] };
-     *
-     * _.unset(object, ['a', '0', 'b', 'c']);
-     * // => true
-     *
-     * console.log(object);
-     * // => { 'a': [{ 'b': {} }] };
-     */
-    function unset(object, path) {
-      return object == null ? true : baseUnset(object, path);
-    }
-
-    /**
-     * This method is like `_.set` except that accepts `updater` to produce the
-     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
-     * is invoked with one argument: (value).
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.6.0
-     * @category Object
-     * @param {Object} object The object to modify.
-     * @param {Array|string} path The path of the property to set.
-     * @param {Function} updater The function to produce the updated value.
-     * @returns {Object} Returns `object`.
-     * @example
-     *
-     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
-     *
-     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
-     * console.log(object.a[0].b.c);
-     * // => 9
-     *
-     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
-     * console.log(object.x[0].y.z);
-     * // => 0
-     */
-    function update(object, path, updater) {
-      return object == null ? object : baseUpdate(object, path, castFunction(updater));
-    }
-
-    /**
-     * This method is like `_.update` except that it accepts `customizer` which is
-     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
-     * path creation is handled by the method instead. The `customizer` is invoked
-     * with three arguments: (nsValue, key, nsObject).
-     *
-     * **Note:** This method mutates `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.6.0
-     * @category Object
-     * @param {Object} object The object to modify.
-     * @param {Array|string} path The path of the property to set.
-     * @param {Function} updater The function to produce the updated value.
-     * @param {Function} [customizer] The function to customize assigned values.
-     * @returns {Object} Returns `object`.
-     * @example
-     *
-     * var object = {};
-     *
-     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
-     * // => { '0': { '1': 'a' } }
-     */
-    function updateWith(object, path, updater, customizer) {
-      customizer = typeof customizer == 'function' ? customizer : undefined;
-      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
-    }
-
-    /**
-     * Creates an array of the own enumerable string keyed property values of `object`.
-     *
-     * **Note:** Non-object values are coerced to objects.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Object
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property values.
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.values(new Foo);
-     * // => [1, 2] (iteration order is not guaranteed)
-     *
-     * _.values('hi');
-     * // => ['h', 'i']
-     */
-    function values(object) {
-      return object == null ? [] : baseValues(object, keys(object));
-    }
-
-    /**
-     * Creates an array of the own and inherited enumerable string keyed property
-     * values of `object`.
-     *
-     * **Note:** Non-object values are coerced to objects.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Object
-     * @param {Object} object The object to query.
-     * @returns {Array} Returns the array of property values.
-     * @example
-     *
-     * function Foo() {
-     *   this.a = 1;
-     *   this.b = 2;
-     * }
-     *
-     * Foo.prototype.c = 3;
-     *
-     * _.valuesIn(new Foo);
-     * // => [1, 2, 3] (iteration order is not guaranteed)
-     */
-    function valuesIn(object) {
-      return object == null ? [] : baseValues(object, keysIn(object));
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Clamps `number` within the inclusive `lower` and `upper` bounds.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Number
-     * @param {number} number The number to clamp.
-     * @param {number} [lower] The lower bound.
-     * @param {number} upper The upper bound.
-     * @returns {number} Returns the clamped number.
-     * @example
-     *
-     * _.clamp(-10, -5, 5);
-     * // => -5
-     *
-     * _.clamp(10, -5, 5);
-     * // => 5
-     */
-    function clamp(number, lower, upper) {
-      if (upper === undefined) {
-        upper = lower;
-        lower = undefined;
-      }
-      if (upper !== undefined) {
-        upper = toNumber(upper);
-        upper = upper === upper ? upper : 0;
-      }
-      if (lower !== undefined) {
-        lower = toNumber(lower);
-        lower = lower === lower ? lower : 0;
-      }
-      return baseClamp(toNumber(number), lower, upper);
-    }
-
-    /**
-     * Checks if `n` is between `start` and up to, but not including, `end`. If
-     * `end` is not specified, it's set to `start` with `start` then set to `0`.
-     * If `start` is greater than `end` the params are swapped to support
-     * negative ranges.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.3.0
-     * @category Number
-     * @param {number} number The number to check.
-     * @param {number} [start=0] The start of the range.
-     * @param {number} end The end of the range.
-     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
-     * @see _.range, _.rangeRight
-     * @example
-     *
-     * _.inRange(3, 2, 4);
-     * // => true
-     *
-     * _.inRange(4, 8);
-     * // => true
-     *
-     * _.inRange(4, 2);
-     * // => false
-     *
-     * _.inRange(2, 2);
-     * // => false
-     *
-     * _.inRange(1.2, 2);
-     * // => true
-     *
-     * _.inRange(5.2, 4);
-     * // => false
-     *
-     * _.inRange(-3, -2, -6);
-     * // => true
-     */
-    function inRange(number, start, end) {
-      start = toFinite(start);
-      if (end === undefined) {
-        end = start;
-        start = 0;
-      } else {
-        end = toFinite(end);
-      }
-      number = toNumber(number);
-      return baseInRange(number, start, end);
-    }
-
-    /**
-     * Produces a random number between the inclusive `lower` and `upper` bounds.
-     * If only one argument is provided a number between `0` and the given number
-     * is returned. If `floating` is `true`, or either `lower` or `upper` are
-     * floats, a floating-point number is returned instead of an integer.
-     *
-     * **Note:** JavaScript follows the IEEE-754 standard for resolving
-     * floating-point values which can produce unexpected results.
-     *
-     * @static
-     * @memberOf _
-     * @since 0.7.0
-     * @category Number
-     * @param {number} [lower=0] The lower bound.
-     * @param {number} [upper=1] The upper bound.
-     * @param {boolean} [floating] Specify returning a floating-point number.
-     * @returns {number} Returns the random number.
-     * @example
-     *
-     * _.random(0, 5);
-     * // => an integer between 0 and 5
-     *
-     * _.random(5);
-     * // => also an integer between 0 and 5
-     *
-     * _.random(5, true);
-     * // => a floating-point number between 0 and 5
-     *
-     * _.random(1.2, 5.2);
-     * // => a floating-point number between 1.2 and 5.2
-     */
-    function random(lower, upper, floating) {
-      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
-        upper = floating = undefined;
-      }
-      if (floating === undefined) {
-        if (typeof upper == 'boolean') {
-          floating = upper;
-          upper = undefined;
-        }
-        else if (typeof lower == 'boolean') {
-          floating = lower;
-          lower = undefined;
-        }
-      }
-      if (lower === undefined && upper === undefined) {
-        lower = 0;
-        upper = 1;
-      }
-      else {
-        lower = toFinite(lower);
-        if (upper === undefined) {
-          upper = lower;
-          lower = 0;
-        } else {
-          upper = toFinite(upper);
-        }
-      }
-      if (lower > upper) {
-        var temp = lower;
-        lower = upper;
-        upper = temp;
-      }
-      if (floating || lower % 1 || upper % 1) {
-        var rand = nativeRandom();
-        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
-      }
-      return baseRandom(lower, upper);
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the camel cased string.
-     * @example
-     *
-     * _.camelCase('Foo Bar');
-     * // => 'fooBar'
-     *
-     * _.camelCase('--foo-bar--');
-     * // => 'fooBar'
-     *
-     * _.camelCase('__FOO_BAR__');
-     * // => 'fooBar'
-     */
-    var camelCase = createCompounder(function(result, word, index) {
-      word = word.toLowerCase();
-      return result + (index ? capitalize(word) : word);
-    });
-
-    /**
-     * Converts the first character of `string` to upper case and the remaining
-     * to lower case.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to capitalize.
-     * @returns {string} Returns the capitalized string.
-     * @example
-     *
-     * _.capitalize('FRED');
-     * // => 'Fred'
-     */
-    function capitalize(string) {
-      return upperFirst(toString(string).toLowerCase());
-    }
-
-    /**
-     * Deburrs `string` by converting
-     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
-     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
-     * letters to basic Latin letters and removing
-     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to deburr.
-     * @returns {string} Returns the deburred string.
-     * @example
-     *
-     * _.deburr('déjà vu');
-     * // => 'deja vu'
-     */
-    function deburr(string) {
-      string = toString(string);
-      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
-    }
-
-    /**
-     * Checks if `string` ends with the given target string.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to inspect.
-     * @param {string} [target] The string to search for.
-     * @param {number} [position=string.length] The position to search up to.
-     * @returns {boolean} Returns `true` if `string` ends with `target`,
-     *  else `false`.
-     * @example
-     *
-     * _.endsWith('abc', 'c');
-     * // => true
-     *
-     * _.endsWith('abc', 'b');
-     * // => false
-     *
-     * _.endsWith('abc', 'b', 2);
-     * // => true
-     */
-    function endsWith(string, target, position) {
-      string = toString(string);
-      target = baseToString(target);
-
-      var length = string.length;
-      position = position === undefined
-        ? length
-        : baseClamp(toInteger(position), 0, length);
-
-      var end = position;
-      position -= target.length;
-      return position >= 0 && string.slice(position, end) == target;
-    }
-
-    /**
-     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
-     * corresponding HTML entities.
-     *
-     * **Note:** No other characters are escaped. To escape additional
-     * characters use a third-party library like [_he_](https://mths.be/he).
-     *
-     * Though the ">" character is escaped for symmetry, characters like
-     * ">" and "/" don't need escaping in HTML and have no special meaning
-     * unless they're part of a tag or unquoted attribute value. See
-     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
-     * (under "semi-related fun fact") for more details.
-     *
-     * When working with HTML you should always
-     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
-     * XSS vectors.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category String
-     * @param {string} [string=''] The string to escape.
-     * @returns {string} Returns the escaped string.
-     * @example
-     *
-     * _.escape('fred, barney, & pebbles');
-     * // => 'fred, barney, &amp; pebbles'
-     */
-    function escape(string) {
-      string = toString(string);
-      return (string && reHasUnescapedHtml.test(string))
-        ? string.replace(reUnescapedHtml, escapeHtmlChar)
-        : string;
-    }
-
-    /**
-     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
-     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to escape.
-     * @returns {string} Returns the escaped string.
-     * @example
-     *
-     * _.escapeRegExp('[lodash](https://lodash.com/)');
-     * // => '\[lodash\]\(https://lodash\.com/\)'
-     */
-    function escapeRegExp(string) {
-      string = toString(string);
-      return (string && reHasRegExpChar.test(string))
-        ? string.replace(reRegExpChar, '\\$&')
-        : string;
-    }
-
-    /**
-     * Converts `string` to
-     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the kebab cased string.
-     * @example
-     *
-     * _.kebabCase('Foo Bar');
-     * // => 'foo-bar'
-     *
-     * _.kebabCase('fooBar');
-     * // => 'foo-bar'
-     *
-     * _.kebabCase('__FOO_BAR__');
-     * // => 'foo-bar'
-     */
-    var kebabCase = createCompounder(function(result, word, index) {
-      return result + (index ? '-' : '') + word.toLowerCase();
-    });
-
-    /**
-     * Converts `string`, as space separated words, to lower case.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the lower cased string.
-     * @example
-     *
-     * _.lowerCase('--Foo-Bar--');
-     * // => 'foo bar'
-     *
-     * _.lowerCase('fooBar');
-     * // => 'foo bar'
-     *
-     * _.lowerCase('__FOO_BAR__');
-     * // => 'foo bar'
-     */
-    var lowerCase = createCompounder(function(result, word, index) {
-      return result + (index ? ' ' : '') + word.toLowerCase();
-    });
-
-    /**
-     * Converts the first character of `string` to lower case.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the converted string.
-     * @example
-     *
-     * _.lowerFirst('Fred');
-     * // => 'fred'
-     *
-     * _.lowerFirst('FRED');
-     * // => 'fRED'
-     */
-    var lowerFirst = createCaseFirst('toLowerCase');
-
-    /**
-     * Pads `string` on the left and right sides if it's shorter than `length`.
-     * Padding characters are truncated if they can't be evenly divided by `length`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to pad.
-     * @param {number} [length=0] The padding length.
-     * @param {string} [chars=' '] The string used as padding.
-     * @returns {string} Returns the padded string.
-     * @example
-     *
-     * _.pad('abc', 8);
-     * // => '  abc   '
-     *
-     * _.pad('abc', 8, '_-');
-     * // => '_-abc_-_'
-     *
-     * _.pad('abc', 3);
-     * // => 'abc'
-     */
-    function pad(string, length, chars) {
-      string = toString(string);
-      length = toInteger(length);
-
-      var strLength = length ? stringSize(string) : 0;
-      if (!length || strLength >= length) {
-        return string;
-      }
-      var mid = (length - strLength) / 2;
-      return (
-        createPadding(nativeFloor(mid), chars) +
-        string +
-        createPadding(nativeCeil(mid), chars)
-      );
-    }
-
-    /**
-     * Pads `string` on the right side if it's shorter than `length`. Padding
-     * characters are truncated if they exceed `length`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to pad.
-     * @param {number} [length=0] The padding length.
-     * @param {string} [chars=' '] The string used as padding.
-     * @returns {string} Returns the padded string.
-     * @example
-     *
-     * _.padEnd('abc', 6);
-     * // => 'abc   '
-     *
-     * _.padEnd('abc', 6, '_-');
-     * // => 'abc_-_'
-     *
-     * _.padEnd('abc', 3);
-     * // => 'abc'
-     */
-    function padEnd(string, length, chars) {
-      string = toString(string);
-      length = toInteger(length);
-
-      var strLength = length ? stringSize(string) : 0;
-      return (length && strLength < length)
-        ? (string + createPadding(length - strLength, chars))
-        : string;
-    }
-
-    /**
-     * Pads `string` on the left side if it's shorter than `length`. Padding
-     * characters are truncated if they exceed `length`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to pad.
-     * @param {number} [length=0] The padding length.
-     * @param {string} [chars=' '] The string used as padding.
-     * @returns {string} Returns the padded string.
-     * @example
-     *
-     * _.padStart('abc', 6);
-     * // => '   abc'
-     *
-     * _.padStart('abc', 6, '_-');
-     * // => '_-_abc'
-     *
-     * _.padStart('abc', 3);
-     * // => 'abc'
-     */
-    function padStart(string, length, chars) {
-      string = toString(string);
-      length = toInteger(length);
-
-      var strLength = length ? stringSize(string) : 0;
-      return (length && strLength < length)
-        ? (createPadding(length - strLength, chars) + string)
-        : string;
-    }
-
-    /**
-     * Converts `string` to an integer of the specified radix. If `radix` is
-     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
-     * hexadecimal, in which case a `radix` of `16` is used.
-     *
-     * **Note:** This method aligns with the
-     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
-     *
-     * @static
-     * @memberOf _
-     * @since 1.1.0
-     * @category String
-     * @param {string} string The string to convert.
-     * @param {number} [radix=10] The radix to interpret `value` by.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {number} Returns the converted integer.
-     * @example
-     *
-     * _.parseInt('08');
-     * // => 8
-     *
-     * _.map(['6', '08', '10'], _.parseInt);
-     * // => [6, 8, 10]
-     */
-    function parseInt(string, radix, guard) {
-      if (guard || radix == null) {
-        radix = 0;
-      } else if (radix) {
-        radix = +radix;
-      }
-      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
-    }
-
-    /**
-     * Repeats the given string `n` times.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to repeat.
-     * @param {number} [n=1] The number of times to repeat the string.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {string} Returns the repeated string.
-     * @example
-     *
-     * _.repeat('*', 3);
-     * // => '***'
-     *
-     * _.repeat('abc', 2);
-     * // => 'abcabc'
-     *
-     * _.repeat('abc', 0);
-     * // => ''
-     */
-    function repeat(string, n, guard) {
-      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
-        n = 1;
-      } else {
-        n = toInteger(n);
-      }
-      return baseRepeat(toString(string), n);
-    }
-
-    /**
-     * Replaces matches for `pattern` in `string` with `replacement`.
-     *
-     * **Note:** This method is based on
-     * [`String#replace`](https://mdn.io/String/replace).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to modify.
-     * @param {RegExp|string} pattern The pattern to replace.
-     * @param {Function|string} replacement The match replacement.
-     * @returns {string} Returns the modified string.
-     * @example
-     *
-     * _.replace('Hi Fred', 'Fred', 'Barney');
-     * // => 'Hi Barney'
-     */
-    function replace() {
-      var args = arguments,
-          string = toString(args[0]);
-
-      return args.length < 3 ? string : string.replace(args[1], args[2]);
-    }
-
-    /**
-     * Converts `string` to
-     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the snake cased string.
-     * @example
-     *
-     * _.snakeCase('Foo Bar');
-     * // => 'foo_bar'
-     *
-     * _.snakeCase('fooBar');
-     * // => 'foo_bar'
-     *
-     * _.snakeCase('--FOO-BAR--');
-     * // => 'foo_bar'
-     */
-    var snakeCase = createCompounder(function(result, word, index) {
-      return result + (index ? '_' : '') + word.toLowerCase();
-    });
-
-    /**
-     * Splits `string` by `separator`.
-     *
-     * **Note:** This method is based on
-     * [`String#split`](https://mdn.io/String/split).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to split.
-     * @param {RegExp|string} separator The separator pattern to split by.
-     * @param {number} [limit] The length to truncate results to.
-     * @returns {Array} Returns the string segments.
-     * @example
-     *
-     * _.split('a-b-c', '-', 2);
-     * // => ['a', 'b']
-     */
-    function split(string, separator, limit) {
-      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
-        separator = limit = undefined;
-      }
-      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
-      if (!limit) {
-        return [];
-      }
-      string = toString(string);
-      if (string && (
-            typeof separator == 'string' ||
-            (separator != null && !isRegExp(separator))
-          )) {
-        separator = baseToString(separator);
-        if (!separator && hasUnicode(string)) {
-          return castSlice(stringToArray(string), 0, limit);
-        }
-      }
-      return string.split(separator, limit);
-    }
-
-    /**
-     * Converts `string` to
-     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
-     *
-     * @static
-     * @memberOf _
-     * @since 3.1.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the start cased string.
-     * @example
-     *
-     * _.startCase('--foo-bar--');
-     * // => 'Foo Bar'
-     *
-     * _.startCase('fooBar');
-     * // => 'Foo Bar'
-     *
-     * _.startCase('__FOO_BAR__');
-     * // => 'FOO BAR'
-     */
-    var startCase = createCompounder(function(result, word, index) {
-      return result + (index ? ' ' : '') + upperFirst(word);
-    });
-
-    /**
-     * Checks if `string` starts with the given target string.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to inspect.
-     * @param {string} [target] The string to search for.
-     * @param {number} [position=0] The position to search from.
-     * @returns {boolean} Returns `true` if `string` starts with `target`,
-     *  else `false`.
-     * @example
-     *
-     * _.startsWith('abc', 'a');
-     * // => true
-     *
-     * _.startsWith('abc', 'b');
-     * // => false
-     *
-     * _.startsWith('abc', 'b', 1);
-     * // => true
-     */
-    function startsWith(string, target, position) {
-      string = toString(string);
-      position = position == null
-        ? 0
-        : baseClamp(toInteger(position), 0, string.length);
-
-      target = baseToString(target);
-      return string.slice(position, position + target.length) == target;
-    }
-
-    /**
-     * Creates a compiled template function that can interpolate data properties
-     * in "interpolate" delimiters, HTML-escape interpolated data properties in
-     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
-     * properties may be accessed as free variables in the template. If a setting
-     * object is given, it takes precedence over `_.templateSettings` values.
-     *
-     * **Note:** In the development build `_.template` utilizes
-     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
-     * for easier debugging.
-     *
-     * For more information on precompiling templates see
-     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
-     *
-     * For more information on Chrome extension sandboxes see
-     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category String
-     * @param {string} [string=''] The template string.
-     * @param {Object} [options={}] The options object.
-     * @param {RegExp} [options.escape=_.templateSettings.escape]
-     *  The HTML "escape" delimiter.
-     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
-     *  The "evaluate" delimiter.
-     * @param {Object} [options.imports=_.templateSettings.imports]
-     *  An object to import into the template as free variables.
-     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
-     *  The "interpolate" delimiter.
-     * @param {string} [options.sourceURL='lodash.templateSources[n]']
-     *  The sourceURL of the compiled template.
-     * @param {string} [options.variable='obj']
-     *  The data object variable name.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Function} Returns the compiled template function.
-     * @example
-     *
-     * // Use the "interpolate" delimiter to create a compiled template.
-     * var compiled = _.template('hello <%= user %>!');
-     * compiled({ 'user': 'fred' });
-     * // => 'hello fred!'
-     *
-     * // Use the HTML "escape" delimiter to escape data property values.
-     * var compiled = _.template('<b><%- value %></b>');
-     * compiled({ 'value': '<script>' });
-     * // => '<b>&lt;script&gt;</b>'
-     *
-     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
-     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
-     * compiled({ 'users': ['fred', 'barney'] });
-     * // => '<li>fred</li><li>barney</li>'
-     *
-     * // Use the internal `print` function in "evaluate" delimiters.
-     * var compiled = _.template('<% print("hello " + user); %>!');
-     * compiled({ 'user': 'barney' });
-     * // => 'hello barney!'
-     *
-     * // Use the ES template literal delimiter as an "interpolate" delimiter.
-     * // Disable support by replacing the "interpolate" delimiter.
-     * var compiled = _.template('hello ${ user }!');
-     * compiled({ 'user': 'pebbles' });
-     * // => 'hello pebbles!'
-     *
-     * // Use backslashes to treat delimiters as plain text.
-     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
-     * compiled({ 'value': 'ignored' });
-     * // => '<%- value %>'
-     *
-     * // Use the `imports` option to import `jQuery` as `jq`.
-     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
-     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
-     * compiled({ 'users': ['fred', 'barney'] });
-     * // => '<li>fred</li><li>barney</li>'
-     *
-     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
-     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
-     * compiled(data);
-     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
-     *
-     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
-     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
-     * compiled.source;
-     * // => function(data) {
-     * //   var __t, __p = '';
-     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
-     * //   return __p;
-     * // }
-     *
-     * // Use custom template delimiters.
-     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
-     * var compiled = _.template('hello {{ user }}!');
-     * compiled({ 'user': 'mustache' });
-     * // => 'hello mustache!'
-     *
-     * // Use the `source` property to inline compiled templates for meaningful
-     * // line numbers in error messages and stack traces.
-     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
-     *   var JST = {\
-     *     "main": ' + _.template(mainText).source + '\
-     *   };\
-     * ');
-     */
-    function template(string, options, guard) {
-      // Based on John Resig's `tmpl` implementation
-      // (http://ejohn.org/blog/javascript-micro-templating/)
-      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
-      var settings = lodash.templateSettings;
-
-      if (guard && isIterateeCall(string, options, guard)) {
-        options = undefined;
-      }
-      string = toString(string);
-      options = assignInWith({}, options, settings, customDefaultsAssignIn);
-
-      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
-          importsKeys = keys(imports),
-          importsValues = baseValues(imports, importsKeys);
-
-      var isEscaping,
-          isEvaluating,
-          index = 0,
-          interpolate = options.interpolate || reNoMatch,
-          source = "__p += '";
-
-      // Compile the regexp to match each delimiter.
-      var reDelimiters = RegExp(
-        (options.escape || reNoMatch).source + '|' +
-        interpolate.source + '|' +
-        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
-        (options.evaluate || reNoMatch).source + '|$'
-      , 'g');
-
-      // Use a sourceURL for easier debugging.
-      var sourceURL = '//# sourceURL=' +
-        ('sourceURL' in options
-          ? options.sourceURL
-          : ('lodash.templateSources[' + (++templateCounter) + ']')
-        ) + '\n';
-
-      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
-        interpolateValue || (interpolateValue = esTemplateValue);
-
-        // Escape characters that can't be included in string literals.
-        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
-
-        // Replace delimiters with snippets.
-        if (escapeValue) {
-          isEscaping = true;
-          source += "' +\n__e(" + escapeValue + ") +\n'";
-        }
-        if (evaluateValue) {
-          isEvaluating = true;
-          source += "';\n" + evaluateValue + ";\n__p += '";
-        }
-        if (interpolateValue) {
-          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
-        }
-        index = offset + match.length;
-
-        // The JS engine embedded in Adobe products needs `match` returned in
-        // order to produce the correct `offset` value.
-        return match;
-      });
-
-      source += "';\n";
-
-      // If `variable` is not specified wrap a with-statement around the generated
-      // code to add the data object to the top of the scope chain.
-      var variable = options.variable;
-      if (!variable) {
-        source = 'with (obj) {\n' + source + '\n}\n';
-      }
-      // Cleanup code by stripping empty strings.
-      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
-        .replace(reEmptyStringMiddle, '$1')
-        .replace(reEmptyStringTrailing, '$1;');
-
-      // Frame code as the function body.
-      source = 'function(' + (variable || 'obj') + ') {\n' +
-        (variable
-          ? ''
-          : 'obj || (obj = {});\n'
-        ) +
-        "var __t, __p = ''" +
-        (isEscaping
-           ? ', __e = _.escape'
-           : ''
-        ) +
-        (isEvaluating
-          ? ', __j = Array.prototype.join;\n' +
-            "function print() { __p += __j.call(arguments, '') }\n"
-          : ';\n'
-        ) +
-        source +
-        'return __p\n}';
-
-      var result = attempt(function() {
-        return Function(importsKeys, sourceURL + 'return ' + source)
-          .apply(undefined, importsValues);
-      });
-
-      // Provide the compiled function's source by its `toString` method or
-      // the `source` property as a convenience for inlining compiled templates.
-      result.source = source;
-      if (isError(result)) {
-        throw result;
-      }
-      return result;
-    }
-
-    /**
-     * Converts `string`, as a whole, to lower case just like
-     * [String#toLowerCase](https://mdn.io/toLowerCase).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the lower cased string.
-     * @example
-     *
-     * _.toLower('--Foo-Bar--');
-     * // => '--foo-bar--'
-     *
-     * _.toLower('fooBar');
-     * // => 'foobar'
-     *
-     * _.toLower('__FOO_BAR__');
-     * // => '__foo_bar__'
-     */
-    function toLower(value) {
-      return toString(value).toLowerCase();
-    }
-
-    /**
-     * Converts `string`, as a whole, to upper case just like
-     * [String#toUpperCase](https://mdn.io/toUpperCase).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the upper cased string.
-     * @example
-     *
-     * _.toUpper('--foo-bar--');
-     * // => '--FOO-BAR--'
-     *
-     * _.toUpper('fooBar');
-     * // => 'FOOBAR'
-     *
-     * _.toUpper('__foo_bar__');
-     * // => '__FOO_BAR__'
-     */
-    function toUpper(value) {
-      return toString(value).toUpperCase();
-    }
-
-    /**
-     * Removes leading and trailing whitespace or specified characters from `string`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to trim.
-     * @param {string} [chars=whitespace] The characters to trim.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {string} Returns the trimmed string.
-     * @example
-     *
-     * _.trim('  abc  ');
-     * // => 'abc'
-     *
-     * _.trim('-_-abc-_-', '_-');
-     * // => 'abc'
-     *
-     * _.map(['  foo  ', '  bar  '], _.trim);
-     * // => ['foo', 'bar']
-     */
-    function trim(string, chars, guard) {
-      string = toString(string);
-      if (string && (guard || chars === undefined)) {
-        return string.replace(reTrim, '');
-      }
-      if (!string || !(chars = baseToString(chars))) {
-        return string;
-      }
-      var strSymbols = stringToArray(string),
-          chrSymbols = stringToArray(chars),
-          start = charsStartIndex(strSymbols, chrSymbols),
-          end = charsEndIndex(strSymbols, chrSymbols) + 1;
-
-      return castSlice(strSymbols, start, end).join('');
-    }
-
-    /**
-     * Removes trailing whitespace or specified characters from `string`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to trim.
-     * @param {string} [chars=whitespace] The characters to trim.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {string} Returns the trimmed string.
-     * @example
-     *
-     * _.trimEnd('  abc  ');
-     * // => '  abc'
-     *
-     * _.trimEnd('-_-abc-_-', '_-');
-     * // => '-_-abc'
-     */
-    function trimEnd(string, chars, guard) {
-      string = toString(string);
-      if (string && (guard || chars === undefined)) {
-        return string.replace(reTrimEnd, '');
-      }
-      if (!string || !(chars = baseToString(chars))) {
-        return string;
-      }
-      var strSymbols = stringToArray(string),
-          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
-
-      return castSlice(strSymbols, 0, end).join('');
-    }
-
-    /**
-     * Removes leading whitespace or specified characters from `string`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to trim.
-     * @param {string} [chars=whitespace] The characters to trim.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {string} Returns the trimmed string.
-     * @example
-     *
-     * _.trimStart('  abc  ');
-     * // => 'abc  '
-     *
-     * _.trimStart('-_-abc-_-', '_-');
-     * // => 'abc-_-'
-     */
-    function trimStart(string, chars, guard) {
-      string = toString(string);
-      if (string && (guard || chars === undefined)) {
-        return string.replace(reTrimStart, '');
-      }
-      if (!string || !(chars = baseToString(chars))) {
-        return string;
-      }
-      var strSymbols = stringToArray(string),
-          start = charsStartIndex(strSymbols, stringToArray(chars));
-
-      return castSlice(strSymbols, start).join('');
-    }
-
-    /**
-     * Truncates `string` if it's longer than the given maximum string length.
-     * The last characters of the truncated string are replaced with the omission
-     * string which defaults to "...".
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to truncate.
-     * @param {Object} [options={}] The options object.
-     * @param {number} [options.length=30] The maximum string length.
-     * @param {string} [options.omission='...'] The string to indicate text is omitted.
-     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
-     * @returns {string} Returns the truncated string.
-     * @example
-     *
-     * _.truncate('hi-diddly-ho there, neighborino');
-     * // => 'hi-diddly-ho there, neighbo...'
-     *
-     * _.truncate('hi-diddly-ho there, neighborino', {
-     *   'length': 24,
-     *   'separator': ' '
-     * });
-     * // => 'hi-diddly-ho there,...'
-     *
-     * _.truncate('hi-diddly-ho there, neighborino', {
-     *   'length': 24,
-     *   'separator': /,? +/
-     * });
-     * // => 'hi-diddly-ho there...'
-     *
-     * _.truncate('hi-diddly-ho there, neighborino', {
-     *   'omission': ' [...]'
-     * });
-     * // => 'hi-diddly-ho there, neig [...]'
-     */
-    function truncate(string, options) {
-      var length = DEFAULT_TRUNC_LENGTH,
-          omission = DEFAULT_TRUNC_OMISSION;
-
-      if (isObject(options)) {
-        var separator = 'separator' in options ? options.separator : separator;
-        length = 'length' in options ? toInteger(options.length) : length;
-        omission = 'omission' in options ? baseToString(options.omission) : omission;
-      }
-      string = toString(string);
-
-      var strLength = string.length;
-      if (hasUnicode(string)) {
-        var strSymbols = stringToArray(string);
-        strLength = strSymbols.length;
-      }
-      if (length >= strLength) {
-        return string;
-      }
-      var end = length - stringSize(omission);
-      if (end < 1) {
-        return omission;
-      }
-      var result = strSymbols
-        ? castSlice(strSymbols, 0, end).join('')
-        : string.slice(0, end);
-
-      if (separator === undefined) {
-        return result + omission;
-      }
-      if (strSymbols) {
-        end += (result.length - end);
-      }
-      if (isRegExp(separator)) {
-        if (string.slice(end).search(separator)) {
-          var match,
-              substring = result;
-
-          if (!separator.global) {
-            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
-          }
-          separator.lastIndex = 0;
-          while ((match = separator.exec(substring))) {
-            var newEnd = match.index;
-          }
-          result = result.slice(0, newEnd === undefined ? end : newEnd);
-        }
-      } else if (string.indexOf(baseToString(separator), end) != end) {
-        var index = result.lastIndexOf(separator);
-        if (index > -1) {
-          result = result.slice(0, index);
-        }
-      }
-      return result + omission;
-    }
-
-    /**
-     * The inverse of `_.escape`; this method converts the HTML entities
-     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
-     * their corresponding characters.
-     *
-     * **Note:** No other HTML entities are unescaped. To unescape additional
-     * HTML entities use a third-party library like [_he_](https://mths.be/he).
-     *
-     * @static
-     * @memberOf _
-     * @since 0.6.0
-     * @category String
-     * @param {string} [string=''] The string to unescape.
-     * @returns {string} Returns the unescaped string.
-     * @example
-     *
-     * _.unescape('fred, barney, &amp; pebbles');
-     * // => 'fred, barney, & pebbles'
-     */
-    function unescape(string) {
-      string = toString(string);
-      return (string && reHasEscapedHtml.test(string))
-        ? string.replace(reEscapedHtml, unescapeHtmlChar)
-        : string;
-    }
-
-    /**
-     * Converts `string`, as space separated words, to upper case.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the upper cased string.
-     * @example
-     *
-     * _.upperCase('--foo-bar');
-     * // => 'FOO BAR'
-     *
-     * _.upperCase('fooBar');
-     * // => 'FOO BAR'
-     *
-     * _.upperCase('__foo_bar__');
-     * // => 'FOO BAR'
-     */
-    var upperCase = createCompounder(function(result, word, index) {
-      return result + (index ? ' ' : '') + word.toUpperCase();
-    });
-
-    /**
-     * Converts the first character of `string` to upper case.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category String
-     * @param {string} [string=''] The string to convert.
-     * @returns {string} Returns the converted string.
-     * @example
-     *
-     * _.upperFirst('fred');
-     * // => 'Fred'
-     *
-     * _.upperFirst('FRED');
-     * // => 'FRED'
-     */
-    var upperFirst = createCaseFirst('toUpperCase');
-
-    /**
-     * Splits `string` into an array of its words.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category String
-     * @param {string} [string=''] The string to inspect.
-     * @param {RegExp|string} [pattern] The pattern to match words.
-     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
-     * @returns {Array} Returns the words of `string`.
-     * @example
-     *
-     * _.words('fred, barney, & pebbles');
-     * // => ['fred', 'barney', 'pebbles']
-     *
-     * _.words('fred, barney, & pebbles', /[^, ]+/g);
-     * // => ['fred', 'barney', '&', 'pebbles']
-     */
-    function words(string, pattern, guard) {
-      string = toString(string);
-      pattern = guard ? undefined : pattern;
-
-      if (pattern === undefined) {
-        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
-      }
-      return string.match(pattern) || [];
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Attempts to invoke `func`, returning either the result or the caught error
-     * object. Any additional arguments are provided to `func` when it's invoked.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Util
-     * @param {Function} func The function to attempt.
-     * @param {...*} [args] The arguments to invoke `func` with.
-     * @returns {*} Returns the `func` result or error object.
-     * @example
-     *
-     * // Avoid throwing errors for invalid selectors.
-     * var elements = _.attempt(function(selector) {
-     *   return document.querySelectorAll(selector);
-     * }, '>_>');
-     *
-     * if (_.isError(elements)) {
-     *   elements = [];
-     * }
-     */
-    var attempt = baseRest(function(func, args) {
-      try {
-        return apply(func, undefined, args);
-      } catch (e) {
-        return isError(e) ? e : new Error(e);
-      }
-    });
-
-    /**
-     * Binds methods of an object to the object itself, overwriting the existing
-     * method.
-     *
-     * **Note:** This method doesn't set the "length" property of bound functions.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Util
-     * @param {Object} object The object to bind and assign the bound methods to.
-     * @param {...(string|string[])} methodNames The object method names to bind.
-     * @returns {Object} Returns `object`.
-     * @example
-     *
-     * var view = {
-     *   'label': 'docs',
-     *   'click': function() {
-     *     console.log('clicked ' + this.label);
-     *   }
-     * };
-     *
-     * _.bindAll(view, ['click']);
-     * jQuery(element).on('click', view.click);
-     * // => Logs 'clicked docs' when clicked.
-     */
-    var bindAll = flatRest(function(object, methodNames) {
-      arrayEach(methodNames, function(key) {
-        key = toKey(key);
-        baseAssignValue(object, key, bind(object[key], object));
-      });
-      return object;
-    });
-
-    /**
-     * Creates a function that iterates over `pairs` and invokes the corresponding
-     * function of the first predicate to return truthy. The predicate-function
-     * pairs are invoked with the `this` binding and arguments of the created
-     * function.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Util
-     * @param {Array} pairs The predicate-function pairs.
-     * @returns {Function} Returns the new composite function.
-     * @example
-     *
-     * var func = _.cond([
-     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
-     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
-     *   [_.stubTrue,                      _.constant('no match')]
-     * ]);
-     *
-     * func({ 'a': 1, 'b': 2 });
-     * // => 'matches A'
-     *
-     * func({ 'a': 0, 'b': 1 });
-     * // => 'matches B'
-     *
-     * func({ 'a': '1', 'b': '2' });
-     * // => 'no match'
-     */
-    function cond(pairs) {
-      var length = pairs == null ? 0 : pairs.length,
-          toIteratee = getIteratee();
-
-      pairs = !length ? [] : arrayMap(pairs, function(pair) {
-        if (typeof pair[1] != 'function') {
-          throw new TypeError(FUNC_ERROR_TEXT);
-        }
-        return [toIteratee(pair[0]), pair[1]];
-      });
-
-      return baseRest(function(args) {
-        var index = -1;
-        while (++index < length) {
-          var pair = pairs[index];
-          if (apply(pair[0], this, args)) {
-            return apply(pair[1], this, args);
-          }
-        }
-      });
-    }
-
-    /**
-     * Creates a function that invokes the predicate properties of `source` with
-     * the corresponding property values of a given object, returning `true` if
-     * all predicates return truthy, else `false`.
-     *
-     * **Note:** The created function is equivalent to `_.conformsTo` with
-     * `source` partially applied.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Util
-     * @param {Object} source The object of property predicates to conform to.
-     * @returns {Function} Returns the new spec function.
-     * @example
-     *
-     * var objects = [
-     *   { 'a': 2, 'b': 1 },
-     *   { 'a': 1, 'b': 2 }
-     * ];
-     *
-     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
-     * // => [{ 'a': 1, 'b': 2 }]
-     */
-    function conforms(source) {
-      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
-    }
-
-    /**
-     * Creates a function that returns `value`.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.4.0
-     * @category Util
-     * @param {*} value The value to return from the new function.
-     * @returns {Function} Returns the new constant function.
-     * @example
-     *
-     * var objects = _.times(2, _.constant({ 'a': 1 }));
-     *
-     * console.log(objects);
-     * // => [{ 'a': 1 }, { 'a': 1 }]
-     *
-     * console.log(objects[0] === objects[1]);
-     * // => true
-     */
-    function constant(value) {
-      return function() {
-        return value;
-      };
-    }
-
-    /**
-     * Checks `value` to determine whether a default value should be returned in
-     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
-     * or `undefined`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.14.0
-     * @category Util
-     * @param {*} value The value to check.
-     * @param {*} defaultValue The default value.
-     * @returns {*} Returns the resolved value.
-     * @example
-     *
-     * _.defaultTo(1, 10);
-     * // => 1
-     *
-     * _.defaultTo(undefined, 10);
-     * // => 10
-     */
-    function defaultTo(value, defaultValue) {
-      return (value == null || value !== value) ? defaultValue : value;
-    }
-
-    /**
-     * Creates a function that returns the result of invoking the given functions
-     * with the `this` binding of the created function, where each successive
-     * invocation is supplied the return value of the previous.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Util
-     * @param {...(Function|Function[])} [funcs] The functions to invoke.
-     * @returns {Function} Returns the new composite function.
-     * @see _.flowRight
-     * @example
-     *
-     * function square(n) {
-     *   return n * n;
-     * }
-     *
-     * var addSquare = _.flow([_.add, square]);
-     * addSquare(1, 2);
-     * // => 9
-     */
-    var flow = createFlow();
-
-    /**
-     * This method is like `_.flow` except that it creates a function that
-     * invokes the given functions from right to left.
-     *
-     * @static
-     * @since 3.0.0
-     * @memberOf _
-     * @category Util
-     * @param {...(Function|Function[])} [funcs] The functions to invoke.
-     * @returns {Function} Returns the new composite function.
-     * @see _.flow
-     * @example
-     *
-     * function square(n) {
-     *   return n * n;
-     * }
-     *
-     * var addSquare = _.flowRight([square, _.add]);
-     * addSquare(1, 2);
-     * // => 9
-     */
-    var flowRight = createFlow(true);
-
-    /**
-     * This method returns the first argument it receives.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Util
-     * @param {*} value Any value.
-     * @returns {*} Returns `value`.
-     * @example
-     *
-     * var object = { 'a': 1 };
-     *
-     * console.log(_.identity(object) === object);
-     * // => true
-     */
-    function identity(value) {
-      return value;
-    }
-
-    /**
-     * Creates a function that invokes `func` with the arguments of the created
-     * function. If `func` is a property name, the created function returns the
-     * property value for a given element. If `func` is an array or object, the
-     * created function returns `true` for elements that contain the equivalent
-     * source properties, otherwise it returns `false`.
-     *
-     * @static
-     * @since 4.0.0
-     * @memberOf _
-     * @category Util
-     * @param {*} [func=_.identity] The value to convert to a callback.
-     * @returns {Function} Returns the callback.
-     * @example
-     *
-     * var users = [
-     *   { 'user': 'barney', 'age': 36, 'active': true },
-     *   { 'user': 'fred',   'age': 40, 'active': false }
-     * ];
-     *
-     * // The `_.matches` iteratee shorthand.
-     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
-     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
-     *
-     * // The `_.matchesProperty` iteratee shorthand.
-     * _.filter(users, _.iteratee(['user', 'fred']));
-     * // => [{ 'user': 'fred', 'age': 40 }]
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.map(users, _.iteratee('user'));
-     * // => ['barney', 'fred']
-     *
-     * // Create custom iteratee shorthands.
-     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
-     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
-     *     return func.test(string);
-     *   };
-     * });
-     *
-     * _.filter(['abc', 'def'], /ef/);
-     * // => ['def']
-     */
-    function iteratee(func) {
-      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
-    }
-
-    /**
-     * Creates a function that performs a partial deep comparison between a given
-     * object and `source`, returning `true` if the given object has equivalent
-     * property values, else `false`.
-     *
-     * **Note:** The created function is equivalent to `_.isMatch` with `source`
-     * partially applied.
-     *
-     * Partial comparisons will match empty array and empty object `source`
-     * values against any array or object value, respectively. See `_.isEqual`
-     * for a list of supported value comparisons.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Util
-     * @param {Object} source The object of property values to match.
-     * @returns {Function} Returns the new spec function.
-     * @example
-     *
-     * var objects = [
-     *   { 'a': 1, 'b': 2, 'c': 3 },
-     *   { 'a': 4, 'b': 5, 'c': 6 }
-     * ];
-     *
-     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
-     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
-     */
-    function matches(source) {
-      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
-    }
-
-    /**
-     * Creates a function that performs a partial deep comparison between the
-     * value at `path` of a given object to `srcValue`, returning `true` if the
-     * object value is equivalent, else `false`.
-     *
-     * **Note:** Partial comparisons will match empty array and empty object
-     * `srcValue` values against any array or object value, respectively. See
-     * `_.isEqual` for a list of supported value comparisons.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.2.0
-     * @category Util
-     * @param {Array|string} path The path of the property to get.
-     * @param {*} srcValue The value to match.
-     * @returns {Function} Returns the new spec function.
-     * @example
-     *
-     * var objects = [
-     *   { 'a': 1, 'b': 2, 'c': 3 },
-     *   { 'a': 4, 'b': 5, 'c': 6 }
-     * ];
-     *
-     * _.find(objects, _.matchesProperty('a', 4));
-     * // => { 'a': 4, 'b': 5, 'c': 6 }
-     */
-    function matchesProperty(path, srcValue) {
-      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
-    }
-
-    /**
-     * Creates a function that invokes the method at `path` of a given object.
-     * Any additional arguments are provided to the invoked method.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.7.0
-     * @category Util
-     * @param {Array|string} path The path of the method to invoke.
-     * @param {...*} [args] The arguments to invoke the method with.
-     * @returns {Function} Returns the new invoker function.
-     * @example
-     *
-     * var objects = [
-     *   { 'a': { 'b': _.constant(2) } },
-     *   { 'a': { 'b': _.constant(1) } }
-     * ];
-     *
-     * _.map(objects, _.method('a.b'));
-     * // => [2, 1]
-     *
-     * _.map(objects, _.method(['a', 'b']));
-     * // => [2, 1]
-     */
-    var method = baseRest(function(path, args) {
-      return function(object) {
-        return baseInvoke(object, path, args);
-      };
-    });
-
-    /**
-     * The opposite of `_.method`; this method creates a function that invokes
-     * the method at a given path of `object`. Any additional arguments are
-     * provided to the invoked method.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.7.0
-     * @category Util
-     * @param {Object} object The object to query.
-     * @param {...*} [args] The arguments to invoke the method with.
-     * @returns {Function} Returns the new invoker function.
-     * @example
-     *
-     * var array = _.times(3, _.constant),
-     *     object = { 'a': array, 'b': array, 'c': array };
-     *
-     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
-     * // => [2, 0]
-     *
-     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
-     * // => [2, 0]
-     */
-    var methodOf = baseRest(function(object, args) {
-      return function(path) {
-        return baseInvoke(object, path, args);
-      };
-    });
-
-    /**
-     * Adds all own enumerable string keyed function properties of a source
-     * object to the destination object. If `object` is a function, then methods
-     * are added to its prototype as well.
-     *
-     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
-     * avoid conflicts caused by modifying the original.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Util
-     * @param {Function|Object} [object=lodash] The destination object.
-     * @param {Object} source The object of functions to add.
-     * @param {Object} [options={}] The options object.
-     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
-     * @returns {Function|Object} Returns `object`.
-     * @example
-     *
-     * function vowels(string) {
-     *   return _.filter(string, function(v) {
-     *     return /[aeiou]/i.test(v);
-     *   });
-     * }
-     *
-     * _.mixin({ 'vowels': vowels });
-     * _.vowels('fred');
-     * // => ['e']
-     *
-     * _('fred').vowels().value();
-     * // => ['e']
-     *
-     * _.mixin({ 'vowels': vowels }, { 'chain': false });
-     * _('fred').vowels();
-     * // => ['e']
-     */
-    function mixin(object, source, options) {
-      var props = keys(source),
-          methodNames = baseFunctions(source, props);
-
-      if (options == null &&
-          !(isObject(source) && (methodNames.length || !props.length))) {
-        options = source;
-        source = object;
-        object = this;
-        methodNames = baseFunctions(source, keys(source));
-      }
-      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
-          isFunc = isFunction(object);
-
-      arrayEach(methodNames, function(methodName) {
-        var func = source[methodName];
-        object[methodName] = func;
-        if (isFunc) {
-          object.prototype[methodName] = function() {
-            var chainAll = this.__chain__;
-            if (chain || chainAll) {
-              var result = object(this.__wrapped__),
-                  actions = result.__actions__ = copyArray(this.__actions__);
-
-              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
-              result.__chain__ = chainAll;
-              return result;
-            }
-            return func.apply(object, arrayPush([this.value()], arguments));
-          };
-        }
-      });
-
-      return object;
-    }
-
-    /**
-     * Reverts the `_` variable to its previous value and returns a reference to
-     * the `lodash` function.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Util
-     * @returns {Function} Returns the `lodash` function.
-     * @example
-     *
-     * var lodash = _.noConflict();
-     */
-    function noConflict() {
-      if (root._ === this) {
-        root._ = oldDash;
-      }
-      return this;
-    }
-
-    /**
-     * This method returns `undefined`.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.3.0
-     * @category Util
-     * @example
-     *
-     * _.times(2, _.noop);
-     * // => [undefined, undefined]
-     */
-    function noop() {
-      // No operation performed.
-    }
-
-    /**
-     * Creates a function that gets the argument at index `n`. If `n` is negative,
-     * the nth argument from the end is returned.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Util
-     * @param {number} [n=0] The index of the argument to return.
-     * @returns {Function} Returns the new pass-thru function.
-     * @example
-     *
-     * var func = _.nthArg(1);
-     * func('a', 'b', 'c', 'd');
-     * // => 'b'
-     *
-     * var func = _.nthArg(-2);
-     * func('a', 'b', 'c', 'd');
-     * // => 'c'
-     */
-    function nthArg(n) {
-      n = toInteger(n);
-      return baseRest(function(args) {
-        return baseNth(args, n);
-      });
-    }
-
-    /**
-     * Creates a function that invokes `iteratees` with the arguments it receives
-     * and returns their results.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Util
-     * @param {...(Function|Function[])} [iteratees=[_.identity]]
-     *  The iteratees to invoke.
-     * @returns {Function} Returns the new function.
-     * @example
-     *
-     * var func = _.over([Math.max, Math.min]);
-     *
-     * func(1, 2, 3, 4);
-     * // => [4, 1]
-     */
-    var over = createOver(arrayMap);
-
-    /**
-     * Creates a function that checks if **all** of the `predicates` return
-     * truthy when invoked with the arguments it receives.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Util
-     * @param {...(Function|Function[])} [predicates=[_.identity]]
-     *  The predicates to check.
-     * @returns {Function} Returns the new function.
-     * @example
-     *
-     * var func = _.overEvery([Boolean, isFinite]);
-     *
-     * func('1');
-     * // => true
-     *
-     * func(null);
-     * // => false
-     *
-     * func(NaN);
-     * // => false
-     */
-    var overEvery = createOver(arrayEvery);
-
-    /**
-     * Creates a function that checks if **any** of the `predicates` return
-     * truthy when invoked with the arguments it receives.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Util
-     * @param {...(Function|Function[])} [predicates=[_.identity]]
-     *  The predicates to check.
-     * @returns {Function} Returns the new function.
-     * @example
-     *
-     * var func = _.overSome([Boolean, isFinite]);
-     *
-     * func('1');
-     * // => true
-     *
-     * func(null);
-     * // => true
-     *
-     * func(NaN);
-     * // => false
-     */
-    var overSome = createOver(arraySome);
-
-    /**
-     * Creates a function that returns the value at `path` of a given object.
-     *
-     * @static
-     * @memberOf _
-     * @since 2.4.0
-     * @category Util
-     * @param {Array|string} path The path of the property to get.
-     * @returns {Function} Returns the new accessor function.
-     * @example
-     *
-     * var objects = [
-     *   { 'a': { 'b': 2 } },
-     *   { 'a': { 'b': 1 } }
-     * ];
-     *
-     * _.map(objects, _.property('a.b'));
-     * // => [2, 1]
-     *
-     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
-     * // => [1, 2]
-     */
-    function property(path) {
-      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
-    }
-
-    /**
-     * The opposite of `_.property`; this method creates a function that returns
-     * the value at a given path of `object`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.0.0
-     * @category Util
-     * @param {Object} object The object to query.
-     * @returns {Function} Returns the new accessor function.
-     * @example
-     *
-     * var array = [0, 1, 2],
-     *     object = { 'a': array, 'b': array, 'c': array };
-     *
-     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
-     * // => [2, 0]
-     *
-     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
-     * // => [2, 0]
-     */
-    function propertyOf(object) {
-      return function(path) {
-        return object == null ? undefined : baseGet(object, path);
-      };
-    }
-
-    /**
-     * Creates an array of numbers (positive and/or negative) progressing from
-     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
-     * `start` is specified without an `end` or `step`. If `end` is not specified,
-     * it's set to `start` with `start` then set to `0`.
-     *
-     * **Note:** JavaScript follows the IEEE-754 standard for resolving
-     * floating-point values which can produce unexpected results.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Util
-     * @param {number} [start=0] The start of the range.
-     * @param {number} end The end of the range.
-     * @param {number} [step=1] The value to increment or decrement by.
-     * @returns {Array} Returns the range of numbers.
-     * @see _.inRange, _.rangeRight
-     * @example
-     *
-     * _.range(4);
-     * // => [0, 1, 2, 3]
-     *
-     * _.range(-4);
-     * // => [0, -1, -2, -3]
-     *
-     * _.range(1, 5);
-     * // => [1, 2, 3, 4]
-     *
-     * _.range(0, 20, 5);
-     * // => [0, 5, 10, 15]
-     *
-     * _.range(0, -4, -1);
-     * // => [0, -1, -2, -3]
-     *
-     * _.range(1, 4, 0);
-     * // => [1, 1, 1]
-     *
-     * _.range(0);
-     * // => []
-     */
-    var range = createRange();
-
-    /**
-     * This method is like `_.range` except that it populates values in
-     * descending order.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Util
-     * @param {number} [start=0] The start of the range.
-     * @param {number} end The end of the range.
-     * @param {number} [step=1] The value to increment or decrement by.
-     * @returns {Array} Returns the range of numbers.
-     * @see _.inRange, _.range
-     * @example
-     *
-     * _.rangeRight(4);
-     * // => [3, 2, 1, 0]
-     *
-     * _.rangeRight(-4);
-     * // => [-3, -2, -1, 0]
-     *
-     * _.rangeRight(1, 5);
-     * // => [4, 3, 2, 1]
-     *
-     * _.rangeRight(0, 20, 5);
-     * // => [15, 10, 5, 0]
-     *
-     * _.rangeRight(0, -4, -1);
-     * // => [-3, -2, -1, 0]
-     *
-     * _.rangeRight(1, 4, 0);
-     * // => [1, 1, 1]
-     *
-     * _.rangeRight(0);
-     * // => []
-     */
-    var rangeRight = createRange(true);
-
-    /**
-     * This method returns a new empty array.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.13.0
-     * @category Util
-     * @returns {Array} Returns the new empty array.
-     * @example
-     *
-     * var arrays = _.times(2, _.stubArray);
-     *
-     * console.log(arrays);
-     * // => [[], []]
-     *
-     * console.log(arrays[0] === arrays[1]);
-     * // => false
-     */
-    function stubArray() {
-      return [];
-    }
-
-    /**
-     * This method returns `false`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.13.0
-     * @category Util
-     * @returns {boolean} Returns `false`.
-     * @example
-     *
-     * _.times(2, _.stubFalse);
-     * // => [false, false]
-     */
-    function stubFalse() {
-      return false;
-    }
-
-    /**
-     * This method returns a new empty object.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.13.0
-     * @category Util
-     * @returns {Object} Returns the new empty object.
-     * @example
-     *
-     * var objects = _.times(2, _.stubObject);
-     *
-     * console.log(objects);
-     * // => [{}, {}]
-     *
-     * console.log(objects[0] === objects[1]);
-     * // => false
-     */
-    function stubObject() {
-      return {};
-    }
-
-    /**
-     * This method returns an empty string.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.13.0
-     * @category Util
-     * @returns {string} Returns the empty string.
-     * @example
-     *
-     * _.times(2, _.stubString);
-     * // => ['', '']
-     */
-    function stubString() {
-      return '';
-    }
-
-    /**
-     * This method returns `true`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.13.0
-     * @category Util
-     * @returns {boolean} Returns `true`.
-     * @example
-     *
-     * _.times(2, _.stubTrue);
-     * // => [true, true]
-     */
-    function stubTrue() {
-      return true;
-    }
-
-    /**
-     * Invokes the iteratee `n` times, returning an array of the results of
-     * each invocation. The iteratee is invoked with one argument; (index).
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Util
-     * @param {number} n The number of times to invoke `iteratee`.
-     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
-     * @returns {Array} Returns the array of results.
-     * @example
-     *
-     * _.times(3, String);
-     * // => ['0', '1', '2']
-     *
-     *  _.times(4, _.constant(0));
-     * // => [0, 0, 0, 0]
-     */
-    function times(n, iteratee) {
-      n = toInteger(n);
-      if (n < 1 || n > MAX_SAFE_INTEGER) {
-        return [];
-      }
-      var index = MAX_ARRAY_LENGTH,
-          length = nativeMin(n, MAX_ARRAY_LENGTH);
-
-      iteratee = getIteratee(iteratee);
-      n -= MAX_ARRAY_LENGTH;
-
-      var result = baseTimes(length, iteratee);
-      while (++index < n) {
-        iteratee(index);
-      }
-      return result;
-    }
-
-    /**
-     * Converts `value` to a property path array.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Util
-     * @param {*} value The value to convert.
-     * @returns {Array} Returns the new property path array.
-     * @example
-     *
-     * _.toPath('a.b.c');
-     * // => ['a', 'b', 'c']
-     *
-     * _.toPath('a[0].b.c');
-     * // => ['a', '0', 'b', 'c']
-     */
-    function toPath(value) {
-      if (isArray(value)) {
-        return arrayMap(value, toKey);
-      }
-      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
-    }
-
-    /**
-     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Util
-     * @param {string} [prefix=''] The value to prefix the ID with.
-     * @returns {string} Returns the unique ID.
-     * @example
-     *
-     * _.uniqueId('contact_');
-     * // => 'contact_104'
-     *
-     * _.uniqueId();
-     * // => '105'
-     */
-    function uniqueId(prefix) {
-      var id = ++idCounter;
-      return toString(prefix) + id;
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * Adds two numbers.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.4.0
-     * @category Math
-     * @param {number} augend The first number in an addition.
-     * @param {number} addend The second number in an addition.
-     * @returns {number} Returns the total.
-     * @example
-     *
-     * _.add(6, 4);
-     * // => 10
-     */
-    var add = createMathOperation(function(augend, addend) {
-      return augend + addend;
-    }, 0);
-
-    /**
-     * Computes `number` rounded up to `precision`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.10.0
-     * @category Math
-     * @param {number} number The number to round up.
-     * @param {number} [precision=0] The precision to round up to.
-     * @returns {number} Returns the rounded up number.
-     * @example
-     *
-     * _.ceil(4.006);
-     * // => 5
-     *
-     * _.ceil(6.004, 2);
-     * // => 6.01
-     *
-     * _.ceil(6040, -2);
-     * // => 6100
-     */
-    var ceil = createRound('ceil');
-
-    /**
-     * Divide two numbers.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.7.0
-     * @category Math
-     * @param {number} dividend The first number in a division.
-     * @param {number} divisor The second number in a division.
-     * @returns {number} Returns the quotient.
-     * @example
-     *
-     * _.divide(6, 4);
-     * // => 1.5
-     */
-    var divide = createMathOperation(function(dividend, divisor) {
-      return dividend / divisor;
-    }, 1);
-
-    /**
-     * Computes `number` rounded down to `precision`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.10.0
-     * @category Math
-     * @param {number} number The number to round down.
-     * @param {number} [precision=0] The precision to round down to.
-     * @returns {number} Returns the rounded down number.
-     * @example
-     *
-     * _.floor(4.006);
-     * // => 4
-     *
-     * _.floor(0.046, 2);
-     * // => 0.04
-     *
-     * _.floor(4060, -2);
-     * // => 4000
-     */
-    var floor = createRound('floor');
-
-    /**
-     * Computes the maximum value of `array`. If `array` is empty or falsey,
-     * `undefined` is returned.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Math
-     * @param {Array} array The array to iterate over.
-     * @returns {*} Returns the maximum value.
-     * @example
-     *
-     * _.max([4, 2, 8, 6]);
-     * // => 8
-     *
-     * _.max([]);
-     * // => undefined
-     */
-    function max(array) {
-      return (array && array.length)
-        ? baseExtremum(array, identity, baseGt)
-        : undefined;
-    }
-
-    /**
-     * This method is like `_.max` except that it accepts `iteratee` which is
-     * invoked for each element in `array` to generate the criterion by which
-     * the value is ranked. The iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Math
-     * @param {Array} array The array to iterate over.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {*} Returns the maximum value.
-     * @example
-     *
-     * var objects = [{ 'n': 1 }, { 'n': 2 }];
-     *
-     * _.maxBy(objects, function(o) { return o.n; });
-     * // => { 'n': 2 }
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.maxBy(objects, 'n');
-     * // => { 'n': 2 }
-     */
-    function maxBy(array, iteratee) {
-      return (array && array.length)
-        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
-        : undefined;
-    }
-
-    /**
-     * Computes the mean of the values in `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Math
-     * @param {Array} array The array to iterate over.
-     * @returns {number} Returns the mean.
-     * @example
-     *
-     * _.mean([4, 2, 8, 6]);
-     * // => 5
-     */
-    function mean(array) {
-      return baseMean(array, identity);
-    }
-
-    /**
-     * This method is like `_.mean` except that it accepts `iteratee` which is
-     * invoked for each element in `array` to generate the value to be averaged.
-     * The iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.7.0
-     * @category Math
-     * @param {Array} array The array to iterate over.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {number} Returns the mean.
-     * @example
-     *
-     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
-     *
-     * _.meanBy(objects, function(o) { return o.n; });
-     * // => 5
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.meanBy(objects, 'n');
-     * // => 5
-     */
-    function meanBy(array, iteratee) {
-      return baseMean(array, getIteratee(iteratee, 2));
-    }
-
-    /**
-     * Computes the minimum value of `array`. If `array` is empty or falsey,
-     * `undefined` is returned.
-     *
-     * @static
-     * @since 0.1.0
-     * @memberOf _
-     * @category Math
-     * @param {Array} array The array to iterate over.
-     * @returns {*} Returns the minimum value.
-     * @example
-     *
-     * _.min([4, 2, 8, 6]);
-     * // => 2
-     *
-     * _.min([]);
-     * // => undefined
-     */
-    function min(array) {
-      return (array && array.length)
-        ? baseExtremum(array, identity, baseLt)
-        : undefined;
-    }
-
-    /**
-     * This method is like `_.min` except that it accepts `iteratee` which is
-     * invoked for each element in `array` to generate the criterion by which
-     * the value is ranked. The iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Math
-     * @param {Array} array The array to iterate over.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {*} Returns the minimum value.
-     * @example
-     *
-     * var objects = [{ 'n': 1 }, { 'n': 2 }];
-     *
-     * _.minBy(objects, function(o) { return o.n; });
-     * // => { 'n': 1 }
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.minBy(objects, 'n');
-     * // => { 'n': 1 }
-     */
-    function minBy(array, iteratee) {
-      return (array && array.length)
-        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
-        : undefined;
-    }
-
-    /**
-     * Multiply two numbers.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.7.0
-     * @category Math
-     * @param {number} multiplier The first number in a multiplication.
-     * @param {number} multiplicand The second number in a multiplication.
-     * @returns {number} Returns the product.
-     * @example
-     *
-     * _.multiply(6, 4);
-     * // => 24
-     */
-    var multiply = createMathOperation(function(multiplier, multiplicand) {
-      return multiplier * multiplicand;
-    }, 1);
-
-    /**
-     * Computes `number` rounded to `precision`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.10.0
-     * @category Math
-     * @param {number} number The number to round.
-     * @param {number} [precision=0] The precision to round to.
-     * @returns {number} Returns the rounded number.
-     * @example
-     *
-     * _.round(4.006);
-     * // => 4
-     *
-     * _.round(4.006, 2);
-     * // => 4.01
-     *
-     * _.round(4060, -2);
-     * // => 4100
-     */
-    var round = createRound('round');
-
-    /**
-     * Subtract two numbers.
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Math
-     * @param {number} minuend The first number in a subtraction.
-     * @param {number} subtrahend The second number in a subtraction.
-     * @returns {number} Returns the difference.
-     * @example
-     *
-     * _.subtract(6, 4);
-     * // => 2
-     */
-    var subtract = createMathOperation(function(minuend, subtrahend) {
-      return minuend - subtrahend;
-    }, 0);
-
-    /**
-     * Computes the sum of the values in `array`.
-     *
-     * @static
-     * @memberOf _
-     * @since 3.4.0
-     * @category Math
-     * @param {Array} array The array to iterate over.
-     * @returns {number} Returns the sum.
-     * @example
-     *
-     * _.sum([4, 2, 8, 6]);
-     * // => 20
-     */
-    function sum(array) {
-      return (array && array.length)
-        ? baseSum(array, identity)
-        : 0;
-    }
-
-    /**
-     * This method is like `_.sum` except that it accepts `iteratee` which is
-     * invoked for each element in `array` to generate the value to be summed.
-     * The iteratee is invoked with one argument: (value).
-     *
-     * @static
-     * @memberOf _
-     * @since 4.0.0
-     * @category Math
-     * @param {Array} array The array to iterate over.
-     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
-     * @returns {number} Returns the sum.
-     * @example
-     *
-     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
-     *
-     * _.sumBy(objects, function(o) { return o.n; });
-     * // => 20
-     *
-     * // The `_.property` iteratee shorthand.
-     * _.sumBy(objects, 'n');
-     * // => 20
-     */
-    function sumBy(array, iteratee) {
-      return (array && array.length)
-        ? baseSum(array, getIteratee(iteratee, 2))
-        : 0;
-    }
-
-    /*------------------------------------------------------------------------*/
-
-    // Add methods that return wrapped values in chain sequences.
-    lodash.after = after;
-    lodash.ary = ary;
-    lodash.assign = assign;
-    lodash.assignIn = assignIn;
-    lodash.assignInWith = assignInWith;
-    lodash.assignWith = assignWith;
-    lodash.at = at;
-    lodash.before = before;
-    lodash.bind = bind;
-    lodash.bindAll = bindAll;
-    lodash.bindKey = bindKey;
-    lodash.castArray = castArray;
-    lodash.chain = chain;
-    lodash.chunk = chunk;
-    lodash.compact = compact;
-    lodash.concat = concat;
-    lodash.cond = cond;
-    lodash.conforms = conforms;
-    lodash.constant = constant;
-    lodash.countBy = countBy;
-    lodash.create = create;
-    lodash.curry = curry;
-    lodash.curryRight = curryRight;
-    lodash.debounce = debounce;
-    lodash.defaults = defaults;
-    lodash.defaultsDeep = defaultsDeep;
-    lodash.defer = defer;
-    lodash.delay = delay;
-    lodash.difference = difference;
-    lodash.differenceBy = differenceBy;
-    lodash.differenceWith = differenceWith;
-    lodash.drop = drop;
-    lodash.dropRight = dropRight;
-    lodash.dropRightWhile = dropRightWhile;
-    lodash.dropWhile = dropWhile;
-    lodash.fill = fill;
-    lodash.filter = filter;
-    lodash.flatMap = flatMap;
-    lodash.flatMapDeep = flatMapDeep;
-    lodash.flatMapDepth = flatMapDepth;
-    lodash.flatten = flatten;
-    lodash.flattenDeep = flattenDeep;
-    lodash.flattenDepth = flattenDepth;
-    lodash.flip = flip;
-    lodash.flow = flow;
-    lodash.flowRight = flowRight;
-    lodash.fromPairs = fromPairs;
-    lodash.functions = functions;
-    lodash.functionsIn = functionsIn;
-    lodash.groupBy = groupBy;
-    lodash.initial = initial;
-    lodash.intersection = intersection;
-    lodash.intersectionBy = intersectionBy;
-    lodash.intersectionWith = intersectionWith;
-    lodash.invert = invert;
-    lodash.invertBy = invertBy;
-    lodash.invokeMap = invokeMap;
-    lodash.iteratee = iteratee;
-    lodash.keyBy = keyBy;
-    lodash.keys = keys;
-    lodash.keysIn = keysIn;
-    lodash.map = map;
-    lodash.mapKeys = mapKeys;
-    lodash.mapValues = mapValues;
-    lodash.matches = matches;
-    lodash.matchesProperty = matchesProperty;
-    lodash.memoize = memoize;
-    lodash.merge = merge;
-    lodash.mergeWith = mergeWith;
-    lodash.method = method;
-    lodash.methodOf = methodOf;
-    lodash.mixin = mixin;
-    lodash.negate = negate;
-    lodash.nthArg = nthArg;
-    lodash.omit = omit;
-    lodash.omitBy = omitBy;
-    lodash.once = once;
-    lodash.orderBy = orderBy;
-    lodash.over = over;
-    lodash.overArgs = overArgs;
-    lodash.overEvery = overEvery;
-    lodash.overSome = overSome;
-    lodash.partial = partial;
-    lodash.partialRight = partialRight;
-    lodash.partition = partition;
-    lodash.pick = pick;
-    lodash.pickBy = pickBy;
-    lodash.property = property;
-    lodash.propertyOf = propertyOf;
-    lodash.pull = pull;
-    lodash.pullAll = pullAll;
-    lodash.pullAllBy = pullAllBy;
-    lodash.pullAllWith = pullAllWith;
-    lodash.pullAt = pullAt;
-    lodash.range = range;
-    lodash.rangeRight = rangeRight;
-    lodash.rearg = rearg;
-    lodash.reject = reject;
-    lodash.remove = remove;
-    lodash.rest = rest;
-    lodash.reverse = reverse;
-    lodash.sampleSize = sampleSize;
-    lodash.set = set;
-    lodash.setWith = setWith;
-    lodash.shuffle = shuffle;
-    lodash.slice = slice;
-    lodash.sortBy = sortBy;
-    lodash.sortedUniq = sortedUniq;
-    lodash.sortedUniqBy = sortedUniqBy;
-    lodash.split = split;
-    lodash.spread = spread;
-    lodash.tail = tail;
-    lodash.take = take;
-    lodash.takeRight = takeRight;
-    lodash.takeRightWhile = takeRightWhile;
-    lodash.takeWhile = takeWhile;
-    lodash.tap = tap;
-    lodash.throttle = throttle;
-    lodash.thru = thru;
-    lodash.toArray = toArray;
-    lodash.toPairs = toPairs;
-    lodash.toPairsIn = toPairsIn;
-    lodash.toPath = toPath;
-    lodash.toPlainObject = toPlainObject;
-    lodash.transform = transform;
-    lodash.unary = unary;
-    lodash.union = union;
-    lodash.unionBy = unionBy;
-    lodash.unionWith = unionWith;
-    lodash.uniq = uniq;
-    lodash.uniqBy = uniqBy;
-    lodash.uniqWith = uniqWith;
-    lodash.unset = unset;
-    lodash.unzip = unzip;
-    lodash.unzipWith = unzipWith;
-    lodash.update = update;
-    lodash.updateWith = updateWith;
-    lodash.values = values;
-    lodash.valuesIn = valuesIn;
-    lodash.without = without;
-    lodash.words = words;
-    lodash.wrap = wrap;
-    lodash.xor = xor;
-    lodash.xorBy = xorBy;
-    lodash.xorWith = xorWith;
-    lodash.zip = zip;
-    lodash.zipObject = zipObject;
-    lodash.zipObjectDeep = zipObjectDeep;
-    lodash.zipWith = zipWith;
-
-    // Add aliases.
-    lodash.entries = toPairs;
-    lodash.entriesIn = toPairsIn;
-    lodash.extend = assignIn;
-    lodash.extendWith = assignInWith;
-
-    // Add methods to `lodash.prototype`.
-    mixin(lodash, lodash);
-
-    /*------------------------------------------------------------------------*/
-
-    // Add methods that return unwrapped values in chain sequences.
-    lodash.add = add;
-    lodash.attempt = attempt;
-    lodash.camelCase = camelCase;
-    lodash.capitalize = capitalize;
-    lodash.ceil = ceil;
-    lodash.clamp = clamp;
-    lodash.clone = clone;
-    lodash.cloneDeep = cloneDeep;
-    lodash.cloneDeepWith = cloneDeepWith;
-    lodash.cloneWith = cloneWith;
-    lodash.conformsTo = conformsTo;
-    lodash.deburr = deburr;
-    lodash.defaultTo = defaultTo;
-    lodash.divide = divide;
-    lodash.endsWith = endsWith;
-    lodash.eq = eq;
-    lodash.escape = escape;
-    lodash.escapeRegExp = escapeRegExp;
-    lodash.every = every;
-    lodash.find = find;
-    lodash.findIndex = findIndex;
-    lodash.findKey = findKey;
-    lodash.findLast = findLast;
-    lodash.findLastIndex = findLastIndex;
-    lodash.findLastKey = findLastKey;
-    lodash.floor = floor;
-    lodash.forEach = forEach;
-    lodash.forEachRight = forEachRight;
-    lodash.forIn = forIn;
-    lodash.forInRight = forInRight;
-    lodash.forOwn = forOwn;
-    lodash.forOwnRight = forOwnRight;
-    lodash.get = get;
-    lodash.gt = gt;
-    lodash.gte = gte;
-    lodash.has = has;
-    lodash.hasIn = hasIn;
-    lodash.head = head;
-    lodash.identity = identity;
-    lodash.includes = includes;
-    lodash.indexOf = indexOf;
-    lodash.inRange = inRange;
-    lodash.invoke = invoke;
-    lodash.isArguments = isArguments;
-    lodash.isArray = isArray;
-    lodash.isArrayBuffer = isArrayBuffer;
-    lodash.isArrayLike = isArrayLike;
-    lodash.isArrayLikeObject = isArrayLikeObject;
-    lodash.isBoolean = isBoolean;
-    lodash.isBuffer = isBuffer;
-    lodash.isDate = isDate;
-    lodash.isElement = isElement;
-    lodash.isEmpty = isEmpty;
-    lodash.isEqual = isEqual;
-    lodash.isEqualWith = isEqualWith;
-    lodash.isError = isError;
-    lodash.isFinite = isFinite;
-    lodash.isFunction = isFunction;
-    lodash.isInteger = isInteger;
-    lodash.isLength = isLength;
-    lodash.isMap = isMap;
-    lodash.isMatch = isMatch;
-    lodash.isMatchWith = isMatchWith;
-    lodash.isNaN = isNaN;
-    lodash.isNative = isNative;
-    lodash.isNil = isNil;
-    lodash.isNull = isNull;
-    lodash.isNumber = isNumber;
-    lodash.isObject = isObject;
-    lodash.isObjectLike = isObjectLike;
-    lodash.isPlainObject = isPlainObject;
-    lodash.isRegExp = isRegExp;
-    lodash.isSafeInteger = isSafeInteger;
-    lodash.isSet = isSet;
-    lodash.isString = isString;
-    lodash.isSymbol = isSymbol;
-    lodash.isTypedArray = isTypedArray;
-    lodash.isUndefined = isUndefined;
-    lodash.isWeakMap = isWeakMap;
-    lodash.isWeakSet = isWeakSet;
-    lodash.join = join;
-    lodash.kebabCase = kebabCase;
-    lodash.last = last;
-    lodash.lastIndexOf = lastIndexOf;
-    lodash.lowerCase = lowerCase;
-    lodash.lowerFirst = lowerFirst;
-    lodash.lt = lt;
-    lodash.lte = lte;
-    lodash.max = max;
-    lodash.maxBy = maxBy;
-    lodash.mean = mean;
-    lodash.meanBy = meanBy;
-    lodash.min = min;
-    lodash.minBy = minBy;
-    lodash.stubArray = stubArray;
-    lodash.stubFalse = stubFalse;
-    lodash.stubObject = stubObject;
-    lodash.stubString = stubString;
-    lodash.stubTrue = stubTrue;
-    lodash.multiply = multiply;
-    lodash.nth = nth;
-    lodash.noConflict = noConflict;
-    lodash.noop = noop;
-    lodash.now = now;
-    lodash.pad = pad;
-    lodash.padEnd = padEnd;
-    lodash.padStart = padStart;
-    lodash.parseInt = parseInt;
-    lodash.random = random;
-    lodash.reduce = reduce;
-    lodash.reduceRight = reduceRight;
-    lodash.repeat = repeat;
-    lodash.replace = replace;
-    lodash.result = result;
-    lodash.round = round;
-    lodash.runInContext = runInContext;
-    lodash.sample = sample;
-    lodash.size = size;
-    lodash.snakeCase = snakeCase;
-    lodash.some = some;
-    lodash.sortedIndex = sortedIndex;
-    lodash.sortedIndexBy = sortedIndexBy;
-    lodash.sortedIndexOf = sortedIndexOf;
-    lodash.sortedLastIndex = sortedLastIndex;
-    lodash.sortedLastIndexBy = sortedLastIndexBy;
-    lodash.sortedLastIndexOf = sortedLastIndexOf;
-    lodash.startCase = startCase;
-    lodash.startsWith = startsWith;
-    lodash.subtract = subtract;
-    lodash.sum = sum;
-    lodash.sumBy = sumBy;
-    lodash.template = template;
-    lodash.times = times;
-    lodash.toFinite = toFinite;
-    lodash.toInteger = toInteger;
-    lodash.toLength = toLength;
-    lodash.toLower = toLower;
-    lodash.toNumber = toNumber;
-    lodash.toSafeInteger = toSafeInteger;
-    lodash.toString = toString;
-    lodash.toUpper = toUpper;
-    lodash.trim = trim;
-    lodash.trimEnd = trimEnd;
-    lodash.trimStart = trimStart;
-    lodash.truncate = truncate;
-    lodash.unescape = unescape;
-    lodash.uniqueId = uniqueId;
-    lodash.upperCase = upperCase;
-    lodash.upperFirst = upperFirst;
-
-    // Add aliases.
-    lodash.each = forEach;
-    lodash.eachRight = forEachRight;
-    lodash.first = head;
-
-    mixin(lodash, (function() {
-      var source = {};
-      baseForOwn(lodash, function(func, methodName) {
-        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
-          source[methodName] = func;
-        }
-      });
-      return source;
-    }()), { 'chain': false });
-
-    /*------------------------------------------------------------------------*/
-
-    /**
-     * The semantic version number.
-     *
-     * @static
-     * @memberOf _
-     * @type {string}
-     */
-    lodash.VERSION = VERSION;
-
-    // Assign default placeholders.
-    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
-      lodash[methodName].placeholder = lodash;
-    });
-
-    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
-    arrayEach(['drop', 'take'], function(methodName, index) {
-      LazyWrapper.prototype[methodName] = function(n) {
-        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
-
-        var result = (this.__filtered__ && !index)
-          ? new LazyWrapper(this)
-          : this.clone();
-
-        if (result.__filtered__) {
-          result.__takeCount__ = nativeMin(n, result.__takeCount__);
-        } else {
-          result.__views__.push({
-            'size': nativeMin(n, MAX_ARRAY_LENGTH),
-            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
-          });
-        }
-        return result;
-      };
-
-      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
-        return this.reverse()[methodName](n).reverse();
-      };
-    });
-
-    // Add `LazyWrapper` methods that accept an `iteratee` value.
-    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
-      var type = index + 1,
-          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
-
-      LazyWrapper.prototype[methodName] = function(iteratee) {
-        var result = this.clone();
-        result.__iteratees__.push({
-          'iteratee': getIteratee(iteratee, 3),
-          'type': type
-        });
-        result.__filtered__ = result.__filtered__ || isFilter;
-        return result;
-      };
-    });
-
-    // Add `LazyWrapper` methods for `_.head` and `_.last`.
-    arrayEach(['head', 'last'], function(methodName, index) {
-      var takeName = 'take' + (index ? 'Right' : '');
-
-      LazyWrapper.prototype[methodName] = function() {
-        return this[takeName](1).value()[0];
-      };
-    });
-
-    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
-    arrayEach(['initial', 'tail'], function(methodName, index) {
-      var dropName = 'drop' + (index ? '' : 'Right');
-
-      LazyWrapper.prototype[methodName] = function() {
-        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
-      };
-    });
-
-    LazyWrapper.prototype.compact = function() {
-      return this.filter(identity);
-    };
-
-    LazyWrapper.prototype.find = function(predicate) {
-      return this.filter(predicate).head();
-    };
-
-    LazyWrapper.prototype.findLast = function(predicate) {
-      return this.reverse().find(predicate);
-    };
-
-    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
-      if (typeof path == 'function') {
-        return new LazyWrapper(this);
-      }
-      return this.map(function(value) {
-        return baseInvoke(value, path, args);
-      });
-    });
-
-    LazyWrapper.prototype.reject = function(predicate) {
-      return this.filter(negate(getIteratee(predicate)));
-    };
-
-    LazyWrapper.prototype.slice = function(start, end) {
-      start = toInteger(start);
-
-      var result = this;
-      if (result.__filtered__ && (start > 0 || end < 0)) {
-        return new LazyWrapper(result);
-      }
-      if (start < 0) {
-        result = result.takeRight(-start);
-      } else if (start) {
-        result = result.drop(start);
-      }
-      if (end !== undefined) {
-        end = toInteger(end);
-        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
-      }
-      return result;
-    };
-
-    LazyWrapper.prototype.takeRightWhile = function(predicate) {
-      return this.reverse().takeWhile(predicate).reverse();
-    };
-
-    LazyWrapper.prototype.toArray = function() {
-      return this.take(MAX_ARRAY_LENGTH);
-    };
-
-    // Add `LazyWrapper` methods to `lodash.prototype`.
-    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
-      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
-          isTaker = /^(?:head|last)$/.test(methodName),
-          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
-          retUnwrapped = isTaker || /^find/.test(methodName);
-
-      if (!lodashFunc) {
-        return;
-      }
-      lodash.prototype[methodName] = function() {
-        var value = this.__wrapped__,
-            args = isTaker ? [1] : arguments,
-            isLazy = value instanceof LazyWrapper,
-            iteratee = args[0],
-            useLazy = isLazy || isArray(value);
-
-        var interceptor = function(value) {
-          var result = lodashFunc.apply(lodash, arrayPush([value], args));
-          return (isTaker && chainAll) ? result[0] : result;
-        };
-
-        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
-          // Avoid lazy use if the iteratee has a "length" value other than `1`.
-          isLazy = useLazy = false;
-        }
-        var chainAll = this.__chain__,
-            isHybrid = !!this.__actions__.length,
-            isUnwrapped = retUnwrapped && !chainAll,
-            onlyLazy = isLazy && !isHybrid;
-
-        if (!retUnwrapped && useLazy) {
-          value = onlyLazy ? value : new LazyWrapper(this);
-          var result = func.apply(value, args);
-          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
-          return new LodashWrapper(result, chainAll);
-        }
-        if (isUnwrapped && onlyLazy) {
-          return func.apply(this, args);
-        }
-        result = this.thru(interceptor);
-        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
-      };
-    });
-
-    // Add `Array` methods to `lodash.prototype`.
-    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
-      var func = arrayProto[methodName],
-          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
-          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
-
-      lodash.prototype[methodName] = function() {
-        var args = arguments;
-        if (retUnwrapped && !this.__chain__) {
-          var value = this.value();
-          return func.apply(isArray(value) ? value : [], args);
-        }
-        return this[chainName](function(value) {
-          return func.apply(isArray(value) ? value : [], args);
-        });
-      };
-    });
-
-    // Map minified method names to their real names.
-    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
-      var lodashFunc = lodash[methodName];
-      if (lodashFunc) {
-        var key = (lodashFunc.name + ''),
-            names = realNames[key] || (realNames[key] = []);
-
-        names.push({ 'name': methodName, 'func': lodashFunc });
-      }
-    });
-
-    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
-      'name': 'wrapper',
-      'func': undefined
-    }];
-
-    // Add methods to `LazyWrapper`.
-    LazyWrapper.prototype.clone = lazyClone;
-    LazyWrapper.prototype.reverse = lazyReverse;
-    LazyWrapper.prototype.value = lazyValue;
-
-    // Add chain sequence methods to the `lodash` wrapper.
-    lodash.prototype.at = wrapperAt;
-    lodash.prototype.chain = wrapperChain;
-    lodash.prototype.commit = wrapperCommit;
-    lodash.prototype.next = wrapperNext;
-    lodash.prototype.plant = wrapperPlant;
-    lodash.prototype.reverse = wrapperReverse;
-    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
-
-    // Add lazy aliases.
-    lodash.prototype.first = lodash.prototype.head;
-
-    if (symIterator) {
-      lodash.prototype[symIterator] = wrapperToIterator;
-    }
-    return lodash;
-  });
-
-  /*--------------------------------------------------------------------------*/
-
-  // Export lodash.
-  var _ = runInContext();
-
-  // Some AMD build optimizers, like r.js, check for condition patterns like:
-  if (true) {
-    // Expose Lodash on the global object to prevent errors when Lodash is
-    // loaded by a script tag in the presence of an AMD loader.
-    // See http://requirejs.org/docs/errors.html#mismatch for more details.
-    // Use `_.noConflict` to remove Lodash from the global object.
-    root._ = _;
-
-    // Define as an anonymous module so, through path mapping, it can be
-    // referenced as the "underscore" module.
-    !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
-      return _;
-    }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
-  }
-  // Check for `exports` after `define` in case a build optimizer adds it.
-  else if (freeModule) {
-    // Export for Node.js.
-    (freeModule.exports = _)._ = _;
-    // Export for CommonJS support.
-    freeExports._ = _;
-  }
-  else {
-    // Export to the global object.
-    root._ = _;
-  }
-}.call(this));
-
-/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(14), __webpack_require__(15)(module)))
-
-/***/ },
-/* 14 */
-/***/ function(module, exports) {
-
-var g;
-
-// This works in non-strict mode
-g = (function() { return this; })();
-
-try {
-	// This works if eval is allowed (see CSP)
-	g = g || Function("return this")() || (1,eval)("this");
-} catch(e) {
-	// This works if the window reference is available
-	if(typeof window === "object")
-		g = window;
-}
-
-// g can still be undefined, but nothing to do about it...
-// We return undefined, instead of nothing here, so it's
-// easier to handle this case. if(!global) { ...}
-
-module.exports = g;
-
-
-/***/ },
-/* 15 */
-/***/ function(module, exports) {
-
-module.exports = function(module) {
-	if(!module.webpackPolyfill) {
-		module.deprecate = function() {};
-		module.paths = [];
-		// module.parent = undefined by default
-		if(!module.children) module.children = [];
-		Object.defineProperty(module, "loaded", {
-			enumerable: true,
-			configurable: false,
-			get: function() { return module.l; }
-		});
-		Object.defineProperty(module, "id", {
-			enumerable: true,
-			configurable: false,
-			get: function() { return module.i; }
-		});
-		module.webpackPolyfill = 1;
-	}
-	return module;
-}
-
-
-/***/ },
-/* 16 */
-/***/ function(module, exports, __webpack_require__) {
-
-"use strict";
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-"use strict";
-exports.__esModule = true;
-/// <reference path="../typings/index.d.ts" />
-var angular = __webpack_require__(0);
-__webpack_require__(3);
-__webpack_require__(2);
-__webpack_require__(1);
-__webpack_require__(7);
-var routes_1 = __webpack_require__(6);
-var engMap_component_1 = __webpack_require__(5);
-var eline_side_component_1 = __webpack_require__(4);
-angular.module('vnaasgui', [
-    'ui.router',
-    'app',
-    'ngMap'
-])
-    .config(routes_1["default"])
-    .component('engMap', engMap_component_1.engMap)
-    .component('elineSide', eline_side_component_1.elineSide)
-    .run(["$log", "$state", "XosNavigationService", "XosComponentInjector", function ($log, $state, XosNavigationService, XosComponentInjector) {
-    $log.info('[vnaasgui] App is running');
-    XosNavigationService.add({
-        label: 'vNaaS GUI',
-        state: 'xos.vnaasgui'
-    });
-}]);
-
-
-/***/ }
-/******/ ]);
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/xos/gui/.tmp/index.js.map b/xos/gui/.tmp/index.js.map
deleted file mode 100755
index db57b97..0000000
--- a/xos/gui/.tmp/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap d343910db03588c47a4b","webpack:///./~/angular/index.js","webpack:///./~/angular-cookies/index.js","webpack:///./~/angular-resource/index.js","webpack:///./~/angular-ui-router/release/angular-ui-router.js","webpack:///./src/app/components/eline-side.component.ts?6cfa","webpack:///./src/app/components/eline-side.component.ts","webpack:///./src/app/components/engMap.component.ts?2f5c","webpack:///./src/app/components/engMap.component.ts","webpack:///./src/routes.ts?c833","webpack:///./src/routes.ts","webpack:///./~/ngmap/build/scripts/ng-map.js","webpack:///./~/angular-cookies/angular-cookies.js","webpack:///./~/angular-resource/angular-resource.js","webpack:///./~/angular/angular.js","webpack:///./src/app/components/eline-side.component.html","webpack:///./src/app/components/engMap.component.html","webpack:///./~/lodash/lodash.js","webpack:///(webpack)/buildin/global.js","webpack:///(webpack)/buildin/module.js","webpack:///./src/index.ts?fe78","webpack:///./src/index.ts"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA,YAAI;AACJ;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;AC9DA;AACA;;;;;;;ACDA;AACA;;;;;;;ACDA;AACA;;;;;;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,cAAc;AAC7D;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,UAAU;AAC5C,6BAA6B,kBAAkB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,6BAA6B;AAC3D,4CAA4C,yCAAyC,EAAE;AACvF,mCAAmC,2CAA2C,EAAE;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,EAAE,GAAG,oBAAoB;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,mCAAmC,eAAe;AAClD,qCAAqC,aAAa;AAClD;AACA;AACA,0BAA0B,SAAS;AACnC;AACA;AACA;AACA,0CAA0C,kCAAkC;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,WAAW;AACtC;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA,yCAAyC;AACzC,6BAA6B,2BAA2B;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,MAAM;AACN;AACA;AACA;AACA;AACA,yCAAyC,mCAAmC;AAC5E;AACA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,YAAY,MAAM;AAClB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,2BAA2B,uBAAuB;AAClD,oBAAoB,iBAAiB;AACrC;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gFAAgF;AACrG;AACA;AACA,qBAAqB,2FAA2F;AAChH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,uBAAuB,EAAE,sBAAsB,wBAAwB;AAC7G;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,sCAAsC,EAAE;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,2BAA2B;AAC3B;AACA;AACA,kCAAkC,6CAA6C,iBAAiB,EAAE,EAAE;AACpG;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,gCAAgC;AAChC;AACA;AACA,gCAAgC;AAChC;AACA;AACA,2CAA2C,qBAAqB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA,gCAAgC;AAChC;AACA;AACA,2CAA2C,qBAAqB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wGAAwG;AACnJ;AACA,2BAA2B,eAAe,YAAY;AACtD;AACA;AACA,wCAAwC,8DAA8D;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,wCAAwC;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,yCAAyC;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA,mEAAmE;AACnE;AACA;AACA;AACA,6BAA6B,2BAA2B;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,wBAAwB;AACnC;AACA;AACA,oCAAoC,gDAAgD,2BAA2B,EAAE,EAAE;AACnH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,+BAA+B;AAC/B;AACA;AACA;AACA;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA,wDAAwD,kCAAkC,EAAE,oBAAoB;AAChH,0EAA0E,sCAAsC,iBAAiB,EAAE,EAAE,EAAE;AACvI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E,sBAAsB;AACtB;AACA;AACA,gDAAgD;AAChD,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,yBAAyB,EAAE;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,0BAA0B,EAAE;AAC1E;AACA,gCAAgC,2CAA2C,4BAA4B,EAAE,EAAE,WAAW;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,4DAA4D,uBAAuB,EAAE;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,iCAAiC,EAAE;AAC3F;AACA;AACA;AACA,wCAAwC,UAAU,EAAE;AACpD;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,yBAAyB,sBAAsB,yBAAyB,GAAG;AAC3E;AACA;AACA,gCAAgC,mBAAmB;AACnD;AACA;AACA;AACA,kCAAkC,4CAA4C;AAC9E;AACA,iCAAiC,0CAA0C,EAAE;AAC7E,mCAAmC,4CAA4C,EAAE;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,iCAAiC,wBAAwB,yBAAyB,GAAG;AACrF;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,mDAAmD,iCAAiC,EAAE;AACtF;AACA;AACA,eAAe,oBAAoB,wBAAwB;AAC3D;AACA;AACA;AACA;AACA;AACA,kCAAkC,4DAA4D;AAC9F;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,wBAAwB,oCAAoC,sBAAsB,EAAE,QAAQ,GAAG;AAC9H,+BAA+B,wBAAwB,oCAAoC,sBAAsB,EAAE,SAAS,GAAG;AAC/H;AACA;AACA,+BAA+B,wBAAwB,yEAAyE,GAAG;AACnI;AACA,8BAA8B,0BAA0B,sBAAsB,GAAG;AACjF;AACA,6BAA6B,qBAAqB,UAAU,GAAG;AAC/D;AACA,4BAA4B,qCAAqC;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,MAAM;AAC/E;AACA;AACA,yDAAyD,MAAM;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C,mCAAmC;AACnC,sCAAsC;AACtC;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,iBAAiB;AAC5B,yCAAyC;AACzC;AACA,GAAG;AACH;AACA;AACA;AACA,iBAAiB;AACjB,uBAAuB;AACvB;AACA;AACA;AACA;AACA,8BAA8B,qDAAqD,EAAE;AACrF;AACA,8BAA8B,2DAA2D,EAAE;;;AAG3F,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,OAAO;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,iCAAiC,eAAe;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,yBAAyB,EAAE;AACxE,6CAA6C,+BAA+B,EAAE,EAAE;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,0CAA0C,EAAE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,oBAAoB,EAAE;AACzE;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;;AAGH,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,gDAAgD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,8FAA8F;AACxI;AACA;AACA;AACA;AACA,iEAAiE,6BAA6B;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,mBAAmB;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,2BAA2B;AACpE,sCAAsC,2CAA2C;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,2BAA2B;AACrE;AACA;AACA;AACA,8EAA8E,mBAAmB,EAAE;AACnG;AACA;AACA,yEAAyE,eAAe,EAAE;AAC1F,kEAAkE,cAAc,EAAE;AAClF,sEAAsE,cAAc,EAAE;AACtF,sEAAsE,uBAAuB,EAAE;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA,kFAAkF,UAAU;AAC5F;AACA;AACA,iFAAiF,UAAU;AAC3F;AACA;AACA,gFAAgF,UAAU;AAC1F;AACA;AACA,kFAAkF,UAAU;AAC5F;AACA;AACA,iFAAiF,UAAU;AAC3F;AACA;AACA,kFAAkF,UAAU;AAC5F;AACA;AACA,mFAAmF,UAAU;AAC7F;AACA;AACA,iFAAiF,UAAU;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,qDAAqD;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,iBAAiB;AACpD,qGAAqG;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,0DAA0D,EAAE;AACzI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E,iBAAiB;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,YAAY;AAC5C;AACA;AACA,iEAAiE,sCAAsC,EAAE;AACzG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,uBAAuB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,0CAA0C,iBAAiB;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,yBAAyB,EAAE;AAC9E,kDAAkD,+BAA+B,sBAAsB,EAAE,EAAE,EAAE;AAC7G;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,kBAAkB,EAAE;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,UAAU,EAAE,EAAE;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,8BAA8B,EAAE;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gPAAgP;AAChP;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,MAAM,sBAAsB;AACxC,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,4CAA4C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,+BAA+B,EAAE;AACxE,sCAAsC,sBAAsB,EAAE;AAC9D;AACA,oEAAoE,2CAA2C,EAAE;AACjH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,YAAY;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,MAAM;AAClB;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,6DAA6D;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,kFAAkF,EAAE;AAClI;AACA,4CAA4C,iFAAiF,EAAE;AAC/H;AACA,sEAAsE,iEAAiE,EAAE;AACzI;AACA,0DAA0D,yDAAyD,EAAE;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,2BAA2B;AACvE;AACA,wBAAwB,kBAAkB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oGAAoG;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,uCAAuC,EAAE;AACzF;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,YAAY;AACxB;AACA,YAAY,OAAO;AACnB,YAAY,cAAc;AAC1B,YAAY,kBAAkB;AAC9B;AACA;AACA;AACA,kCAAkC,cAAc;AAChD,mCAAmC,eAAe;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,wBAAwB,wBAAwB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD;AACA,+CAA+C,sEAAsE;AACrH;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,0CAA0C,EAAE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,sBAAsB,EAAE;AAC3D;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,sCAAsC;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4FAA4F,kCAAkC,EAAE;AAChI;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAA8D,eAAe,EAAE;AAC7H,6CAA6C,4DAA4D;AACzG,4CAA4C,qEAAqE,kBAAkB,EAAE;AACrI,8CAA8C,yEAAyE,kBAAkB,EAAE;AAC3I,6CAA6C,wEAAwE,kBAAkB,EAAE;AACzI,8CAA8C,6DAA6D;AAC3G,+CAA+C,+DAA+D,0CAA0C,EAAE;AAC1J,6CAA6C,6DAA6D,0CAA0C,EAAE;AACtJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,8BAA8B,oCAAoC,EAAE;AACrH;AACA;AACA;AACA,yBAAyB;AACzB,cAAc;AACd;AACA;AACA;AACA;AACA,oCAAoC,6BAA6B,EAAE;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,+BAA+B,EAAE;AACnE;AACA;AACA,sCAAsC,kCAAkC,EAAE,EAAE;AAC5E;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,sDAAsD,gBAAgB,EAAE,GAAG,EAAE;AACrI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,yBAAyB,EAAE;AACnF;AACA,mCAAmC,0BAA0B,EAAE;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kGAAkG,6BAA6B,EAAE;AACjI;AACA;AACA;AACA;AACA,qEAAqE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,gBAAgB,EAAE;AACvE,kEAAkE,qCAAqC,EAAE;AACzG;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,+BAA+B,eAAe;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C,yCAAyC,UAAU,+BAA+B,EAAE,EAAE,EAAE;AACxF;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,uDAAuD,EAAE;AACpH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,mBAAmB,EAAE;AACxG;AACA,2CAA2C,qCAAqC,EAAE;AAClF,qCAAqC,2BAA2B,EAAE,EAAE;AACpE;AACA,sEAAsE,0BAA0B,EAAE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE,qBAAqB,EAAE;AAC3F;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;;;AAGF,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,eAAe,EAAE;AAC1E;AACA;AACA;AACA;AACA,mGAAmG,UAAU;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0HAA0H;AAC1H;AACA;AACA;AACA,gEAAgE,4DAA4D,EAAE;AAC9H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,6CAA6C,EAAE;AACrF,mEAAmE;AACnE,mEAAmE,mBAAmB,EAAE;AACxF,8DAA8D,8CAA8C,EAAE;AAC9G;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,0BAA0B,iBAAiB,iEAAiE;AAC1J,mDAAmD,uDAAuD;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,0CAA0C,+CAA+C,EAAE,IAAI,EAAE;AACjJ;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA,kDAAkD,iBAAiB;AACnE;AACA,sEAAsE,oBAAoB,EAAE;AAC5F;AACA;AACA;AACA;AACA,gDAAgD,2DAA2D;AAC3G,2EAA2E,qDAAqD,EAAE,IAAI;AACtI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,+CAA+C;AAC9E,2CAA2C,wFAAwF;AACnI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sCAAsC;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,oFAAoF,gBAAgB;AACvI;AACA;AACA;AACA;AACA,EAAE,0CAA0C;AAC5C;AACA;AACA,gCAAgC,aAAa;AAC7C;AACA,+EAA+E,kBAAkB;AACjG,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,2DAA2D;AACrE,UAAU;AACV;AACA;AACA;AACA,uBAAuB,8BAA8B;AACrD;AACA,4DAA4D,iDAAiD,EAAE;AAC/G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC,+DAA+D,cAAc;AAC7E;AACA;AACA,gCAAgC,uJAAuJ;AACvL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,wGAAwG;AAC1H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,6CAA6C,kDAAkD,EAAE,gCAAgC;AACjI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD,kCAAkC,cAAc;AAChD,gDAAgD,iEAAiE,EAAE;AACnH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,6CAA6C,0CAA0C,EAAE;AACzF;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA,wCAAwC;AACxC;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,qFAAqF;AACnH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,WAAW,EAAE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,iBAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,0BAA0B,EAAE;AACzD,6BAA6B,8BAA8B,EAAE;AAC7D,8BAA8B,8BAA8B,EAAE;AAC9D,yBAAyB,gEAAgE,EAAE;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA,uDAAuD,YAAY;AACnE;AACA,uDAAuD,YAAY;AACnE;AACA,mDAAmD,eAAe;AAClE;AACA;AACA;AACA;AACA;AACA,kBAAkB,4BAA4B;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,iBAAiB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,qFAAqF;AACjH,8BAA8B,oFAAoF;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,eAAe,EAAE;AAC3D,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,yCAAyC,0BAA0B,EAAE;AACrE,qCAAqC,2EAA2E,EAAE;AAClH;AACA,cAAc;AACd;AACA,yCAAyC,sBAAsB,EAAE;AACjE,yCAAyC,gCAAgC,EAAE;AAC3E;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,qCAAqC,qDAAqD,EAAE;AAC5F;AACA;AACA,qDAAqD,mCAAmC,EAAE;AAC1F,kBAAkB;AAClB,iCAAiC,EAAE;AACnC,kCAAkC,EAAE;AACpC,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,8CAA8C,aAAa,eAAe;AAC/H,oFAAoF;AACpF;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,aAAa;AAC/E;AACA,kCAAkC,gCAAgC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,4DAA4D;AAC5F;AACA;AACA;AACA;AACA,qEAAqE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iFAAiF;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,sCAAsC;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gFAAgF,MAAM;AACtF;AACA;AACA;AACA,iBAAiB,mBAAmB;AACpC;AACA;AACA;AACA,gFAAgF,UAAU;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,GAAG;AAClB,eAAe,SAAS;AACxB,eAAe,eAAe,KAAK;AACnC;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA,iBAAiB,8BAA8B;AAC/C;AACA,mBAAmB;AACnB;AACA,iBAAiB,OAAO,YAAY;AACpC,gDAAgD,2BAA2B,WAAW,OAAO,YAAY,OAAO,+CAA+C,6BAA6B,WAAW,OAAO,YAAY,OAAO;AACjO;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,yCAAyC,EAAE;AACpG;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,gEAAgE,EAAE;AAC7H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,GAAG;AAClC;AACA,SAAS;AACT,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,wCAAwC,iBAAiB;AACzD,4FAA4F,0BAA0B,EAAE,qDAAqD,yBAAyB,EAAE,sEAAsE,kCAAkC,EAAE,0BAA0B,cAAc,EAAE;AAC5V;AACA;AACA;AACA,iDAAiD,yCAAyC;AAC1F,iDAAiD,iCAAiC;AAClF;AACA;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA,4BAA4B,0BAA0B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,0BAA0B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,cAAc;AAChC;AACA;AACA;AACA,+BAA+B,WAAW;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,+BAA+B,WAAW;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,uCAAuC;AAC3F,2CAA2C;AAC3C;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,GAAG,aAAa,oBAAoB;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,+DAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,+BAA+B,EAAE;AACjF,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,oEAAoE,8DAA8D,EAAE;AACpI;AACA;AACA;AACA;AACA,+DAA+D,4CAA4C,EAAE;AAC7G,qIAAqI,8CAA8C,EAAE;AACrL;AACA;AACA;AACA,qDAAqD,8CAA8C,EAAE;AACrG;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA,sCAAsC,IAAI;AAC1C;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,sDAAsD,4CAA4C;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,uEAAuE,aAAa,EAAE;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,8DAA8D,sCAAsC,EAAE;AACtG;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF,wFAAwF,EAAE;AAC9K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,qBAAqB,OAAO;AAC5B;AACA,oBAAoB,OAAO,eAAe;AAC1C;AACA,0BAA0B,OAAO;AACjC;AACA,uBAAuB,OAAO;AAC9B;AACA,sBAAsB,OAAO;AAC7B;AACA;AACA;AACA;AACA;AACA,0BAA0B,OAAO;AACjC;AACA,qBAAqB,OAAO;AAC5B;AACA,yBAAyB,OAAO;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,SAAS;AACT;AACA;AACA;AACA,6BAA6B,+BAA+B;AAC5D,6BAA6B;AAC7B;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB;AACA;AACA,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,iBAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA,aAAa,UAAU,WAAW;AAClC;AACA;AACA;AACA;AACA,+BAA+B,iBAAiB;AAChD;AACA;AACA;AACA;AACA,aAAa,UAAU,WAAW;AAClC;AACA;AACA;AACA;AACA,oCAAoC,UAAU;AAC9C;AACA;AACA;AACA;AACA,8BAA8B,iBAAiB;AAC/C;AACA;AACA;AACA;AACA,sCAAsC,UAAU;AAChD;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA,2BAA2B,WAAW,oBAAoB,EAAE;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;AACA,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA,0BAA0B,QAAQ;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;AACjC;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA,wHAAwH;AACxH;AACA;AACA;AACA,0BAA0B,QAAQ;AAClC;AACA,wHAAwH;AACxH;AACA;AACA;AACA,yCAAyC,SAAS;AAClD;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA,gEAAgE;AAChE;AACA;AACA;AACA,2BAA2B;AAC3B,4BAA4B;AAC5B,+BAA+B;AAC/B;AACA;AACA,gBAAgB,OAAO;AACvB;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,2BAA2B,aAAa;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,uBAAuB,2BAA2B,EAAE,EAAE;AAC9F;AACA,mCAAmC,4BAA4B,uBAAuB,EAAE,EAAE;AAC1F,uCAAuC,6BAA6B,yBAAyB,EAAE,EAAE;AACjG,qCAAqC,6BAA6B,wBAAwB,EAAE,EAAE;AAC9F;AACA,2CAA2C,+BAA+B,iBAAiB;AAC3F,yCAAyC,4BAA4B,+BAA+B,iBAAiB;AACrH;AACA,wCAAwC;AACxC,8CAA8C;AAC9C;AACA,0CAA0C,oBAAoB,iBAAiB;AAC/E;AACA;AACA,yFAAyF,UAAU;AACnG;AACA;AACA,wFAAwF,UAAU;AAClG;AACA;AACA,uFAAuF,UAAU;AACjG;AACA;AACA,yFAAyF,UAAU;AACnG;AACA;AACA,wFAAwF,UAAU;AAClG;AACA;AACA,yFAAyF,UAAU;AACnG;AACA;AACA,0FAA0F,UAAU;AACpG;AACA;AACA,wFAAwF,UAAU;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,oBAAoB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,uBAAuB,oBAAoB;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,qBAAqB;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E,oBAAoB,EAAE;AACpG;AACA;AACA;AACA;AACA;AACA,oDAAoD,iBAAiB;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,uCAAuC,EAAE;AAClF,0CAA0C,qCAAqC,EAAE;AACjF;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,oDAAoD,aAAa;AACjE;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,oCAAoC,gBAAgB;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,qCAAqC,cAAc;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,wCAAwC,gBAAgB;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,uCAAuC,eAAe;AACvG;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA,6BAA6B,0CAA0C,wCAAwC,EAAE,QAAQ;AACzH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,uBAAuB,EAAE,gCAAgC;AAC3H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,qDAAqD,WAAW,EAAE;AACpF,kBAAkB,qDAAqD,YAAY,EAAE;AACrF,kBAAkB,qDAAqD,cAAc;AACrF,kBAAkB,qDAAqD,gBAAgB;AACvF;AACA;AACA;AACA;AACA,gCAAgC;AAChC,gCAAgC;AAChC,gCAAgC;AAChC,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,kDAAkD,EAAE;AACzI;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,SAAS;AACzB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,0CAA0C,+BAA+B;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,kBAAkB;AACxD;AACA;AACA;AACA;AACA,yDAAyD;AACzD,oGAAoG;AACpG;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D,mDAAmD;AACnD;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA,uFAAuF,sBAAsB,EAAE;AAC/G;AACA;AACA,iBAAiB;AACjB;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,gCAAgC,EAAE;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,uCAAuC,cAAc;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA,oEAAoE,GAAG,gBAAgB;AACvF;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,mDAAmD;AACrG,yDAAyD,iBAAiB;AAC1E,qFAAqF;AACrF,6DAA6D,kBAAkB,EAAE,gCAAgC;AACjH;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,oBAAoB,EAAE;AACtD;AACA;AACA,8CAA8C,kDAAkD;AAChG;AACA,qBAAqB;AACrB,uDAAuD,uCAAuC;AAC9F;AACA,qBAAqB;AACrB,qDAAqD,sCAAsC;AAC3F;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,qBAAqB;AACtE,oDAAoD,uCAAuC;AAC3F,OAAO,qDAAqD,gCAAgC;AAC5F;AACA;AACA;AACA,8BAA8B;AAC9B,sCAAsC,6BAA6B,wBAAwB,UAAU,iDAAiD,EAAE,EAAE,EAAE;AAC5J;AACA,mCAAmC,iHAAiH;AACpJ;AACA,4CAA4C,uCAAuC;AACnF;AACA,6CAA6C,8GAA8G;AAC3J;AACA,0CAA0C,oIAAoI;AAC9K;AACA,+BAA+B,6BAA6B;AAC5D;AACA;AACA,iDAAiD,6EAA6E,EAAE;AAChI,kDAAkD,kGAAkG,EAAE;AACtJ,gDAAgD,2DAA2D,yBAAyB,EAAE,gBAAgB,EAAE;AACxJ,gDAAgD,2DAA2D,mBAAmB,EAAE,4BAA4B,EAAE;AAC9J,mDAAmD,4DAA4D,UAAU,EAAE,6BAA6B,EAAE;AAC1J;AACA;AACA,kFAAkF,+DAA+D,UAAU,EAAE,6BAA6B,EAAE;AAC5L,iFAAiF,iHAAiH,EAAE;AACpM,oFAAoF,+FAA+F,EAAE;AACrL;AACA;AACA,2DAA2D,UAAU,EAAE;AACvE;AACA;AACA;AACA,6CAA6C,yEAAyE,EAAE;AACxH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yBAAyB;AAC1D,wCAAwC,0BAA0B;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,qEAAqE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,2BAA2B,+BAA+B,GAAG,EAAE;AACxI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,WAAW,MAAM;AAC/D,mFAAmF;AACnF;AACA;AACA,oCAAoC,oBAAoB;AACxD,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,WAAW;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,iCAAiC;AAC1F;AACA,cAAc;AACd;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,MAAM;AACxB;AACA;AACA;AACA;AACA;AACA,yCAAyC,gBAAgB;AACzD;AACA;AACA;AACA;AACA,+BAA+B,WAAW;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,oCAAoC,EAAE;AACzH;AACA;AACA;AACA,2BAA2B,uCAAuC,EAAE;AACpE;AACA;AACA,MAAM;AACN;AACA,2BAA2B,mCAAmC,EAAE;AAChE;AACA;AACA,MAAM;AACN;AACA,2BAA2B,oCAAoC,EAAE;AACjE;AACA;AACA,MAAM;AACN;AACA,2BAA2B,qCAAqC,EAAE;AAClE;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,6CAA6C;AACrF;AACA;AACA;AACA;AACA,mDAAmD,kDAAkD,6BAA6B,GAAG;AACrI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gGAAgG,uCAAuC,EAAE;AACzI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,kBAAkB,QAAQ;AAC1B,SAAS,kDAAkD;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,yEAAyE;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA,4BAA4B,qBAAqB;AACjD;AACA,2BAA2B,aAAa;AACxC,4BAA4B,uBAAuB;AACnD;AACA,0BAA0B,aAAa;AACvC,mCAAmC,cAAc;AACjD;AACA;AACA;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,QAAQ;AACxB;AACA,4BAA4B,qBAAqB;AACjD;AACA,2BAA2B,cAAc;AACzC,4BAA4B,QAAQ;AACpC;AACA,0BAA0B,aAAa;AACvC,mCAAmC,cAAc;AACjD;AACA;AACA;AACA,kBAAkB,QAAQ;AAC1B,SAAS,kDAAkD;AAC3D;AACA;AACA;AACA,mCAAmC,eAAe;AAClD,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA,6CAA6C,oDAAoD;AACjG;AACA;AACA,qCAAqC,iEAAiE;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,gEAAgE;AAChE;AACA,sDAAsD,yBAAyB;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,8DAA8D;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C,gDAAgD;AAChD;AACA;AACA;AACA,wBAAwB,gCAAgC;AACxD;AACA;AACA,gBAAgB,cAAc;AAC9B,gBAAgB,QAAQ,+BAA+B,sBAAsB;AAC7E;AACA,gBAAgB,QAAQ;AACxB;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA,+CAA+C,0BAA0B;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC,4CAA4C;AAC5C,iDAAiD;AACjD,yCAAyC;AACzC,iCAAiC;AACjC;AACA;AACA;AACA,wBAAwB,sCAAsC;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC,wCAAwC;AACxC,sCAAsC;AACtC,8CAA8C;AAC9C,2CAA2C;AAC3C,uCAAuC;AACvC,mCAAmC;AACnC;AACA;AACA,gBAAgB,OAAO;AACvB;AACA,gBAAgB,QAAQ,+BAA+B,sBAAsB;AAC7E;AACA,gBAAgB,QAAQ;AACxB;AACA,4BAA4B,eAAe;AAC3C;AACA;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA,+CAA+C,0BAA0B;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,gBAAgB;AAC5D;AACA;AACA,gBAAgB,cAAc;AAC9B,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB;AACA,yBAAyB,aAAa;AACtC;AACA;AACA,2BAA2B,aAAa;AACxC,4BAA4B,uBAAuB;AACnD;AACA,4BAA4B,cAAc;AAC1C;AACA,kBAAkB,OAAO;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,sBAAsB,kBAAkB;AAC9E,uDAAuD;AACvD,yCAAyC;AACzC;AACA;AACA,sCAAsC;AACtC;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB;AACA;AACA,sFAAsF;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gBAAgB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gBAAgB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gBAAgB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA,4CAA4C,WAAW,EAAE;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,oDAAoD;AACjF;AACA;AACA;AACA;AACA;AACA,kEAAkE,4CAA4C,gBAAgB,EAAE,EAAE,EAAE;AACpI;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,kCAAkC,sBAAsB,EAAE;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E,EAAE;AAChF;AACA,sGAAsG,iCAAiC,EAAE;AACzI,4FAA4F,EAAE;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E,EAAE;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,EAAE;AACvE;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,qDAAqD,iCAAiC;AACtF;AACA;AACA;AACA;AACA,2FAA2F,gDAAgD,EAAE;AAC7I;AACA,2DAA2D,2BAA2B,EAAE;AACxF;AACA;AACA;AACA,4DAA4D,sBAAsB,EAAE;AACpF;AACA;AACA,oCAAoC,oCAAoC,EAAE;AAC1E;AACA;AACA;AACA;AACA;AACA,6CAA6C,2CAA2C,EAAE;AAC1F,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,YAAY;AACZ;AACA;AACA,2FAA2F;AAC3F;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,uEAAuE,WAAW,mBAAmB;AACrG,iEAAiE,WAAW,mBAAmB;AAC/F;AACA,mEAAmE,sBAAsB;AACzF;AACA,8CAA8C,2CAA2C,kDAAkD,qBAAqB,cAAc,GAAG,EAAE,GAAG,EAAE;AACxL;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,sCAAsC,EAAE,EAAE;AAC7G;AACA,kEAAkE;AAClE;AACA;AACA;AACA,uCAAuC,iBAAiB;;;AAGxD,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,sCAAsC;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,mBAAmB,gCAAgC;AACnD;AACA,gCAAgC,MAAM,cAAc;AACpD;AACA,gCAAgC;AAChC;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA,iDAAiD,4CAA4C,EAAE;AAC/F;AACA;AACA;AACA;AACA,sDAAsD,uDAAuD;AAC7G;AACA;AACA;AACA;AACA;AACA,oDAAoD,4CAA4C;AAChG;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,0CAA0C;AAC1C,0EAA0E,gBAAgB;AAC1F,6CAA6C,qCAAqC;AAClF,0BAA0B,yDAAyD,EAAE;AACrF,+BAA+B,0EAA0E,EAAE;AAC3G,4BAA4B,UAAU,mDAAmD,EAAE,EAAE,EAAE,GAAG,KAAK;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,+CAA+C,EAAE,IAAI;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,4BAA4B;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA,gBAAgB,OAAO;AACvB,iBAAiB,wBAAwB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,iBAAiB,wBAAwB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0FAA0F,iBAAiB;AAC3G;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,GAAG,GAAG;AAC5C;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,QAAQ;AACrF;AACA;AACA;AACA,yCAAyC,iBAAiB,KAAK,gBAAgB;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mIAAmI,QAAQ;AAC3I;AACA;AACA;AACA,6DAA6D,iBAAiB;AAC9E;AACA;AACA,6DAA6D,iBAAiB;AAC9E;AACA;AACA,6DAA6D,iBAAiB;AAC9E;AACA;AACA;AACA,qCAAqC,aAAa;AAClD;AACA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA,kIAAkI;AAClI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE;AACjE,qCAAqC,EAAE;AACvC;AACA;AACA;AACA;AACA;AACA,+FAA+F,YAAY,EAAE;AAC7G;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,iBAAiB;AACrD;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,sBAAsB,EAAE;AACrF,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,YAAY,EAAE;AAC7G;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,qBAAqB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,qBAAqB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,oBAAoB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,oBAAoB,2CAA2C,EAAE;AACpI;AACA;AACA;AACA;AACA,8CAA8C,kBAAkB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC,gCAAgC,cAAc;AAC9C,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,mBAAmB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,uBAAuB,wBAAwB,EAAE,EAAE;AAC1G,0DAA0D,2BAA2B;AACrF,uDAAuD,4CAA4C;AACnG,yDAAyD,sCAAsC;AAC/F;AACA,kBAAkB;AAClB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,+DAA+D;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,wFAAwF;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA,YAAY,QAAQ;AACpB;AACA,cAAc,oCAAoC;AAClD;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,+FAA+F;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,gCAAgC;AACrE;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,YAAY,gCAAgC,EAAE;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,wBAAwB;AACvE;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,aAAa;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wFAAwF,WAAW,oCAAoC;AACvI;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,oCAAoC;AACvG,iGAAiG,oCAAoC;AACrI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,qEAAqE,EAAE;AAC3H;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,yBAAyB,EAAE;AAC1G,mFAAmF,yBAAyB,EAAE;AAC9G;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,uEAAuE,aAAa,EAAE;AACtF;AACA,qGAAqG,0CAA0C,EAAE;AACjJ;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,oCAAoC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,8GAA8G;AACtJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,UAAU;AACV;AACA;;;AAGA;AACA;AACA,CAAC;AACD;AACA,6C;;;;;;;ACpzPA;;;;;;;;;;;;;;;ACcA;AACA,QAAQ,aAAa;ADErB,IAAI;AAEJ;IAIE,mBACU,cACA,eACA,OACA,MACA,QAAW;QAJX;QACA;QACA;QACA;QACA;QAER,OAAO;;IAGF,gCAAP,UAAiB,MAAS;QAA1B;QACE,IAAI,OAAO,KAAK;QAChB,OAAO,KAAK;QACZ,KAAK,QAAQ,KAAK,UAAC,KAAG;YACpB,KAAK,OAAO;YACZ,MAAK,OAAO,QAAW,KAAK,OAAI;WAE/B,SAAM,UAAC,OAAK;YACX,MAAK,OAAO,MAAM,wBAAsB,KAAK,OAAI,OAAK,MAAM;;;IAI3D,kCAAP,UAAmB,MAAS;QAA5B;QACE,IAAI,OAAO,KAAK;QAChB,KAAK,UAAU,KAAK,UAAC,KAAG;YACtB,MAAK,OAAO,QAAW,OAAI;WAE5B,SAAM,UAAC,OAAK;YACT,MAAK,OAAO,MAAM,0BAAwB,OAAI,OAAK,MAAM;;;IAKjE;;AAnCS,oBAAU,CAAC,gBAAgB,iBAAiB,SAAS,QAAQ;AAqCzD,oBAAuC;IAClD,UAAU,oBAAQ;IAClB,cAAc;IACd,YAAY;IACZ,UAAU;QACR,KAAK;;;;;;;;;;AE/DT;;;;;;;;;;;;;;;ACcA;AACA,QAAQ,aAAa;ADIrB;AAIA,IAAI;AAEJ;IA8BE,gBACU,OACA,eACA,WACA,WACA,cACA,oBACA,WACA,WAAc;QAPd;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QAzBH,YAAO;QACP,cAAS;QACT,iBAAY,IAAI;QAChB,aAAQ;QACR,YAAO;QAEP,iBAAY;QACZ,kBAAa;QACb,sBAAiB;QAGjB,iBAAY,CAAC,EAAC,eAAe,kBAAkB,eAAe,oBAAoB,WAAW,CAAC,EAAC,SAAS,gBAAc,EAAC,eAAe,aAAa,eAAe,OAAO,WAAW,CAAC,EAAC,SAAS,gBAAc,EAAC,eAAe,OAAO,eAAe,OAAO,WAAW,CAAC,EAAC,cAAc,YAAU,EAAC,eAAe,QAAQ,eAAe,OAAO,WAAW,CAAC,EAAC,cAAc,CAAC,OAAM,EAAC,aAAa,SAAO,EAAC,eAAe,gBAAgB,eAAe,OAAO,WAAW,CAAC,EAAC,cAAc,mBAAiB,EAAC,eAAe,iBAAiB,eAAe,eAAe,WAAW,CAAC,EAAC,cAAc,YAAU,EAAC,eAAe,WAAW,eAAe,OAAO,WAAW,CAAC,EAAC,cAAc,YAAU,EAAC,eAAe,SAAS,eAAe,OAAO,WAAW,CAAC,EAAC,SAAS,aAAY,EAAC,cAAc;QAgBrwB,OAAO;;IAGT;QAAA;QACE,KAAK,MAAM,SAAS,KAAK,eAAG;YAC1B,MAAK,MAAM;YACX,MAAK,kBAAkB,MAAK,cAAc,MAAM,wBAAwB,gCAAgC,UACtG,eAAG;gBACD,MAAK,OAAO;gBACZ,MAAK,UAAU;;YAGnB,MAAK,oBAAoB,MAAK,cAAc,MAAM,SAAS,iBAAiB,UAC1E,eAAG;gBACD,MAAK,SAAS;gBACd,MAAK;gBACL,MAAK,UAAU;;YAGnB,MAAK,kBAAkB,MAAK,cAAc,MAAM,oBAAoB,4BAA4B,UAC9F,eAAG;gBACD,MAAK,OAAO;;;;IAMpB;QACE,IAAI,KAAK,iBAAiB;YACxB,KAAK,gBAAgB;;;IAIlB,6BAAP,UAAiB,KAAU;QAEzB,IAAI,SAAS,IAAI,OAAO,KAAK;QAE7B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;YACzC,KAAK,KAAK,GAAG,cAAc;YAC3B,IAAI,OAAO,KAAK,MAAM,KAAK,KAAK,GAAG;YACnC,KAAK,UAAU,IAAI,KAAK,KAAK,GAAG,QAAQ;YACxC,IAAI,SAAS,IAAI,OAAO,KAAK,OAAO,KAAK,IAAI,KAAK;YAClD,OAAO,OAAO;;QAEhB,IAAI,UAAU,OAAO;QACrB,IAAI,UAAU;;IAIT,+BAAP;QAAA;QACE,KAAK,OAAO,QAAQ,UAAC,OAAU;YAC7B,IAAI,eAAe,MAAK,UAAU,IAAI,MAAM;YAC5C,IAAI,aAAa,MAAK,UAAU,IAAI,MAAM;YAC1C,MAAM,OAAO,CAAC,cAAc;;;IAKzB,6BAAP,UAAiB,cAAkB;QACjC,IAAI,SAAS,SAAS,cAAc;QACpC,QAAQ;YACN,KAAK;gBACH,OAAO;YACT,KAAK;gBACH,OAAO;YACT;gBACE,OAAO;;;IAKN,2BAAP,UAAe,GAAQ,KAAQ;QAC7B,KAAK,cAAc;QACnB,KAAK,IAAI,eAAe,YAAY;;;IAK/B,8BAAP,UAAkB,GAAQ,OAAY,QAAe;QACnD,KAAK,YAAY,CAAC,KAAK;QACvB,IAAI,QAAQ;YACV,KAAK,QAAQ,EAAE,KAAK,KAAK,QAAQ,EAAC,IAAI,MAAM;;QAE9C,KAAK,aAAa,gBAAgB,aAAa,EAAC,OAAO,KAAK,OAAO,SAAS,KAAK,MAAM,KAAK,QAAO;QACnG,IAAI,CAAC,KAAK,aAAa,KAAK,YAAY;YACtC,KAAK,aAAa;YAClB,KAAK,iBAAiB;YACtB,KAAK,YAAY,cAAc;;;IAK5B,oCAAP,UAAwB,KAAQ;QAC9B,OAAO;YACL,KAAK,iBAAiB;YACtB,KAAK,aAAa;YAClB,IAAI,cAAc;YAClB,KAAK,cAAc;YACnB,KAAK,QAAQ;gBACX,MAAM,IAAI;gBACV,UAAU,IAAI;gBACd,oBAAoB,IAAI;;YAE1B,KAAK,WAAW,IAAI,KAAK,OAAO;;;IAK7B,oCAAP,UAAwB,KAAQ;QAC9B,KAAK,MAAM,qBAAqB,IAAI;QACpC,IAAI,KAAK,MAAM,SAAS,KAAK,MAAM,UAAU;YAC3C,KAAK,MAAM,OAAO,KAAK,MAAM,OAAO,IAAI;;QAE1C,OAAO,KAAK,MAAM;QAClB,IAAM,WAAW,KAAK,UAAU,YAAY;QAC5C,IAAI,MAAM,IAAI,SAAS;QACvB,KAAK,IAAI,QAAQ,KAAK,OAAO;YAC3B,IAAI,MAAM;gBACR,IAAI,QAAQ,KAAK,MAAM;;;QAI3B,KAAK,QAAQ;;IAGjB;;AAnKS,iBAAU;IACf;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;AAVS;AAuKA,iBAAoC;IAC/C,UAAU,oBAAQ;IAClB,cAAc;IACd,YAAY;;;;;;;;;AEnMd;;;;;;;;;;;;;;;ACcA;AACA,QAAQ,aAAa;ADErB,qBAAe;AAEf,sBAAsB,gBAA2C,mBAA4C;IAC3G,kBAAkB,UAAU,OAAO,WAAW;IAE9C;SACG,MAAM,eAAe;QACpB,KAAK;QACL,QAAQ;QACR,WAAW;;;;;;;;;AE3BjB;AACA;AACA;AACA,CAAC;AACD;AACA,CAAC;AACD;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kBAAkB;AAClB,iBAAiB;AACjB,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,KAAK;AACpB,eAAe,KAAK;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAyB;AAC5C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+BAA+B;AAC/B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iDAAiD,YAAY;AAC7D;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,MAAM;AACN;AACA;;AAEA,2BAA2B;;AAE3B;AACA;AACA;AACA;AACA;AACA,wDAAwD,cAAc;AACtE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,gBAAgB,WAAW;AAC3B;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL,IAAI;;AAEJ;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+CAA+C,aAAa;AAC5D;;AAEA;;AAEA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,+CAA+C,aAAa;AAC5D;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB,UAAU,OAAO;AACjB,UAAU,QAAQ;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA,uCAAuC,QAAQ;AAC/C;AACA;AACA,sEAAsE;AACtE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA,uCAAuC;AACvC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,0EAA0E;AAC1E;AACA;;AAEA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iDAAiD,aAAa;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,2BAA2B;;AAE3B;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO;;AAEP;AACA,qCAAqC;AACrC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP,MAAM;AACN;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA,MAAM;AACN,IAAI;AACJ;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,YAAY;AACnC,qBAAqB,mCAAmC;AACxD,kBAAkB,QAAQ;AAC1B,uBAAuB,aAAa;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,iDAAiD,aAAa;AAC9D;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa,sCAAsC;AACnD,2DAA2D,cAAc;AACzE;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT,OAAO;;AAEP;AACA;AACA,OAAO;AACP;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA,CAAC;;;AAGD;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,eAAe,gBAAgB,iBAAiB,UAAU,eAAe;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA,2EAA2E,gCAAgC;AAC3G;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;AACT;AACA,MAAM;AACN,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mDAAmD,aAAa;AAChE;;AAEA;AACA;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,2BAA2B;AAC3B;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB;AACA,UAAU,QAAQ;AAClB;AACA,UAAU,WAAW;AACrB;AACA;AACA,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,eAAe,IAAI,eAAe;AACtD,8BAA8B,mBAAmB,IAAI,mBAAmB;AACxE,8BAA8B,mBAAmB,IAAI,mBAAmB;AACxE,6BAA6B,kBAAkB,IAAI,kBAAkB,iBAAiB;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,iDAAiD,aAAa;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oCAAoC,oBAAoB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP,MAAM;;AAEN;AACA;AACA;AACA;AACA;;AAEA,IAAI;AACJ;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA,UAAU,IAAI;AACd,UAAU,gBAAgB;AAC1B;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA,mEAAmE;AACnE;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,OAAO;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,mDAAmD,aAAa;AAChE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,eAAe;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,sBAAsB;;AAEtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,Q;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,UAAU,WAAW;AACrB;AACA;AACA,UAAU,WAAW;AACrB;AACA;AACA,UAAU,MAAM;AAChB;AACA,UAAU,OAAO;AACjB;AACA,WAAW,4DAA4D;AACvE,wBAAwB,gBAAgB;AACxC;AACA,UAAU,QAAQ;AAClB;AACA;AACA,UAAU,QAAQ;AAClB;AACA,mBAAmB;AACnB,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,QAAQ;AAClB;AACA;AACA;AACA,UAAU,QAAQ;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,UAAU,WAAW;AACrB;AACA;AACA,UAAU,QAAQ;AAClB;AACA,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,4DAA4D,aAAa;AACzE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA,6DAA6D;;AAE7D;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,mHAAmH,aAAa;AAChI;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iDAAiD,aAAa;AAC9D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA,uDAAuD,aAAa;AACpE;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,UAAU,WAAW;AACrB;AACA;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,wBAAwB;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,S;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,sDAAsD,aAAa;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;;AAEA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iDAAiD,aAAa;AAC9D;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,OAAO;;AAEP,MAAM;;AAEN;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA,gEAAgE;AAChE;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA,gEAAgE;AAChE;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA,mCAAmC,qBAAqB;AACxD;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA;AACA,OAAO,WAAW;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAU,EAAE;;AAEZ;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,eAAe,YAAY;AAC3B,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C;AACA;AACA;AACA;AACA;;AAEA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,0C;AACA;AACA;AACA;AACA,2BAA2B,kBAAkB;AAC7C;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,aAAa;AACb;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iCAAiC;AACjC,aAAa;AACb;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qBAAqB,iBAAiB;AACtC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,qCAAqC;AACrC;AACA,yDAAyD,uBAAuB;AAChF;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,eAAe,KAAK;AACpB,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,KAAK;AACpB,eAAe,KAAK;AACpB,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA,WAAW,yCAAyC;AACpD;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,eAAe;AACf,0DAA0D,8BAA8B;AACxF;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,KAAK;AACpB,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D,+CAA+C;AAC/C;AACA,qCAAqC;AACrC,iCAAiC;AACjC;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA,uCAAuC;AACvC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,KAAK;AACpB,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qBAAqB;AACrB;;AAEA,oDAAoD,MAAM,KAAK;AAC/D;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,gDAAgD;AAChD;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA,mBAAmB;AACnB;;AAEA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;;AAEN;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,KAAK;AAClB;AACA;AACA;AACA,yBAAyB,wBAAwB;AACjD;AACA,QAAQ;AACR;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;;AAEA;;AAEA;AACA,iCAAiC;AACjC;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,CAAC;;;;AAID;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,OAAO;AACpB,YAAY,4DAA4D;AACxE,0BAA0B,gBAAgB;AAC1C;AACA,aAAa,SAAS;AACtB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;;AAEA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;;AAEA;AACA;AACA,iBAAiB,uBAAuB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAiC;AACjC;AACA,iBAAiB,uBAAuB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,YAAY;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,IAAI;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,wBAAwB;AAC1C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAuB;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,2BAA2B,eAAe;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,2BAA2B,eAAe;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,KAAK;AAClB;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,KAAK;AACL,wBAAwB,gBAAgB;AACxC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,UAAU;AACV;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,cAAc;AAC5E,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,YAAY;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,eAAe,KAAK;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,IAAI;AACjB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA,QAAQ;AACR,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,IAAI;AACjB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA,CAAC,G;;;;;;ACx3GD;AACA;AACA;AACA;AACA;AACA,4BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,oCAAoC;AAC5C;;;AAGA;AACA,QAAQ,0BAA0B;AAClC;AACA;AACA;AACA;AACA,mEAAmE,kCAAkC;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA,yBAAyB,YAAY;AACrC;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;;AAEA;AACA,wCAAwC;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,4BAA4B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB;AACnB;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB;AACnB;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oCAAoC;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,4BAA4B;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB;AACpB,8BAA8B;AAC9B,uBAAuB;AACvB,8BAA8B;;AAE9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,CAAC;;;AAGD,CAAC;;;;;;;AC1UD;AACA;AACA;AACA;AACA;AACA,4BAA4B;;AAE5B;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,8DAA8D,EAAE;AAChE;AACA;AACA,mCAAmC,kCAAkC;AACrE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,mCAAmC,MAAM,2BAA2B;AAC5E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA,iBAAiB,kBAAkB;AACnC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,qBAAqB;AACjE;AACA,iBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,iCAAiC;AACrF;AACA;AACA;AACA;AACA;AACA,oDAAoD,uBAAuB;AAC3E;AACA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA;AACA;AACA;AACA,yDAAyD,kCAAkC;AAC3F;AACA,UAAU,UAAU,8CAA8C;AAClE,oBAAoB,8CAA8C;AAClE;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA,uBAAuB,OAAO;AAC9B;AACA,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,SAAS,oEAAoE;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,oFAAoF;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,cAAc;AACrC;AACA,QAAQ,qCAAqC;AAC7C;AACA,yBAAyB,OAAO;AAChC,iCAAiC,kCAAkC,GAAG,qBAAqB;AAC3F;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA;AACA;AACA,iCAAiC,QAAQ;AACzC;AACA;AACA;AACA,8BAA8B,OAAO;AACrC;AACA,6BAA6B,QAAQ;AACrC;AACA,yCAAyC,kCAAkC;AAC3E;AACA,WAAW,OAAO;AAClB;AACA;AACA,qCAAqC,QAAQ;AAC7C;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA,MAAM,YAAY,aAAa;AAC/B,kBAAkB,cAAc;AAChC,kBAAkB,2BAA2B;AAC7C,kBAAkB,gBAAgB;AAClC,kBAAkB,gBAAgB;AAClC;AACA;AACA,sCAAsC,eAAe;AACrD;AACA;AACA;AACA;AACA;AACA,4CAA4C,aAAa;AACzD,0BAA0B,WAAW;AACrC;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,oBAAoB;AAC5C;AACA;AACA;AACA;AACA,QAAQ,sEAAsE;AAC9E;AACA;AACA,qDAAqD,6BAA6B;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE,qBAAqB;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,yBAAyB;AAChC,gBAAgB,uBAAuB;AACvC,OAAO;;AAEP;AACA;AACA;AACA,6BAA6B,oCAAoC;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC,2BAA2B;;AAE3B;AACA,qBAAqB,YAAY;AACjC,4DAA4D;AAC5D,MAAM;;AAEN;AACA,mCAAmC,cAAc;AACjD;AACA;AACA,8BAA8B;AAC9B,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4CAA4C,aAAa;AACzD,eAAe,WAAW;AAC1B;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,aAAa;AACzD,eAAe,WAAW;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,4CAA4C,aAAa;AACzD,eAAe,WAAW;AAC1B;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,WAAW;AACX,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,qBAAqB;AACjD;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,UAAU;AACxD;AACA,eAAe;AACf,MAAM;;AAEN;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,2CAA2C,sBAAsB;AACjE;AACA;AACA;AACA;AACA;AACA,QAAQ,0BAA0B;AAClC;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,QAAQ;AAC9C;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA,uCAAuC,2BAA2B;AAClE;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA;AACA;AACA,UAAU,2BAA2B;AACrC;AACA;AACA;AACA;AACA,iBAAiB,cAAc;AAC/B,kBAAkB,eAAe;AACjC,mBAAmB,6BAA6B;AAChD,oBAAoB,iBAAiB;AACrC,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,eAAe;AACvC,wBAAwB,cAAc;AACtC,wBAAwB,4BAA4B;AACpD,wBAAwB,cAAc;AACtC,wBAAwB;AACxB;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gBAAgB,cAAc;AAC9B,iBAAiB,eAAe;AAChC,kBAAkB,6BAA6B;AAC/C,mBAAmB,iBAAiB;AACpC,mBAAmB;AACnB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iCAAiC;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa;AACb;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,eAAe;AACf;AACA,WAAW;;AAEX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;;AAGA;AACA;;AAEA,2BAA2B;;AAE3B;AACA;AACA,kCAAkC;AAClC;AACA,oCAAoC,qBAAqB;AACzD;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;AACA,yCAAyC;AACzC;;AAEA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B;;AAE3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,EAAE;AACrF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,uBAAuB,yCAAyC;AAChE;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oEAAoE,EAAE;AACtE,mCAAmC,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,EAAE;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB,iBAAiB;AACjB,+CAA+C;AAC/C;AACA,2CAA2C;AAC3C;AACA;AACA;;AAEA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA,8BAA8B,kBAAkB;AAChD;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA,+CAA+C;AAC/C;AACA;;AAEA;AACA;;AAEA;AACA,KAAK;AACL,GAAG;;;AAGH,CAAC;;;;;;;ACj1BD;AACA;AACA;AACA;AACA;AACA,mBAAmB;;AAEnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,EAAE,KAAK,EAAE;AAC9C;AACA;AACA;AACA,iCAAiC,EAAE,6BAA6B,EAAE;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB;AACA,aAAa,+DAA+D;AAC5E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA,mCAAmC,KAAK;AACxC;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;;AAEA,kCAAkC,yBAAyB;AAC3D;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA,0BAA0B,OAAO;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA,kCAAkC;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA,kCAAkC;;;AAGlC;AACA;AACA;AACA,0CAA0C,mDAAmD;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,oDAAoD;AAC9F;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8DAA8D;AAC9D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA,WAAW,EAAE;AACb,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,WAAW,aAAa;AACxB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB,aAAa,aAAa;AAC1B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,wCAAwC,cAAc;AACtD;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;;;AAGA;AACA;AACA,WAAW,oBAAoB;AAC/B,aAAa;AACb;AACA;AACA,+BAA+B;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;;AAGA;AACA;;AAEA,mCAAmC,QAAQ;AAC3C;AACA;AACA;AACA,qCAAqC,QAAQ;AAC7C;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E;AACA;AACA,IAAI,oBAAoB;AACxB;AACA,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,aAAa,OAAO;AACpB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E;AAC1E;AACA,UAAU,8BAA8B;AACxC;AACA;AACA,UAAU,OAAO;AACjB,UAAU,UAAU;AACpB,YAAY,OAAO;AACnB;AACA;AACA;AACA;;;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,0BAA0B,cAAc,EAAE,MAAM;AAChD,uBAAuB;AACvB,4BAA4B;AAC5B;AACA;AACA,WAAW,EAAE;AACb,aAAa,EAAE;AACf;AACA,sBAAsB;AACtB;;;AAGA,yBAAyB,4BAA4B;;AAErD;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,6BAA6B;;;AAG7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,2BAA2B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,0BAA0B;;;AAG1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,0BAA0B;;;AAG1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,4BAA4B;;;AAG5B;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;;AAEA;AACA;AACA,aAAa,OAAO,iBAAiB;AACrC;AACA;AACA,cAAc;AACd,aAAa,kBAAkB;AAC/B;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb;AACA,WAAW,gBAAgB;AAC3B;AACA,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,aAAa;AACnC,wBAAwB,eAAe;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,QAAQ;AACjD;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,iDAAiD,kBAAkB;AACnE;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yBAAyB,cAAc;AACvC,yBAAyB,cAAc;AACvC,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,qBAAqB,cAAc;AACnC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,WAAW;AACtB,WAAW,KAAK;AAChB,aAAa,WAAW;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,wCAAwC;AACnD,WAAW,eAAe;AAC1B;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,2BAA2B;AACxC;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,YAAY;AACf;AACA;AACA;AACA;AACA;AACA,2DAA2D,kCAAkC;AAC7F,GAAG;AACH;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;;AAGA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA,GAAG;AACH;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;;AAEA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,eAAe;AAC1B,MAAM,4BAA4B;AAClC,WAAW,SAAS;AACpB;AACA;AACA,SAAS,8CAA8C;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,wBAAwB;AAC9B;AACA,uCAAuC,4CAA4C;AACnF,uCAAuC,qBAAqB,GAAG,+BAA+B;AAC9F,MAAM,8BAA8B;AACpC,mCAAmC,qCAAqC,gBAAgB,8BAA8B;AACtH;AACA;AACA;AACA,mCAAmC,qBAAqB;AACxD;AACA,0BAA0B,qBAAqB;AAC/C;AACA;AACA,4FAA4F,OAAO;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,GAAG,KAAK,GAAG,MAAM;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,GAAG,KAAK,GAAG,MAAM;;AAEzC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,oBAAoB,MAAM;;AAE1B;AACA;AACA;AACA;AACA;;AAEA;AACA,wBAAwB,GAAG,KAAK,GAAG,MAAM;;AAEzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,sCAAsC;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,+BAA+B;AACjD;AACA;AACA;AACA,gFAAgF,4CAA4C;AAC5H,YAAY,qBAAqB,GAAG,+BAA+B,MAAM,8BAA8B;AACvG,iCAAiC,qCAAqC,gBAAgB,8BAA8B;AACpH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,8BAA8B;AACzC;AACA;AACA,aAAa;AACb,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA,aAAa,eAAe;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yDAAyD,EAAE;AAC3D,+BAA+B,oBAAoB;AACnD;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,2CAA2C;AACnD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gDAAgD;;AAEhD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,EAAE;AAC/B;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,2BAA2B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wCAAwC,EAAE,OAAO,EAAE;AACnD;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;AACA;AACA,8DAA8D,EAAE;AAChE;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,MAAM;AACjB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA,iBAAiB,+CAA+C;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,6BAA6B;AACnE;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,eAAe,gCAAgC;AAC/C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,qBAAqB;AACxE,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA,kDAAkD,+BAA+B;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+BAA+B;AACvC,QAAQ,wBAAwB;AAChC;AACA,eAAe,QAAQ;AACvB,eAAe,iBAAiB;AAChC;AACA,eAAe,UAAU;AACzB,eAAe,4CAA4C;AAC3D,iBAAiB,eAAe,sBAAsB,qBAAqB;AAC3E;AACA;;AAEA;;AAEA;AACA;AACA,oEAAoE,EAAE;AACtE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,EAAE;AACtD;AACA;AACA;;AAEA,mBAAmB,mBAAmB;AACtC;;AAEA,mBAAmB,kBAAkB;AACrC;;AAEA,mBAAmB,kBAAkB;AACrC;;AAEA;;AAEA,mBAAmB,eAAe;AAClC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B,uBAAuB,cAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,mBAAmB;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,4CAA4C;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE,EAAE;AAC1E;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA,kBAAkB,iDAAiD;AACnE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA,kBAAkB,+CAA+C;AACjE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA,kBAAkB,+CAA+C;AACjE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,EAAE;AACvB;AACA,kBAAkB,2CAA2C;AAC7D;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,EAAE;AACvB;AACA;AACA,kBAAkB,iDAAiD;AACnE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA,kBAAkB,mDAAmD;AACrE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,wBAAwB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB,+DAA+D;AACjF,cAAc,iCAAiC;AAC/C;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA,kBAAkB,6DAA6D;AAC/E;AACA;AACA,2DAA2D,iBAAiB;AAC5E;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,cAAc;AACnC;AACA,qBAAqB,SAAS;AAC9B;AACA,kBAAkB,qEAAqE;AACvF;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,cAAc;AACnC;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA,kBAAkB,iEAAiE;AACnF;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,OAAO;AAC5B,iBAAiB,0EAA0E;AAC3F;AACA;AACA,kBAAkB,iEAAiE;AACnF;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA,cAAc,gDAAgD;AAC9D;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oCAAoC,QAAQ;AAC5C;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA,sCAAsC;AACtC,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB,eAAe,OAAO;AACtB,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,aAAa;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,SAAS,0BAA0B;AACnC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAkB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,gCAAgC;AAChE,sCAAsC,uDAAuD;AAC7F;AACA,8CAA8C,gCAAgC;AAC9E;AACA;AACA,eAAe,uDAAuD;AACtE;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kBAAkB;AAC7B,aAAa,OAAO;AACpB;;AAEA;;AAEA,+BAA+B;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qBAAqB,eAAe;;;AAGpC;AACA;AACA,uBAAuB;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4BAA4B;AAC5B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,2CAA2C,OAAO;AAClD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA,yCAAyC,UAAU,UAAU;AAC7D;;AAEA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,yBAAyB;AACzB;AACA,KAAK;AACL,uBAAuB;AACvB;AACA,OAAO;AACP,6BAA6B;AAC7B;AACA;AACA,SAAS,OAAO,uBAAuB,uBAAuB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;;AAGA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,yBAAyB,YAAY;AACrC;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,sCAAsC,QAAQ;AAC9C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,qBAAqB;AACpD;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA,CAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;AACL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,eAAe;AAClC;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,iBAAiB,eAAe;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,mBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;;AAEA,qCAAqC,QAAQ;AAC7C;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;;AAEA,6CAA6C,QAAQ;AACrD;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,oCAAoC,8BAA8B,EAAE;AACpE,wCAAwC,uCAAuC,EAAE;AACjF,8CAA8C,yCAAyC,EAAE;AACzF,mDAAmD,kDAAkD,EAAE;AACvG;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;;AAEA,qCAAqC,QAAQ;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,oCAAoC;AAClE;AACA,WAAW,wBAAwB;AACnC,QAAQ,qBAAqB;AAC7B,WAAW,SAAS;AACpB;AACA,aAAa,SAAS,uBAAuB,+BAA+B;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,mCAAmC,sBAAsB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,eAAe;AAC9D;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,+BAA+B;AAC1F;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,EAAE;AAChB;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,6BAA6B;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,IAAI,+CAA+C;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,YAAY,EAAE;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,gCAAgC,kCAAkC;AAClE,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA,aAAa,EAAE;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB;AACA,aAAa,OAAO;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,gFAAgF;AAChF;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C;AACA;AACA,WAAW,SAAS;AACpB;AACA,aAAa,eAAe;AAC5B;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,6BAA6B;AACrC,aAAa,+BAA+B;AAC5C,IAAI,qBAAqB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,+BAA+B;AACnE;AACA;AACA;AACA;AACA;AACA,oBAAoB,6BAA6B;AACjD;AACA;AACA,MAAM,sDAAsD;AAC5D,QAAQ;AACR,MAAM,iDAAiD;AACvD;AACA,MAAM,2CAA2C;AACjD;AACA,MAAM,8CAA8C;AACpD;AACA;AACA,MAAM,8CAA8C;AACpD;AACA;AACA,MAAM,uDAAuD;AAC7D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8CAA8C,+BAA+B;AAC7E;AACA;AACA;AACA;AACA,qBAAqB,mBAAmB;AACxC,IAAI,mCAAmC;AACvC;AACA;AACA;AACA,2DAA2D,mCAAmC;AAC9F,WAAW;AACX,uCAAuC,mBAAmB;AAC1D;AACA;AACA,WAAW,OAAO;AAClB;AACA,WAAW,oBAAoB;AAC/B;AACA;AACA,QAAQ,+CAA+C;AACvD;AACA,QAAQ,yDAAyD;AACjE;AACA,aAAa,OAAO;;AAEpB;AACA;AACA;AACA,IAAI,iDAAiD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,aAAa;AACrE,OAAO;AACP,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oDAAoD;AACvE;AACA;AACA,WAAW,OAAO;AAClB,WAAW,iCAAiC;AAC5C,sFAAsF,aAAa;AACnG,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oDAAoD;AACvE;AACA;AACA,WAAW,OAAO;AAClB,WAAW,iCAAiC;AAC5C;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA,IAAI,oDAAoD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,0CAA0C,+BAA+B;AACzE;AACA;AACA;AACA;AACA;AACA,uCAAuC,4BAA4B;AACnE,eAAe,wCAAwC;AACvD;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,iCAAiC;AACpE;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,6CAA6C,+BAA+B;AAC5E,0DAA0D,gCAAgC;AAC1F;AACA;AACA,eAAe,gCAAgC;AAC/C,uDAAuD,4BAA4B;AACnF,gCAAgC,wCAAwC;AACxE;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,+CAA+C,+BAA+B;AAC9E;AACA;AACA;AACA;AACA,wDAAwD,uBAAuB;AAC/E;AACA,WAAW,OAAO;AAClB,WAAW,iCAAiC;AAC5C;AACA,WAAW,4CAA4C;AACvD;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAmB;AAC5C,aAAa,gCAAgC;AAC7C;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,8DAA8D,EAAE;AAChE,WAAW;AACX,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA,iDAAiD;AACjD;AACA;AACA;AACA;AACA,mCAAmC,qCAAqC,EAAE;;AAE1E;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,EAAE;AACnD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,oDAAoD,EAAE;AACtD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA,6BAA6B,2CAA2C;;AAExE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,qDAAqD,wBAAwB;AAC7E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sCAAsC,QAAQ;AAC9C;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,EAAE,WAAW,EAAE;AACxF;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,qEAAqE,EAAE;AACvE;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA,oFAAoF,EAAE;AACtF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;;AAGA;AACA;AACA,mFAAmF;AACnF;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,yCAAyC;AAC7C;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uCAAuC;AACzD,MAAM,yCAAyC;AAC/C;AACA;AACA;AACA,MAAM,uCAAuC;AAC7C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yCAAyC;AAChE;AACA;AACA;AACA,0BAA0B,yCAAyC;AACnE;AACA,MAAM,iGAAiG;AACvG;AACA,oCAAoC,uCAAuC;AAC3E;AACA;AACA,aAAa,QAAQ;AACrB,4BAA4B,yCAAyC;AACrE;AACA,gBAAgB,yBAAyB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,qDAAqD;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA,0BAA0B,GAAG;AAC7B,oBAAoB,GAAG;AACvB;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB,SAAS;AAC3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,oDAAoD,yBAAyB;AAC7E;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX,SAAS;AACT;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,oBAAoB;AACrC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,OAAO;AACP;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA,2FAA2F,EAAE;AAC7F;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kJAAkJ,EAAE;AACpJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,sCAAsC;AAC9C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,WAAW;AAC5B;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAkB;AACnC;AACA;AACA,iBAAiB,YAAY;AAC7B,iBAAiB,UAAU;AAC3B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+GAA+G;AAC/G;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,WAAW;AAC5B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,YAAY;AAC7B,iBAAiB,SAAS;AAC1B;AACA,kBAAkB,QAAQ;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,WAAW;AAC5B;AACA,iBAAiB,YAAY;AAC7B,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,WAAW;AAC5B;AACA,iBAAiB,YAAY;AAC7B,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,OAAO;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,OAAO;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uBAAuB,sBAAsB;AAC7C;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;;AAEP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb,WAAW;AACX;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,sEAAsE;AACrF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,0CAA0C;AACnE;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,kDAAkD,2BAA2B;;AAE7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,WAAW;AACxB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C;AACA,aAAa,OAAO;AACpB,aAAa,SAAS;AACtB,aAAa,QAAQ;AACrB;AACA;AACA,+DAA+D;AAC/D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C;AACA,aAAa,iBAAiB;AAC9B,cAAc,iBAAiB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,WAAW;AACxB,aAAa,QAAQ;AACrB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,gCAAgC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,uBAAuB;AACzD;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA,SAAS,QAAQ;AACjB;AACA,aAAa,OAAO;AACpB;AACA,OAAO,OAAO;AACd,QAAQ,GAAG,QAAQ,OAAO,OAAO,EAAE;AACnC;AACA,QAAQ,GAAG,QAAQ,OAAO;AAC1B,OAAO,KAAK,WAAW,OAAO;AAC9B,OAAO,KAAK;AACZ,OAAO,KAAK;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,yDAAyD,EAAE;AAC3D;;AAEA;AACA,2BAA2B,YAAY,YAAY;AACnD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,kBAAkB,UAAU,iCAAiC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,gCAAgC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,EAAE;AACrB;AACA,qBAAqB,EAAE;AACvB;AACA;AACA;AACA;AACA,4DAA4D,SAAS;;AAErE;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,gCAAgC;AAC/E;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,EAAE;AACvB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,gCAAgC;AACtE;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gCAAgC;AACzD,iCAAiC,kCAAkC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,gCAAgC;AACxF;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,UAAU,WAAW;AAC/C;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD,iDAAiD;AACjD;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,mCAAmC;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,qCAAqC;AAC7C;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,kCAAkC;AAC/D;AACA;AACA,IAAI,+CAA+C;AACnD;AACA;AACA;AACA;AACA,YAAY,sCAAsC;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mCAAmC;AAC7C,UAAU,mCAAmC,sDAAsD,MAAM;AACzG;AACA,aAAa,yCAAyC,yDAAyD,MAAM;AACrH,UAAU,uCAAuC;AACjD,UAAU,mCAAmC;AAC7C,UAAU,qDAAqD;AAC/D,UAAU,6BAA6B;AACvC,UAAU,uCAAuC,qEAAqE,MAAM;AAC5H,UAAU,2CAA2C;AACrD,UAAU,mDAAmD;AAC7D,UAAU,iCAAiC;AAC3C,UAAU,2CAA2C;AACrD,UAAU,iCAAiC;AAC3C;AACA,eAAe,wCAAwC,yDAAyD,MAAM;AACtH,eAAe,0CAA0C,0DAA0D;AACnH;AACA;AACA,+CAA+C;AAC/C,UAAU;AACV;AACA,aAAa,2BAA2B;AACxC,cAAc,wCAAwC,yDAAyD,MAAM;AACrH,cAAc,0CAA0C,0DAA0D;AAClH;AACA;AACA,aAAa,2BAA2B,4BAA4B;AACpE;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D;AAC3D;AACA;AACA;AACA,6DAA6D;AAC7D,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA,0BAA0B,+CAA+C;AACzE;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,cAAc;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,sBAAsB,YAAY;AAClC;AACA,qBAAqB,oBAAoB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,aAAa;AACpC;AACA,sBAAsB,oBAAoB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE;AACjE,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,+CAA+C,cAAc;AAC7D,sDAAsD,gBAAgB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,IAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA,sBAAsB,MAAM,8CAA8C,sBAAsB;AAChG;AACA,OAAO,MAAM;AACb;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA,gDAAgD,oDAAoD;AACpG;AACA,qDAAqD;AACrD;AACA;AACA,iDAAiD,qBAAqB;AACtE,kDAAkD;AAClD,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,uBAAuB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,0CAA0C;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA,gFAAgF,WAAW;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4FAA4F;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,gBAAgB,qBAAqB,yBAAyB;AACzF,YAAY,iCAAiC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF;AACtF;AACA;AACA;AACA,6FAA6F;AAC7F,yDAAyD;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,yCAAyC;AAC7C;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE;AACvE;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,gCAAgC;AAClD,kCAAkC,yCAAyC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,uDAAuD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kEAAkE;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,mBAAmB;AACxD;AACA;AACA;AACA;AACA,YAAY,sFAAsF;AAClG;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,IAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA,wCAAwC,4BAA4B;AACpE,sFAAsF,mBAAmB;AACzG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,mBAAmB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,MAAM;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,WAAW,GAAG,eAAe,MAAM;AACzF;AACA,yBAAyB,mBAAmB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kDAAkD;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,KAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,+BAA+B,MAAM;AACrC,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,MAAM;AAClC;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,wCAAwC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,aAAa,0CAA0C;AACvD;AACA;AACA,mBAAmB,gCAAgC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,OAAO;AAC1D;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,2CAA2C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD,iCAAiC;AACjC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,iDAAiD,MAAM;AACvD;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sBAAsB,EAAE,kBAAkB,EAAE;AAC5C,2BAA2B,KAAK,EAAE,KAAK,EAAE,OAAO;AAChD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,EAAE;AAC9D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kEAAkE,EAAE;AACpE;AACA;AACA;AACA,yCAAyC,EAAE;AAC3C;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA,gCAAgC,EAAE,mBAAmB,EAAE;AACvD;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,cAAc;AAC3B;AACA;AACA,aAAa,eAAe;AAC5B,SAAS,sCAAsC,UAAU,2BAA2B;AACpF,eAAe,oBAAoB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb;AACA,WAAW;AACX;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,SAAS,0EAA0E;AACnF;AACA;AACA,2BAA2B,oBAAoB;AAC/C,gEAAgE;AAChE,gCAAgC;AAChC,6BAA6B,QAAQ;AACrC;AACA;AACA,yBAAyB,oBAAoB;AAC7C;AACA;AACA;AACA,mDAAmD,qCAAqC;AACxF;AACA;AACA;AACA;AACA;AACA,4BAA4B,oBAAoB;AAChD;AACA;AACA,sDAAsD,qCAAqC;AAC3F;AACA;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;AACjC;AACA,eAAe,wDAAwD;AACvE,2BAA2B,SAAS,aAAa,iDAAiD;AAClG;AACA,wBAAwB,wBAAwB;AAChD;AACA,0DAA0D,sCAAsC;AAChG;AACA;AACA;AACA,eAAe,oBAAoB;AACnC;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,YAAY;AAClD;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,sCAAsC,YAAY;AAClD,oBAAoB;AACpB,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,QAAQ;AACR;AACA;AACA,wDAAwD,sCAAsC;AAC9F;AACA;AACA,eAAe,iEAAiE;AAChF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+CAA+C,mCAAmC;AAClF;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,gDAAgD;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,2BAA2B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,2BAA2B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iEAAiE;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,cAAc;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,EAAE;AAC9C;AACA;AACA;AACA;AACA,qDAAqD,QAAQ;AAC7D;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA,iBAAiB,OAAO;AACxB;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,eAAe;AAChC,iBAAiB,SAAS;AAC1B;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,4BAA4B;AAC7C;AACA,yBAAyB;AACzB,sBAAsB;AACtB,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;;AAGA;AACA;AACA,kDAAkD,uBAAuB;AACzE;AACA;AACA,yCAAyC,EAAE,4BAA4B;AACvE,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,wCAAwC;AACvD;AACA,eAAe,YAAY;AAC3B;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,qBAAqB,qBAAqB;AAC1C;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,oBAAoB;AACzC;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA,wCAAwC,QAAQ;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;;AAEA,aAAa;AACb;;AAEA,aAAa;AACb;;AAEA,aAAa;AACb;AACA;;AAEA;;AAEA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uDAAuD,QAAQ;AAC/D;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,EAAE,sBAAsB,EAAE;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA,eAAe,KAAK;AACpB,eAAe,OAAO;AACtB,eAAe,wCAAwC;AACvD;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA,eAAe,QAAQ;AACvB;AACA,eAAe,iBAAiB;AAChC,eAAe,iBAAiB;AAChC,eAAe,OAAO;AACtB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,QAAQ;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,gBAAgB;AAChB;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+CAA+C,oDAAoD;AACnG;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC,WAAW;;AAEX;;AAEA;AACA;AACA,aAAa;;AAEb;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe;;AAEf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,eAAe;;AAEf;AACA;AACA;AACA,gFAAgF,EAAE;AAClF;AACA,eAAe;;AAEf;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAiC;AACjC;AACA,4BAA4B,iEAAiE;AAC7F;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,6CAA6C,EAAE,wCAAwC,EAAE;AACzF;AACA;;AAEA;;AAEA,oCAAoC;;AAEpC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,mBAAmB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,mBAAmB;AAChE;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,+CAA+C,+BAA+B,EAAE;AAChF;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,SAAS;;AAET;AACA,2CAA2C,QAAQ;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,kFAAkF,EAAE;AACpF,0BAA0B,EAAE;AAC5B;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,6BAA6B,EAAE,6BAA6B,EAAE;AAC9D;AACA;AACA,OAAO;AACP;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,QAAQ;AACrD,gDAAgD,mDAAmD;AACnG;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,QAAQ;AAClD;AACA;AACA;AACA;AACA,8CAA8C,2CAA2C;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA,0CAA0C,QAAQ;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,6CAA6C,EAAE,wCAAwC,EAAE;AACzF;AACA;;AAEA,iCAAiC;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,gEAAgE,GAAG,EAAE,GAAG,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE;AACrG;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,SAAS;AACT;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,+EAA+E,EAAE;AACjF;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,OAAO;AACP;;;AAGA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,KAAK;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,QAAQ;AACrD;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB,iBAAiB;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA;;;AAGA;AACA,gCAAgC,kCAAkC,EAAE;AACpE;;;AAGA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA,sDAAsD,wCAAwC;AAC9F;AACA;AACA;AACA;AACA;AACA,iCAAiC,EAAE,mBAAmB,EAAE,0BAA0B,EAAE;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,4DAA4D,QAAQ;AACpE;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,mDAAmD,oDAAoD;;;AAGvG;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,GAAG;AACtE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,0CAA0C;AAC1C;AACA,WAAW,OAAO;AAClB;;;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,oBAAoB;AACrC;AACA,mBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yCAAyC;AACjD;AACA;AACA;AACA,IAAI,+CAA+C;AACnD;AACA;AACA,sBAAsB;AACtB;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,cAAc;AAC3B;AACA,aAAa,eAAe;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA,mCAAmC,+BAA+B;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+CAA+C,EAAE;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6CAA6C,EAAE;AAC/C;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,uCAAuC,EAAE,SAAS,EAAE;AACpD;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,uCAAuC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,sDAAsD;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA,SAAS,MAAM,WAAW,sBAAsB,EAAE;AAClD;AACA,WAAW,MAAM;AACjB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA,qCAAqC,qCAAqC;AAC1E,yBAAyB,KAAK;AAC9B;AACA;AACA,IAAI,KAAK;AACT;AACA,oCAAoC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,oBAAoB;AAClC;AACA;AACA,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,QAAQ,aAAa;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,oBAAoB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM,6CAA6C;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA,KAAK;AACL;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B,aAAa,kBAAkB;AAC/B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,4BAA4B;AACvC,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,qBAAqB;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,qBAAqB;AACpE;AACA,+BAA+B,eAAe;AAC9C,MAAM,uCAAuC;AAC7C,sBAAsB,kCAAkC;AACxD;AACA,wCAAwC,OAAO;AAC/C;AACA;AACA,wCAAwC,OAAO;AAC/C;AACA;AACA,iCAAiC,OAAO;AACxC,eAAe,0CAA0C;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,8CAA8C;AACxF;AACA,mFAAmF,+BAA+B;AAClH,mBAAmB,mDAAmD;AACtE;AACA,6CAA6C,OAAO;AACpD;AACA,MAAM,sBAAsB;AAC5B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,6DAA6D;AACrF;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,4CAA4C;AACpD;AACA,gEAAgE;AAChE,iBAAiB;AACjB;AACA,sCAAsC,kCAAkC;AACxE;AACA;AACA;AACA;AACA;AACA,4EAA4E,uCAAuC;AACnH,gEAAgE,oBAAoB;AACpF;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,YAAY;AACZ;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA,0BAA0B,OAAO;AACjC,2BAA2B,uBAAuB;AAClD,0BAA0B,OAAO;AACjC,8BAA8B,OAAO;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,UAAU;AACV,UAAU;AACV,UAAU;AACV,UAAU;AACV,UAAU;AACV,UAAU;AACV;AACA;AACA;AACA,iCAAiC,oBAAoB;AACrD,QAAQ,qDAAqD;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,SAAS;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,wBAAwB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,eAAe;AACf;AACA;AACA,kCAAkC,IAAI,aAAa,IAAI;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,QAAQ,uBAAuB;AAC/B;AACA,aAAa,uCAAuC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+CAA+C;AACvD,QAAQ,4DAA4D;AACpE;AACA,iCAAiC,uBAAuB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yCAAyC;AACjD;AACA;AACA;AACA;AACA;AACA,gEAAgE;AAChE,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,yBAAyB;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wFAAwF;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gGAAgG;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA,2BAA2B,OAAO;AAClC,wBAAwB,qBAAqB;AAC7C;AACA,2BAA2B,uBAAuB;AAClD;AACA,yBAAyB,cAAc;AACvC,4BAA4B,OAAO;AACnC;AACA;AACA,kCAAkC,OAAO;AACzC;AACA;AACA,wCAAwC,OAAO;AAC/C;AACA;AACA,mCAAmC,OAAO;AAC1C,mCAAmC,OAAO;AAC1C;AACA,cAAc,oEAAoE;AAClF;AACA;AACA,iBAAiB;AACjB;AACA;AACA,cAAc,oFAAoF;AAClG;AACA;AACA,iBAAiB;AACjB;AACA,oCAAoC,8CAA8C;AAClF;AACA;AACA,aAAa,0BAA0B;AACvC,oCAAoC,oCAAoC;AACxE,2CAA2C;AAC3C,4CAA4C;AAC5C,0BAA0B,eAAe;AACzC,aAAa,uCAAuC;AACpD,iBAAiB,kCAAkC;AACnD,4BAA4B,eAAe,iCAAiC;AAC5E;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA,iCAAiC,OAAO;AACxC;AACA;AACA,iBAAiB,YAAY,YAAY,qBAAqB;AAC9D;AACA;AACA;AACA,kBAAkB,eAAe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,QAAQ;AACrC,+BAA+B,MAAM;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,iBAAiB,8DAA8D;AAC/E;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA,mGAAmG,EAAE;AACrG;;AAEA;AACA,+HAA+H,EAAE;AACjI;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;;AAEA;;;AAGA;AACA,iDAAiD,QAAQ;AACzD;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;;AAET;AACA;;AAEA;AACA;AACA,kCAAkC;AAClC;;AAEA,8BAA8B;;AAE9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,WAAW;AACjD;AACA,QAAQ,6FAA6F;AACrG,2CAA2C,6DAA6D;AACxG;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,+BAA+B;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,sBAAsB;AAChD;AACA,eAAe,qBAAqB;AACpC;AACA,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,EAAE;AAClB,gBAAgB,QAAQ;AACxB,kBAAkB,YAAY;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;;AAGA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;;;AAGA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kCAAkC,EAAE;AACpC,2BAA2B,EAAE;AAC7B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,aAAa;AACb,gDAAgD;AAChD;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,eAAe;AACf;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,8EAA8E,EAAE;AAChF;;AAEA;AACA;AACA;AACA,wEAAwE,EAAE,aAAa,EAAE;AACzF;;AAEA;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,gBAAgB;AACzD;AACA,IAAI;AACJ;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,uBAAuB;AACpD;AACA;AACA;AACA,IAAI,qBAAqB,KAAK,qCAAqC;AACnE;AACA,uDAAuD;AACvD,gBAAgB;AAChB;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,mCAAmC,EAAE;AACrC;AACA;AACA;;AAEA;AACA,4DAA4D,EAAE,GAAG,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,SAAS;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;;AAGH;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,uBAAuB;AACvB,qBAAqB;;AAErB;AACA;AACA;AACA;AACA,qFAAqF;AACrF;AACA,aAAa,QAAQ;AACrB,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uFAAuF;AACvF;AACA,aAAa,QAAQ;AACrB,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,2BAA2B;AACxC,QAAQ,mDAAmD;AAC3D;AACA;AACA;AACA;AACA,gCAAgC;AAChC,yCAAyC,kBAAkB;AAC3D,qBAAqB,eAAe;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC,wBAAwB;AACxB;AACA;AACA,mCAAmC,UAAU,GAAG,MAAM;AACtD;AACA;AACA;AACA,+BAA+B,UAAU,GAAG,MAAM;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+CAA+C;AACvD;AACA;AACA,qCAAqC,MAAM,YAAY,GAAG,UAAU,GAAG;AACvE;AACA;AACA;AACA;AACA,WAAW,2BAA2B;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,UAAU,IAAI,EAAE,4BAA4B,GAAG;AACnG;AACA,yBAAyB,UAAU;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,IAAI,IAAI,wCAAwC,KAAK,SAAS;AAC7F,kFAAkF;AAClF;AACA;AACA,8DAA8D,KAAK;AACnE,oFAAoF;AACpF;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,WAAW,sBAAsB;AAC5D;AACA;AACA;AACA;AACA,2BAA2B,WAAW,qBAAqB,EAAE;AAC7D;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB;AACA;AACA,eAAe,QAAQ;AACvB,0BAA0B;AAC1B,0BAA0B,qCAAqC,mBAAmB;AAClF;AACA,eAAe,SAAS;AACxB;AACA,iBAAiB,kBAAkB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kDAAkD,QAAQ;AAC1D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB,QAAQ;AAC5B;AACA;;AAEA;AACA,aAAa;AACb;AACA;;AAEA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,2FAA2F;AAC3F;AACA,YAAY,6EAA6E;AACzF;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,yFAAyF;AACzF;AACA,YAAY,yEAAyE;AACrF;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,uDAAuD;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,WAAW;AAC3B;AACA,gBAAgB,OAAO;AACvB,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,SAAS;AACzB,uCAAuC,wCAAwC;AAC/E,gBAAgB,MAAM;AACtB,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,SAAS;AACrD,4CAA4C,SAAS;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,OAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,mBAAmB,OAAO;AAC1B;AACA,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,mBAAmB,QAAQ;AAC3B;AACA,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,mBAAmB,EAAE;AACrB;AACA,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;;AAEA;AACA,qBAAqB;AACrB;;;AAGA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,oCAAoC,GAAG;AACvC;;AAEA;AACA,oDAAoD,EAAE;AACtD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,uDAAuD,EAAE,yBAAyB,EAAE;AACpF;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yDAAyD;;AAEzD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;;AAEA;;;AAGA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,qBAAqB,EAAE;AACvB;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B,cAAc,gBAAgB;AAC9B;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA,aAAa,+CAA+C;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,uCAAuC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,kCAAkC;AAClC;AACA;AACA;AACA,WAAW;;AAEX;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B,cAAc,OAAO;AACrB;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,kBAAkB;AAC/B;AACA;AACA,yBAAyB,QAAQ;AACjC;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA;AACA,kBAAkB;AAClB,8BAA8B,eAAe;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,8BAA8B;AAC9E;AACA,MAAM,iEAAiE;AACvE;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,wBAAwB;AACxB;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;;AAGL;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;;AAEA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA,CAAC;AACD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,mDAAmD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA,yCAAyC;AACzC;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO,YAAY;;AAEnB;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA,wFAAwF,4BAA4B,EAAE;AACtH,cAAc;;;AAGd;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO,2BAA2B,KAAK;AACvC,0BAA0B,4BAA4B;AACtD;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,+CAA+C;AAC3E;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,gDAAgD,EAAE,WAAW,EAAE,iBAAiB,EAAE;AAClF;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,EAAE;AACpC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA,iDAAiD,UAAU;AAC3D;AACA,yBAAyB;AACzB,gBAAgB;AAChB;AACA;AACA,GAAG;;AAEH;AACA,YAAY;AACZ,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB;AAChB;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,cAAc;AACd,KAAK;AACL;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK,wBAAwB;AAC7B;AACA,KAAK;AACL;AACA,KAAK;AACL,iBAAiB;AACjB,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mBAAmB;AACnB;AACA,OAAO;AACP,mBAAmB;AACnB;AACA,OAAO;AACP,mBAAmB;AACnB,OAAO;AACP;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,kBAAkB;;AAElB;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,GAAG;;AAEH;AACA;AACA,YAAY;AACZ,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA,YAAY;AACZ,GAAG;;AAEH;AACA;AACA,oCAAoC;AACpC;AACA,wBAAwB;AACxB;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA,mBAAmB;;AAEnB,YAAY;AACZ,GAAG;;AAEH;AACA;AACA,gCAAgC,EAAE,IAAI,EAAE,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE;AAC/F;AACA,GAAG;;AAEH;AACA;AACA,iEAAiE,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,iEAAiE,EAAE;AACnE;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA,aAAa,0BAA0B;AACvC,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,YAAY,sEAAsE,2BAA2B;AAC7G;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,WAAW,4BAA4B;AACvC,eAAe,4BAA4B;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,qDAAqD;AACrD;AACA;AACA,GAAG;;AAEH;AACA,qCAAqC;AACrC;AACA;AACA,WAAW;AACX,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,0DAA0D;AAC1D;AACA,GAAG;;AAEH;AACA,6FAA6F;AAC7F,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kFAAkF,cAAc,EAAE;AAClG;AACA,4CAA4C;AAC5C,SAAS;AACT;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,cAAc,EAAE;AACvF;AACA;AACA;AACA;AACA;AACA,mEAAmE,aAAa,EAAE;AAClF,oEAAoE,cAAc,EAAE;AACpF;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E;AAC1E;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wHAAwH;AACxH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,yJAAyJ;AACzJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,WAAW;AACX;AACA,WAAW;AACX;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT,uBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,+CAA+C;AAC/C;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA,8CAA8C;AAC9C,GAAG;;AAEH;AACA;AACA;AACA,KAAK;AACL;AACA,gCAAgC;AAChC;AACA,kBAAkB;AAClB;AACA,wBAAwB;AACxB;AACA,oBAAoB;AACpB;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,yBAAyB,iBAAiB;AAC1C;AACA;AACA;AACA,4BAA4B,kDAAkD;AAC9E,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2BAA2B,iBAAiB;AAC5C;AACA;AACA;AACA;AACA,4BAA4B,aAAa;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,WAAW;AACrC;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,uBAAuB,iBAAiB;AACxC;AACA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,WAAW;AACX,SAAS;AACT,qBAAqB;AACrB;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;AACA;AACA,uBAAuB,iBAAiB;AACxC;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA;AACA,0BAA0B,cAAc;AACxC;AACA;AACA;AACA,0BAA0B,cAAc;AACxC;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA,uBAAuB,mBAAmB,kDAAkD,SAAS;AACrG,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,OAAO;AACP;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,OAAO;AACP;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,OAAO;AACP;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kCAAkC;AACvD;AACA;AACA;AACA;AACA,oBAAoB,MAAM;AAC1B,mBAAmB,MAAM;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,0BAA0B;AACvC;AACA,sBAAsB,OAAO;AAC7B;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA,yBAAyB,QAAQ;AACjC;AACA,uBAAuB,0BAA0B;AACjD;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,UAAU;AACtB;AACA,YAAY,UAAU;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,wDAAwD;AACxD;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA,mDAAmD,QAAQ;AAC3D,6DAA6D;AAC7D;AACA;;AAEA;AACA;;AAEA,qDAAqD,QAAQ;AAC7D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;;AAEP;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,0BAA0B;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,uBAAuB,EAAE;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,WAAW,6BAA6B;AACxC;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,eAAe,sBAAsB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,mBAAmB;AAC9B,WAAW,eAAe;AAC1B;AACA,UAAU,SAAS;AACnB;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kCAAkC,8BAA8B;AAChE,oCAAoC,gCAAgC;AACpE,sCAAsC,kCAAkC;AACxE;;;AAGA;AACA,oBAAoB;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,0CAA0C,QAAQ;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,qBAAqB,EAAE;AAChD;;AAEA;AACA;AACA;AACA;AACA;AACA,yEAAyE,EAAE;AAC3E;AACA,KAAK;AACL;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,8CAA8C,QAAQ;AACtD;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB,eAAe,QAAQ;AACvB;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,sBAAsB;AACrC;AACA,aAAa,EAAE;AACf,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB,eAAe,QAAQ;AACvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iCAAiC;AAC9C,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iCAAiC;AAC9C,eAAe,QAAQ;AACvB;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA,6DAA6D,EAAE;AAC/D;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,0BAA0B;AAC1B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;;AAEA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D;AACA;AACA;AACA;AACA,8EAA8E;AAC9E;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,gCAAgC;AACxE;AACA;AACA;AACA,IAAI,4CAA4C;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gDAAgD,+BAA+B;AAC/E,QAAQ,+BAA+B;AACvC,QAAQ,sCAAsC;AAC9C,0DAA0D,+BAA+B;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,2CAA2C;AAClF;AACA;AACA;AACA,eAAe,6BAA6B;AAC5C,0FAA0F,SAAS;AACnG,eAAe,oBAAoB;AACnC;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gCAAgC;AAC9D;AACA,8CAA8C,4CAA4C;AAC1F,kEAAkE,8CAA8C;AAChH;AACA,UAAU,8CAA8C;AACxD;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA,iBAAiB,MAAM,oBAAoB,kCAAkC;AAC7E;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D,qBAAqB;AACrB;AACA,qBAAqB,4CAA4C;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,qBAAqB;AAClD,kCAAkC,mBAAmB;AACrD;AACA;AACA,+GAA+G,kCAAkC;AACjJ;AACA;AACA;AACA;AACA;AACA,8CAA8C,0CAA0C;AACxF;AACA;AACA,iBAAiB,0CAA0C;AAC3D;AACA;AACA,eAAe,gDAAgD;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY;AACZ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,aAAa,EAAE;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,oBAAoB;AACrC,aAAa,0CAA0C;AACvD;AACA;AACA,sCAAsC;AACtC;AACA,iBAAiB,gCAAgC;AACjD;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,2DAA2D,qBAAqB;AAC1G;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0CAA0C;AACjE;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+BAA+B;AAChD,wBAAwB;AACxB;AACA,iBAAiB,sCAAsC;AACvD;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,SAAS;;AAET;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;;AAEX;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB,mBAAmB,kCAAkC;AAC7F;AACA,aAAa,0CAA0C;AACvD;AACA;AACA,iBAAiB,8CAA8C;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,oCAAoC;AACpC;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,eAAe;AAC1C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,6BAA6B,qBAAqB;AAClD;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,0CAA0C;AACzE,kCAAkC,yCAAyC;AAC3E,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA,UAAU,4CAA4C;AACtD,UAAU,+CAA+C;AACzD,mCAAmC,0CAA0C;AAC7E,YAAY,8CAA8C;AAC1D;AACA;AACA;AACA,UAAU,0CAA0C;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY;AACZ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA,0CAA0C,wCAAwC;AAClF;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX,uCAAuC;;AAEvC;AACA;AACA;AACA,kBAAkB,EAAE;AACpB,2DAA2D,EAAE;AAC7D;AACA;;AAEA,SAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA,wCAAwC;AACxC;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,4CAA4C;AACpE;AACA;AACA;AACA;AACA,UAAU,qCAAqC;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gEAAgE,aAAa;AAC7E;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8CAA8C,0BAA0B,EAAE;AAC1E;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA,gEAAgE,kCAAkC;AAClG;AACA;AACA,iBAAiB,UAAU;AAC3B,mBAAmB,EAAE;AACrB;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,gDAAgD;AAC3E;AACA;AACA;AACA,UAAU,6CAA6C;AACvD;AACA;AACA;AACA;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA,+DAA+D,kCAAkC;AACjG;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA,yBAAyB,8CAA8C;AACvE,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,8CAA8C;AACjE,UAAU,oDAAoD;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kCAAkC;AACnD,aAAa,wCAAwC;AACrD;AACA,aAAa,6CAA6C;AAC1D,iBAAiB,uCAAuC;AACxD,+CAA+C,4CAA4C;AAC3F;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA,+DAA+D,kCAAkC;AACjG;AACA;AACA,mBAAmB,EAAE;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA,+DAA+D,kCAAkC;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,sCAAsC;AACvF;AACA;AACA;AACA;AACA;AACA,+BAA+B,MAAM;AACrC;AACA,gCAAgC,MAAM;AACtC;AACA,wBAAwB,OAAO;AAC/B,mCAAmC,UAAU;AAC7C;AACA,kCAAkC,SAAS;AAC3C;AACA,oCAAoC,QAAQ;AAC5C;AACA,iBAAiB,OAAO;AACxB,iBAAiB,yBAAyB;AAC1C,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,8BAA8B;AACnD;AACA;AACA,UAAU,wCAAwC;AAClD;AACA;AACA;AACA;AACA,yCAAyC,wCAAwC;AACjF,mBAAmB,6CAA6C;AAChE;AACA,iBAAiB,OAAO;AACxB,iBAAiB,KAAK;AACtB,kBAAkB,OAAO,oBAAoB,8BAA8B;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAwB;AACnE;AACA;AACA,eAAe;AACf;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA,qDAAqD,YAAY;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;;AAEA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,8BAA8B;AACnD;AACA;AACA,UAAU,wCAAwC;AAClD;AACA;AACA;AACA,yCAAyC,wCAAwC;AACjF,mBAAmB,6CAA6C;AAChE;AACA,iBAAiB,OAAO;AACxB,iBAAiB,KAAK;AACtB,kBAAkB,OAAO,oBAAoB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA,2CAA2C,EAAE;AAC7C;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,8EAA8E;AAC9E,4BAA4B;AAC5B,IAAI,wBAAwB;AAC5B,qCAAqC,+BAA+B;AACpE;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,2BAA2B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,2BAA2B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,EAAE;AAC/D;AACA;AACA;AACA,4CAA4C;AAC5C;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E;AAC9E,6BAA6B;AAC7B;AACA,mDAAmD,mCAAmC;AACtF;AACA;AACA;AACA;AACA;AACA,UAAU,mDAAmD;AAC7D;AACA;AACA;AACA,4BAA4B,mDAAmD;AAC/E;AACA,sBAAsB;AACtB,6CAA6C,MAAM;AACnD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA2E;AAC3E,gBAAgB;AAChB,uEAAuE;AACvE,0FAA0F;AAC1F,IAAI;AACJ;AACA,kFAAkF;AAClF,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA,gBAAgB,+CAA+C;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,MAAM;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA,gBAAgB,+CAA+C;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,MAAM;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kDAAkD,OAAO;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,OAAO;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mBAAmB;AAC/B;AACA,eAAe,OAAO;AACtB;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE,GAAG,SAAS,EAAE;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8FAA8F,EAAE;AAChG;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,8BAA8B,6CAA6C;AAC3E,sDAAsD;AACtD;AACA,yEAAyE;AACzE,sDAAsD;AACtD;AACA,eAAe,EAAE,8BAA8B;AAC/C;AACA,iBAAiB,EAAE,8CAA8C;AACjE,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8BAA8B,qDAAqD;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE,qCAAqC;AACtD,kCAAkC;AAClC,iBAAiB,EAAE,2CAA2C;AAC9D,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,4FAA4F,EAAE;AAC9F;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA,YAAY;AACZ;AACA;AACA,GAAG;AACH;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,mBAAmB;AACpF;AACA;AACA;AACA,oBAAoB,+CAA+C;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD,mCAAmC,2CAA2C;AAC9E;AACA;AACA;AACA;AACA;AACA,2EAA2E;AAC3E,mCAAmC,qDAAqD;AACxF,gCAAgC;AAChC,IAAI,yCAAyC;AAC7C;AACA,mBAAmB,yCAAyC,OAAO;AACnE,4DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA,6BAA6B,0CAA0C;AACvE,iCAAiC,iCAAiC;AAClE;AACA;AACA,uCAAuC;AACvC,8BAA8B;AAC9B,8BAA8B;AAC9B,QAAQ,KAAK,yCAAyC;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yCAAyC;AACrD;AACA,iBAAiB,mCAAmC;AACpD;AACA;AACA,sEAAsE;AACtE,2DAA2D,MAAM;AACjE,2DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF,yCAAyC,sFAAsF,2BAA2B;AAChP;AACA;AACA;AACA;AACA;AACA,0BAA0B,wEAAwE,EAAE,6DAA6D;AACjK;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mDAAmD;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAkB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,sBAAsB;AAC9D;AACA,YAAY;AACZ;AACA,0DAA0D;AAC1D,mCAAmC;AACnC,UAAU;AACV;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,MAAM;AACN,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,wDAAwD;AACxD,iCAAiC;AACjC,QAAQ;AACR,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,+CAA+C,mCAAmC;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4DAA4D,cAAc;AAC1E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB,kCAAkC,iCAAiC;AAC5F,wBAAwB;AACxB,0CAA0C;AAC1C;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,qDAAqD;AAC1E;AACA;AACA;AACA,6CAA6C,mBAAmB;AAChE;AACA;AACA,eAAe,OAAO;AACtB;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE,kCAAkC;AACrD,sCAAsC;AACtC;AACA,4BAA4B,mCAAmC;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE,kCAAkC;AACrD,qCAAqC;AACrC;AACA,4BAA4B,mCAAmC;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE,kCAAkC;AACrD,6CAA6C;AAC7C;AACA,qBAAqB,mCAAmC;AACxD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE,kCAAkC;AACrD,oCAAoC;AACpC;AACA,4BAA4B,mCAAmC;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2DAA2D;AAChF,8BAA8B,qCAAqC;AACnE;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE,qCAAqC;AACtD;AACA,iBAAiB,EAAE;AACnB,qBAAqB,qCAAqC;AAC1D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE,sDAAsD;AACtD,qCAAqC;AACrC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,sCAAsC,YAAY;AAClD;AACA;AACA,UAAU,uBAAuB;AACjC;AACA;AACA,aAAa,QAAQ,0BAA0B,YAAY;AAC3D,eAAe,YAAY,cAAc,YAAY;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,2CAA2C;AACxE;AACA,aAAa,0BAA0B;AACvC,aAAa,SAAS;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA,2CAA2C,EAAE,gBAAgB,EAAE,EAAE,EAAE;AACnE;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uEAAuE;AACvE;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,6CAA6C;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,yCAAyC;AACvE;AACA;AACA;AACA;AACA;AACA,gBAAgB,YAAY;AAC5B,gBAAgB,QAAQ;AACxB,gBAAgB,SAAS;AACzB,uCAAuC,wCAAwC;AAC/E,gBAAgB,MAAM;AACtB,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,cAAc;AACzB;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,6CAA6C;AAC7C;;AAEA,iBAAiB,wBAAwB;AACzC;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,iBAAiB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,IAAI,2BAA2B;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,WAAW,OAAO;AAClB,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA,cAAc,gBAAgB;AAC9B,cAAc,gBAAgB;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,cAAc;AAC3B;AACA;AACA;AACA,sDAAsD,iBAAiB;AACvE;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA,WAAW,yBAAyB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,oBAAoB;AACrD;AACA,gEAAgE,UAAU;AAC1E;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,SAAS,OAAO,4BAA4B,+BAA+B,aAAa;AACxF,gCAAgC,UAAU;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,sCAAsC;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,yCAAyC;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA,iCAAiC,8BAA8B;AAC/D,iCAAiC,kCAAkC;AACnE,iCAAiC,8BAA8B;AAC/D,iCAAiC,8BAA8B;AAC/D,iCAAiC,+BAA+B;AAChE,iCAAiC,kCAAkC;;AAEnE;AACA;AACA;AACA;AACA,iBAAiB,aAAa;AAC9B,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,gBAAgB;AACjC,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,0EAA0E,EAAE;AAC5E;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,oEAAoE,mBAAmB;AACvF,yEAAyE,0BAA0B;AACnG,8DAA8D,4BAA4B;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,cAAc;AACzB,WAAW,iBAAiB;AAC5B;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,yDAAyD,cAAc;AACvE,+BAA+B,gBAAgB;AAC/C,kCAAkC,iBAAiB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA,aAAa,gCAAgC,OAAO;;AAEpD;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,YAAY;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qDAAqD;AACrD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,2BAA2B,mBAAmB;AAC9C;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,qBAAqB,aAAa;AAClC;;AAEA;AACA;AACA,uBAAuB,aAAa;AACpC;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA,UAAU,yCAAyC;;;AAGnD;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gDAAgD,qBAAqB,EAAE;;AAEvE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,iDAAiD;;AAEjD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qBAAqB;AAChC;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA,+BAA+B,+BAA+B;AAC9D,mBAAmB,+BAA+B;AAClD,+BAA+B,8CAA8C;AAC7E,kBAAkB,8CAA8C;AAChE,+BAA+B,2CAA2C;AAC1E,kBAAkB,6CAA6C;AAC/D,+BAA+B,8CAA8C;AAC7E,kBAAkB,gDAAgD;AAClE;AACA;AACA;AACA;AACA,sCAAsC,IAAI,IAAI,EAAE,IAAI,EAAE;AACtD;AACA,oCAAoC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE;AAC/D;AACA,wCAAwC,IAAI,IAAI,EAAE;AAClD;AACA,yCAAyC,IAAI,IAAI,EAAE;AACnD,QAAQ;AACR;AACA;AACA;AACA;AACA;;;AAGA,4BAA4B,EAAE;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,OAAO;AACtF;AACA;AACA,WAAW,EAAE;AACb,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,mCAAmC,EAAE,eAAe,UAAU;AAC9D,kCAAkC,EAAE,eAAe,YAAY;AAC/D;AACA;AACA;AACA,wEAAwE,IAAI,EAAE,mBAAmB;AACjG,uEAAuE,IAAI,EAAE,mBAAmB;AAChG,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,WAAW,cAAc;AACzB;AACA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA,aAAa,aAAa;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA,8BAA8B,8BAA8B;AAC5D;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA,8BAA8B,iCAAiC;AAC/D;AACA,oBAAoB,YAAY;AAChC;AACA;AACA,kCAAkC,wCAAwC;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU,GAAG,UAAU;AAC1C,MAAM,UAAU,GAAG,UAAU;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,aAAa;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,oCAAoC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B,WAAW,2CAA2C;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,YAAY;AACvB;AACA;AACA,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA,4CAA4C,wBAAwB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,cAAc;AACjC,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc;AACd;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,eAAe,aAAa,SAAS;AAC/D;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA,oFAAoF,iBAAiB;AACrG;AACA;AACA;AACA,qFAAqF,iBAAiB;AACtG;AACA;AACA;AACA,mFAAmF,iBAAiB;AACpG;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,cAAc;AACjC,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc;AACd;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B;AAC1B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,eAAe,aAAa,SAAS;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF,iBAAiB;AACrG;AACA;AACA;AACA,qFAAqF,iBAAiB;AACtG;AACA;AACA;AACA,mFAAmF,iBAAiB;AACpG;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,cAAc;AACjC,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc;AACd;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B;AAC1B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,aAAa;AAClC,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,aAAa;AAClC,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,oCAAoC;AAClD,cAAc,oCAAoC;AAClD,cAAc,oCAAoC;AAClD,cAAc,oCAAoC;AAClD,cAAc;AACd;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,yEAAyE,EAAE;AAC3E;;AAEA,kCAAkC,iCAAiC;AACnE,qCAAqC,uBAAuB;;AAE5D;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8CAA8C,mBAAmB,EAAE;;AAEnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2CAA2C;AAChE;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA,6CAA6C,QAAQ;AACrD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,mBAAmB;AACtD;AACA;AACA;AACA,cAAc;AACd,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,YAAY;AACZ;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,yBAAyB;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,MAAM;AACtC;AACA,0CAA0C,MAAM;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,MAAM;AACnD;AACA;AACA;AACA;AACA,gDAAgD,MAAM;AACtD;AACA;AACA;AACA,WAAW,SAAS,0CAA0C;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,OAAO;AAC1C;AACA;AACA,kCAAkC,OAAO;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,MAAM;AACtC;AACA,WAAW,MAAM;AACjB,MAAM,MAAM;AACZ;AACA;AACA;AACA,8CAA8C,MAAM;AACpD;AACA;AACA;AACA;AACA,iDAAiD,MAAM;AACvD;AACA;AACA;AACA,WAAW,SAAS,yCAAyC;AAC7D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,MAAM;AACtC;AACA,WAAW,MAAM;AACjB,MAAM,MAAM;AACZ;AACA;AACA;AACA,iDAAiD,MAAM;AACvD;AACA;AACA;AACA;AACA,oDAAoD,MAAM;AAC1D;AACA;AACA;AACA,WAAW,SAAS,4CAA4C;AAChE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,kCAAkC;AACtC;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,WAAW,WAAW,oBAAoB,kCAAkC;AAC5E;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,wBAAwB;AACtF;AACA;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,WAAW,WAAW,mBAAmB,kCAAkC;AAC3E;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,WAAW,WAAW,oBAAoB,kCAAkC;AAC5E;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,WAAW,WAAW,oBAAoB,kCAAkC;AAC5E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB,MAAM,gBAAgB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,WAAW,WAAW,gBAAgB,kCAAkC;AACxE;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,6BAA6B;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA,aAAa,OAAO,mCAAmC,0BAA0B;AACjF,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,aAAa,OAAO,mCAAmC,0BAA0B;AACjF,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,+BAA+B;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,yCAAyC;AAC7C;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,yBAAyB,mCAAmC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C,MAAM,mCAAmC;AACzC;AACA;AACA,oEAAoE;AACpE,OAAO,mCAAmC;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC,uCAAuC,qBAAqB;AAC5D,uCAAuC,qBAAqB;AAC5D,iCAAiC,eAAe;AAChD,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,eAAe;AACf;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA,+CAA+C;AAC/C,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B,GAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,MAAM,OAAO,KAAK,4BAA4B,EAAE,gCAAgC,EAAE,+BAA+B,KAAK,yCAAyC,KAAK;AAC9L;AACA,wBAAwB,GAAG,MAAM,EAAE,MAAM,EAAE;AAC3C,iCAAiC,GAAG,6CAA6C,IAAI;AACrF,wBAAwB,GAAG;AAC3B,yBAAyB,GAAG;AAC5B,iDAAiD,IAAI;;AAErD;AACA;AACA;AACA;AACA,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ,+DAA+D;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,cAAc;AACxC,yCAAyC,qBAAqB;AAC9D,yCAAyC,qBAAqB;AAC9D,mCAAmC,eAAe;AAClD,4CAA4C,0BAA0B;AACtE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,iDAAiD;AACzD;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,uBAAuB,6BAA6B;AACpD;AACA,eAAe,QAAQ;AACvB;AACA,uBAAuB,6BAA6B;AACpD;AACA,eAAe,eAAe;AAC9B;AACA,eAAe,eAAe;AAC9B;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,oCAAoC;AAC7D,uCAAuC,qBAAqB;AAC5D,uCAAuC,qBAAqB;AAC5D,iCAAiC,eAAe;AAChD,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,uEAAuE;AACvE,qCAAqC;AACrC,4DAA4D,iDAAiD,EAAE,EAAE;AACjH;AACA;;AAEA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,iDAAiD;AACxD;AACA,cAAc,OAAO;AACrB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA,4CAA4C,+CAA+C;AAC3F;AACA,cAAc,QAAQ;AACtB;AACA,4CAA4C,+CAA+C;AAC3F;AACA,cAAc,eAAe;AAC7B;AACA,cAAc,eAAe;AAC7B;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,6CAA6C;AACnE,oCAAoC,qBAAqB;AACzD,oCAAoC,qBAAqB;AACzD,8BAA8B,eAAe;AAC7C,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,mCAAmC;AACnC,0DAA0D,iDAAiD,EAAE,EAAE;AAC/G;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iDAAiD;AACvD;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,+BAA+B,2BAA2B;AAC1D;AACA,aAAa,QAAQ;AACrB;AACA,+BAA+B,2BAA2B;AAC1D;AACA,aAAa,eAAe;AAC5B;AACA,aAAa,eAAe;AAC5B;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,kCAAkC;AACxD,oCAAoC,qBAAqB;AACzD,oCAAoC,qBAAqB;AACzD,8BAA8B,eAAe;AAC7C,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,mCAAmC;AACnC,0DAA0D,iDAAiD,EAAE,EAAE;AAC/G;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,iDAAiD;AACxD;AACA,cAAc,OAAO;AACrB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA,gCAAgC,2BAA2B;AAC3D;AACA,cAAc,QAAQ;AACtB;AACA,gCAAgC,2BAA2B;AAC3D;AACA,cAAc,eAAe;AAC7B;AACA,cAAc,eAAe;AAC7B;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,kCAAkC;AACxD,oCAAoC,qBAAqB;AACzD,oCAAoC,qBAAqB;AACzD,8BAA8B,eAAe;AAC7C,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,mCAAmC;AACnC,0DAA0D,iDAAiD,EAAE,EAAE;AAC/G;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iDAAiD;AACvD;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,+BAA+B,2BAA2B;AAC1D;AACA,aAAa,QAAQ;AACrB;AACA,+BAA+B,2BAA2B;AAC1D;AACA,aAAa,eAAe;AAC5B;AACA,aAAa,eAAe;AAC5B;;AAEA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,iCAAiC;AACtD,mCAAmC,qBAAqB;AACxD,mCAAmC,qBAAqB;AACxD,6BAA6B,eAAe;AAC5C,sCAAsC,0BAA0B;AAChE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,mCAAmC;AACnC,0DAA0D,iDAAiD,EAAE,EAAE;AAC/G;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,mDAAmD;AACxG;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ,+DAA+D;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,eAAe;AACxC,uCAAuC,qBAAqB;AAC5D,uCAAuC,qBAAqB;AAC5D,iCAAiC,eAAe;AAChD,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,8BAA8B;AACrE;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ,+DAA+D;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,UAAU;AAClC,uCAAuC,qBAAqB;AAC5D,uCAAuC,qBAAqB;AAC5D,iCAAiC,eAAe;AAChD,0CAA0C,0BAA0B;AACpE,qCAAqC,qBAAqB;AAC1D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA,WAAW;AACX;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,8BAA8B;AAChG;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ,+DAA+D;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,YAAY;AACtC,yCAAyC,qBAAqB;AAC9D,yCAAyC,qBAAqB;AAC9D,mCAAmC,eAAe;AAClD,4CAA4C,0BAA0B;AACtE,yCAAyC,uBAAuB;AAChE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA,WAAW;AACX;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAmB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,YAAY;AACzB;AACA,oCAAoC,uCAAuC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;;AAEA,qFAAqF,KAAK,UAAU,KAAK;AACzG;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC,0CAA0C,qBAAqB;AAC/D,0CAA0C,qBAAqB;AAC/D;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC,0CAA0C,qBAAqB;AAC/D,0CAA0C,qBAAqB;AAC/D;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,YAAY;AACzB,aAAa,YAAY;AACzB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,sBAAsB;AAChD,0BAA0B,sBAAsB;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;AACL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,mDAAmD,EAAE;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,kDAAkD,EAAE;AACpD;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,mCAAmC,aAAa,EAAE;AAClD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,mCAAmC,aAAa,EAAE;AAClD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,2EAA2E,EAAE;AAC7E,sCAAsC,EAAE;AACxC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;AACH;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,uCAAuC;AAC3C;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ,+DAA+D;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,wBAAwB;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ,+DAA+D;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,MAAM;AAC5B,wCAAwC,wBAAwB;AAChE,wCAAwC,wBAAwB;AAChE,wCAAwC,wBAAwB;AAChE,wCAAwC,wBAAwB;AAChE,+BAA+B,eAAe;AAC9C,wCAAwC,0BAA0B;AAClE,yCAAyC,2BAA2B;AACpE,yCAAyC,2BAA2B;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,gCAAgC;AAC7E;AACA;AACA,SAAS;;AAET;AACA;AACA;;AAEA,6CAA6C,iBAAiB;AAC9D;AACA;AACA,SAAS;;AAET;AACA;AACA;;AAEA,6CAA6C,yBAAyB;AACtE;AACA;AACA,SAAS;;AAET;AACA;AACA;;AAEA,6CAA6C,eAAe;AAC5D;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;;AAEA,6CAA6C,eAAe;AAC5D;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;;;AAID;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,kCAAkC;AAC3D,8CAA8C,wBAAwB;AACtE,IAAI,sBAAsB;AAC1B,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B,aAAa;AACb;AACA;AACA;AACA,oDAAoD,MAAM;AAC1D,gBAAgB;AAChB;AACA;AACA;AACA,2BAA2B,MAAM;AACjC;AACA;AACA,2BAA2B,aAAa;AACxC;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,cAAc;AACpB;AACA,kDAAkD,cAAc;AAChE;AACA;AACA;AACA;AACA,IAAI,mCAAmC;AACvC;AACA;AACA;AACA,WAAW,WAAW,SAAS,kCAAkC;AACjE;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,KAAK;AACtE;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,gCAAgC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,iCAAiC,YAAY,GAAG,MAAM;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,qCAAqC;AAChG,mGAAmG;AACnG,cAAc,uEAAuE;AACrF;AACA;AACA;AACA,oCAAoC,2CAA2C;AAC/E,UAAU,6EAA6E;AACvF;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,aAAa,kCAAkC;AACrE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,WAAW,kCAAkC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,uBAAuB,WAAW;AAClC,yBAAyB,SAAS;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;AACA,mBAAmB,oBAAoB;AACvC;AACA,qBAAqB,oBAAoB;AACzC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA,8BAA8B,wBAAwB,EAAE;AACxD;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,wCAAwC;AAC/D;AACA,QAAQ,4CAA4C;AACpD;AACA;AACA;AACA;AACA,MAAM,oCAAoC;AAC1C,MAAM,0CAA0C;AAChD;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,qDAAqD;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gBAAgB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;;;AAGA;AACA;AACA;AACA;AACA,wCAAwC,0CAA0C;AAClF,IAAI,gDAAgD;AACpD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,mCAAmC;AACvC;AACA;AACA;AACA,IAAI,qCAAqC;AACzC;AACA;AACA,WAAW,WAAW,aAAa,kCAAkC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,mCAAmC;AACvC;AACA;AACA;AACA,IAAI,qCAAqC;AACzC;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM,OAAO,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,+BAA+B;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,WAAW;AAClD,+CAA+C,WAAW;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA,4EAA4E;AAC5E;AACA;AACA;AACA,YAAY,4BAA4B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,IAAI,iDAAiD,QAAQ;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,gFAAgF;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,QAAQ;AAC7F;AACA;AACA;AACA,kFAAkF,QAAQ;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,6CAA6C;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,QAAQ;AAChE;AACA;AACA;AACA,iFAAiF,QAAQ;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mCAAmC;AAC7C,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,2CAA2C;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,aAAa;AAClF;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,cAAc,MAAM,aAAa;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,aAAa;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;;AAEA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC,mBAAmB;AACnB;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa;AACb;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE,YAAY,qEAAqE;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,cAAc;AACzC;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,aAAa,kCAAkC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE,gBAAgB,qEAAqE;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,YAAY,kCAAkC;AACpE,cAAc,qEAAqE;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE,gBAAgB,qEAAqE;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,eAAe,kCAAkC;AACvE,iBAAiB,qEAAqE;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,eAAe,kCAAkC;AACvE,iBAAiB,qEAAqE;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE,gBAAgB,qEAAqE;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,YAAY,kCAAkC;AACpE;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E;;AAE9E;AACA;AACA,2BAA2B,iBAAiB;AAC5C,0BAA0B,gBAAgB;AAC1C;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,aAAa,kCAAkC;AACrE,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,WAAW,kCAAkC;AACnE,KAAK,qEAAqE;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA,oBAAoB,MAAM;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE,YAAY,qEAAqE;AACjF;AACA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,SAAS,kCAAkC;AACjE,WAAW,qEAAqE;AAChF;AACA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,SAAS,kCAAkC;AACjE,WAAW,qEAAqE;AAChF;AACA;AACA;AACA;AACA,yDAAyD;AACzD,gBAAgB;AAChB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,QAAQ,kCAAkC;AAChE,UAAU,qEAAqE;AAC/E;AACA;AACA;AACA;AACA,kDAAkD;AAClD,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE,YAAY,qEAAqE;AACjF;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,WAAW;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC;AACA;AACA;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD,8BAA8B;AAC9B,mBAAmB,kEAAkE;AACrF,IAAI,wCAAwC,wCAAwC;AACpF,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA,yCAAyC,4CAA4C;AACrF;AACA;AACA,WAAW,QAAQ,6CAA6C;AAChE,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,cAAc;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,+CAA+C;AAC7D,cAAc,+CAA+C;AAC7D;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;;AAEf;AACA;;AAEA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,WAAW;AACX;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,GAAG,8BAA8B;AAC5C;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,uCAAuC,4BAA4B;AACvE,mEAAmE;AACnE;AACA;AACA;AACA;AACA,8DAA8D,0BAA0B;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,SAAS,kCAAkC;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,6CAA6C,YAAY,MAAM,YAAY,OAAO,QAAQ;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AACpE,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B,yCAAyC,0BAA0B;AACnE,yCAAyC,0BAA0B;AACnE,8BAA8B,eAAe;AAC7C,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C,aAAa,eAAe;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAc,EAAE;AAChB,gBAAgB,8CAA8C;AAC9D;AACA;AACA,cAAc,EAAE;AAChB;AACA,cAAc,iBAAiB;AAC/B,0DAA0D;AAC1D,iBAAiB;AACjB,SAAS,gEAAgE;AACzE;;AAEA;AACA;AACA,KAAK,0DAA0D;;AAE/D,8CAA8C;AAC9C,iBAAiB;;AAEjB;AACA,QAAQ,0DAA0D;AAClE,uCAAuC;AACvC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc,iBAAiB;AAC/B;AACA;;AAEA,+CAA+C;AAC/C,kBAAkB;;AAElB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,0BAA0B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,0BAA0B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,cAAc,iBAAiB;AAC/B;AACA;AACA;AACA,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,OAAO;AACrB;AACA;AACA;AACA,6CAA6C,wBAAwB;AACrE;AACA;AACA;AACA;AACA;AACA,6CAA6C,oBAAoB;AACjE,2CAA2C;AAC3C,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2BAA2B,+BAA+B;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;;AAEnC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe;AACf,qBAAqB;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB,sBAAsB;AACtB,4BAA4B;AAC5B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,eAAe;AACpD,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL,sDAAsD,EAAE,gCAAgC,EAAE;AAC1F;AACA;AACA,GAAG;;;AAGH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,mBAAmB;AACrE;AACA;AACA;AACA;AACA,0BAA0B,gBAAgB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,gBAAgB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,mDAAmD;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E,EAAE;AAC9E;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,OAAO;AACP;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;AACA,qBAAqB,0BAA0B;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gFAAgF;AAChF,qEAAqE;AACrE,iEAAiE;AACjE;AACA;AACA;AACA,2DAA2D,qBAAqB;AAChF;AACA;AACA;AACA;AACA;AACA,kBAAkB,iDAAiD;AACnE;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,qBAAqB;AAC/B;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA,2CAA2C,qCAAqC;AAChF,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,kDAAkD;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,6BAA6B;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,OAAO;AACP,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yCAAyC;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,qBAAqB;AAC5E,uEAAuE,qBAAqB;AAC5F;AACA,IAAI,mDAAmD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,qBAAqB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,2CAA2C,qBAAqB;AAChE;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,aAAa,OAAO;AACpB,cAAc,aAAa;AAC3B;AACA;AACA;;AAEA;AACA,uBAAuB;;AAEvB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA,yDAAyD,cAAc;AACvE,mFAAmF;AACnF;AACA;AACA;AACA;AACA,yDAAyD,gBAAgB;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,oCAAoC;AAC/D,8BAA8B,6CAA6C;AAC3E,iCAAiC,gDAAgD;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,oCAAoC;AAC/D,8BAA8B,oCAAoC;AAClE,iCAAiC,uCAAuC;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,uBAAuB,mDAAmD;AAC1E;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,mBAAmB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,iBAAiB;AACtD,oEAAoE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,qBAAqB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO,qCAAqC,cAAc;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,gCAAgC;AAC9C;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF;AACtF;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,wCAAwC,OAAO;AAC/C;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,0CAA0C,iCAAiC;;AAE3E;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,qCAAqC;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,IAAI;AACJ;AACA;AACA,eAAe;AACf,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,yBAAyB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ;AACnB,IAAI,6EAA6E;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,2BAA2B;AAC1C,eAAe,+CAA+C;AAC9D,eAAe,yBAAyB;AACxC,eAAe,6CAA6C;AAC5D,eAAe;AACf;AACA,8CAA8C;AAC9C,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;AAIA,8CAA8C,qCAAqC;AACnF;AACA;AACA,gCAAgC,EAAE,uBAAuB;AACzD,6CAA6C;AAC7C,0BAA0B,gCAAgC;AAC1D;AACA;AACA;AACA;AACA;AACA,uCAAuC,uBAAuB;AAC9D;AACA;AACA,uCAAuC,uBAAuB;AAC9D;AACA;AACA,uCAAuC,uBAAuB;AAC9D,UAAU;AACV;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,EAAE,cAAc,EAAE;AACvC;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uDAAuD,iCAAiC,EAAE;AAC1F,8DAA8D,uBAAuB;AACrF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,2BAA2B,4BAA4B;AACvD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,2BAA2B,4BAA4B;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,gFAAgF,QAAQ;AACxF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,WAAW;;AAEX;AACA;AACA,aAAa;AACb;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wBAAwB,0DAA0D,EAAE;AACpF,wBAAwB,uBAAuB;AAC/C;AACA;;AAEA,OAAO;;AAEP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,WAAW;AACX;AACA,WAAW;;AAEX;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe;AACf;AACA;;AAEA,SAAS;AACT;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,gDAAgD,QAAQ;AACxD;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,WAAW;;AAEX;AACA;AACA;AACA,SAAS;;AAET;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,8BAA8B;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE;AACpE,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,oCAAoC,sBAAsB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C,6EAA6E;AAC7E,4BAA4B,aAAa,+BAA+B;AACxE,+BAA+B,kBAAkB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,gCAAgC,SAAS;AACzC,gCAAgC,SAAS,OAAO,SAAS;AACzD,kCAAkC,SAAS,IAAI,SAAS;AACxD,oCAAoC,SAAS,IAAI,SAAS,OAAO,4BAA4B;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA,2CAA2C,sBAAsB;AACjE;;AAEA;AACA;AACA;AACA,+BAA+B;AAC/B,uCAAuC,SAAS;AAChD,uCAAuC,SAAS,OAAO,SAAS;AAChE,yCAAyC,SAAS,IAAI,SAAS;AAC/D,2CAA2C,SAAS,IAAI,SAAS,OAAO,4BAA4B;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA,qFAAqF;AACrF;AACA,4CAA4C;AAC5C,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA,OAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,aAAa;AAC/B,kBAAkB,cAAc;AAChC,kBAAkB,cAAc;AAChC,kBAAkB,cAAc;AAChC,kBAAkB,cAAc;AAChC,kBAAkB,cAAc;AAChC;AACA;AACA,6DAA6D,mCAAmC;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,yBAAyB,MAAM,uBAAuB;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yDAAyD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,0DAA0D;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,cAAc;AACd;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC,MAAM,6BAA6B;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kBAAkB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,uBAAuB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,gBAAgB;AACjC;AACA;AACA;AACA,eAAe,YAAY,IAAI,aAAa,UAAU,YAAY;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,qCAAqC;AAChD,WAAW,sCAAsC;AACjD,WAAW,kCAAkC;AAC7C,WAAW,mCAAmC;AAC9C,WAAW,mCAAmC;AAC9C,WAAW,uCAAuC;AAClD,WAAW,oCAAoC;AAC/C,WAAW,qCAAqC;AAChD,WAAW;AACX;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,2HAA2H,EAAE;AAC7H;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,wJAAwJ,EAAE;AAC1J;AACA;AACA;AACA;;AAEA;AACA;AACA,mDAAmD,EAAE;AACrD;AACA;;AAEA;AACA,0BAA0B;;AAE1B;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,yBAAyB,0BAA0B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,eAAe;AACf;AACA,4HAA4H,EAAE,kBAAkB,EAAE,oBAAoB,EAAE;AACxK;AACA,aAAa;AACb;AACA,uCAAuC;AACvC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+DAA+D,gBAAgB;AAC/E;AACA;AACA;AACA;AACA;;AAEA;AACA,yBAAyB,0BAA0B;AACnD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,eAAe;;AAEf;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,+BAA+B;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,2DAA2D;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iEAAiE;AAC1E;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,+CAA+C;AAC/C,+BAA+B;AAC/B,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iCAAiC;AACvC,MAAM,uCAAuC;AAC7C;AACA;AACA,WAAW,WAAW,gBAAgB,kCAAkC;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,+BAA+B;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,2DAA2D;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iEAAiE;AAC1E;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,+CAA+C;AAC/C,+BAA+B;AAC/B,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iCAAiC;AACvC,MAAM,uCAAuC;AAC7C;AACA;AACA;AACA,WAAW,WAAW,gBAAgB,kCAAkC;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,wCAAwC;AAC/D;AACA,QAAQ,4CAA4C;AACpD;AACA;AACA,WAAW,WAAW;AACtB;AACA,IAAI,kCAAkC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,YAAY;AAC9E,uEAAuE,0BAA0B;AACjG,+DAA+D;AAC/D;AACA;AACA,uBAAuB,SAAS;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,yBAAyB;AACxE;AACA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,WAAW;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,+CAA+C,QAAQ;AACvD;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;;AAE3B;AACA;AACA,aAAa;AACb,WAAW;AACX;AACA,OAAO;AACP;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,uCAAuC,qCAAqC;AAC5E;;AAEA;AACA;AACA,uCAAuC,4CAA4C;AACnF,KAAK;AACL;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,4CAA4C;AACtE;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,YAAY;AACnC,8DAA8D;AAC9D,kEAAkE,OAAO;AACzE;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,wBAAwB,OAAO,UAAU,MAAM;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D;AAC3D;AACA,qDAAqD;AACrD;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,MAAM,IAAI,OAAO;AACrD,0BAA0B,MAAM;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,2DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,EAAE;AACvB;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,yCAAyC;AAC3F,4BAA4B,yCAAyC;AACrE,IAAI,wCAAwC,MAAM,iCAAiC;AACnF;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC;;AAED;;AAEA,6BAA6B;;AAE7B;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,2BAA2B;;AAE3B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;;AAGA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;;;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,wBAAwB;AACzE;AACA,8EAA8E,yBAAyB;AACvG,IAAI,4BAA4B;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,+BAA+B;AACzC,OAAO,wEAAwE;AAC/E,UAAU,2BAA2B;AACrC,qBAAqB,+EAA+E;AACpG;AACA,OAAO,4FAA4F;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB,uCAAuC,4BAA4B;AACnE,WAAW,QAAQ;AACnB,IAAI,6EAA6E;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,cAAc;AACxC;AACA;AACA;AACA,4BAA4B,mBAAmB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,qBAAqB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE,WAAW,IAAI,aAAa;AAClG;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,0BAA0B;AACtC,YAAY,0BAA0B;AACtC,YAAY;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uFAAuF,aAAa;AACpG;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,0BAA0B;AACtC,YAAY,6BAA6B;AACzC,YAAY,0BAA0B;AACtC,YAAY,QAAQ,cAAc,iBAAiB;AACnD,YAAY;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,wCAAwC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,0BAA0B;AACtC,YAAY,0BAA0B;AACtC,YAAY;AACZ;AACA,0BAA0B,0BAA0B;AACpD;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,+BAA+B;AAC/B,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;;AAEP;AACA,wCAAwC;AACxC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAW;AACX;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;;AAEnD;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,wDAAwD,KAAK,wBAAwB;AACtH,8BAA8B,oBAAoB,MAAM,sBAAsB;AAC9E;AACA;AACA;AACA;AACA,wDAAwD;AACxD;AACA;AACA;AACA,YAAY,sEAAsE;AAClF,IAAI,gEAAgE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,4BAA4B;AACrE,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;;AAE3B;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,wDAAwD,KAAK,wBAAwB;AACpH,yCAAyC,oBAAoB;AAC7D;AACA,sDAAsD;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAmB;AACrD,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,uBAAuB,EAAE,yBAAyB,EAAE,YAAY,EAAE;AAClE;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,wDAAwD,KAAK,wBAAwB;AACxH,yCAAyC,oBAAoB;AAC7D;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAmB;AACrD,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,wDAAwD,KAAK,wBAAwB;AACxH,yCAAyC,oBAAoB;AAC7D;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAmB;AACrD,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,2CAA2C,gBAAgB,mCAAmC,4BAA4B,+BAA+B,GAAG;AAC5J,CAAC;AACD,CAAC;;AAED;AACA;AACA,GAAG;;AAEH,CAAC;;AAED,gIAAgI,0GAA0G,yBAAyB,UAAU,eAAe,iBAAiB,mBAAmB,WAAW,mBAAmB,W;;;;;;AChkhC9V,gJAAgJ,grBAAgrB,iBAAiB,gWAAgW,6BAA6B,8lDAA8lD,kL;;;;;;ACA5yF,gJAAgJ,25BAA25B,cAAc,sHAAsH,QAAQ,2BAA2B,uBAAuB,uBAAuB,qBAAqB,qNAAqN,qBAAqB,uDAAuD,kCAAkC,sCAAsC,uBAAuB,sCAAsC,uBAAuB,weAAwe,UAAU,uBAAuB,YAAY,+BAA+B,oCAAoC,0GAA0G,OAAO,4O;;;;;;sDCA35E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2CAA2C;AAC3C;AACA,2DAA2D;;AAE3D;AACA,+CAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;;AAEA;AACA;AACA;AACA;;AAEA;AACA,yBAAyB;AACzB,yBAAyB;AACzB;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,0BAA0B,MAAM,aAAa,OAAO;;AAEpD;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,EAAE;AACnD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,2CAA2C,GAAG;;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe;AACf,cAAc;AACd,cAAc;AACd,gBAAgB;AAChB,eAAe;AACf;;AAEA;AACA;AACA,UAAU;AACV,SAAS;AACT,SAAS;AACT,WAAW;AACX,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,EAAE;AACf,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,aAAa,EAAE;AACf,aAAa,MAAM;AACnB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,aAAa,SAAS;AACtB,aAAa,OAAO;AACpB,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,SAAS;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,MAAM;AACnB,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,aAAa,EAAE;AACf,aAAa,QAAQ;AACrB;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,aAAa,EAAE;AACf,aAAa,QAAQ;AACrB;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa,SAAS;AACtB,aAAa,SAAS;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,OAAO;AACpB,aAAa,SAAS;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa,SAAS;AACtB,aAAa,EAAE;AACf,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,eAAe,EAAE;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,aAAa,SAAS;AACtB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,SAAS;AACxB;AACA;AACA,cAAc,2BAA2B;AACzC;AACA;AACA,mBAAmB,gCAAgC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,6BAA6B;AAC9D;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA,oCAAoC,6BAA6B,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,aAAa;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,aAAa;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,EAAE;AACnB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,6BAA6B;AAC5C,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT,gBAAgB;AAChB,OAAO;;AAEP;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qEAAqE;AACrE;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,aAAa;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,YAAY;AAC3B,iBAAiB,YAAY;AAC7B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,mBAAmB;AAClC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,gBAAgB,QAAQ;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,gBAAgB,QAAQ;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,eAAe,OAAO,WAAW;AACjC,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,4BAA4B;;AAE5B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO,WAAW;AACjC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO,WAAW;AACjC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,+CAA+C;AACpF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,oEAAoE;AACpE;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,0CAA0C;AAC1C,wCAAwC;AACxC,+DAA+D;AAC/D,iEAAiE;AACjE;AACA;AACA,cAAc;AACd;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,MAAM;AACvB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,KAAK;AACpB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS,GAAG,SAAS,KAAK,SAAS;AAC3D,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB;AAC5D;AACA,mCAAmC,iBAAiB;AACpD,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,oCAAoC;AAC9C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,4CAA4C,kBAAkB,EAAE;AAChE;AACA;AACA;AACA,gCAAgC,qCAAqC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,qCAAqC;AAC/C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,uCAAuC,kBAAkB,EAAE;AAC3D;AACA;AACA;AACA,2BAA2B,oCAAoC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,qCAAqC;AAC/C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,uCAAuC,2BAA2B,EAAE;AACpE;AACA;AACA;AACA,2BAA2B,kCAAkC;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,oCAAoC;AAC9C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,2CAA2C,4BAA4B,EAAE;AACzE;AACA;AACA;AACA,+BAA+B,mCAAmC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,SAAS,KAAK,SAAS,GAAG,SAAS;AAC7D,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB;AAC5D,sBAAsB,iBAAiB,GAAG,iBAAiB;AAC3D;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,KAAK;AACpB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,qBAAqB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS;AAClE;AACA,4BAA4B,SAAS,GAAG,SAAS;AACjD;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,qBAAqB,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB;AAC9E;AACA,8BAA8B,iBAAiB;AAC/C;AACA,eAAe,iBAAiB,GAAG,iBAAiB;AACpD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,qBAAqB;AACpC,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA,iCAAiC,SAAS,eAAe,YAAY,EAAE;AACvE;AACA;AACA;AACA,iCAAiC,SAAS;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA,qCAAqC,SAAS,eAAe,YAAY,EAAE;AAC3E;AACA;AACA;AACA,qCAAqC,SAAS;AAC9C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,oCAAoC;AAC9C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,4CAA4C,kBAAkB,EAAE;AAChE;AACA;AACA;AACA,gCAAgC,qCAAqC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,qCAAqC;AAC/C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,uCAAuC,kBAAkB,EAAE;AAC3D;AACA;AACA;AACA,2BAA2B,oCAAoC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS,KAAK,SAAS,GAAG,SAAS;AACtD,eAAe,SAAS,GAAG,SAAS;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB;AAC5D,sBAAsB,iBAAiB,GAAG,iBAAiB;AAC3D;AACA;AACA,eAAe,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB;AACxE;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,SAAS,GAAG,SAAS,GAAG,SAAS;AACnD,eAAe,SAAS,GAAG,SAAS;AACpC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB;AAChF;AACA;AACA,eAAe,iBAAiB,GAAG,iBAAiB;AACpD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,KAAK;AACpB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,KAAK,SAAS,GAAG,SAAS;AACpD,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB;AAC5D,sBAAsB,iBAAiB,GAAG,iBAAiB;AAC3D;AACA;AACA,eAAe,iBAAiB,GAAG,iBAAiB;AACpD;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc,OAAO,QAAQ,SAAS,GAAG,SAAS,GAAG;AACrD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,+BAA+B;AACzC,UAAU,+BAA+B;AACzC,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,8BAA8B;;AAExE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,8BAA8B;AACxC,UAAU;AACV;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,gBAAgB,OAAO;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,+CAA+C;AACzD,UAAU;AACV;AACA;AACA;AACA,uBAAuB,oCAAoC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,UAAU,8CAA8C;AACxD,UAAU;AACV;AACA;AACA,oCAAoC,kBAAkB,EAAE;AACxD;AACA;AACA;AACA,wBAAwB,4BAA4B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA,UAAU,+CAA+C;AACzD,UAAU,gDAAgD;AAC1D,UAAU;AACV;AACA;AACA,kCAAkC,mBAAmB,EAAE;AACvD;AACA;AACA;AACA,sBAAsB,2BAA2B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,aAAa;AAC9B;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,kBAAkB,iBAAiB;AACnC;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,aAAa;AAC9B;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,oBAAoB;AACnC,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,sBAAsB;AACrC;AACA,eAAe,KAAK;AACpB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,4BAA4B;AACtC,UAAU;AACV;AACA;AACA;AACA;AACA,QAAQ;AACR,cAAc,OAAO,4BAA4B,QAAQ,8BAA8B;AACvF;AACA;AACA,cAAc,UAAU,4BAA4B,YAAY,8BAA8B;AAC9F;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,iBAAiB;AAC/B;AACA;AACA;AACA,UAAU,mBAAmB;AAC7B,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,qCAAqC;AACpD;AACA,eAAe,SAAS;AACxB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,8BAA8B;AACxC,UAAU,8BAA8B;AACxC,UAAU,8BAA8B;AACxC,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,gDAAgD;AAC1D,UAAU,+CAA+C;AACzD,UAAU;AACV;AACA;AACA,uCAAuC,iBAAiB,EAAE;AAC1D;AACA;AACA;AACA,2BAA2B,4BAA4B;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc,iBAAiB,EAAE;;AAEtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,iBAAiB,yBAAyB;AAC1C;AACA;AACA,QAAQ,IAAI;AACZ,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,UAAU,+CAA+C;AACzD,UAAU;AACV;AACA;AACA,oCAAoC,kBAAkB,EAAE;AACxD;AACA;AACA;AACA,wBAAwB,4BAA4B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,oBAAoB;AACnC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,gBAAgB,OAAO;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mCAAmC;AAC7C,UAAU;AACV;AACA;AACA;AACA,sBAAsB,oCAAoC;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,yBAAyB;AACxC;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,8BAA8B;AACxC,UAAU,8BAA8B;AACxC,UAAU,8BAA8B;AACxC,UAAU;AACV;AACA;AACA,qCAAqC,eAAe,EAAE;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,oBAAoB,iCAAiC;AACrD,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,QAAQ;AACvB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,kDAAkD,kBAAkB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,KAAK;AACpB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,KAAK;AACpB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA,qBAAqB;AACrB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,yBAAyB;AACxC;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,qBAAqB;AACpC,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,oBAAoB;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB;AACrB;AACA,6BAA6B,mBAAmB,cAAc,EAAE,EAAE;AAClE;AACA;AACA,6BAA6B,mBAAmB,cAAc,EAAE,EAAE;AAClE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB;AACrB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA,iCAAiC,kBAAkB,EAAE;AACrD;AACA;AACA;AACA;AACA;AACA,kDAAkD,kBAAkB,EAAE;AACtE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,SAAS;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB;AACrB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB;AACrB;AACA,0BAA0B,SAAS;AACnC;AACA;AACA,0BAA0B,SAAS;AACnC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,MAAM;AACvB;AACA;AACA,kBAAkB,iBAAiB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS;AAC1B,cAAc;AACd;AACA,iBAAiB,SAAS;AAC1B,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS;AAC1B,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,GAAG,SAAS,GAAG,SAAS;AAClD,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,GAAG,SAAS,GAAG,SAAS;AAClD,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,qBAAqB;AACpC,iBAAiB,MAAM;AACvB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,mBAAmB,SAAS,GAAG,SAAS,GAAG,SAAS;AACpD,cAAc;AACd;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,uBAAuB,OAAO,SAAS,EAAE,GAAG,OAAO,iBAAiB,EAAE;AACtE,cAAc,OAAO,iBAAiB;AACtC;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA,qBAAqB,4BAA4B;AACjD,qBAAqB,6BAA6B;AAClD,qBAAqB;AACrB;AACA;AACA,qCAAqC,mBAAmB,EAAE;AAC1D;AACA;AACA;AACA,yBAAyB,2BAA2B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA,qBAAqB,4BAA4B;AACjD,qBAAqB,6BAA6B;AAClD,qBAAqB;AACrB;AACA;AACA,yCAAyC,mBAAmB,EAAE;AAC9D;AACA;AACA;AACA,6BAA6B,4BAA4B;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB,OAAO,SAAS;AACrC,6BAA6B,gBAAgB,SAAS,GAAG;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,gBAAgB,SAAS,GAAG;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,QAAQ;AACR,cAAc;AACd;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,KAAK;AACpB,iBAAiB,EAAE;AACnB;AACA;AACA,qBAAqB,QAAQ,OAAO,oBAAoB,EAAE;AAC1D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,kBAAkB,iBAAiB;AACnC;AACA,QAAQ;AACR,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,qBAAqB,+BAA+B;AACpD,qBAAqB;AACrB;AACA;AACA,uCAAuC,cAAc,EAAE;AACvD,cAAc,2BAA2B;AACzC;AACA;AACA;AACA,cAAc,2BAA2B;AACzC;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,gBAAgB,SAAS,GAAG,SAAS;AACrC;AACA;AACA;AACA,gBAAgB,SAAS,GAAG,SAAS;AACrC;AACA;AACA;AACA,cAAc,QAAQ,iBAAiB,GAAG,iBAAiB;AAC3D;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,oBAAoB;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,qBAAqB;AACpC,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,qBAAqB;AACpC,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA,gCAAgC;AAChC,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA,qBAAqB,QAAQ,OAAO,+BAA+B,EAAE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO,WAAW;AAChC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,oBAAoB,yBAAyB;AAC7C;AACA,QAAQ,IAAI;AACZ,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA,cAAc,QAAQ,QAAQ,EAAE;AAChC;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ,QAAQ,EAAE;AAChC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA,iDAAiD,cAAc,EAAE;AACjE;AACA;AACA;AACA,iDAAiD,sBAAsB,EAAE;AACzE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO,WAAW;AAChC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kCAAkC,KAAK;AACvC;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,eAAe,gBAAgB;AAC/B,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,gBAAgB,OAAO;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA,iBAAiB,sBAAsB;AACvC,qBAAqB,UAAU;AAC/B;AACA;AACA,sEAAsE,2BAA2B,EAAE;AACnG,iBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA,4DAA4D;AAC5D,iBAAiB,mBAAmB;AACpC;AACA;AACA;AACA;AACA,0CAA0C,OAAO;AACjD,iBAAiB,oBAAoB;AACrC;AACA;AACA;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA;AACA;AACA,qDAAqD,2BAA2B,EAAE;AAClF,wCAAwC,aAAa,eAAe,EAAE;AACtE,iBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA,wDAAwD,qCAAqC;AAC7F;AACA;AACA;AACA;AACA,0DAA0D,qBAAqB;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,YAAY;AACvD,0CAA0C,QAAQ;AAClD,iBAAiB,qBAAqB;AACtC;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+BAA+B;;AAE/B,mCAAmC;AACnC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,wBAAwB;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP,mBAAmB;;AAEnB;AACA;AACA;AACA;AACA,8BAA8B,mBAAmB;AACjD;AACA;AACA;AACA;AACA,4CAA4C;;AAE5C;AACA,uDAAuD;AACvD;AACA;AACA,6BAA6B,EAAE;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C,+BAA+B,iCAAiC;AAChE,cAAc;AACd;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iCAAiC;AACjC,aAAa,QAAQ,QAAQ,UAAU,aAAa;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,KAAK;AACpB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,qBAAqB;AACpC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B,sBAAsB,kBAAkB;AACxC;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA,aAAa,qBAAqB;AAClC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,iBAAiB;AAC3B,UAAU;AACV;AACA;AACA,qCAAqC,mBAAmB,cAAc,EAAE,EAAE;AAC1E,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA,4CAA4C,SAAS;AACrD;AACA;AACA,eAAe,SAAS,GAAG,SAAS;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,8CAA8C;AACxD,UAAU;AACV;AACA;AACA;AACA,mCAAmC,mCAAmC;AACtE,eAAe,8CAA8C;AAC7D;AACA;AACA;AACA,eAAe,4BAA4B;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,yBAAyB;AACnC,UAAU;AACV;AACA;AACA,oCAAoC,iBAAiB;AACrD,eAAe,yBAAyB;AACxC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,yBAAyB;AACnC,UAAU;AACV;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,OAAO,qBAAqB,EAAE;AACxC,UAAU,OAAO,qBAAqB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,QAAQ;AACvB,iBAAiB,gBAAgB;AACjC;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,gBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAmB,GAAG,iBAAiB;AACvD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4BAA4B,qDAAqD;AACjF;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,OAAO,SAAS,EAAE;AAC5B,UAAU,OAAO,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA,qCAAqC,YAAY,EAAE;AACnD,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS;AACpE;AACA,sCAAsC,YAAY,EAAE;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA,qCAAqC,YAAY,EAAE;AACnD,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS;AACpE;AACA,qCAAqC,YAAY,EAAE;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK,MAAM,iBAAiB;;AAE5B;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,mCAAmC,4DAA4D;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAoB,yCAAyC;AAC7D;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;;;;;;;AC3rhBD;;AAEA;AACA,iBAAiB,aAAa,EAAE;;AAEhC;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC,GAAG;AACH;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC,GAAG;AACH;AACA;AACA;AACA;;;;;;;;AClBA;;;;;;;;;;;;;;;ACcA;AACA,QAAQ,aAAa;;ADGrB;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA,QAAQ,OAAO,WAAW;IACtB;IACA;IACA;;KAED,OAAO;KACP,UAAU,UAAU;KACpB,UAAU,aAAa;KACvB,uEAAI,UACH,MACA,QACA,sBACA,sBAAyB;IACzB,KAAK,KAAK;IAEV,qBAAqB,IAAI;QACvB,OAAO;QACP,OAAO","file":"index.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmory imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmory exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tObject.defineProperty(exports, name, {\n \t\t\tconfigurable: false,\n \t\t\tenumerable: true,\n \t\t\tget: getter\n \t\t});\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 16);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap d343910db03588c47a4b","require('./angular');\nmodule.exports = angular;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular/index.js\n// module id = 0\n// module chunks = 0","require('./angular-cookies');\nmodule.exports = 'ngCookies';\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-cookies/index.js\n// module id = 1\n// module chunks = 0","require('./angular-resource');\nmodule.exports = 'ngResource';\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-resource/index.js\n// module id = 2\n// module chunks = 0","/*!\n * State-based routing for AngularJS\n * @version v1.0.0-beta.1\n * @link https://ui-router.github.io\n * @license MIT License, http://www.opensource.org/licenses/MIT\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"angular-ui-router\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"angular-ui-router\"] = factory();\n\telse\n\t\troot[\"angular-ui-router\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Main entry point for angular 1.x build\n\t * @module ng1\n\t */\n\t/** for typedoc */\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t__export(__webpack_require__(1));\n\t__export(__webpack_require__(53));\n\t__export(__webpack_require__(55));\n\t__webpack_require__(58);\n\t__webpack_require__(59);\n\t__webpack_require__(60);\n\t__webpack_require__(61);\n\tObject.defineProperty(exports, \"__esModule\", { value: true });\n\texports.default = \"ui.router\";\n\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module common */ /** */\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t__export(__webpack_require__(2));\n\t__export(__webpack_require__(46));\n\t__export(__webpack_require__(47));\n\t__export(__webpack_require__(48));\n\t__export(__webpack_require__(49));\n\t__export(__webpack_require__(50));\n\t__export(__webpack_require__(51));\n\t__export(__webpack_require__(52));\n\t__export(__webpack_require__(44));\n\tvar router_1 = __webpack_require__(26);\n\texports.UIRouter = router_1.UIRouter;\n\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module common */ /** for typedoc */\n\t__export(__webpack_require__(3));\n\t__export(__webpack_require__(6));\n\t__export(__webpack_require__(7));\n\t__export(__webpack_require__(5));\n\t__export(__webpack_require__(4));\n\t__export(__webpack_require__(8));\n\t__export(__webpack_require__(9));\n\t__export(__webpack_require__(12));\n\n\n/***/ },\n/* 3 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Random utility functions used in the UI-Router code\n\t *\n\t * @preferred @module common\n\t */ /** for typedoc */\n\t\"use strict\";\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar w = typeof window === 'undefined' ? {} : window;\n\tvar angular = w.angular || {};\n\texports.fromJson = angular.fromJson || JSON.parse.bind(JSON);\n\texports.toJson = angular.toJson || JSON.stringify.bind(JSON);\n\texports.copy = angular.copy || _copy;\n\texports.forEach = angular.forEach || _forEach;\n\texports.extend = angular.extend || _extend;\n\texports.equals = angular.equals || _equals;\n\texports.identity = function (x) { return x; };\n\texports.noop = function () { return undefined; };\n\texports.abstractKey = 'abstract';\n\t/**\n\t * Binds and copies functions onto an object\n\t *\n\t * Takes functions from the 'from' object, binds those functions to the _this object, and puts the bound functions\n\t * on the 'to' object.\n\t *\n\t * This example creates an new class instance whose functions are prebound to the new'd object.\n\t * @example\n\t * ```\n\t *\n\t * class Foo {\n\t *   constructor(data) {\n\t *     // Binds all functions from Foo.prototype to 'this',\n\t *     // then copies them to 'this'\n\t *     bindFunctions(Foo.prototype, this, this);\n\t *     this.data = data;\n\t *   }\n\t *\n\t *   log() {\n\t *     console.log(this.data);\n\t *   }\n\t * }\n\t *\n\t * let myFoo = new Foo([1,2,3]);\n\t * var logit = myFoo.log;\n\t * logit(); // logs [1, 2, 3] from the myFoo 'this' instance\n\t * ```\n\t *\n\t * This example creates a bound version of a service function, and copies it to another object\n\t * @example\n\t * ```\n\t *\n\t * var SomeService = {\n\t *   this.data = [3, 4, 5];\n\t *   this.log = function() {\n\t *     console.log(this.data);\n\t *   }\n\t * }\n\t *\n\t * // Constructor fn\n\t * function OtherThing() {\n\t *   // Binds all functions from SomeService to SomeService,\n\t *   // then copies them to 'this'\n\t *   bindFunctions(SomeService, this, SomeService);\n\t * }\n\t *\n\t * let myOtherThing = new OtherThing();\n\t * myOtherThing.log(); // logs [3, 4, 5] from SomeService's 'this'\n\t * ```\n\t *\n\t * @param from The object which contains the functions to be bound\n\t * @param to The object which will receive the bound functions\n\t * @param bindTo The object which the functions will be bound to\n\t * @param fnNames The function names which will be bound (Defaults to all the functions found on the 'from' object)\n\t */\n\tfunction bindFunctions(from, to, bindTo, fnNames) {\n\t    if (fnNames === void 0) { fnNames = Object.keys(from); }\n\t    return fnNames.filter(function (name) { return typeof from[name] === 'function'; })\n\t        .forEach(function (name) { return to[name] = from[name].bind(bindTo); });\n\t}\n\texports.bindFunctions = bindFunctions;\n\t/**\n\t * prototypal inheritance helper.\n\t * Creates a new object which has `parent` object as its prototype, and then copies the properties from `extra` onto it\n\t */\n\texports.inherit = function (parent, extra) {\n\t    return exports.extend(new (exports.extend(function () { }, { prototype: parent }))(), extra);\n\t};\n\t/**\n\t * Given an arguments object, converts the arguments at index idx and above to an array.\n\t * This is similar to es6 rest parameters.\n\t *\n\t * Optionally, the argument at index idx may itself already be an array.\n\t *\n\t * For example,\n\t * given either:\n\t *        arguments = [ obj, \"foo\", \"bar\" ]\n\t * or:\n\t *        arguments = [ obj, [\"foo\", \"bar\"] ]\n\t * then:\n\t *        restArgs(arguments, 1) == [\"foo\", \"bar\"]\n\t *\n\t * This allows functions like pick() to be implemented such that it allows either a bunch\n\t * of string arguments (like es6 rest parameters), or a single array of strings:\n\t *\n\t * given:\n\t *        var obj = { foo: 1, bar: 2, baz: 3 };\n\t * then:\n\t *        pick(obj, \"foo\", \"bar\");   // returns { foo: 1, bar: 2 }\n\t *        pick(obj, [\"foo\", \"bar\"]); // returns { foo: 1, bar: 2 }\n\t */\n\tvar restArgs = function (args, idx) {\n\t    if (idx === void 0) { idx = 0; }\n\t    return Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(args, idx));\n\t};\n\t/** Given an array, returns true if the object is found in the array, (using indexOf) */\n\texports.inArray = function (array, obj) { return array.indexOf(obj) !== -1; };\n\t/** Given an array, and an item, if the item is found in the array, it removes it (in-place).  The same array is returned */\n\texports.removeFrom = hof_1.curry(function (array, obj) {\n\t    var idx = array.indexOf(obj);\n\t    if (idx >= 0)\n\t        array.splice(idx, 1);\n\t    return array;\n\t});\n\t/**\n\t * Applies a set of defaults to an options object.  The options object is filtered\n\t * to only those properties of the objects in the defaultsList.\n\t * Earlier objects in the defaultsList take precedence when applying defaults.\n\t */\n\tfunction defaults(opts) {\n\t    if (opts === void 0) { opts = {}; }\n\t    var defaultsList = [];\n\t    for (var _i = 1; _i < arguments.length; _i++) {\n\t        defaultsList[_i - 1] = arguments[_i];\n\t    }\n\t    var defaults = merge.apply(null, [{}].concat(defaultsList));\n\t    return exports.extend({}, defaults, pick(opts || {}, Object.keys(defaults)));\n\t}\n\texports.defaults = defaults;\n\t/**\n\t * Merges properties from the list of objects to the destination object.\n\t * If a property already exists in the destination object, then it is not overwritten.\n\t */\n\tfunction merge(dst) {\n\t    var objs = [];\n\t    for (var _i = 1; _i < arguments.length; _i++) {\n\t        objs[_i - 1] = arguments[_i];\n\t    }\n\t    exports.forEach(objs, function (obj) {\n\t        exports.forEach(obj, function (value, key) {\n\t            if (!dst.hasOwnProperty(key))\n\t                dst[key] = value;\n\t        });\n\t    });\n\t    return dst;\n\t}\n\texports.merge = merge;\n\t/** Reduce function that merges each element of the list into a single object, using extend */\n\texports.mergeR = function (memo, item) { return exports.extend(memo, item); };\n\t/**\n\t * Finds the common ancestor path between two states.\n\t *\n\t * @param {Object} first The first state.\n\t * @param {Object} second The second state.\n\t * @return {Array} Returns an array of state names in descending order, not including the root.\n\t */\n\tfunction ancestors(first, second) {\n\t    var path = [];\n\t    for (var n in first.path) {\n\t        if (first.path[n] !== second.path[n])\n\t            break;\n\t        path.push(first.path[n]);\n\t    }\n\t    return path;\n\t}\n\texports.ancestors = ancestors;\n\t/**\n\t * Performs a non-strict comparison of the subset of two objects, defined by a list of keys.\n\t *\n\t * @param {Object} a The first object.\n\t * @param {Object} b The second object.\n\t * @param {Array} keys The list of keys within each object to compare. If the list is empty or not specified,\n\t *                     it defaults to the list of keys in `a`.\n\t * @return {Boolean} Returns `true` if the keys match, otherwise `false`.\n\t */\n\tfunction equalForKeys(a, b, keys) {\n\t    if (keys === void 0) { keys = Object.keys(a); }\n\t    for (var i = 0; i < keys.length; i++) {\n\t        var k = keys[i];\n\t        if (a[k] != b[k])\n\t            return false; // Not '===', values aren't necessarily normalized\n\t    }\n\t    return true;\n\t}\n\texports.equalForKeys = equalForKeys;\n\tfunction pickOmitImpl(predicate, obj) {\n\t    var objCopy = {}, keys = restArgs(arguments, 2);\n\t    for (var key in obj) {\n\t        if (predicate(keys, key))\n\t            objCopy[key] = obj[key];\n\t    }\n\t    return objCopy;\n\t}\n\t/** Return a copy of the object only containing the whitelisted properties. */\n\tfunction pick(obj) { return pickOmitImpl.apply(null, [exports.inArray].concat(restArgs(arguments))); }\n\texports.pick = pick;\n\t/** Return a copy of the object omitting the blacklisted properties. */\n\tfunction omit(obj) { return pickOmitImpl.apply(null, [hof_1.not(exports.inArray)].concat(restArgs(arguments))); }\n\texports.omit = omit;\n\t/**\n\t * Maps an array, or object to a property (by name)\n\t */\n\tfunction pluck(collection, propName) {\n\t    return map(collection, hof_1.prop(propName));\n\t}\n\texports.pluck = pluck;\n\t/** Filters an Array or an Object's properties based on a predicate */\n\tfunction filter(collection, callback) {\n\t    var arr = predicates_1.isArray(collection), result = arr ? [] : {};\n\t    var accept = arr ? function (x) { return result.push(x); } : function (x, key) { return result[key] = x; };\n\t    exports.forEach(collection, function (item, i) {\n\t        if (callback(item, i))\n\t            accept(item, i);\n\t    });\n\t    return result;\n\t}\n\texports.filter = filter;\n\t/** Finds an object from an array, or a property of an object, that matches a predicate */\n\tfunction find(collection, callback) {\n\t    var result;\n\t    exports.forEach(collection, function (item, i) {\n\t        if (result)\n\t            return;\n\t        if (callback(item, i))\n\t            result = item;\n\t    });\n\t    return result;\n\t}\n\texports.find = find;\n\t/** Given an object, returns a new object, where each property is transformed by the callback function */\n\texports.mapObj = map;\n\t/** Maps an array or object properties using a callback function */\n\tfunction map(collection, callback) {\n\t    var result = predicates_1.isArray(collection) ? [] : {};\n\t    exports.forEach(collection, function (item, i) { return result[i] = callback(item, i); });\n\t    return result;\n\t}\n\texports.map = map;\n\t/**\n\t * Given an object, return its enumerable property values\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let foo = { a: 1, b: 2, c: 3 }\n\t * let vals = values(foo); // [ 1, 2, 3 ]\n\t * ```\n\t */\n\texports.values = function (obj) { return Object.keys(obj).map(function (key) { return obj[key]; }); };\n\t/**\n\t * Reduce function that returns true if all of the values are truthy.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let vals = [ 1, true, {}, \"hello world\"];\n\t * vals.reduce(allTrueR, true); // true\n\t *\n\t * vals.push(0);\n\t * vals.reduce(allTrueR, true); // false\n\t * ```\n\t */\n\texports.allTrueR = function (memo, elem) { return memo && elem; };\n\t/**\n\t * Reduce function that returns true if any of the values are truthy.\n\t *\n\t *  * @example\n\t * ```\n\t *\n\t * let vals = [ 0, null, undefined ];\n\t * vals.reduce(anyTrueR, true); // false\n\t *\n\t * vals.push(\"hello world\");\n\t * vals.reduce(anyTrueR, true); // true\n\t * ```\n\t */\n\texports.anyTrueR = function (memo, elem) { return memo || elem; };\n\t/**\n\t * Reduce function which un-nests a single level of arrays\n\t * @example\n\t * ```\n\t *\n\t * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n\t * input.reduce(unnestR, []) // [ \"a\", \"b\", \"c\", \"d\", [ \"double, \"nested\" ] ]\n\t * ```\n\t */\n\texports.unnestR = function (memo, elem) { return memo.concat(elem); };\n\t/**\n\t * Reduce function which recursively un-nests all arrays\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n\t * input.reduce(unnestR, []) // [ \"a\", \"b\", \"c\", \"d\", \"double, \"nested\" ]\n\t * ```\n\t */\n\texports.flattenR = function (memo, elem) { return predicates_1.isArray(elem) ? memo.concat(elem.reduce(exports.flattenR, [])) : pushR(memo, elem); };\n\t/** Reduce function that pushes an object to an array, then returns the array.  Mostly just for [[flattenR]] */\n\tfunction pushR(arr, obj) { arr.push(obj); return arr; }\n\texports.pushR = pushR;\n\t/** Reduce function that filters out duplicates */\n\texports.uniqR = function (acc, token) { return exports.inArray(acc, token) ? acc : pushR(acc, token); };\n\t/**\n\t * Return a new array with a single level of arrays unnested.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n\t * unnest(input) // [ \"a\", \"b\", \"c\", \"d\", [ \"double, \"nested\" ] ]\n\t * ```\n\t */\n\texports.unnest = function (arr) { return arr.reduce(exports.unnestR, []); };\n\t/**\n\t * Return a completely flattened version of an array.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n\t * flatten(input) // [ \"a\", \"b\", \"c\", \"d\", \"double, \"nested\" ]\n\t * ```\n\t */\n\texports.flatten = function (arr) { return arr.reduce(exports.flattenR, []); };\n\t/**\n\t * Given a .filter Predicate, builds a .filter Predicate which throws an error if any elements do not pass.\n\t * @example\n\t * ```\n\t *\n\t * let isNumber = (obj) => typeof(obj) === 'number';\n\t * let allNumbers = [ 1, 2, 3, 4, 5 ];\n\t * allNumbers.filter(assertPredicate(isNumber)); //OK\n\t *\n\t * let oneString = [ 1, 2, 3, 4, \"5\" ];\n\t * oneString.filter(assertPredicate(isNumber, \"Not all numbers\")); // throws Error(\"\"Not all numbers\"\");\n\t * ```\n\t */\n\tfunction assertPredicate(predicate, errMsg) {\n\t    if (errMsg === void 0) { errMsg = \"assert failure\"; }\n\t    return function (obj) {\n\t        if (!predicate(obj)) {\n\t            throw new Error(predicates_1.isFunction(errMsg) ? errMsg(obj) : errMsg);\n\t        }\n\t        return true;\n\t    };\n\t}\n\texports.assertPredicate = assertPredicate;\n\t/**\n\t * Like _.pairs: Given an object, returns an array of key/value pairs\n\t *\n\t * @example\n\t * ```\n\t *\n\t * pairs({ foo: \"FOO\", bar: \"BAR }) // [ [ \"foo\", \"FOO\" ], [ \"bar\": \"BAR\" ] ]\n\t * ```\n\t */\n\texports.pairs = function (object) { return Object.keys(object).map(function (key) { return [key, object[key]]; }); };\n\t/**\n\t * Given two or more parallel arrays, returns an array of tuples where\n\t * each tuple is composed of [ a[i], b[i], ... z[i] ]\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let foo = [ 0, 2, 4, 6 ];\n\t * let bar = [ 1, 3, 5, 7 ];\n\t * let baz = [ 10, 30, 50, 70 ];\n\t * arrayTuples(foo, bar);       // [ [0, 1], [2, 3], [4, 5], [6, 7] ]\n\t * arrayTuples(foo, bar, baz);  // [ [0, 1, 10], [2, 3, 30], [4, 5, 50], [6, 7, 70] ]\n\t * ```\n\t */\n\tfunction arrayTuples() {\n\t    var arrayArgs = [];\n\t    for (var _i = 0; _i < arguments.length; _i++) {\n\t        arrayArgs[_i - 0] = arguments[_i];\n\t    }\n\t    if (arrayArgs.length === 0)\n\t        return [];\n\t    var length = arrayArgs.reduce(function (min, arr) { return Math.min(arr.length, min); }, 9007199254740991); // aka 2^53 − 1 aka Number.MAX_SAFE_INTEGER\n\t    return Array.apply(null, Array(length)).map(function (ignored, idx) { return arrayArgs.map(function (arr) { return arr[idx]; }); });\n\t}\n\texports.arrayTuples = arrayTuples;\n\t/**\n\t * Reduce function which builds an object from an array of [key, value] pairs.\n\t *\n\t * Each iteration sets the key/val pair on the memo object, then returns the memo for the next iteration.\n\t *\n\t * Each keyValueTuple should be an array with values [ key: string, value: any ]\n\t *\n\t * @example\n\t * ```\n\t *\n\t * var pairs = [ [\"fookey\", \"fooval\"], [\"barkey\", \"barval\"] ]\n\t *\n\t * var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {})\n\t * // pairsToObj == { fookey: \"fooval\", barkey: \"barval\" }\n\t *\n\t * // Or, more simply:\n\t * var pairsToObj = pairs.reduce(applyPairs, {})\n\t * // pairsToObj == { fookey: \"fooval\", barkey: \"barval\" }\n\t * ```\n\t */\n\tfunction applyPairs(memo, keyValTuple) {\n\t    var key, value;\n\t    if (predicates_1.isArray(keyValTuple))\n\t        key = keyValTuple[0], value = keyValTuple[1];\n\t    if (!predicates_1.isString(key))\n\t        throw new Error(\"invalid parameters to applyPairs\");\n\t    memo[key] = value;\n\t    return memo;\n\t}\n\texports.applyPairs = applyPairs;\n\t/** Get the last element of an array */\n\tfunction tail(arr) {\n\t    return arr.length && arr[arr.length - 1] || undefined;\n\t}\n\texports.tail = tail;\n\t/**\n\t * shallow copy from src to dest\n\t *\n\t * note: This is a shallow copy, while angular.copy is a deep copy.\n\t * ui-router uses `copy` only to make copies of state parameters.\n\t */\n\tfunction _copy(src, dest) {\n\t    if (dest)\n\t        Object.keys(dest).forEach(function (key) { return delete dest[key]; });\n\t    if (!dest)\n\t        dest = {};\n\t    return exports.extend(dest, src);\n\t}\n\tfunction _forEach(obj, cb, _this) {\n\t    if (predicates_1.isArray(obj))\n\t        return obj.forEach(cb, _this);\n\t    Object.keys(obj).forEach(function (key) { return cb(obj[key], key); });\n\t}\n\tfunction _copyProps(to, from) { Object.keys(from).forEach(function (key) { return to[key] = from[key]; }); return to; }\n\tfunction _extend(toObj, rest) {\n\t    return restArgs(arguments, 1).filter(exports.identity).reduce(_copyProps, toObj);\n\t}\n\tfunction _equals(o1, o2) {\n\t    if (o1 === o2)\n\t        return true;\n\t    if (o1 === null || o2 === null)\n\t        return false;\n\t    if (o1 !== o1 && o2 !== o2)\n\t        return true; // NaN === NaN\n\t    var t1 = typeof o1, t2 = typeof o2;\n\t    if (t1 !== t2 || t1 !== 'object')\n\t        return false;\n\t    var tup = [o1, o2];\n\t    if (hof_1.all(predicates_1.isArray)(tup))\n\t        return _arraysEq(o1, o2);\n\t    if (hof_1.all(predicates_1.isDate)(tup))\n\t        return o1.getTime() === o2.getTime();\n\t    if (hof_1.all(predicates_1.isRegExp)(tup))\n\t        return o1.toString() === o2.toString();\n\t    if (hof_1.all(predicates_1.isFunction)(tup))\n\t        return true; // meh\n\t    var predicates = [predicates_1.isFunction, predicates_1.isArray, predicates_1.isDate, predicates_1.isRegExp];\n\t    if (predicates.map(hof_1.any).reduce(function (b, fn) { return b || !!fn(tup); }, false))\n\t        return false;\n\t    var key, keys = {};\n\t    for (key in o1) {\n\t        if (!_equals(o1[key], o2[key]))\n\t            return false;\n\t        keys[key] = true;\n\t    }\n\t    for (key in o2) {\n\t        if (!keys[key])\n\t            return false;\n\t    }\n\t    return true;\n\t}\n\tfunction _arraysEq(a1, a2) {\n\t    if (a1.length !== a2.length)\n\t        return false;\n\t    return arrayTuples(a1, a2).reduce(function (b, t) { return b && _equals(t[0], t[1]); }, true);\n\t}\n\t// issue #2676\n\texports.silenceUncaughtInPromise = function (promise) {\n\t    return promise.catch(function (e) { return 0; }) && promise;\n\t};\n\texports.silentRejection = function (error) {\n\t    return exports.silenceUncaughtInPromise(coreservices_1.services.$q.reject(error));\n\t};\n\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** Predicates @module common_predicates */ /** */\n\tvar hof_1 = __webpack_require__(5);\n\tvar toStr = Object.prototype.toString;\n\tvar tis = function (t) { return function (x) { return typeof (x) === t; }; };\n\texports.isUndefined = tis('undefined');\n\texports.isDefined = hof_1.not(exports.isUndefined);\n\texports.isNull = function (o) { return o === null; };\n\texports.isFunction = tis('function');\n\texports.isNumber = tis('number');\n\texports.isString = tis('string');\n\texports.isObject = function (x) { return x !== null && typeof x === 'object'; };\n\texports.isArray = Array.isArray;\n\texports.isDate = (function (x) { return toStr.call(x) === '[object Date]'; });\n\texports.isRegExp = (function (x) { return toStr.call(x) === '[object RegExp]'; });\n\t/**\n\t * Predicate which checks if a value is injectable\n\t *\n\t * A value is \"injectable\" if it is a function, or if it is an ng1 array-notation-style array\n\t * where all the elements in the array are Strings, except the last one, which is a Function\n\t */\n\tfunction isInjectable(val) {\n\t    if (exports.isArray(val) && val.length) {\n\t        var head = val.slice(0, -1), tail = val.slice(-1);\n\t        return !(head.filter(hof_1.not(exports.isString)).length || tail.filter(hof_1.not(exports.isFunction)).length);\n\t    }\n\t    return exports.isFunction(val);\n\t}\n\texports.isInjectable = isInjectable;\n\t/**\n\t * Predicate which checks if a value looks like a Promise\n\t *\n\t * It is probably a Promise if it's an object, and it has a `then` property which is a Function\n\t */\n\texports.isPromise = hof_1.and(exports.isObject, hof_1.pipe(hof_1.prop('then'), exports.isFunction));\n\n\n/***/ },\n/* 5 */\n/***/ function(module, exports) {\n\n\t/**\n\t * Higher order functions\n\t *\n\t * @module common_hof\n\t */ /** */\n\t\"use strict\";\n\t/**\n\t * Returns a new function for [Partial Application](https://en.wikipedia.org/wiki/Partial_application) of the original function.\n\t *\n\t * Given a function with N parameters, returns a new function that supports partial application.\n\t * The new function accepts anywhere from 1 to N parameters.  When that function is called with M parameters,\n\t * where M is less than N, it returns a new function that accepts the remaining parameters.  It continues to\n\t * accept more parameters until all N parameters have been supplied.\n\t *\n\t *\n\t * This contrived example uses a partially applied function as an predicate, which returns true\n\t * if an object is found in both arrays.\n\t * @example\n\t * ```\n\t * // returns true if an object is in both of the two arrays\n\t * function inBoth(array1, array2, object) {\n\t *   return array1.indexOf(object) !== -1 &&\n\t *          array2.indexOf(object) !== 1;\n\t * }\n\t * let obj1, obj2, obj3, obj4, obj5, obj6, obj7\n\t * let foos = [obj1, obj3]\n\t * let bars = [obj3, obj4, obj5]\n\t *\n\t * // A curried \"copy\" of inBoth\n\t * let curriedInBoth = curry(inBoth);\n\t * // Partially apply both the array1 and array2\n\t * let inFoosAndBars = curriedInBoth(foos, bars);\n\t *\n\t * // Supply the final argument; since all arguments are\n\t * // supplied, the original inBoth function is then called.\n\t * let obj1InBoth = inFoosAndBars(obj1); // false\n\t *\n\t * // Use the inFoosAndBars as a predicate.\n\t * // Filter, on each iteration, supplies the final argument\n\t * let allObjs = [ obj1, obj2, obj3, obj4, obj5, obj6, obj7 ];\n\t * let foundInBoth = allObjs.filter(inFoosAndBars); // [ obj3 ]\n\t *\n\t * ```\n\t *\n\t * Stolen from: http://stackoverflow.com/questions/4394747/javascript-curry-function\n\t *\n\t * @param fn\n\t * @returns {*|function(): (*|any)}\n\t */\n\tfunction curry(fn) {\n\t    var initial_args = [].slice.apply(arguments, [1]);\n\t    var func_args_length = fn.length;\n\t    function curried(args) {\n\t        if (args.length >= func_args_length)\n\t            return fn.apply(null, args);\n\t        return function () {\n\t            return curried(args.concat([].slice.apply(arguments)));\n\t        };\n\t    }\n\t    return curried(initial_args);\n\t}\n\texports.curry = curry;\n\t/**\n\t * Given a varargs list of functions, returns a function that composes the argument functions, right-to-left\n\t * given: f(x), g(x), h(x)\n\t * let composed = compose(f,g,h)\n\t * then, composed is: f(g(h(x)))\n\t */\n\tfunction compose() {\n\t    var args = arguments;\n\t    var start = args.length - 1;\n\t    return function () {\n\t        var i = start, result = args[start].apply(this, arguments);\n\t        while (i--)\n\t            result = args[i].call(this, result);\n\t        return result;\n\t    };\n\t}\n\texports.compose = compose;\n\t/**\n\t * Given a varargs list of functions, returns a function that is composes the argument functions, left-to-right\n\t * given: f(x), g(x), h(x)\n\t * let piped = pipe(f,g,h);\n\t * then, piped is: h(g(f(x)))\n\t */\n\tfunction pipe() {\n\t    var funcs = [];\n\t    for (var _i = 0; _i < arguments.length; _i++) {\n\t        funcs[_i - 0] = arguments[_i];\n\t    }\n\t    return compose.apply(null, [].slice.call(arguments).reverse());\n\t}\n\texports.pipe = pipe;\n\t/**\n\t * Given a property name, returns a function that returns that property from an object\n\t * let obj = { foo: 1, name: \"blarg\" };\n\t * let getName = prop(\"name\");\n\t * getName(obj) === \"blarg\"\n\t */\n\texports.prop = function (name) { return function (obj) { return obj && obj[name]; }; };\n\t/**\n\t * Given a property name and a value, returns a function that returns a boolean based on whether\n\t * the passed object has a property that matches the value\n\t * let obj = { foo: 1, name: \"blarg\" };\n\t * let getName = propEq(\"name\", \"blarg\");\n\t * getName(obj) === true\n\t */\n\texports.propEq = curry(function (name, val, obj) { return obj && obj[name] === val; });\n\t/**\n\t * Given a dotted property name, returns a function that returns a nested property from an object, or undefined\n\t * let obj = { id: 1, nestedObj: { foo: 1, name: \"blarg\" }, };\n\t * let getName = prop(\"nestedObj.name\");\n\t * getName(obj) === \"blarg\"\n\t * let propNotFound = prop(\"this.property.doesnt.exist\");\n\t * propNotFound(obj) === undefined\n\t */\n\texports.parse = function (name) { return pipe.apply(null, name.split(\".\").map(exports.prop)); };\n\t/**\n\t * Given a function that returns a truthy or falsey value, returns a\n\t * function that returns the opposite (falsey or truthy) value given the same inputs\n\t */\n\texports.not = function (fn) { return function () {\n\t    var args = [];\n\t    for (var _i = 0; _i < arguments.length; _i++) {\n\t        args[_i - 0] = arguments[_i];\n\t    }\n\t    return !fn.apply(null, args);\n\t}; };\n\t/**\n\t * Given two functions that return truthy or falsey values, returns a function that returns truthy\n\t * if both functions return truthy for the given arguments\n\t */\n\tfunction and(fn1, fn2) {\n\t    return function () {\n\t        var args = [];\n\t        for (var _i = 0; _i < arguments.length; _i++) {\n\t            args[_i - 0] = arguments[_i];\n\t        }\n\t        return fn1.apply(null, args) && fn2.apply(null, args);\n\t    };\n\t}\n\texports.and = and;\n\t/**\n\t * Given two functions that return truthy or falsey values, returns a function that returns truthy\n\t * if at least one of the functions returns truthy for the given arguments\n\t */\n\tfunction or(fn1, fn2) {\n\t    return function () {\n\t        var args = [];\n\t        for (var _i = 0; _i < arguments.length; _i++) {\n\t            args[_i - 0] = arguments[_i];\n\t        }\n\t        return fn1.apply(null, args) || fn2.apply(null, args);\n\t    };\n\t}\n\texports.or = or;\n\t/**\n\t * Check if all the elements of an array match a predicate function\n\t *\n\t * @param fn1 a predicate function `fn1`\n\t * @returns a function which takes an array and returns true if `fn1` is true for all elements of the array\n\t */\n\texports.all = function (fn1) { return function (arr) { return arr.reduce(function (b, x) { return b && !!fn1(x); }, true); }; };\n\texports.any = function (fn1) { return function (arr) { return arr.reduce(function (b, x) { return b || !!fn1(x); }, false); }; };\n\texports.none = exports.not(exports.any);\n\t/** Given a class, returns a Predicate function that returns true if the object is of that class */\n\texports.is = function (ctor) { return function (obj) { return (obj != null && obj.constructor === ctor || obj instanceof ctor); }; };\n\t/** Given a value, returns a Predicate function that returns true if another value is === equal to the original value */\n\texports.eq = function (val) { return function (other) { return val === other; }; };\n\t/** Given a value, returns a function which returns the value */\n\texports.val = function (v) { return function () { return v; }; };\n\tfunction invoke(fnName, args) {\n\t    return function (obj) { return obj[fnName].apply(obj, args); };\n\t}\n\texports.invoke = invoke;\n\t/**\n\t * Sorta like Pattern Matching (a functional programming conditional construct)\n\t *\n\t * See http://c2.com/cgi/wiki?PatternMatching\n\t *\n\t * This is a conditional construct which allows a series of predicates and output functions\n\t * to be checked and then applied.  Each predicate receives the input.  If the predicate\n\t * returns truthy, then its matching output function (mapping function) is provided with\n\t * the input and, then the result is returned.\n\t *\n\t * Each combination (2-tuple) of predicate + output function should be placed in an array\n\t * of size 2: [ predicate, mapFn ]\n\t *\n\t * These 2-tuples should be put in an outer array.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * // Here's a 2-tuple where the first element is the isString predicate\n\t * // and the second element is a function that returns a description of the input\n\t * let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];\n\t *\n\t * // Second tuple: predicate \"isNumber\", mapfn returns a description\n\t * let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];\n\t *\n\t * let third = [ (input) => input === null,  (input) => `Oh, null...` ];\n\t *\n\t * let fourth = [ (input) => input === undefined,  (input) => `notdefined` ];\n\t *\n\t * let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);\n\t *\n\t * console.log(descriptionOf(undefined)); // 'notdefined'\n\t * console.log(descriptionOf(55)); // '(55) That's a number!'\n\t * console.log(descriptionOf(\"foo\")); // 'Here's your string foo'\n\t * ```\n\t *\n\t * @param struct A 2D array.  Each element of the array should be an array, a 2-tuple,\n\t * with a Predicate and a mapping/output function\n\t * @returns {function(any): *}\n\t */\n\tfunction pattern(struct) {\n\t    return function (x) {\n\t        for (var i = 0; i < struct.length; i++) {\n\t            if (struct[i][0](x))\n\t                return struct[i][1](x);\n\t        }\n\t    };\n\t}\n\texports.pattern = pattern;\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports) {\n\n\t/**\n\t * This module is a stub for core services such as Dependency Injection or Browser Location.\n\t * Core services may be implemented by a specific framework, such as ng1 or ng2, or be pure javascript.\n\t *\n\t * @module common\n\t */\n\t\"use strict\";\n\t/** for typedoc */\n\t//import {IQService} from \"angular\";\n\t//import {IInjectorService} from \"angular\";\n\tvar notImplemented = function (fnname) { return function () {\n\t    throw new Error(fnname + \"(): No coreservices implementation for UI-Router is loaded. You should include one of: ['angular1.js']\");\n\t}; };\n\tvar services = {\n\t    $q: undefined,\n\t    $injector: undefined,\n\t    location: {},\n\t    locationConfig: {},\n\t    template: {}\n\t};\n\texports.services = services;\n\t[\"replace\", \"url\", \"path\", \"search\", \"hash\", \"onChange\"]\n\t    .forEach(function (key) { return services.location[key] = notImplemented(key); });\n\t[\"port\", \"protocol\", \"host\", \"baseHref\", \"html5Mode\", \"hashPrefix\"]\n\t    .forEach(function (key) { return services.locationConfig[key] = notImplemented(key); });\n\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t/** @module common */\n\t/**\n\t * Matches state names using glob-like patterns.\n\t *\n\t * See: [[StateService.includes]]\n\t */\n\tvar Glob = (function () {\n\t    function Glob(text) {\n\t        this.text = text;\n\t        this.glob = text.split('.');\n\t    }\n\t    Glob.prototype.matches = function (name) {\n\t        var segments = name.split('.');\n\t        // match single stars\n\t        for (var i = 0, l = this.glob.length; i < l; i++) {\n\t            if (this.glob[i] === '*')\n\t                segments[i] = '*';\n\t        }\n\t        // match greedy starts\n\t        if (this.glob[0] === '**') {\n\t            segments = segments.slice(segments.indexOf(this.glob[1]));\n\t            segments.unshift('**');\n\t        }\n\t        // match greedy ends\n\t        if (this.glob[this.glob.length - 1] === '**') {\n\t            segments.splice(segments.indexOf(this.glob[this.glob.length - 2]) + 1, Number.MAX_VALUE);\n\t            segments.push('**');\n\t        }\n\t        if (this.glob.length != segments.length)\n\t            return false;\n\t        return segments.join('') === this.glob.join('');\n\t    };\n\t    Glob.is = function (text) {\n\t        return text.indexOf('*') > -1;\n\t    };\n\t    Glob.fromString = function (text) {\n\t        if (!this.is(text))\n\t            return null;\n\t        return new Glob(text);\n\t    };\n\t    return Glob;\n\t}());\n\texports.Glob = Glob;\n\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\t/** @module common */ /** for typedoc */\n\t\"use strict\";\n\tvar Queue = (function () {\n\t    function Queue(_items, _limit) {\n\t        if (_items === void 0) { _items = []; }\n\t        if (_limit === void 0) { _limit = null; }\n\t        this._items = _items;\n\t        this._limit = _limit;\n\t    }\n\t    Queue.prototype.enqueue = function (item) {\n\t        var items = this._items;\n\t        items.push(item);\n\t        if (this._limit && items.length > this._limit)\n\t            items.shift();\n\t        return item;\n\t    };\n\t    Queue.prototype.dequeue = function () {\n\t        if (this.size())\n\t            return this._items.splice(0, 1)[0];\n\t    };\n\t    Queue.prototype.clear = function () {\n\t        var current = this._items;\n\t        this._items = [];\n\t        return current;\n\t    };\n\t    Queue.prototype.size = function () {\n\t        return this._items.length;\n\t    };\n\t    Queue.prototype.remove = function (item) {\n\t        var idx = this._items.indexOf(item);\n\t        return idx > -1 && this._items.splice(idx, 1)[0];\n\t    };\n\t    Queue.prototype.peekTail = function () {\n\t        return this._items[this._items.length - 1];\n\t    };\n\t    Queue.prototype.peekHead = function () {\n\t        if (this.size())\n\t            return this._items[0];\n\t    };\n\t    return Queue;\n\t}());\n\texports.Queue = Queue;\n\n\n/***/ },\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module common_strings */ /** */\n\t\"use strict\";\n\tvar predicates_1 = __webpack_require__(4);\n\tvar rejectFactory_1 = __webpack_require__(10);\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar transition_1 = __webpack_require__(11);\n\tvar resolvable_1 = __webpack_require__(19);\n\t/**\n\t * Returns a string shortened to a maximum length\n\t *\n\t * If the string is already less than the `max` length, return the string.\n\t * Else return the string, shortened to `max - 3` and append three dots (\"...\").\n\t *\n\t * @param max the maximum length of the string to return\n\t * @param str the input string\n\t */\n\tfunction maxLength(max, str) {\n\t    if (str.length <= max)\n\t        return str;\n\t    return str.substr(0, max - 3) + \"...\";\n\t}\n\texports.maxLength = maxLength;\n\t/**\n\t * Returns a string, with spaces added to the end, up to a desired str length\n\t *\n\t * If the string is already longer than the desired length, return the string.\n\t * Else returns the string, with extra spaces on the end, such that it reaches `length` characters.\n\t *\n\t * @param length the desired length of the string to return\n\t * @param str the input string\n\t */\n\tfunction padString(length, str) {\n\t    while (str.length < length)\n\t        str += \" \";\n\t    return str;\n\t}\n\texports.padString = padString;\n\tfunction kebobString(camelCase) {\n\t    return camelCase\n\t        .replace(/^([A-Z])/, function ($1) { return $1.toLowerCase(); }) // replace first char\n\t        .replace(/([A-Z])/g, function ($1) { return \"-\" + $1.toLowerCase(); }); // replace rest\n\t}\n\texports.kebobString = kebobString;\n\tfunction _toJson(obj) {\n\t    return JSON.stringify(obj);\n\t}\n\tfunction _fromJson(json) {\n\t    return predicates_1.isString(json) ? JSON.parse(json) : json;\n\t}\n\tfunction promiseToString(p) {\n\t    return \"Promise(\" + JSON.stringify(p) + \")\";\n\t}\n\tfunction functionToString(fn) {\n\t    var fnStr = fnToString(fn);\n\t    var namedFunctionMatch = fnStr.match(/^(function [^ ]+\\([^)]*\\))/);\n\t    return namedFunctionMatch ? namedFunctionMatch[1] : fnStr;\n\t}\n\texports.functionToString = functionToString;\n\tfunction fnToString(fn) {\n\t    var _fn = predicates_1.isArray(fn) ? fn.slice(-1)[0] : fn;\n\t    return _fn && _fn.toString() || \"undefined\";\n\t}\n\texports.fnToString = fnToString;\n\tvar stringifyPatternFn = null;\n\tvar stringifyPattern = function (value) {\n\t    var isTransitionRejectionPromise = rejectFactory_1.Rejection.isTransitionRejectionPromise;\n\t    stringifyPatternFn = stringifyPatternFn || hof_1.pattern([\n\t        [hof_1.not(predicates_1.isDefined), hof_1.val(\"undefined\")],\n\t        [predicates_1.isNull, hof_1.val(\"null\")],\n\t        [predicates_1.isPromise, hof_1.val(\"[Promise]\")],\n\t        [isTransitionRejectionPromise, function (x) { return x._transitionRejection.toString(); }],\n\t        [hof_1.is(rejectFactory_1.Rejection), hof_1.invoke(\"toString\")],\n\t        [hof_1.is(transition_1.Transition), hof_1.invoke(\"toString\")],\n\t        [hof_1.is(resolvable_1.Resolvable), hof_1.invoke(\"toString\")],\n\t        [predicates_1.isInjectable, functionToString],\n\t        [hof_1.val(true), common_1.identity]\n\t    ]);\n\t    return stringifyPatternFn(value);\n\t};\n\tfunction stringify(o) {\n\t    var seen = [];\n\t    function format(val) {\n\t        if (predicates_1.isObject(val)) {\n\t            if (seen.indexOf(val) !== -1)\n\t                return '[circular ref]';\n\t            seen.push(val);\n\t        }\n\t        return stringifyPattern(val);\n\t    }\n\t    return JSON.stringify(o, function (key, val) { return format(val); }).replace(/\\\\\"/g, '\"');\n\t}\n\texports.stringify = stringify;\n\t/** Returns a function that splits a string on a character or substring */\n\texports.beforeAfterSubstr = function (char) { return function (str) {\n\t    if (!str)\n\t        return [\"\", \"\"];\n\t    var idx = str.indexOf(char);\n\t    if (idx === -1)\n\t        return [str, \"\"];\n\t    return [str.substr(0, idx), str.substr(idx + 1)];\n\t}; };\n\n\n/***/ },\n/* 10 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module transition */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar strings_1 = __webpack_require__(9);\n\t(function (RejectType) {\n\t    RejectType[RejectType[\"SUPERSEDED\"] = 2] = \"SUPERSEDED\";\n\t    RejectType[RejectType[\"ABORTED\"] = 3] = \"ABORTED\";\n\t    RejectType[RejectType[\"INVALID\"] = 4] = \"INVALID\";\n\t    RejectType[RejectType[\"IGNORED\"] = 5] = \"IGNORED\";\n\t    RejectType[RejectType[\"ERROR\"] = 6] = \"ERROR\";\n\t})(exports.RejectType || (exports.RejectType = {}));\n\tvar RejectType = exports.RejectType;\n\tvar Rejection = (function () {\n\t    function Rejection(type, message, detail) {\n\t        this.type = type;\n\t        this.message = message;\n\t        this.detail = detail;\n\t    }\n\t    Rejection.prototype.toString = function () {\n\t        var detailString = function (d) { return d && d.toString !== Object.prototype.toString ? d.toString() : strings_1.stringify(d); };\n\t        var type = this.type, message = this.message, detail = detailString(this.detail);\n\t        return \"TransitionRejection(type: \" + type + \", message: \" + message + \", detail: \" + detail + \")\";\n\t    };\n\t    Rejection.prototype.toPromise = function () {\n\t        return common_1.extend(common_1.silentRejection(this), { _transitionRejection: this });\n\t    };\n\t    /** Returns true if the obj is a rejected promise created from the `asPromise` factory */\n\t    Rejection.isTransitionRejectionPromise = function (obj) {\n\t        return obj && (typeof obj.then === 'function') && obj._transitionRejection instanceof Rejection;\n\t    };\n\t    /** Returns a TransitionRejection due to transition superseded */\n\t    Rejection.superseded = function (detail, options) {\n\t        var message = \"The transition has been superseded by a different transition (see detail).\";\n\t        var rejection = new Rejection(RejectType.SUPERSEDED, message, detail);\n\t        if (options && options.redirected) {\n\t            rejection.redirected = true;\n\t        }\n\t        return rejection;\n\t    };\n\t    /** Returns a TransitionRejection due to redirected transition */\n\t    Rejection.redirected = function (detail) {\n\t        return Rejection.superseded(detail, { redirected: true });\n\t    };\n\t    /** Returns a TransitionRejection due to invalid transition */\n\t    Rejection.invalid = function (detail) {\n\t        var message = \"This transition is invalid (see detail)\";\n\t        return new Rejection(RejectType.INVALID, message, detail);\n\t    };\n\t    /** Returns a TransitionRejection due to ignored transition */\n\t    Rejection.ignored = function (detail) {\n\t        var message = \"The transition was ignored.\";\n\t        return new Rejection(RejectType.IGNORED, message, detail);\n\t    };\n\t    /** Returns a TransitionRejection due to aborted transition */\n\t    Rejection.aborted = function (detail) {\n\t        // TODO think about how to encapsulate an Error() object\n\t        var message = \"The transition has been aborted.\";\n\t        return new Rejection(RejectType.ABORTED, message, detail);\n\t    };\n\t    /** Returns a TransitionRejection due to aborted transition */\n\t    Rejection.errored = function (detail) {\n\t        // TODO think about how to encapsulate an Error() object\n\t        var message = \"The transition errored.\";\n\t        return new Rejection(RejectType.ERROR, message, detail);\n\t    };\n\t    return Rejection;\n\t}());\n\texports.Rejection = Rejection;\n\n\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module transition */ /** for typedoc */\n\tvar trace_1 = __webpack_require__(12);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\tvar transitionHook_1 = __webpack_require__(13);\n\tvar hookRegistry_1 = __webpack_require__(15);\n\tvar hookBuilder_1 = __webpack_require__(16);\n\tvar node_1 = __webpack_require__(21);\n\tvar pathFactory_1 = __webpack_require__(20);\n\tvar targetState_1 = __webpack_require__(14);\n\tvar param_1 = __webpack_require__(22);\n\tvar resolvable_1 = __webpack_require__(19);\n\tvar rejectFactory_1 = __webpack_require__(10);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar router_1 = __webpack_require__(26);\n\tvar transitionCount = 0;\n\tvar stateSelf = hof_1.prop(\"self\");\n\t/**\n\t * Represents a transition between two states.\n\t *\n\t * When navigating to a state, we are transitioning **from** the current state **to** the new state.\n\t *\n\t * This object contains all contextual information about the to/from states, parameters, resolves.\n\t * It has information about all states being entered and exited as a result of the transition.\n\t */\n\tvar Transition = (function () {\n\t    /**\n\t     * Creates a new Transition object.\n\t     *\n\t     * If the target state is not valid, an error is thrown.\n\t     *\n\t     * @param fromPath The path of [[PathNode]]s from which the transition is leaving.  The last node in the `fromPath`\n\t     *        encapsulates the \"from state\".\n\t     * @param targetState The target state and parameters being transitioned to (also, the transition options)\n\t     * @param router The [[UIRouter]] instance\n\t     */\n\t    function Transition(fromPath, targetState, router) {\n\t        var _this = this;\n\t        /** @hidden */\n\t        this._deferred = coreservices_1.services.$q.defer();\n\t        /**\n\t         * This promise is resolved or rejected based on the outcome of the Transition.\n\t         *\n\t         * When the transition is successful, the promise is resolved\n\t         * When the transition is unsuccessful, the promise is rejected with the [[TransitionRejection]] or javascript error\n\t         */\n\t        this.promise = this._deferred.promise;\n\t        this.treeChanges = function () { return _this._treeChanges; };\n\t        this.isActive = function () { return _this === _this._options.current(); };\n\t        this.router = router;\n\t        if (!targetState.valid()) {\n\t            throw new Error(targetState.error());\n\t        }\n\t        // Makes the Transition instance a hook registry (onStart, etc)\n\t        hookRegistry_1.HookRegistry.mixin(new hookRegistry_1.HookRegistry(), this);\n\t        // current() is assumed to come from targetState.options, but provide a naive implementation otherwise.\n\t        this._options = common_1.extend({ current: hof_1.val(this) }, targetState.options());\n\t        this.$id = transitionCount++;\n\t        var toPath = pathFactory_1.PathFactory.buildToPath(fromPath, targetState);\n\t        this._treeChanges = pathFactory_1.PathFactory.treeChanges(fromPath, toPath, this._options.reloadState);\n\t        var enteringStates = this._treeChanges.entering.map(function (node) { return node.state; });\n\t        pathFactory_1.PathFactory.applyViewConfigs(router.transitionService.$view, this._treeChanges.to, enteringStates);\n\t        var rootResolvables = [\n\t            new resolvable_1.Resolvable(router_1.UIRouter, function () { return router; }, [], undefined, router),\n\t            new resolvable_1.Resolvable(Transition, function () { return _this; }, [], undefined, this),\n\t            new resolvable_1.Resolvable('$transition$', function () { return _this; }, [], undefined, this),\n\t            new resolvable_1.Resolvable('$stateParams', function () { return _this.params(); }, [], undefined, this.params())\n\t        ];\n\t        var rootNode = this._treeChanges.to[0];\n\t        var context = new resolveContext_1.ResolveContext(this._treeChanges.to);\n\t        context.addResolvables(rootResolvables, rootNode.state);\n\t    }\n\t    /** @inheritdoc */\n\t    Transition.prototype.onBefore = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onStart = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onExit = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onRetain = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onEnter = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onFinish = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onSuccess = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onError = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    Transition.prototype.$from = function () {\n\t        return common_1.tail(this._treeChanges.from).state;\n\t    };\n\t    Transition.prototype.$to = function () {\n\t        return common_1.tail(this._treeChanges.to).state;\n\t    };\n\t    /**\n\t     * Returns the \"from state\"\n\t     *\n\t     * @returns The state object for the Transition's \"from state\".\n\t     */\n\t    Transition.prototype.from = function () {\n\t        return this.$from().self;\n\t    };\n\t    /**\n\t     * Returns the \"to state\"\n\t     *\n\t     * @returns The state object for the Transition's target state (\"to state\").\n\t     */\n\t    Transition.prototype.to = function () {\n\t        return this.$to().self;\n\t    };\n\t    /**\n\t     * Determines whether two transitions are equivalent.\n\t     */\n\t    Transition.prototype.is = function (compare) {\n\t        if (compare instanceof Transition) {\n\t            // TODO: Also compare parameters\n\t            return this.is({ to: compare.$to().name, from: compare.$from().name });\n\t        }\n\t        return !((compare.to && !hookRegistry_1.matchState(this.$to(), compare.to)) ||\n\t            (compare.from && !hookRegistry_1.matchState(this.$from(), compare.from)));\n\t    };\n\t    /**\n\t     * Gets transition parameter values\n\t     *\n\t     * @param pathname Pick which treeChanges path to get parameters for:\n\t     *   (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)\n\t     * @returns transition parameter values for the desired path.\n\t     */\n\t    Transition.prototype.params = function (pathname) {\n\t        if (pathname === void 0) { pathname = \"to\"; }\n\t        return this._treeChanges[pathname].map(hof_1.prop(\"paramValues\")).reduce(common_1.mergeR, {});\n\t    };\n\t    /**\n\t     * Creates a [[UIInjector]] Dependency Injector\n\t     *\n\t     * Returns a Dependency Injector for the Transition's target state (to state).\n\t     * The injector provides resolve values which the target state has access to.\n\t     *\n\t     * The `UIInjector` can also provide values from the native root/global injector (ng1/ng2).\n\t     *\n\t     * If a `state` is provided, the injector that is returned will be limited to resolve values that the provided state has access to.\n\t     *\n\t     * @param state Limits the resolves provided to only the resolves the provided state has access to.\n\t     * @returns a [[UIInjector]]\n\t     */\n\t    Transition.prototype.injector = function (state) {\n\t        var path = this.treeChanges().to;\n\t        if (state)\n\t            path = pathFactory_1.PathFactory.subPath(path, function (node) { return node.state === state || node.state.name === state; });\n\t        return new resolveContext_1.ResolveContext(path).injector();\n\t    };\n\t    /**\n\t     * Gets all available resolve tokens (keys)\n\t     *\n\t     * This method can be used in conjunction with [[getResolve]] to inspect the resolve values\n\t     * available to the Transition.\n\t     *\n\t     * The returned tokens include those defined on [[StateDeclaration.resolve]] blocks, for the states\n\t     * in the Transition's [[TreeChanges.to]] path.\n\t     *\n\t     * @returns an array of resolve tokens (keys)\n\t     */\n\t    Transition.prototype.getResolveTokens = function () {\n\t        return new resolveContext_1.ResolveContext(this._treeChanges.to).getTokens();\n\t    };\n\t    /**\n\t     * Gets resolved values\n\t     *\n\t     * This method can be used in conjunction with [[getResolveTokens]] to inspect what resolve values\n\t     * are available to the Transition.\n\t     *\n\t     * Given a token, returns the resolved data for that token.\n\t     * Given an array of tokens, returns an array of resolved data for those tokens.\n\t     *\n\t     * If a resolvable hasn't yet been fetched, returns `undefined` for that token\n\t     * If a resolvable doesn't exist for the token, throws an error.\n\t     *\n\t     * @param token the token (or array of tokens)\n\t     *\n\t     * @returns an array of resolve tokens (keys)\n\t     */\n\t    Transition.prototype.getResolveValue = function (token) {\n\t        var resolveContext = new resolveContext_1.ResolveContext(this._treeChanges.to);\n\t        var getData = function (token) {\n\t            var resolvable = resolveContext.getResolvable(token);\n\t            if (resolvable === undefined) {\n\t                throw new Error(\"Dependency Injection token not found: ${stringify(token)}\");\n\t            }\n\t            return resolvable.data;\n\t        };\n\t        if (predicates_1.isArray(token)) {\n\t            return token.map(getData);\n\t        }\n\t        return getData(token);\n\t    };\n\t    /**\n\t     * Dynamically adds a new [[Resolvable]] (`resolve`) to this transition.\n\t     *\n\t     * @param resolvable an [[Resolvable]] object\n\t     * @param state the state in the \"to path\" which should receive the new resolve (otherwise, the root state)\n\t     */\n\t    Transition.prototype.addResolvable = function (resolvable, state) {\n\t        if (state === void 0) { state = \"\"; }\n\t        var stateName = (typeof state === \"string\") ? state : state.name;\n\t        var topath = this._treeChanges.to;\n\t        var targetNode = common_1.find(topath, function (node) { return node.state.name === stateName; });\n\t        var resolveContext = new resolveContext_1.ResolveContext(topath);\n\t        resolveContext.addResolvables([resolvable], targetNode.state);\n\t    };\n\t    /**\n\t     * Gets the previous transition, from which this transition was redirected.\n\t     *\n\t     * @returns The previous Transition, or null if this Transition is not the result of a redirection\n\t     */\n\t    Transition.prototype.previous = function () {\n\t        return this._options.previous || null;\n\t    };\n\t    /**\n\t     * Get the transition options\n\t     *\n\t     * @returns the options for this Transition.\n\t     */\n\t    Transition.prototype.options = function () {\n\t        return this._options;\n\t    };\n\t    /**\n\t     * Gets the states being entered.\n\t     *\n\t     * @returns an array of states that will be entered during this transition.\n\t     */\n\t    Transition.prototype.entering = function () {\n\t        return common_1.map(this._treeChanges.entering, hof_1.prop('state')).map(stateSelf);\n\t    };\n\t    /**\n\t     * Gets the states being exited.\n\t     *\n\t     * @returns an array of states that will be exited during this transition.\n\t     */\n\t    Transition.prototype.exiting = function () {\n\t        return common_1.map(this._treeChanges.exiting, hof_1.prop('state')).map(stateSelf).reverse();\n\t    };\n\t    /**\n\t     * Gets the states being retained.\n\t     *\n\t     * @returns an array of states that are already entered from a previous Transition, that will not be\n\t     *    exited during this Transition\n\t     */\n\t    Transition.prototype.retained = function () {\n\t        return common_1.map(this._treeChanges.retained, hof_1.prop('state')).map(stateSelf);\n\t    };\n\t    /**\n\t     * Get the [[ViewConfig]]s associated with this Transition\n\t     *\n\t     * Each state can define one or more views (template/controller), which are encapsulated as `ViewConfig` objects.\n\t     * This method fetches the `ViewConfigs` for a given path in the Transition (e.g., \"to\" or \"entering\").\n\t     *\n\t     * @param pathname the name of the path to fetch views for:\n\t     *   (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)\n\t     * @param state If provided, only returns the `ViewConfig`s for a single state in the path\n\t     *\n\t     * @returns a list of ViewConfig objects for the given path.\n\t     */\n\t    Transition.prototype.views = function (pathname, state) {\n\t        if (pathname === void 0) { pathname = \"entering\"; }\n\t        var path = this._treeChanges[pathname];\n\t        path = !state ? path : path.filter(hof_1.propEq('state', state));\n\t        return path.map(hof_1.prop(\"views\")).filter(common_1.identity).reduce(common_1.unnestR, []);\n\t    };\n\t    /**\n\t     * Creates a new transition that is a redirection of the current one.\n\t     *\n\t     * This transition can be returned from a [[TransitionService]] hook to\n\t     * redirect a transition to a new state and/or set of parameters.\n\t     *\n\t     * @returns Returns a new [[Transition]] instance.\n\t     */\n\t    Transition.prototype.redirect = function (targetState) {\n\t        var newOptions = common_1.extend({}, this.options(), targetState.options(), { previous: this });\n\t        targetState = new targetState_1.TargetState(targetState.identifier(), targetState.$state(), targetState.params(), newOptions);\n\t        var newTransition = this.router.transitionService.create(this._treeChanges.from, targetState);\n\t        var originalEnteringNodes = this.treeChanges().entering;\n\t        var redirectEnteringNodes = newTransition.treeChanges().entering;\n\t        // --- Re-use resolve data from original transition ---\n\t        // When redirecting from a parent state to a child state where the parent parameter values haven't changed\n\t        // (because of the redirect), the resolves fetched by the original transition are still valid in the\n\t        // redirected transition.\n\t        //\n\t        // This allows you to define a redirect on a parent state which depends on an async resolve value.\n\t        // You can wait for the resolve, then redirect to a child state based on the result.\n\t        // The redirected transition does not have to re-fetch the resolve.\n\t        // ---------------------------------------------------------\n\t        var nodeIsReloading = function (reloadState) { return function (node) {\n\t            return reloadState && node.state.includes[reloadState.name];\n\t        }; };\n\t        // Find any \"entering\" nodes in the redirect path that match the original path and aren't being reloaded\n\t        var matchingEnteringNodes = node_1.PathNode.matching(redirectEnteringNodes, originalEnteringNodes)\n\t            .filter(hof_1.not(nodeIsReloading(targetState.options().reloadState)));\n\t        // Use the existing (possibly pre-resolved) resolvables for the matching entering nodes.\n\t        matchingEnteringNodes.forEach(function (node, idx) {\n\t            node.resolvables = originalEnteringNodes[idx].resolvables;\n\t        });\n\t        return newTransition;\n\t    };\n\t    /** @hidden If a transition doesn't exit/enter any states, returns any [[Param]] whose value changed */\n\t    Transition.prototype._changedParams = function () {\n\t        var _a = this._treeChanges, to = _a.to, from = _a.from;\n\t        if (this._options.reload || common_1.tail(to).state !== common_1.tail(from).state)\n\t            return undefined;\n\t        var nodeSchemas = to.map(function (node) { return node.paramSchema; });\n\t        var _b = [to, from].map(function (path) { return path.map(function (x) { return x.paramValues; }); }), toValues = _b[0], fromValues = _b[1];\n\t        var tuples = common_1.arrayTuples(nodeSchemas, toValues, fromValues);\n\t        return tuples.map(function (_a) {\n\t            var schema = _a[0], toVals = _a[1], fromVals = _a[2];\n\t            return param_1.Param.changed(schema, toVals, fromVals);\n\t        }).reduce(common_1.unnestR, []);\n\t    };\n\t    /**\n\t     * Returns true if the transition is dynamic.\n\t     *\n\t     * A transition is dynamic if no states are entered nor exited, but at least one dynamic parameter has changed.\n\t     *\n\t     * @returns true if the Transition is dynamic\n\t     */\n\t    Transition.prototype.dynamic = function () {\n\t        var changes = this._changedParams();\n\t        return !changes ? false : changes.map(function (x) { return x.dynamic; }).reduce(common_1.anyTrueR, false);\n\t    };\n\t    /**\n\t     * Returns true if the transition is ignored.\n\t     *\n\t     * A transition is ignored if no states are entered nor exited, and no parameter values have changed.\n\t     *\n\t     * @returns true if the Transition is ignored.\n\t     */\n\t    Transition.prototype.ignored = function () {\n\t        var changes = this._changedParams();\n\t        return !changes ? false : changes.length === 0;\n\t    };\n\t    /**\n\t     * @hidden\n\t     */\n\t    Transition.prototype.hookBuilder = function () {\n\t        return new hookBuilder_1.HookBuilder(this.router.transitionService, this, {\n\t            transition: this,\n\t            current: this._options.current\n\t        });\n\t    };\n\t    /**\n\t     * Runs the transition\n\t     *\n\t     * This method is generally called from the [[StateService.transitionTo]]\n\t     *\n\t     * @returns a promise for a successful transition.\n\t     */\n\t    Transition.prototype.run = function () {\n\t        var _this = this;\n\t        var runSynchronousHooks = transitionHook_1.TransitionHook.runSynchronousHooks;\n\t        var hookBuilder = this.hookBuilder();\n\t        var globals = this.router.globals;\n\t        globals.transitionHistory.enqueue(this);\n\t        var syncResult = runSynchronousHooks(hookBuilder.getOnBeforeHooks());\n\t        if (rejectFactory_1.Rejection.isTransitionRejectionPromise(syncResult)) {\n\t            syncResult.catch(function () { return 0; }); // issue #2676\n\t            var rejectReason = syncResult._transitionRejection;\n\t            this._deferred.reject(rejectReason);\n\t            return this.promise;\n\t        }\n\t        if (!this.valid()) {\n\t            var error = new Error(this.error());\n\t            this._deferred.reject(error);\n\t            return this.promise;\n\t        }\n\t        if (this.ignored()) {\n\t            trace_1.trace.traceTransitionIgnored(this);\n\t            this._deferred.reject(rejectFactory_1.Rejection.ignored());\n\t            return this.promise;\n\t        }\n\t        // When the chain is complete, then resolve or reject the deferred\n\t        var transitionSuccess = function () {\n\t            trace_1.trace.traceSuccess(_this.$to(), _this);\n\t            _this.success = true;\n\t            _this._deferred.resolve(_this.to());\n\t            runSynchronousHooks(hookBuilder.getOnSuccessHooks(), true);\n\t        };\n\t        var transitionError = function (error) {\n\t            trace_1.trace.traceError(error, _this);\n\t            _this.success = false;\n\t            _this._deferred.reject(error);\n\t            runSynchronousHooks(hookBuilder.getOnErrorHooks(), true);\n\t        };\n\t        trace_1.trace.traceTransitionStart(this);\n\t        // Chain the next hook off the previous\n\t        var appendHookToChain = function (prev, nextHook) {\n\t            return prev.then(function () { return nextHook.invokeHook(); });\n\t        };\n\t        // Run the hooks, then resolve or reject the overall deferred in the .then() handler\n\t        hookBuilder.asyncHooks()\n\t            .reduce(appendHookToChain, syncResult)\n\t            .then(transitionSuccess, transitionError);\n\t        return this.promise;\n\t    };\n\t    /**\n\t     * Checks if the Transition is valid\n\t     *\n\t     * @returns true if the Transition is valid\n\t     */\n\t    Transition.prototype.valid = function () {\n\t        return !this.error();\n\t    };\n\t    /**\n\t     * The reason the Transition is invalid\n\t     *\n\t     * @returns an error message explaining why the transition is invalid\n\t     */\n\t    Transition.prototype.error = function () {\n\t        var state = this.$to();\n\t        if (state.self[common_1.abstractKey])\n\t            return \"Cannot transition to abstract state '\" + state.name + \"'\";\n\t        if (!param_1.Param.validates(state.parameters(), this.params()))\n\t            return \"Param values not valid for state '\" + state.name + \"'\";\n\t    };\n\t    /**\n\t     * A string representation of the Transition\n\t     *\n\t     * @returns A string representation of the Transition\n\t     */\n\t    Transition.prototype.toString = function () {\n\t        var fromStateOrName = this.from();\n\t        var toStateOrName = this.to();\n\t        var avoidEmptyHash = function (params) {\n\t            return (params[\"#\"] !== null && params[\"#\"] !== undefined) ? params : common_1.omit(params, \"#\");\n\t        };\n\t        // (X) means the to state is invalid.\n\t        var id = this.$id, from = predicates_1.isObject(fromStateOrName) ? fromStateOrName.name : fromStateOrName, fromParams = common_1.toJson(avoidEmptyHash(this._treeChanges.from.map(hof_1.prop('paramValues')).reduce(common_1.mergeR, {}))), toValid = this.valid() ? \"\" : \"(X) \", to = predicates_1.isObject(toStateOrName) ? toStateOrName.name : toStateOrName, toParams = common_1.toJson(avoidEmptyHash(this.params()));\n\t        return \"Transition#\" + id + \"( '\" + from + \"'\" + fromParams + \" -> \" + toValid + \"'\" + to + \"'\" + toParams + \" )\";\n\t    };\n\t    Transition.diToken = Transition;\n\t    return Transition;\n\t}());\n\texports.Transition = Transition;\n\n\n/***/ },\n/* 12 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/**\n\t * UI-Router Transition Tracing\n\t *\n\t * Enable transition tracing to print transition information to the console, in order to help debug your application.\n\t * Tracing logs detailed information about each Transition to your console.\n\t *\n\t * To enable tracing, import the [[trace]] singleton and enable one or more categories.\n\t *\n\t * ES6\n\t * ```\n\t *\n\t * import {trace} from \"ui-router-ng2\"; // or \"angular-ui-router\"\n\t * trace.enable(1, 5); // TRANSITION and VIEWCONFIG\n\t * ```\n\t *\n\t * CJS\n\t * ```\n\t *\n\t * let trace = require(\"angular-ui-router\").trace; // or \"ui-router-ng2\"\n\t * trace.enable(\"TRANSITION\", \"VIEWCONFIG\");\n\t * ```\n\t *\n\t * Globals\n\t * ```\n\t *\n\t * let trace = window[\"angular-ui-router\"].trace; // or \"ui-router-ng2\"\n\t * trace.enable(); // Trace everything (very verbose)\n\t * ```\n\t *\n\t * @module trace\n\t */ /** for typedoc */\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar strings_1 = __webpack_require__(9);\n\t/** @hidden */\n\tfunction uiViewString(viewData) {\n\t    if (!viewData)\n\t        return 'ui-view (defunct)';\n\t    return (\"[ui-view#\" + viewData.id + \" tag \") +\n\t        (\"in template from '\" + (viewData.creationContext && viewData.creationContext.name || '(root)') + \"' state]: \") +\n\t        (\"fqn: '\" + viewData.fqn + \"', \") +\n\t        (\"name: '\" + viewData.name + \"@\" + viewData.creationContext + \"')\");\n\t}\n\t/** @hidden */\n\tvar viewConfigString = function (viewConfig) {\n\t    return (\"[ViewConfig#\" + viewConfig.$id + \" from '\" + (viewConfig.viewDecl.$context.name || '(root)') + \"' state]: target ui-view: '\" + viewConfig.viewDecl.$uiViewName + \"@\" + viewConfig.viewDecl.$uiViewContextAnchor + \"'\");\n\t};\n\t/** @hidden */\n\tfunction normalizedCat(input) {\n\t    return predicates_1.isNumber(input) ? Category[input] : Category[Category[input]];\n\t}\n\t/**\n\t * Trace categories\n\t *\n\t * [[Trace.enable]] or [[Trace.disable]] a category\n\t *\n\t * `trace.enable(Category.TRANSITION)`\n\t *\n\t * These can also be provided using a matching string, or position ordinal\n\t *\n\t * `trace.enable(\"TRANSITION\")`\n\t *\n\t * `trace.enable(1)`\n\t */\n\t(function (Category) {\n\t    Category[Category[\"RESOLVE\"] = 0] = \"RESOLVE\";\n\t    Category[Category[\"TRANSITION\"] = 1] = \"TRANSITION\";\n\t    Category[Category[\"HOOK\"] = 2] = \"HOOK\";\n\t    Category[Category[\"INVOKE\"] = 3] = \"INVOKE\";\n\t    Category[Category[\"UIVIEW\"] = 4] = \"UIVIEW\";\n\t    Category[Category[\"VIEWCONFIG\"] = 5] = \"VIEWCONFIG\";\n\t})(exports.Category || (exports.Category = {}));\n\tvar Category = exports.Category;\n\t/**\n\t * Prints UI-Router Transition trace information to the console.\n\t */\n\tvar Trace = (function () {\n\t    function Trace() {\n\t        /** @hidden */\n\t        this._enabled = {};\n\t        this.approximateDigests = 0;\n\t    }\n\t    /** @hidden */\n\t    Trace.prototype._set = function (enabled, categories) {\n\t        var _this = this;\n\t        if (!categories.length) {\n\t            categories = Object.keys(Category)\n\t                .filter(function (k) { return isNaN(parseInt(k, 10)); })\n\t                .map(function (key) { return Category[key]; });\n\t        }\n\t        categories.map(normalizedCat).forEach(function (category) { return _this._enabled[category] = enabled; });\n\t    };\n\t    /**\n\t     * Enables a trace [[Category]]\n\t     *\n\t     * ```\n\t     * trace.enable(\"TRANSITION\");\n\t     * ```\n\t     *\n\t     * @param categories categories to enable. If `categories` is omitted, all categories are enabled.\n\t     *        Also takes strings (category name) or ordinal (category position)\n\t     */\n\t    Trace.prototype.enable = function () {\n\t        var categories = [];\n\t        for (var _i = 0; _i < arguments.length; _i++) {\n\t            categories[_i - 0] = arguments[_i];\n\t        }\n\t        this._set(true, categories);\n\t    };\n\t    /**\n\t     * Disables a trace [[Category]]\n\t     *\n\t     * ```\n\t     * trace.disable(\"VIEWCONFIG\");\n\t     * ```\n\t     *\n\t     * @param categories categories to disable. If `categories` is omitted, all categories are disabled.\n\t     *        Also takes strings (category name) or ordinal (category position)\n\t     */\n\t    Trace.prototype.disable = function () {\n\t        var categories = [];\n\t        for (var _i = 0; _i < arguments.length; _i++) {\n\t            categories[_i - 0] = arguments[_i];\n\t        }\n\t        this._set(false, categories);\n\t    };\n\t    /**\n\t     * Retrieves the enabled stateus of a [[Category]]\n\t     *\n\t     * ```\n\t     * trace.enabled(\"VIEWCONFIG\"); // true or false\n\t     * ```\n\t     *\n\t     * @returns boolean true if the category is enabled\n\t     */\n\t    Trace.prototype.enabled = function (category) {\n\t        return !!this._enabled[normalizedCat(category)];\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceTransitionStart = function (transition) {\n\t        if (!this.enabled(Category.TRANSITION))\n\t            return;\n\t        var tid = transition.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(transition);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \": Started  -> \" + transitionStr);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceTransitionIgnored = function (trans) {\n\t        if (!this.enabled(Category.TRANSITION))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(trans);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \": Ignored  <> \" + transitionStr);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceHookInvocation = function (step, options) {\n\t        if (!this.enabled(Category.HOOK))\n\t            return;\n\t        var tid = hof_1.parse(\"transition.$id\")(options), digest = this.approximateDigests, event = hof_1.parse(\"traceData.hookType\")(options) || \"internal\", context = hof_1.parse(\"traceData.context.state.name\")(options) || hof_1.parse(\"traceData.context\")(options) || \"unknown\", name = strings_1.functionToString(step.fn);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \":   Hook -> \" + event + \" context: \" + context + \", \" + strings_1.maxLength(200, name));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceHookResult = function (hookResult, transitionResult, transitionOptions) {\n\t        if (!this.enabled(Category.HOOK))\n\t            return;\n\t        var tid = hof_1.parse(\"transition.$id\")(transitionOptions), digest = this.approximateDigests, hookResultStr = strings_1.stringify(hookResult), transitionResultStr = strings_1.stringify(transitionResult);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \":   <- Hook returned: \" + strings_1.maxLength(200, hookResultStr) + \", transition result: \" + strings_1.maxLength(200, transitionResultStr));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceResolvePath = function (path, when, trans) {\n\t        if (!this.enabled(Category.RESOLVE))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, pathStr = path && path.toString();\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \":         Resolving \" + pathStr + \" (\" + when + \")\");\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceResolvableResolved = function (resolvable, trans) {\n\t        if (!this.enabled(Category.RESOLVE))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, resolvableStr = resolvable && resolvable.toString(), result = strings_1.stringify(resolvable.data);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \":               <- Resolved  \" + resolvableStr + \" to: \" + strings_1.maxLength(200, result));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceError = function (error, trans) {\n\t        if (!this.enabled(Category.TRANSITION))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(trans);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \": <- Rejected \" + transitionStr + \", reason: \" + error);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceSuccess = function (finalState, trans) {\n\t        if (!this.enabled(Category.TRANSITION))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, state = finalState.name, transitionStr = strings_1.stringify(trans);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \": <- Success  \" + transitionStr + \", final state: \" + state);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceUIViewEvent = function (event, viewData, extra) {\n\t        if (extra === void 0) { extra = \"\"; }\n\t        if (!this.enabled(Category.UIVIEW))\n\t            return;\n\t        console.log(\"ui-view: \" + strings_1.padString(30, event) + \" \" + uiViewString(viewData) + extra);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceUIViewConfigUpdated = function (viewData, context) {\n\t        if (!this.enabled(Category.UIVIEW))\n\t            return;\n\t        this.traceUIViewEvent(\"Updating\", viewData, \" with ViewConfig from context='\" + context + \"'\");\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceUIViewScopeCreated = function (viewData, newScope) {\n\t        if (!this.enabled(Category.UIVIEW))\n\t            return;\n\t        this.traceUIViewEvent(\"Created scope for\", viewData, \", scope #\" + newScope.$id);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceUIViewFill = function (viewData, html) {\n\t        if (!this.enabled(Category.UIVIEW))\n\t            return;\n\t        this.traceUIViewEvent(\"Fill\", viewData, \" with: \" + strings_1.maxLength(200, html));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceViewServiceEvent = function (event, viewConfig) {\n\t        if (!this.enabled(Category.VIEWCONFIG))\n\t            return;\n\t        console.log(\"VIEWCONFIG: \" + event + \" \" + viewConfigString(viewConfig));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceViewServiceUIViewEvent = function (event, viewData) {\n\t        if (!this.enabled(Category.VIEWCONFIG))\n\t            return;\n\t        console.log(\"VIEWCONFIG: \" + event + \" \" + uiViewString(viewData));\n\t    };\n\t    return Trace;\n\t}());\n\texports.Trace = Trace;\n\t/**\n\t * The [[Trace]] singleton\n\t *\n\t * @example\n\t * ```js\n\t *\n\t * import {trace} from \"angular-ui-router\";\n\t * trace.enable(1, 5);\n\t * ```\n\t */\n\tvar trace = new Trace();\n\texports.trace = trace;\n\n\n/***/ },\n/* 13 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar strings_1 = __webpack_require__(9);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\tvar trace_1 = __webpack_require__(12);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar rejectFactory_1 = __webpack_require__(10);\n\tvar targetState_1 = __webpack_require__(14);\n\tvar defaultOptions = {\n\t    async: true,\n\t    rejectIfSuperseded: true,\n\t    current: common_1.noop,\n\t    transition: null,\n\t    traceData: {},\n\t    bind: null\n\t};\n\t/** @hidden */\n\tvar TransitionHook = (function () {\n\t    function TransitionHook(transition, stateContext, hookFn, resolveContext, options) {\n\t        var _this = this;\n\t        this.transition = transition;\n\t        this.stateContext = stateContext;\n\t        this.hookFn = hookFn;\n\t        this.resolveContext = resolveContext;\n\t        this.options = options;\n\t        this.isSuperseded = function () { return _this.options.current() !== _this.options.transition; };\n\t        this.options = common_1.defaults(options, defaultOptions);\n\t    }\n\t    TransitionHook.prototype.invokeHook = function () {\n\t        var _a = this, options = _a.options, hookFn = _a.hookFn, resolveContext = _a.resolveContext;\n\t        trace_1.trace.traceHookInvocation(this, options);\n\t        if (options.rejectIfSuperseded && this.isSuperseded()) {\n\t            return rejectFactory_1.Rejection.superseded(options.current()).toPromise();\n\t        }\n\t        var hookResult = hookFn.call(options.bind, this.transition, this.stateContext);\n\t        return this.handleHookResult(hookResult);\n\t    };\n\t    /**\n\t     * This method handles the return value of a Transition Hook.\n\t     *\n\t     * A hook can return false, a redirect (TargetState), or a promise (which may resolve to false or a redirect)\n\t     */\n\t    TransitionHook.prototype.handleHookResult = function (hookResult) {\n\t        var _this = this;\n\t        if (!predicates_1.isDefined(hookResult))\n\t            return undefined;\n\t        /**\n\t         * Handles transition superseded, transition aborted and transition redirect.\n\t         */\n\t        var mapHookResult = hof_1.pattern([\n\t            // Transition is no longer current\n\t            [this.isSuperseded, function () { return rejectFactory_1.Rejection.superseded(_this.options.current()).toPromise(); }],\n\t            // If the hook returns false, abort the current Transition\n\t            [hof_1.eq(false), function () { return rejectFactory_1.Rejection.aborted(\"Hook aborted transition\").toPromise(); }],\n\t            // If the hook returns a Transition, halt the current Transition and redirect to that Transition.\n\t            [hof_1.is(targetState_1.TargetState), function (target) { return rejectFactory_1.Rejection.redirected(target).toPromise(); }],\n\t            // A promise was returned, wait for the promise and then chain another hookHandler\n\t            [predicates_1.isPromise, function (promise) { return promise.then(_this.handleHookResult.bind(_this)); }]\n\t        ]);\n\t        var transitionResult = mapHookResult(hookResult);\n\t        if (transitionResult)\n\t            trace_1.trace.traceHookResult(hookResult, transitionResult, this.options);\n\t        return transitionResult;\n\t    };\n\t    TransitionHook.prototype.toString = function () {\n\t        var _a = this, options = _a.options, hookFn = _a.hookFn;\n\t        var event = hof_1.parse(\"traceData.hookType\")(options) || \"internal\", context = hof_1.parse(\"traceData.context.state.name\")(options) || hof_1.parse(\"traceData.context\")(options) || \"unknown\", name = strings_1.fnToString(hookFn);\n\t        return event + \" context: \" + context + \", \" + strings_1.maxLength(200, name);\n\t    };\n\t    /**\n\t     * Given an array of TransitionHooks, runs each one synchronously and sequentially.\n\t     *\n\t     * Returns a promise chain composed of any promises returned from each hook.invokeStep() call\n\t     */\n\t    TransitionHook.runSynchronousHooks = function (hooks, swallowExceptions) {\n\t        if (swallowExceptions === void 0) { swallowExceptions = false; }\n\t        var results = [];\n\t        for (var i = 0; i < hooks.length; i++) {\n\t            try {\n\t                results.push(hooks[i].invokeHook());\n\t            }\n\t            catch (exception) {\n\t                if (!swallowExceptions) {\n\t                    return rejectFactory_1.Rejection.errored(exception).toPromise();\n\t                }\n\t                console.error(\"Swallowed exception during synchronous hook handler: \" + exception); // TODO: What to do here?\n\t            }\n\t        }\n\t        var rejections = results.filter(rejectFactory_1.Rejection.isTransitionRejectionPromise);\n\t        if (rejections.length)\n\t            return rejections[0];\n\t        return results\n\t            .filter(predicates_1.isPromise)\n\t            .reduce(function (chain, promise) { return chain.then(hof_1.val(promise)); }, coreservices_1.services.$q.when());\n\t    };\n\t    return TransitionHook;\n\t}());\n\texports.TransitionHook = TransitionHook;\n\n\n/***/ },\n/* 14 */\n/***/ function(module, exports) {\n\n\t/** @module state */ /** for typedoc */\n\t\"use strict\";\n\t/**\n\t * @ngdoc object\n\t * @name ui.router.state.type:TargetState\n\t *\n\t * @description\n\t * Encapsulate the desired target of a transition.\n\t * Wraps an identifier for a state, a set of parameters, and transition options with the definition of the state.\n\t *\n\t * @param {StateOrName} _identifier  An identifier for a state. Either a fully-qualified path, or the object\n\t *            used to define the state.\n\t * @param {IState} _definition The `State` object definition.\n\t * @param {ParamsOrArray} _params Parameters for the target state\n\t * @param {TransitionOptions} _options Transition options.\n\t */\n\tvar TargetState = (function () {\n\t    function TargetState(_identifier, _definition, _params, _options) {\n\t        if (_params === void 0) { _params = {}; }\n\t        if (_options === void 0) { _options = {}; }\n\t        this._identifier = _identifier;\n\t        this._definition = _definition;\n\t        this._options = _options;\n\t        this._params = _params || {};\n\t    }\n\t    TargetState.prototype.name = function () {\n\t        return this._definition && this._definition.name || this._identifier;\n\t    };\n\t    TargetState.prototype.identifier = function () {\n\t        return this._identifier;\n\t    };\n\t    TargetState.prototype.params = function () {\n\t        return this._params;\n\t    };\n\t    TargetState.prototype.$state = function () {\n\t        return this._definition;\n\t    };\n\t    TargetState.prototype.state = function () {\n\t        return this._definition && this._definition.self;\n\t    };\n\t    TargetState.prototype.options = function () {\n\t        return this._options;\n\t    };\n\t    TargetState.prototype.exists = function () {\n\t        return !!(this._definition && this._definition.self);\n\t    };\n\t    TargetState.prototype.valid = function () {\n\t        return !this.error();\n\t    };\n\t    TargetState.prototype.error = function () {\n\t        var base = this.options().relative;\n\t        if (!this._definition && !!base) {\n\t            var stateName = base.name ? base.name : base;\n\t            return \"Could not resolve '\" + this.name() + \"' from state '\" + stateName + \"'\";\n\t        }\n\t        if (!this._definition)\n\t            return \"No such state '\" + this.name() + \"'\";\n\t        if (!this._definition.self)\n\t            return \"State '\" + this.name() + \"' has an invalid definition\";\n\t    };\n\t    return TargetState;\n\t}());\n\texports.TargetState = TargetState;\n\n\n/***/ },\n/* 15 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module transition */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar glob_1 = __webpack_require__(7);\n\t/**\n\t * Determines if the given state matches the matchCriteria\n\t *\n\t * @hidden\n\t *\n\t * @param state a State Object to test against\n\t * @param criterion\n\t * - If a string, matchState uses the string as a glob-matcher against the state name\n\t * - If an array (of strings), matchState uses each string in the array as a glob-matchers against the state name\n\t *   and returns a positive match if any of the globs match.\n\t * - If a function, matchState calls the function with the state and returns true if the function's result is truthy.\n\t * @returns {boolean}\n\t */\n\tfunction matchState(state, criterion) {\n\t    var toMatch = predicates_1.isString(criterion) ? [criterion] : criterion;\n\t    function matchGlobs(_state) {\n\t        var globStrings = toMatch;\n\t        for (var i = 0; i < globStrings.length; i++) {\n\t            var glob = glob_1.Glob.fromString(globStrings[i]);\n\t            if ((glob && glob.matches(_state.name)) || (!glob && globStrings[i] === _state.name)) {\n\t                return true;\n\t            }\n\t        }\n\t        return false;\n\t    }\n\t    var matchFn = (predicates_1.isFunction(toMatch) ? toMatch : matchGlobs);\n\t    return !!matchFn(state);\n\t}\n\texports.matchState = matchState;\n\t/** @hidden */\n\tvar EventHook = (function () {\n\t    function EventHook(matchCriteria, callback, options) {\n\t        if (options === void 0) { options = {}; }\n\t        this.callback = callback;\n\t        this.matchCriteria = common_1.extend({ to: true, from: true, exiting: true, retained: true, entering: true }, matchCriteria);\n\t        this.priority = options.priority || 0;\n\t        this.bind = options.bind || null;\n\t    }\n\t    EventHook._matchingNodes = function (nodes, criterion) {\n\t        if (criterion === true)\n\t            return nodes;\n\t        var matching = nodes.filter(function (node) { return matchState(node.state, criterion); });\n\t        return matching.length ? matching : null;\n\t    };\n\t    /**\n\t     * Determines if this hook's [[matchCriteria]] match the given [[TreeChanges]]\n\t     *\n\t     * @returns an IMatchingNodes object, or null. If an IMatchingNodes object is returned, its values\n\t     * are the matching [[PathNode]]s for each [[HookMatchCriterion]] (to, from, exiting, retained, entering)\n\t     */\n\t    EventHook.prototype.matches = function (treeChanges) {\n\t        var mc = this.matchCriteria, _matchingNodes = EventHook._matchingNodes;\n\t        var matches = {\n\t            to: _matchingNodes([common_1.tail(treeChanges.to)], mc.to),\n\t            from: _matchingNodes([common_1.tail(treeChanges.from)], mc.from),\n\t            exiting: _matchingNodes(treeChanges.exiting, mc.exiting),\n\t            retained: _matchingNodes(treeChanges.retained, mc.retained),\n\t            entering: _matchingNodes(treeChanges.entering, mc.entering),\n\t        };\n\t        // Check if all the criteria matched the TreeChanges object\n\t        var allMatched = [\"to\", \"from\", \"exiting\", \"retained\", \"entering\"]\n\t            .map(function (prop) { return matches[prop]; })\n\t            .reduce(common_1.allTrueR, true);\n\t        return allMatched ? matches : null;\n\t    };\n\t    return EventHook;\n\t}());\n\texports.EventHook = EventHook;\n\t/** @hidden Return a registration function of the requested type. */\n\tfunction makeHookRegistrationFn(hooks, name) {\n\t    return function (matchObject, callback, options) {\n\t        if (options === void 0) { options = {}; }\n\t        var eventHook = new EventHook(matchObject, callback, options);\n\t        hooks[name].push(eventHook);\n\t        return function deregisterEventHook() {\n\t            common_1.removeFrom(hooks[name])(eventHook);\n\t        };\n\t    };\n\t}\n\t/**\n\t * Mixin class acts as a Transition Hook registry.\n\t *\n\t * Holds the registered [[HookFn]] objects.\n\t * Exposes functions to register new hooks.\n\t *\n\t * This is a Mixin class which can be applied to other objects.\n\t *\n\t * The hook registration functions are [[onBefore]], [[onStart]], [[onEnter]], [[onRetain]], [[onExit]], [[onFinish]], [[onSuccess]], [[onError]].\n\t *\n\t * This class is mixed into both the [[TransitionService]] and every [[Transition]] object.\n\t * Global hooks are added to the [[TransitionService]].\n\t * Since each [[Transition]] is itself a `HookRegistry`, hooks can also be added to individual Transitions\n\t * (note: the hook criteria still must match the Transition).\n\t */\n\tvar HookRegistry = (function () {\n\t    function HookRegistry() {\n\t        var _this = this;\n\t        this._transitionEvents = {\n\t            onBefore: [], onStart: [], onEnter: [], onRetain: [], onExit: [], onFinish: [], onSuccess: [], onError: []\n\t        };\n\t        this.getHooks = function (name) { return _this._transitionEvents[name]; };\n\t        /** @inheritdoc */\n\t        this.onBefore = makeHookRegistrationFn(this._transitionEvents, \"onBefore\");\n\t        /** @inheritdoc */\n\t        this.onStart = makeHookRegistrationFn(this._transitionEvents, \"onStart\");\n\t        /** @inheritdoc */\n\t        this.onEnter = makeHookRegistrationFn(this._transitionEvents, \"onEnter\");\n\t        /** @inheritdoc */\n\t        this.onRetain = makeHookRegistrationFn(this._transitionEvents, \"onRetain\");\n\t        /** @inheritdoc */\n\t        this.onExit = makeHookRegistrationFn(this._transitionEvents, \"onExit\");\n\t        /** @inheritdoc */\n\t        this.onFinish = makeHookRegistrationFn(this._transitionEvents, \"onFinish\");\n\t        /** @inheritdoc */\n\t        this.onSuccess = makeHookRegistrationFn(this._transitionEvents, \"onSuccess\");\n\t        /** @inheritdoc */\n\t        this.onError = makeHookRegistrationFn(this._transitionEvents, \"onError\");\n\t    }\n\t    HookRegistry.mixin = function (source, target) {\n\t        Object.keys(source._transitionEvents).concat([\"getHooks\"]).forEach(function (key) { return target[key] = source[key]; });\n\t    };\n\t    return HookRegistry;\n\t}());\n\texports.HookRegistry = HookRegistry;\n\n\n/***/ },\n/* 16 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module transition */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar transitionHook_1 = __webpack_require__(13);\n\tvar resolveContext_1 = __webpack_require__(17);\n\t/**\n\t * This class returns applicable TransitionHooks for a specific Transition instance.\n\t *\n\t * Hooks (IEventHook) may be registered globally, e.g., $transitions.onEnter(...), or locally, e.g.\n\t * myTransition.onEnter(...).  The HookBuilder finds matching IEventHooks (where the match criteria is\n\t * determined by the type of hook)\n\t *\n\t * The HookBuilder also converts IEventHooks objects to TransitionHook objects, which are used to run a Transition.\n\t *\n\t * The HookBuilder constructor is given the $transitions service and a Transition instance.  Thus, a HookBuilder\n\t * instance may only be used for one specific Transition object. (side note: the _treeChanges accessor is private\n\t * in the Transition class, so we must also provide the Transition's _treeChanges)\n\t *\n\t */\n\tvar HookBuilder = (function () {\n\t    function HookBuilder($transitions, transition, baseHookOptions) {\n\t        var _this = this;\n\t        this.$transitions = $transitions;\n\t        this.transition = transition;\n\t        this.baseHookOptions = baseHookOptions;\n\t        this.getOnBeforeHooks = function () { return _this._buildNodeHooks(\"onBefore\", \"to\", tupleSort(), { async: false }); };\n\t        this.getOnStartHooks = function () { return _this._buildNodeHooks(\"onStart\", \"to\", tupleSort()); };\n\t        this.getOnExitHooks = function () { return _this._buildNodeHooks(\"onExit\", \"exiting\", tupleSort(true), { stateHook: true }); };\n\t        this.getOnRetainHooks = function () { return _this._buildNodeHooks(\"onRetain\", \"retained\", tupleSort(false), { stateHook: true }); };\n\t        this.getOnEnterHooks = function () { return _this._buildNodeHooks(\"onEnter\", \"entering\", tupleSort(false), { stateHook: true }); };\n\t        this.getOnFinishHooks = function () { return _this._buildNodeHooks(\"onFinish\", \"to\", tupleSort()); };\n\t        this.getOnSuccessHooks = function () { return _this._buildNodeHooks(\"onSuccess\", \"to\", tupleSort(), { async: false, rejectIfSuperseded: false }); };\n\t        this.getOnErrorHooks = function () { return _this._buildNodeHooks(\"onError\", \"to\", tupleSort(), { async: false, rejectIfSuperseded: false }); };\n\t        this.treeChanges = transition.treeChanges();\n\t        this.toState = common_1.tail(this.treeChanges.to).state;\n\t        this.fromState = common_1.tail(this.treeChanges.from).state;\n\t        this.transitionOptions = transition.options();\n\t    }\n\t    HookBuilder.prototype.asyncHooks = function () {\n\t        var onStartHooks = this.getOnStartHooks();\n\t        var onExitHooks = this.getOnExitHooks();\n\t        var onRetainHooks = this.getOnRetainHooks();\n\t        var onEnterHooks = this.getOnEnterHooks();\n\t        var onFinishHooks = this.getOnFinishHooks();\n\t        var asyncHooks = [onStartHooks, onExitHooks, onRetainHooks, onEnterHooks, onFinishHooks];\n\t        return asyncHooks.reduce(common_1.unnestR, []).filter(common_1.identity);\n\t    };\n\t    /**\n\t     * Returns an array of newly built TransitionHook objects.\n\t     *\n\t     * - Finds all IEventHooks registered for the given `hookType` which matched the transition's [[TreeChanges]].\n\t     * - Finds [[PathNode]] (or `PathNode[]`) to use as the TransitionHook context(s)\n\t     * - For each of the [[PathNode]]s, creates a TransitionHook\n\t     *\n\t     * @param hookType the name of the hook registration function, e.g., 'onEnter', 'onFinish'.\n\t     * @param matchingNodesProp selects which [[PathNode]]s from the [[IMatchingNodes]] object to create hooks for.\n\t     * @param getLocals a function which accepts a [[PathNode]] and returns additional locals to provide to the hook as injectables\n\t     * @param sortHooksFn a function which compares two HookTuple and returns <1, 0, or >1\n\t     * @param options any specific Transition Hook Options\n\t     */\n\t    HookBuilder.prototype._buildNodeHooks = function (hookType, matchingNodesProp, sortHooksFn, options) {\n\t        var _this = this;\n\t        // Find all the matching registered hooks for a given hook type\n\t        var matchingHooks = this._matchingHooks(hookType, this.treeChanges);\n\t        if (!matchingHooks)\n\t            return [];\n\t        var makeTransitionHooks = function (hook) {\n\t            // Fetch the Nodes that caused this hook to match.\n\t            var matches = hook.matches(_this.treeChanges);\n\t            // Select the PathNode[] that will be used as TransitionHook context objects\n\t            var matchingNodes = matches[matchingNodesProp];\n\t            // When invoking 'exiting' hooks, give them the \"from path\" for resolve data.\n\t            // Everything else gets the \"to path\"\n\t            var resolvePath = matchingNodesProp === 'exiting' ? _this.treeChanges.from : _this.treeChanges.to;\n\t            var resolveContext = new resolveContext_1.ResolveContext(resolvePath);\n\t            // Return an array of HookTuples\n\t            return matchingNodes.map(function (node) {\n\t                var _options = common_1.extend({ bind: hook.bind, traceData: { hookType: hookType, context: node } }, _this.baseHookOptions, options);\n\t                var state = _options.stateHook ? node.state : null;\n\t                var context = resolveContext.subContext(node.state);\n\t                var transitionHook = new transitionHook_1.TransitionHook(_this.transition, state, hook.callback, context, _options);\n\t                return { hook: hook, node: node, transitionHook: transitionHook };\n\t            });\n\t        };\n\t        return matchingHooks.map(makeTransitionHooks)\n\t            .reduce(common_1.unnestR, [])\n\t            .sort(sortHooksFn)\n\t            .map(function (tuple) { return tuple.transitionHook; });\n\t    };\n\t    /**\n\t     * Finds all IEventHooks from:\n\t     * - The Transition object instance hook registry\n\t     * - The TransitionService ($transitions) global hook registry\n\t     *\n\t     * which matched:\n\t     * - the eventType\n\t     * - the matchCriteria (to, from, exiting, retained, entering)\n\t     *\n\t     * @returns an array of matched [[IEventHook]]s\n\t     */\n\t    HookBuilder.prototype._matchingHooks = function (hookName, treeChanges) {\n\t        return [this.transition, this.$transitions] // Instance and Global hook registries\n\t            .map(function (reg) { return reg.getHooks(hookName); }) // Get named hooks from registries\n\t            .filter(common_1.assertPredicate(predicates_1.isArray, \"broken event named: \" + hookName)) // Sanity check\n\t            .reduce(common_1.unnestR, []) // Un-nest IEventHook[][] to IEventHook[] array\n\t            .filter(function (hook) { return hook.matches(treeChanges); }); // Only those satisfying matchCriteria\n\t    };\n\t    return HookBuilder;\n\t}());\n\texports.HookBuilder = HookBuilder;\n\t/**\n\t * A factory for a sort function for HookTuples.\n\t *\n\t * The sort function first compares the PathNode depth (how deep in the state tree a node is), then compares\n\t * the EventHook priority.\n\t *\n\t * @param reverseDepthSort a boolean, when true, reverses the sort order for the node depth\n\t * @returns a tuple sort function\n\t */\n\tfunction tupleSort(reverseDepthSort) {\n\t    if (reverseDepthSort === void 0) { reverseDepthSort = false; }\n\t    return function nodeDepthThenPriority(l, r) {\n\t        var factor = reverseDepthSort ? -1 : 1;\n\t        var depthDelta = (l.node.state.path.length - r.node.state.path.length) * factor;\n\t        return depthDelta !== 0 ? depthDelta : r.hook.priority - l.hook.priority;\n\t    };\n\t}\n\n\n/***/ },\n/* 17 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module resolve */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar trace_1 = __webpack_require__(12);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar interface_1 = __webpack_require__(18);\n\tvar resolvable_1 = __webpack_require__(19);\n\tvar pathFactory_1 = __webpack_require__(20);\n\tvar strings_1 = __webpack_require__(9);\n\tvar when = interface_1.resolvePolicies.when;\n\tvar ALL_WHENS = [when.EAGER, when.LAZY];\n\tvar EAGER_WHENS = [when.EAGER];\n\t/**\n\t * Encapsulates Depenency Injection for a path of nodes\n\t *\n\t * UI-Router states are organized as a tree.\n\t * A nested state has a path of ancestors to the root of the tree.\n\t * When a state is being activated, each element in the path is wrapped as a [[PathNode]].\n\t * A `PathNode` is a stateful object that holds things like parameters and resolvables for the state being activated.\n\t *\n\t * The ResolveContext closes over the [[PathNode]]s, and provides DI for the last node in the path.\n\t */\n\tvar ResolveContext = (function () {\n\t    function ResolveContext(_path) {\n\t        this._path = _path;\n\t    }\n\t    /** Gets all the tokens found in the resolve context, de-duplicated */\n\t    ResolveContext.prototype.getTokens = function () {\n\t        return this._path.reduce(function (acc, node) { return acc.concat(node.resolvables.map(function (r) { return r.token; })); }, []).reduce(common_1.uniqR, []);\n\t    };\n\t    /**\n\t     * Gets the Resolvable that matches the token\n\t     *\n\t     * Gets the last Resolvable that matches the token in this context, or undefined.\n\t     * Throws an error if it doesn't exist in the ResolveContext\n\t     */\n\t    ResolveContext.prototype.getResolvable = function (token) {\n\t        var matching = this._path.map(function (node) { return node.resolvables; })\n\t            .reduce(common_1.unnestR, [])\n\t            .filter(function (r) { return r.token === token; });\n\t        return common_1.tail(matching);\n\t    };\n\t    /**\n\t     * Returns a ResolveContext that includes a portion of this one\n\t     *\n\t     * Given a state, this method creates a new ResolveContext from this one.\n\t     * The new context starts at the first node (root) and stops at the node for the `state` parameter.\n\t     *\n\t     * #### Why\n\t     *\n\t     * When a transition is created, the nodes in the \"To Path\" are injected from a ResolveContext.\n\t     * A ResolveContext closes over a path of [[PathNode]]s and processes the resolvables.\n\t     * The \"To State\" can inject values from its own resolvables, as well as those from all its ancestor state's (node's).\n\t     * This method is used to create a narrower context when injecting ancestor nodes.\n\t     *\n\t     * @example\n\t     * `let ABCD = new ResolveContext([A, B, C, D]);`\n\t     *\n\t     * Given a path `[A, B, C, D]`, where `A`, `B`, `C` and `D` are nodes for states `a`, `b`, `c`, `d`:\n\t     * When injecting `D`, `D` should have access to all resolvables from `A`, `B`, `C`, `D`.\n\t     * However, `B` should only be able to access resolvables from `A`, `B`.\n\t     *\n\t     * When resolving for the `B` node, first take the full \"To Path\" Context `[A,B,C,D]` and limit to the subpath `[A,B]`.\n\t     * `let AB = ABCD.subcontext(a)`\n\t     */\n\t    ResolveContext.prototype.subContext = function (state) {\n\t        return new ResolveContext(pathFactory_1.PathFactory.subPath(this._path, function (node) { return node.state === state; }));\n\t    };\n\t    /**\n\t     * Adds Resolvables to the node that matches the state\n\t     *\n\t     * This adds a [[Resolvable]] (generally one created on the fly; not declared on a [[StateDeclaration.resolve]] block).\n\t     * The resolvable is added to the node matching the `state` parameter.\n\t     *\n\t     * These new resolvables are not automatically fetched.\n\t     * The calling code should either fetch them, fetch something that depends on them,\n\t     * or rely on [[resolvePath]] being called when some state is being entered.\n\t     *\n\t     * Note: each resolvable's [[ResolvePolicy]] is merged with the state's policy, and the global default.\n\t     *\n\t     * @param newResolvables the new Resolvables\n\t     * @param state Used to find the node to put the resolvable on\n\t     */\n\t    ResolveContext.prototype.addResolvables = function (newResolvables, state) {\n\t        var node = common_1.find(this._path, hof_1.propEq('state', state));\n\t        var keys = newResolvables.map(function (r) { return r.token; });\n\t        node.resolvables = node.resolvables.filter(function (r) { return keys.indexOf(r.token) === -1; }).concat(newResolvables);\n\t    };\n\t    /**\n\t     * Returns a promise for an array of resolved path Element promises\n\t     *\n\t     * @param when\n\t     * @param trans\n\t     * @returns {Promise<any>|any}\n\t     */\n\t    ResolveContext.prototype.resolvePath = function (when, trans) {\n\t        var _this = this;\n\t        if (when === void 0) { when = \"LAZY\"; }\n\t        // This option determines which 'when' policy Resolvables we are about to fetch.\n\t        var whenOption = common_1.inArray(ALL_WHENS, when) ? when : \"LAZY\";\n\t        // If the caller specified EAGER, only the EAGER Resolvables are fetched.\n\t        // if the caller specified LAZY, both EAGER and LAZY Resolvables are fetched.`\n\t        var matchedWhens = whenOption === interface_1.resolvePolicies.when.EAGER ? EAGER_WHENS : ALL_WHENS;\n\t        // get the subpath to the state argument, if provided\n\t        trace_1.trace.traceResolvePath(this._path, when, trans);\n\t        var promises = this._path.reduce(function (acc, node) {\n\t            var matchesRequestedPolicy = function (resolvable) {\n\t                return common_1.inArray(matchedWhens, resolvable.getPolicy(node.state).when);\n\t            };\n\t            var nodeResolvables = node.resolvables.filter(matchesRequestedPolicy);\n\t            var subContext = _this.subContext(node.state);\n\t            // For the matching Resolvables, start their async fetch process.\n\t            var getResult = function (r) { return r.get(subContext, trans)\n\t                .then(function (value) { return ({ token: r.token, value: value }); }); };\n\t            return acc.concat(nodeResolvables.map(getResult));\n\t        }, []);\n\t        return coreservices_1.services.$q.all(promises);\n\t    };\n\t    ResolveContext.prototype.injector = function () {\n\t        return new UIInjectorImpl(this);\n\t    };\n\t    ResolveContext.prototype.findNode = function (resolvable) {\n\t        return common_1.find(this._path, function (node) { return common_1.inArray(node.resolvables, resolvable); });\n\t    };\n\t    /**\n\t     * Gets the async dependencies of a Resolvable\n\t     *\n\t     * Given a Resolvable, returns its dependencies as a Resolvable[]\n\t     */\n\t    ResolveContext.prototype.getDependencies = function (resolvable) {\n\t        var node = this.findNode(resolvable);\n\t        // Find which other resolvables are \"visible\" to the `resolvable` argument\n\t        // subpath stopping at resolvable's node, or the whole path (if the resolvable isn't in the path)\n\t        var subPath = pathFactory_1.PathFactory.subPath(this._path, function (x) { return x === node; }) || this._path;\n\t        var availableResolvables = subPath\n\t            .reduce(function (acc, node) { return acc.concat(node.resolvables); }, []) //all of subpath's resolvables\n\t            .filter(function (res) { return res !== resolvable; }); // filter out the `resolvable` argument\n\t        var getDependency = function (token) {\n\t            var matching = availableResolvables.filter(function (r) { return r.token === token; });\n\t            if (matching.length)\n\t                return common_1.tail(matching);\n\t            var fromInjector = coreservices_1.services.$injector.get(token);\n\t            if (!fromInjector) {\n\t                throw new Error(\"Could not find Dependency Injection token: \" + strings_1.stringify(token));\n\t            }\n\t            return new resolvable_1.Resolvable(token, function () { return fromInjector; }, [], fromInjector);\n\t        };\n\t        return resolvable.deps.map(getDependency);\n\t    };\n\t    return ResolveContext;\n\t}());\n\texports.ResolveContext = ResolveContext;\n\tvar UIInjectorImpl = (function () {\n\t    function UIInjectorImpl(context) {\n\t        this.context = context;\n\t        /** The native injector ($injector on ng1, Root Injector on ng2, justjs injector for everything else) */\n\t        this.native = coreservices_1.services.$injector;\n\t    }\n\t    UIInjectorImpl.prototype.get = function (token) {\n\t        var resolvable = this.context.getResolvable(token);\n\t        if (resolvable) {\n\t            if (!resolvable.resolved) {\n\t                throw new Error(\"Resolvable async .get() not complete:\" + strings_1.stringify(resolvable.token));\n\t            }\n\t            return resolvable.data;\n\t        }\n\t        return coreservices_1.services.$injector.get(token);\n\t    };\n\t    UIInjectorImpl.prototype.getAsync = function (token) {\n\t        var resolvable = this.context.getResolvable(token);\n\t        if (resolvable)\n\t            return resolvable.get(this.context);\n\t        return coreservices_1.services.$q.when(coreservices_1.services.$injector.get(token));\n\t    };\n\t    return UIInjectorImpl;\n\t}());\n\n\n/***/ },\n/* 18 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\texports.resolvePolicies = {\n\t    when: {\n\t        LAZY: \"LAZY\",\n\t        EAGER: \"EAGER\"\n\t    },\n\t    async: {\n\t        WAIT: \"WAIT\",\n\t        NOWAIT: \"NOWAIT\",\n\t        RXWAIT: \"RXWAIT\"\n\t    }\n\t};\n\n\n/***/ },\n/* 19 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module resolve */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar trace_1 = __webpack_require__(12);\n\tvar strings_1 = __webpack_require__(9);\n\tvar predicates_1 = __webpack_require__(4);\n\t// TODO: explicitly make this user configurable\n\texports.defaultResolvePolicy = {\n\t    when: \"LAZY\",\n\t    async: \"WAIT\"\n\t};\n\t/**\n\t * The basic building block for the resolve system.\n\t *\n\t * Resolvables encapsulate a state's resolve's resolveFn, the resolveFn's declared dependencies, the wrapped (.promise),\n\t * and the unwrapped-when-complete (.data) result of the resolveFn.\n\t *\n\t * Resolvable.get() either retrieves the Resolvable's existing promise, or else invokes resolve() (which invokes the\n\t * resolveFn) and returns the resulting promise.\n\t *\n\t * Resolvable.get() and Resolvable.resolve() both execute within a context path, which is passed as the first\n\t * parameter to those fns.\n\t */\n\tvar Resolvable = (function () {\n\t    function Resolvable(arg1, resolveFn, deps, policy, data) {\n\t        this.resolved = false;\n\t        this.promise = undefined;\n\t        if (arg1 instanceof Resolvable) {\n\t            common_1.extend(this, arg1);\n\t        }\n\t        else if (predicates_1.isFunction(resolveFn)) {\n\t            if (arg1 == null || arg1 == undefined)\n\t                throw new Error(\"new Resolvable(): token argument is required\");\n\t            if (!predicates_1.isFunction(resolveFn))\n\t                throw new Error(\"new Resolvable(): resolveFn argument must be a function\");\n\t            this.token = arg1;\n\t            this.policy = policy;\n\t            this.resolveFn = resolveFn;\n\t            this.deps = deps || [];\n\t            this.data = data;\n\t            this.resolved = data !== undefined;\n\t            this.promise = this.resolved ? coreservices_1.services.$q.when(this.data) : undefined;\n\t        }\n\t        else if (predicates_1.isObject(arg1) && arg1.token && predicates_1.isFunction(arg1.resolveFn)) {\n\t            var literal = arg1;\n\t            return new Resolvable(literal.token, literal.resolveFn, literal.deps, literal.policy, literal.data);\n\t        }\n\t    }\n\t    Resolvable.prototype.getPolicy = function (state) {\n\t        var thisPolicy = this.policy || {};\n\t        var statePolicy = state && state.resolvePolicy || {};\n\t        return {\n\t            when: thisPolicy.when || statePolicy.when || exports.defaultResolvePolicy.when,\n\t            async: thisPolicy.async || statePolicy.async || exports.defaultResolvePolicy.async,\n\t        };\n\t    };\n\t    /**\n\t     * Asynchronously resolve this Resolvable's data\n\t     *\n\t     * Given a ResolveContext that this Resolvable is found in:\n\t     * Wait for this Resolvable's dependencies, then invoke this Resolvable's function\n\t     * and update the Resolvable's state\n\t     */\n\t    Resolvable.prototype.resolve = function (resolveContext, trans) {\n\t        var _this = this;\n\t        var $q = coreservices_1.services.$q;\n\t        // Gets all dependencies from ResolveContext and wait for them to be resolved\n\t        var getResolvableDependencies = function () {\n\t            return $q.all(resolveContext.getDependencies(_this).map(function (r) {\n\t                return r.get(resolveContext, trans);\n\t            }));\n\t        };\n\t        // Invokes the resolve function passing the resolved dependencies as arguments\n\t        var invokeResolveFn = function (resolvedDeps) {\n\t            return _this.resolveFn.apply(null, resolvedDeps);\n\t        };\n\t        /**\n\t         * For RXWAIT policy:\n\t         *\n\t         * Given an observable returned from a resolve function:\n\t         * - enables .cache() mode (this allows multicast subscribers)\n\t         * - then calls toPromise() (this triggers subscribe() and thus fetches)\n\t         * - Waits for the promise, then return the cached observable (not the first emitted value).\n\t         */\n\t        var waitForRx = function (observable$) {\n\t            var cached = observable$.cache();\n\t            return cached.toPromise().then(function () { return cached; });\n\t        };\n\t        // If the resolve policy is RXWAIT, wait for the observable to emit something. otherwise pass through.\n\t        var node = resolveContext.findNode(this);\n\t        var state = node && node.state;\n\t        var maybeWaitForRx = this.getPolicy(state).async === \"RXWAIT\" ? waitForRx : function (x) { return x; };\n\t        // After the final value has been resolved, update the state of the Resolvable\n\t        var applyResolvedValue = function (resolvedValue) {\n\t            _this.data = resolvedValue;\n\t            _this.resolved = true;\n\t            trace_1.trace.traceResolvableResolved(_this, trans);\n\t            return _this.data;\n\t        };\n\t        // Sets the promise property first, then getsResolvableDependencies in the context of the promise chain. Always waits one tick.\n\t        return this.promise = $q.when()\n\t            .then(getResolvableDependencies)\n\t            .then(invokeResolveFn)\n\t            .then(maybeWaitForRx)\n\t            .then(applyResolvedValue);\n\t    };\n\t    /**\n\t     * Gets a promise for this Resolvable's data.\n\t     *\n\t     * Fetches the data and returns a promise.\n\t     * Returns the existing promise if it has already been fetched once.\n\t     */\n\t    Resolvable.prototype.get = function (resolveContext, trans) {\n\t        return this.promise || this.resolve(resolveContext, trans);\n\t    };\n\t    Resolvable.prototype.toString = function () {\n\t        return \"Resolvable(token: \" + strings_1.stringify(this.token) + \", requires: [\" + this.deps.map(strings_1.stringify) + \"])\";\n\t    };\n\t    Resolvable.prototype.clone = function () {\n\t        return new Resolvable(this);\n\t    };\n\t    return Resolvable;\n\t}());\n\texports.Resolvable = Resolvable;\n\n\n/***/ },\n/* 20 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module path */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar targetState_1 = __webpack_require__(14);\n\tvar node_1 = __webpack_require__(21);\n\t/**\n\t * This class contains functions which convert TargetStates, Nodes and paths from one type to another.\n\t */\n\tvar PathFactory = (function () {\n\t    function PathFactory() {\n\t    }\n\t    /** Given a PathNode[], create an TargetState */\n\t    PathFactory.makeTargetState = function (path) {\n\t        var state = common_1.tail(path).state;\n\t        return new targetState_1.TargetState(state, state, path.map(hof_1.prop(\"paramValues\")).reduce(common_1.mergeR, {}));\n\t    };\n\t    PathFactory.buildPath = function (targetState) {\n\t        var toParams = targetState.params();\n\t        return targetState.$state().path.map(function (state) { return new node_1.PathNode(state).applyRawParams(toParams); });\n\t    };\n\t    /** Given a fromPath: PathNode[] and a TargetState, builds a toPath: PathNode[] */\n\t    PathFactory.buildToPath = function (fromPath, targetState) {\n\t        var toPath = PathFactory.buildPath(targetState);\n\t        if (targetState.options().inherit) {\n\t            return PathFactory.inheritParams(fromPath, toPath, Object.keys(targetState.params()));\n\t        }\n\t        return toPath;\n\t    };\n\t    /**\n\t     * Creates ViewConfig objects and adds to nodes.\n\t     *\n\t     * On each [[PathNode]], creates ViewConfig objects from the views: property of the node's state\n\t     */\n\t    PathFactory.applyViewConfigs = function ($view, path, states) {\n\t        // Only apply the viewConfigs to the nodes for the given states\n\t        path.filter(function (node) { return common_1.inArray(states, node.state); }).forEach(function (node) {\n\t            var viewDecls = common_1.values(node.state.views || {});\n\t            var subPath = PathFactory.subPath(path, function (n) { return n === node; });\n\t            var viewConfigs = viewDecls.map(function (view) { return $view.createViewConfig(subPath, view); });\n\t            node.views = viewConfigs.reduce(common_1.unnestR, []);\n\t        });\n\t    };\n\t    /**\n\t     * Given a fromPath and a toPath, returns a new to path which inherits parameters from the fromPath\n\t     *\n\t     * For a parameter in a node to be inherited from the from path:\n\t     * - The toPath's node must have a matching node in the fromPath (by state).\n\t     * - The parameter name must not be found in the toKeys parameter array.\n\t     *\n\t     * Note: the keys provided in toKeys are intended to be those param keys explicitly specified by some\n\t     * caller, for instance, $state.transitionTo(..., toParams).  If a key was found in toParams,\n\t     * it is not inherited from the fromPath.\n\t     */\n\t    PathFactory.inheritParams = function (fromPath, toPath, toKeys) {\n\t        if (toKeys === void 0) { toKeys = []; }\n\t        function nodeParamVals(path, state) {\n\t            var node = common_1.find(path, hof_1.propEq('state', state));\n\t            return common_1.extend({}, node && node.paramValues);\n\t        }\n\t        /**\n\t         * Given an [[PathNode]] \"toNode\", return a new [[PathNode]] with param values inherited from the\n\t         * matching node in fromPath.  Only inherit keys that aren't found in \"toKeys\" from the node in \"fromPath\"\"\n\t         */\n\t        function makeInheritedParamsNode(toNode) {\n\t            // All param values for the node (may include default key/vals, when key was not found in toParams)\n\t            var toParamVals = common_1.extend({}, toNode && toNode.paramValues);\n\t            // limited to only those keys found in toParams\n\t            var incomingParamVals = common_1.pick(toParamVals, toKeys);\n\t            toParamVals = common_1.omit(toParamVals, toKeys);\n\t            var fromParamVals = nodeParamVals(fromPath, toNode.state) || {};\n\t            // extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals\n\t            var ownParamVals = common_1.extend(toParamVals, fromParamVals, incomingParamVals);\n\t            return new node_1.PathNode(toNode.state).applyRawParams(ownParamVals);\n\t        }\n\t        // The param keys specified by the incoming toParams\n\t        return toPath.map(makeInheritedParamsNode);\n\t    };\n\t    /**\n\t     * Computes the tree changes (entering, exiting) between a fromPath and toPath.\n\t     */\n\t    PathFactory.treeChanges = function (fromPath, toPath, reloadState) {\n\t        var keep = 0, max = Math.min(fromPath.length, toPath.length);\n\t        var staticParams = function (state) { return state.parameters({ inherit: false }).filter(hof_1.not(hof_1.prop('dynamic'))).map(hof_1.prop('id')); };\n\t        var nodesMatch = function (node1, node2) { return node1.equals(node2, staticParams(node1.state)); };\n\t        while (keep < max && fromPath[keep].state !== reloadState && nodesMatch(fromPath[keep], toPath[keep])) {\n\t            keep++;\n\t        }\n\t        /** Given a retained node, return a new node which uses the to node's param values */\n\t        function applyToParams(retainedNode, idx) {\n\t            var cloned = node_1.PathNode.clone(retainedNode);\n\t            cloned.paramValues = toPath[idx].paramValues;\n\t            return cloned;\n\t        }\n\t        var from, retained, exiting, entering, to;\n\t        from = fromPath;\n\t        retained = from.slice(0, keep);\n\t        exiting = from.slice(keep);\n\t        // Create a new retained path (with shallow copies of nodes) which have the params of the toPath mapped\n\t        var retainedWithToParams = retained.map(applyToParams);\n\t        entering = toPath.slice(keep);\n\t        to = (retainedWithToParams).concat(entering);\n\t        return { from: from, to: to, retained: retained, exiting: exiting, entering: entering };\n\t    };\n\t    /**\n\t     * Return a subpath of a path, which stops at the first matching node\n\t     *\n\t     * Given an array of nodes, returns a subset of the array starting from the first node,\n\t     * stopping when the first node matches the predicate.\n\t     *\n\t     * @param path a path of [[PathNode]]s\n\t     * @param predicate a [[Predicate]] fn that matches [[PathNode]]s\n\t     * @returns a subpath up to the matching node, or undefined if no match is found\n\t     */\n\t    PathFactory.subPath = function (path, predicate) {\n\t        var node = common_1.find(path, predicate);\n\t        var elementIdx = path.indexOf(node);\n\t        return elementIdx === -1 ? undefined : path.slice(0, elementIdx + 1);\n\t    };\n\t    /** Gets the raw parameter values from a path */\n\t    PathFactory.paramValues = function (path) { return path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {}); };\n\t    return PathFactory;\n\t}());\n\texports.PathFactory = PathFactory;\n\n\n/***/ },\n/* 21 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module path */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar param_1 = __webpack_require__(22);\n\t/**\n\t * A node in a [[TreeChanges]] path\n\t *\n\t * For a [[TreeChanges]] path, this class holds the stateful information for a single node in the path.\n\t * Each PathNode corresponds to a state being entered, exited, or retained.\n\t * The stateful information includes parameter values and resolve data.\n\t */\n\tvar PathNode = (function () {\n\t    function PathNode(state) {\n\t        if (state instanceof PathNode) {\n\t            var node = state;\n\t            this.state = node.state;\n\t            this.paramSchema = node.paramSchema.slice();\n\t            this.paramValues = common_1.extend({}, node.paramValues);\n\t            this.resolvables = node.resolvables.slice();\n\t            this.views = node.views && node.views.slice();\n\t        }\n\t        else {\n\t            this.state = state;\n\t            this.paramSchema = state.parameters({ inherit: false });\n\t            this.paramValues = {};\n\t            this.resolvables = state.resolvables.map(function (res) { return res.clone(); });\n\t        }\n\t    }\n\t    /** Sets [[paramValues]] for the node, from the values of an object hash */\n\t    PathNode.prototype.applyRawParams = function (params) {\n\t        var getParamVal = function (paramDef) { return [paramDef.id, paramDef.value(params[paramDef.id])]; };\n\t        this.paramValues = this.paramSchema.reduce(function (memo, pDef) { return common_1.applyPairs(memo, getParamVal(pDef)); }, {});\n\t        return this;\n\t    };\n\t    /** Gets a specific [[Param]] metadata that belongs to the node */\n\t    PathNode.prototype.parameter = function (name) {\n\t        return common_1.find(this.paramSchema, hof_1.propEq(\"id\", name));\n\t    };\n\t    /**\n\t     * @returns true if the state and parameter values for another PathNode are\n\t     * equal to the state and param values for this PathNode\n\t     */\n\t    PathNode.prototype.equals = function (node, keys) {\n\t        var _this = this;\n\t        if (keys === void 0) { keys = this.paramSchema.map(hof_1.prop('id')); }\n\t        var paramValsEq = function (key) { return _this.parameter(key).type.equals(_this.paramValues[key], node.paramValues[key]); };\n\t        return this.state === node.state && keys.map(paramValsEq).reduce(common_1.allTrueR, true);\n\t    };\n\t    /** Returns a clone of the PathNode */\n\t    PathNode.clone = function (node) {\n\t        return new PathNode(node);\n\t    };\n\t    /**\n\t     * Returns a new path which is a subpath of the first path which matched the second path.\n\t     *\n\t     * The new path starts from root and contains any nodes that match the nodes in the second path.\n\t     * Nodes are compared using their state property and parameter values.\n\t     */\n\t    PathNode.matching = function (pathA, pathB) {\n\t        var matching = [];\n\t        for (var i = 0; i < pathA.length && i < pathB.length; i++) {\n\t            var a = pathA[i], b = pathB[i];\n\t            if (a.state !== b.state)\n\t                break;\n\t            if (!param_1.Param.equals(a.paramSchema, a.paramValues, b.paramValues))\n\t                break;\n\t            matching.push(a);\n\t        }\n\t        return matching;\n\t    };\n\t    return PathNode;\n\t}());\n\texports.PathNode = PathNode;\n\n\n/***/ },\n/* 22 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module params */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar urlMatcherConfig_1 = __webpack_require__(23);\n\tvar type_1 = __webpack_require__(24);\n\tvar paramTypes_1 = __webpack_require__(25);\n\tvar hasOwn = Object.prototype.hasOwnProperty;\n\tvar isShorthand = function (cfg) { return [\"value\", \"type\", \"squash\", \"array\", \"dynamic\"].filter(hasOwn.bind(cfg || {})).length === 0; };\n\t(function (DefType) {\n\t    DefType[DefType[\"PATH\"] = 0] = \"PATH\";\n\t    DefType[DefType[\"SEARCH\"] = 1] = \"SEARCH\";\n\t    DefType[DefType[\"CONFIG\"] = 2] = \"CONFIG\";\n\t})(exports.DefType || (exports.DefType = {}));\n\tvar DefType = exports.DefType;\n\tfunction unwrapShorthand(cfg) {\n\t    cfg = isShorthand(cfg) && { value: cfg } || cfg;\n\t    return common_1.extend(cfg, {\n\t        $$fn: predicates_1.isInjectable(cfg.value) ? cfg.value : function () { return cfg.value; }\n\t    });\n\t}\n\tfunction getType(cfg, urlType, location, id) {\n\t    if (cfg.type && urlType && urlType.name !== 'string')\n\t        throw new Error(\"Param '\" + id + \"' has two type configurations.\");\n\t    if (cfg.type && urlType && urlType.name === 'string' && paramTypes_1.paramTypes.type(cfg.type))\n\t        return paramTypes_1.paramTypes.type(cfg.type);\n\t    if (urlType)\n\t        return urlType;\n\t    if (!cfg.type)\n\t        return (location === DefType.CONFIG ? paramTypes_1.paramTypes.type(\"any\") : paramTypes_1.paramTypes.type(\"string\"));\n\t    return cfg.type instanceof type_1.ParamType ? cfg.type : paramTypes_1.paramTypes.type(cfg.type);\n\t}\n\t/**\n\t * returns false, true, or the squash value to indicate the \"default parameter url squash policy\".\n\t */\n\tfunction getSquashPolicy(config, isOptional) {\n\t    var squash = config.squash;\n\t    if (!isOptional || squash === false)\n\t        return false;\n\t    if (!predicates_1.isDefined(squash) || squash == null)\n\t        return urlMatcherConfig_1.matcherConfig.defaultSquashPolicy();\n\t    if (squash === true || predicates_1.isString(squash))\n\t        return squash;\n\t    throw new Error(\"Invalid squash policy: '\" + squash + \"'. Valid policies: false, true, or arbitrary string\");\n\t}\n\tfunction getReplace(config, arrayMode, isOptional, squash) {\n\t    var replace, configuredKeys, defaultPolicy = [\n\t        { from: \"\", to: (isOptional || arrayMode ? undefined : \"\") },\n\t        { from: null, to: (isOptional || arrayMode ? undefined : \"\") }\n\t    ];\n\t    replace = predicates_1.isArray(config.replace) ? config.replace : [];\n\t    if (predicates_1.isString(squash))\n\t        replace.push({ from: squash, to: undefined });\n\t    configuredKeys = common_1.map(replace, hof_1.prop(\"from\"));\n\t    return common_1.filter(defaultPolicy, function (item) { return configuredKeys.indexOf(item.from) === -1; }).concat(replace);\n\t}\n\tvar Param = (function () {\n\t    function Param(id, type, config, location) {\n\t        config = unwrapShorthand(config);\n\t        type = getType(config, type, location, id);\n\t        var arrayMode = getArrayMode();\n\t        type = arrayMode ? type.$asArray(arrayMode, location === DefType.SEARCH) : type;\n\t        var isOptional = config.value !== undefined;\n\t        var dynamic = predicates_1.isDefined(config.dynamic) ? !!config.dynamic : !!type.dynamic;\n\t        var squash = getSquashPolicy(config, isOptional);\n\t        var replace = getReplace(config, arrayMode, isOptional, squash);\n\t        // array config: param name (param[]) overrides default settings.  explicit config overrides param name.\n\t        function getArrayMode() {\n\t            var arrayDefaults = { array: (location === DefType.SEARCH ? \"auto\" : false) };\n\t            var arrayParamNomenclature = id.match(/\\[\\]$/) ? { array: true } : {};\n\t            return common_1.extend(arrayDefaults, arrayParamNomenclature, config).array;\n\t        }\n\t        common_1.extend(this, { id: id, type: type, location: location, squash: squash, replace: replace, isOptional: isOptional, dynamic: dynamic, config: config, array: arrayMode });\n\t    }\n\t    Param.prototype.isDefaultValue = function (value) {\n\t        return this.isOptional && this.type.equals(this.value(), value);\n\t    };\n\t    /**\n\t     * [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the\n\t     * default value, which may be the result of an injectable function.\n\t     */\n\t    Param.prototype.value = function (value) {\n\t        var _this = this;\n\t        /**\n\t         * [Internal] Get the default value of a parameter, which may be an injectable function.\n\t         */\n\t        var $$getDefaultValue = function () {\n\t            if (!coreservices_1.services.$injector)\n\t                throw new Error(\"Injectable functions cannot be called at configuration time\");\n\t            var defaultValue = coreservices_1.services.$injector.invoke(_this.config.$$fn);\n\t            if (defaultValue !== null && defaultValue !== undefined && !_this.type.is(defaultValue))\n\t                throw new Error(\"Default value (\" + defaultValue + \") for parameter '\" + _this.id + \"' is not an instance of ParamType (\" + _this.type.name + \")\");\n\t            return defaultValue;\n\t        };\n\t        var $replace = function (val) {\n\t            var replacement = common_1.map(common_1.filter(_this.replace, hof_1.propEq('from', val)), hof_1.prop(\"to\"));\n\t            return replacement.length ? replacement[0] : val;\n\t        };\n\t        value = $replace(value);\n\t        return !predicates_1.isDefined(value) ? $$getDefaultValue() : this.type.$normalize(value);\n\t    };\n\t    Param.prototype.isSearch = function () {\n\t        return this.location === DefType.SEARCH;\n\t    };\n\t    Param.prototype.validates = function (value) {\n\t        // There was no parameter value, but the param is optional\n\t        if ((!predicates_1.isDefined(value) || value === null) && this.isOptional)\n\t            return true;\n\t        // The value was not of the correct ParamType, and could not be decoded to the correct ParamType\n\t        var normalized = this.type.$normalize(value);\n\t        if (!this.type.is(normalized))\n\t            return false;\n\t        // The value was of the correct type, but when encoded, did not match the ParamType's regexp\n\t        var encoded = this.type.encode(normalized);\n\t        return !(predicates_1.isString(encoded) && !this.type.pattern.exec(encoded));\n\t    };\n\t    Param.prototype.toString = function () {\n\t        return \"{Param:\" + this.id + \" \" + this.type + \" squash: '\" + this.squash + \"' optional: \" + this.isOptional + \"}\";\n\t    };\n\t    /** Creates a new [[Param]] from a CONFIG block */\n\t    Param.fromConfig = function (id, type, config) {\n\t        return new Param(id, type, config, DefType.CONFIG);\n\t    };\n\t    /** Creates a new [[Param]] from a url PATH */\n\t    Param.fromPath = function (id, type, config) {\n\t        return new Param(id, type, config, DefType.PATH);\n\t    };\n\t    /** Creates a new [[Param]] from a url SEARCH */\n\t    Param.fromSearch = function (id, type, config) {\n\t        return new Param(id, type, config, DefType.SEARCH);\n\t    };\n\t    Param.values = function (params, values) {\n\t        if (values === void 0) { values = {}; }\n\t        return params.map(function (param) { return [param.id, param.value(values[param.id])]; }).reduce(common_1.applyPairs, {});\n\t    };\n\t    /**\n\t     * Finds [[Param]] objects which have different param values\n\t     *\n\t     * Filters a list of [[Param]] objects to only those whose parameter values differ in two param value objects\n\t     *\n\t     * @param params: The list of Param objects to filter\n\t     * @param values1: The first set of parameter values\n\t     * @param values2: the second set of parameter values\n\t     *\n\t     * @returns any Param objects whose values were different between values1 and values2\n\t     */\n\t    Param.changed = function (params, values1, values2) {\n\t        if (values1 === void 0) { values1 = {}; }\n\t        if (values2 === void 0) { values2 = {}; }\n\t        return params.filter(function (param) { return !param.type.equals(values1[param.id], values2[param.id]); });\n\t    };\n\t    /**\n\t     * Checks if two param value objects are equal (for a set of [[Param]] objects)\n\t     *\n\t     * @param params The list of [[Param]] objects to check\n\t     * @param values1 The first set of param values\n\t     * @param values2 The second set of param values\n\t     *\n\t     * @returns true if the param values in values1 and values2 are equal\n\t     */\n\t    Param.equals = function (params, values1, values2) {\n\t        if (values1 === void 0) { values1 = {}; }\n\t        if (values2 === void 0) { values2 = {}; }\n\t        return Param.changed(params, values1, values2).length === 0;\n\t    };\n\t    /** Returns true if a the parameter values are valid, according to the Param definitions */\n\t    Param.validates = function (params, values) {\n\t        if (values === void 0) { values = {}; }\n\t        return params.map(function (param) { return param.validates(values[param.id]); }).reduce(common_1.allTrueR, true);\n\t    };\n\t    return Param;\n\t}());\n\texports.Param = Param;\n\n\n/***/ },\n/* 23 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module url */ /** for typedoc */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar MatcherConfig = (function () {\n\t    function MatcherConfig() {\n\t        this._isCaseInsensitive = false;\n\t        this._isStrictMode = true;\n\t        this._defaultSquashPolicy = false;\n\t    }\n\t    MatcherConfig.prototype.caseInsensitive = function (value) {\n\t        return this._isCaseInsensitive = predicates_1.isDefined(value) ? value : this._isCaseInsensitive;\n\t    };\n\t    MatcherConfig.prototype.strictMode = function (value) {\n\t        return this._isStrictMode = predicates_1.isDefined(value) ? value : this._isStrictMode;\n\t    };\n\t    MatcherConfig.prototype.defaultSquashPolicy = function (value) {\n\t        if (predicates_1.isDefined(value) && value !== true && value !== false && !predicates_1.isString(value))\n\t            throw new Error(\"Invalid squash policy: \" + value + \". Valid policies: false, true, arbitrary-string\");\n\t        return this._defaultSquashPolicy = predicates_1.isDefined(value) ? value : this._defaultSquashPolicy;\n\t    };\n\t    return MatcherConfig;\n\t}());\n\texports.MatcherConfig = MatcherConfig;\n\t// TODO: Do not export global instance; create one in UIRouter() constructor\n\texports.matcherConfig = new MatcherConfig();\n\n\n/***/ },\n/* 24 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module params */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\t/**\n\t * Wraps up a `ParamType` object to handle array values.\n\t */\n\tfunction ArrayType(type, mode) {\n\t    var _this = this;\n\t    // Wrap non-array value as array\n\t    function arrayWrap(val) { return predicates_1.isArray(val) ? val : (predicates_1.isDefined(val) ? [val] : []); }\n\t    // Unwrap array value for \"auto\" mode. Return undefined for empty array.\n\t    function arrayUnwrap(val) {\n\t        switch (val.length) {\n\t            case 0: return undefined;\n\t            case 1: return mode === \"auto\" ? val[0] : val;\n\t            default: return val;\n\t        }\n\t    }\n\t    // Wraps type (.is/.encode/.decode) functions to operate on each value of an array\n\t    function arrayHandler(callback, allTruthyMode) {\n\t        return function handleArray(val) {\n\t            if (predicates_1.isArray(val) && val.length === 0)\n\t                return val;\n\t            var arr = arrayWrap(val);\n\t            var result = common_1.map(arr, callback);\n\t            return (allTruthyMode === true) ? common_1.filter(result, function (x) { return !x; }).length === 0 : arrayUnwrap(result);\n\t        };\n\t    }\n\t    // Wraps type (.equals) functions to operate on each value of an array\n\t    function arrayEqualsHandler(callback) {\n\t        return function handleArray(val1, val2) {\n\t            var left = arrayWrap(val1), right = arrayWrap(val2);\n\t            if (left.length !== right.length)\n\t                return false;\n\t            for (var i = 0; i < left.length; i++) {\n\t                if (!callback(left[i], right[i]))\n\t                    return false;\n\t            }\n\t            return true;\n\t        };\n\t    }\n\t    ['encode', 'decode', 'equals', '$normalize'].map(function (name) {\n\t        _this[name] = (name === 'equals' ? arrayEqualsHandler : arrayHandler)(type[name].bind(type));\n\t    });\n\t    common_1.extend(this, {\n\t        dynamic: type.dynamic,\n\t        name: type.name,\n\t        pattern: type.pattern,\n\t        is: arrayHandler(type.is.bind(type), true),\n\t        $arrayMode: mode\n\t    });\n\t}\n\t/**\n\t * A class that implements Custom Parameter Type functionality.\n\t *\n\t * This class has naive implementations for all the [[ParamTypeDefinition]] methods.\n\t *\n\t * An instance of this class is created when a custom [[ParamTypeDefinition]] object is registered with the [[UrlMatcherFactory.type]].\n\t *\n\t * Used by [[UrlMatcher]] when matching or formatting URLs, or comparing and validating parameter values.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * {\n\t *   decode: function(val) { return parseInt(val, 10); },\n\t *   encode: function(val) { return val && val.toString(); },\n\t *   equals: function(a, b) { return this.is(a) && a === b; },\n\t *   is: function(val) { return angular.isNumber(val) && isFinite(val) && val % 1 === 0; },\n\t *   pattern: /\\d+/\n\t * }\n\t * ```\n\t */\n\tvar ParamType = (function () {\n\t    /**\n\t     * @param def  A configuration object which contains the custom type definition.  The object's\n\t     *        properties will override the default methods and/or pattern in `ParamType`'s public interface.\n\t     * @returns a new ParamType object\n\t     */\n\t    function ParamType(def) {\n\t        this.pattern = /.*/;\n\t        common_1.extend(this, def);\n\t    }\n\t    // consider these four methods to be \"abstract methods\" that should be overridden\n\t    /** @inheritdoc */\n\t    ParamType.prototype.is = function (val, key) { return true; };\n\t    /** @inheritdoc */\n\t    ParamType.prototype.encode = function (val, key) { return val; };\n\t    /** @inheritdoc */\n\t    ParamType.prototype.decode = function (val, key) { return val; };\n\t    /** @inheritdoc */\n\t    ParamType.prototype.equals = function (a, b) { return a == b; };\n\t    ParamType.prototype.$subPattern = function () {\n\t        var sub = this.pattern.toString();\n\t        return sub.substr(1, sub.length - 2);\n\t    };\n\t    ParamType.prototype.toString = function () {\n\t        return \"{ParamType:\" + this.name + \"}\";\n\t    };\n\t    /** Given an encoded string, or a decoded object, returns a decoded object */\n\t    ParamType.prototype.$normalize = function (val) {\n\t        return this.is(val) ? val : this.decode(val);\n\t    };\n\t    /**\n\t     * Wraps an existing custom ParamType as an array of ParamType, depending on 'mode'.\n\t     * e.g.:\n\t     * - urlmatcher pattern \"/path?{queryParam[]:int}\"\n\t     * - url: \"/path?queryParam=1&queryParam=2\n\t     * - $stateParams.queryParam will be [1, 2]\n\t     * if `mode` is \"auto\", then\n\t     * - url: \"/path?queryParam=1 will create $stateParams.queryParam: 1\n\t     * - url: \"/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]\n\t     */\n\t    ParamType.prototype.$asArray = function (mode, isSearch) {\n\t        if (!mode)\n\t            return this;\n\t        if (mode === \"auto\" && !isSearch)\n\t            throw new Error(\"'auto' array mode is for query parameters only\");\n\t        return new ArrayType(this, mode);\n\t    };\n\t    return ParamType;\n\t}());\n\texports.ParamType = ParamType;\n\n\n/***/ },\n/* 25 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module params */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar type_1 = __webpack_require__(24);\n\t// Use tildes to pre-encode slashes.\n\t// If the slashes are simply URLEncoded, the browser can choose to pre-decode them,\n\t// and bidirectional encoding/decoding fails.\n\t// Tilde was chosen because it's not a RFC 3986 section 2.2 Reserved Character\n\tfunction valToString(val) { return val != null ? val.toString().replace(/~/g, \"~~\").replace(/\\//g, \"~2F\") : val; }\n\tfunction valFromString(val) { return val != null ? val.toString().replace(/~2F/g, \"/\").replace(/~~/g, \"~\") : val; }\n\tvar ParamTypes = (function () {\n\t    function ParamTypes() {\n\t        this.enqueue = true;\n\t        this.typeQueue = [];\n\t        this.defaultTypes = {\n\t            \"hash\": {\n\t                encode: valToString,\n\t                decode: valFromString,\n\t                is: hof_1.is(String),\n\t                pattern: /.*/,\n\t                equals: function (a, b) { return a == b; } // allow coersion for null/undefined/\"\"\n\t            },\n\t            \"string\": {\n\t                encode: valToString,\n\t                decode: valFromString,\n\t                is: hof_1.is(String),\n\t                pattern: /[^/]*/\n\t            },\n\t            \"int\": {\n\t                encode: valToString,\n\t                decode: function (val) { return parseInt(val, 10); },\n\t                is: function (val) { return predicates_1.isDefined(val) && this.decode(val.toString()) === val; },\n\t                pattern: /-?\\d+/\n\t            },\n\t            \"bool\": {\n\t                encode: function (val) { return val && 1 || 0; },\n\t                decode: function (val) { return parseInt(val, 10) !== 0; },\n\t                is: hof_1.is(Boolean),\n\t                pattern: /0|1/\n\t            },\n\t            \"date\": {\n\t                encode: function (val) {\n\t                    return !this.is(val) ? undefined : [\n\t                        val.getFullYear(),\n\t                        ('0' + (val.getMonth() + 1)).slice(-2),\n\t                        ('0' + val.getDate()).slice(-2)\n\t                    ].join(\"-\");\n\t                },\n\t                decode: function (val) {\n\t                    if (this.is(val))\n\t                        return val;\n\t                    var match = this.capture.exec(val);\n\t                    return match ? new Date(match[1], match[2] - 1, match[3]) : undefined;\n\t                },\n\t                is: function (val) { return val instanceof Date && !isNaN(val.valueOf()); },\n\t                equals: function (l, r) {\n\t                    return ['getFullYear', 'getMonth', 'getDate']\n\t                        .reduce(function (acc, fn) { return acc && l[fn]() === r[fn](); }, true);\n\t                },\n\t                pattern: /[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,\n\t                capture: /([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/\n\t            },\n\t            \"json\": {\n\t                encode: common_1.toJson,\n\t                decode: common_1.fromJson,\n\t                is: hof_1.is(Object),\n\t                equals: common_1.equals,\n\t                pattern: /[^/]*/\n\t            },\n\t            \"any\": {\n\t                encode: common_1.identity,\n\t                decode: common_1.identity,\n\t                equals: common_1.equals,\n\t                pattern: /.*/\n\t            }\n\t        };\n\t        // Register default types. Store them in the prototype of this.types.\n\t        var makeType = function (definition, name) { return new type_1.ParamType(common_1.extend({ name: name }, definition)); };\n\t        this.types = common_1.inherit(common_1.map(this.defaultTypes, makeType), {});\n\t    }\n\t    ParamTypes.prototype.type = function (name, definition, definitionFn) {\n\t        if (!predicates_1.isDefined(definition))\n\t            return this.types[name];\n\t        if (this.types.hasOwnProperty(name))\n\t            throw new Error(\"A type named '\" + name + \"' has already been defined.\");\n\t        this.types[name] = new type_1.ParamType(common_1.extend({ name: name }, definition));\n\t        if (definitionFn) {\n\t            this.typeQueue.push({ name: name, def: definitionFn });\n\t            if (!this.enqueue)\n\t                this._flushTypeQueue();\n\t        }\n\t        return this;\n\t    };\n\t    ParamTypes.prototype._flushTypeQueue = function () {\n\t        while (this.typeQueue.length) {\n\t            var type = this.typeQueue.shift();\n\t            if (type.pattern)\n\t                throw new Error(\"You cannot override a type's .pattern at runtime.\");\n\t            common_1.extend(this.types[type.name], coreservices_1.services.$injector.invoke(type.def));\n\t        }\n\t    };\n\t    return ParamTypes;\n\t}());\n\texports.ParamTypes = ParamTypes;\n\texports.paramTypes = new ParamTypes();\n\n\n/***/ },\n/* 26 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module core */ /** */\n\tvar urlMatcherFactory_1 = __webpack_require__(27);\n\tvar urlRouter_1 = __webpack_require__(29);\n\tvar state_1 = __webpack_require__(30);\n\tvar urlRouter_2 = __webpack_require__(29);\n\tvar transitionService_1 = __webpack_require__(31);\n\tvar view_1 = __webpack_require__(37);\n\tvar stateRegistry_1 = __webpack_require__(38);\n\tvar stateService_1 = __webpack_require__(43);\n\tvar globals_1 = __webpack_require__(44);\n\t/**\n\t * The master class used to instantiate an instance of UI-Router.\n\t *\n\t * This class instantiates and wires the global UI-Router services.\n\t *\n\t * After instantiating a new instance of the Router class, configure it for your app.  For instance, register\n\t * your app states with the [[stateRegistry]] (and set url options using ...).  Then, tell UI-Router to monitor\n\t * the URL by calling `urlRouter.listen()` ([[URLRouter.listen]])\n\t */\n\tvar UIRouter = (function () {\n\t    function UIRouter() {\n\t        this.viewService = new view_1.ViewService();\n\t        this.transitionService = new transitionService_1.TransitionService(this);\n\t        this.globals = new globals_1.Globals(this.transitionService);\n\t        this.urlMatcherFactory = new urlMatcherFactory_1.UrlMatcherFactory();\n\t        this.urlRouterProvider = new urlRouter_1.UrlRouterProvider(this.urlMatcherFactory, this.globals.params);\n\t        this.urlRouter = new urlRouter_2.UrlRouter(this.urlRouterProvider);\n\t        this.stateRegistry = new stateRegistry_1.StateRegistry(this.urlMatcherFactory, this.urlRouterProvider);\n\t        /** @hidden TODO: move this to ng1.ts */\n\t        this.stateProvider = new state_1.StateProvider(this.stateRegistry);\n\t        this.stateService = new stateService_1.StateService(this);\n\t        this.viewService.rootContext(this.stateRegistry.root());\n\t        this.globals.$current = this.stateRegistry.root();\n\t        this.globals.current = this.globals.$current.self;\n\t    }\n\t    return UIRouter;\n\t}());\n\texports.UIRouter = UIRouter;\n\n\n/***/ },\n/* 27 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module url */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar urlMatcher_1 = __webpack_require__(28);\n\tvar urlMatcherConfig_1 = __webpack_require__(23);\n\tvar param_1 = __webpack_require__(22);\n\tvar paramTypes_1 = __webpack_require__(25);\n\t/** @hidden */\n\tfunction getDefaultConfig() {\n\t    return {\n\t        strict: urlMatcherConfig_1.matcherConfig.strictMode(),\n\t        caseInsensitive: urlMatcherConfig_1.matcherConfig.caseInsensitive()\n\t    };\n\t}\n\t/**\n\t * Factory for [[UrlMatcher]] instances.\n\t *\n\t * The factory is available to ng1 services as\n\t * `$urlMatcherFactor` or ng1 providers as `$urlMatcherFactoryProvider`.\n\t */\n\tvar UrlMatcherFactory = (function () {\n\t    function UrlMatcherFactory() {\n\t        common_1.extend(this, { UrlMatcher: urlMatcher_1.UrlMatcher, Param: param_1.Param });\n\t    }\n\t    /**\n\t     * Defines whether URL matching should be case sensitive (the default behavior), or not.\n\t     *\n\t     * @param value `false` to match URL in a case sensitive manner; otherwise `true`;\n\t     * @returns the current value of caseInsensitive\n\t     */\n\t    UrlMatcherFactory.prototype.caseInsensitive = function (value) {\n\t        return urlMatcherConfig_1.matcherConfig.caseInsensitive(value);\n\t    };\n\t    /**\n\t     * Defines whether URLs should match trailing slashes, or not (the default behavior).\n\t     *\n\t     * @param value `false` to match trailing slashes in URLs, otherwise `true`.\n\t     * @returns the current value of strictMode\n\t     */\n\t    UrlMatcherFactory.prototype.strictMode = function (value) {\n\t        return urlMatcherConfig_1.matcherConfig.strictMode(value);\n\t    };\n\t    /**\n\t     * Sets the default behavior when generating or matching URLs with default parameter values.\n\t     *\n\t     * @param value A string that defines the default parameter URL squashing behavior.\n\t     *    - `nosquash`: When generating an href with a default parameter value, do not squash the parameter value from the URL\n\t     *    - `slash`: When generating an href with a default parameter value, squash (remove) the parameter value, and, if the\n\t     *             parameter is surrounded by slashes, squash (remove) one slash from the URL\n\t     *    - any other string, e.g. \"~\": When generating an href with a default parameter value, squash (remove)\n\t     *             the parameter value from the URL and replace it with this string.\n\t     * @returns the current value of defaultSquashPolicy\n\t     */\n\t    UrlMatcherFactory.prototype.defaultSquashPolicy = function (value) {\n\t        return urlMatcherConfig_1.matcherConfig.defaultSquashPolicy(value);\n\t    };\n\t    /**\n\t     * Creates a [[UrlMatcher]] for the specified pattern.\n\t     *\n\t     * @param pattern  The URL pattern.\n\t     * @param config  The config object hash.\n\t     * @returns The UrlMatcher.\n\t     */\n\t    UrlMatcherFactory.prototype.compile = function (pattern, config) {\n\t        return new urlMatcher_1.UrlMatcher(pattern, common_1.extend(getDefaultConfig(), config));\n\t    };\n\t    /**\n\t     * Returns true if the specified object is a [[UrlMatcher]], or false otherwise.\n\t     *\n\t     * @param object  The object to perform the type check against.\n\t     * @returns `true` if the object matches the `UrlMatcher` interface, by\n\t     *          implementing all the same methods.\n\t     */\n\t    UrlMatcherFactory.prototype.isMatcher = function (object) {\n\t        // TODO: typeof?\n\t        if (!predicates_1.isObject(object))\n\t            return false;\n\t        var result = true;\n\t        common_1.forEach(urlMatcher_1.UrlMatcher.prototype, function (val, name) {\n\t            if (predicates_1.isFunction(val))\n\t                result = result && (predicates_1.isDefined(object[name]) && predicates_1.isFunction(object[name]));\n\t        });\n\t        return result;\n\t    };\n\t    ;\n\t    /**\n\t     * Creates and registers a custom [[ParamType]] object that can be used to generate URLs with typed parameters.\n\t     *\n\t     * @param name  The type name.\n\t     * @param definition The type definition. See [[ParamTypeDefinition]] for information on the values accepted.\n\t     * @param definitionFn A function that is injected before the app\n\t     *        runtime starts.  The result of this function is merged into the existing `definition`.\n\t     *        See [[ParamType]] for information on the values accepted.\n\t     *\n\t     * @returns - if a type was registered: the [[UrlMatcherFactory]]\n\t     *   - if only the `name` parameter was specified: the currently registered [[ParamType]] object, or undefined\n\t     *\n\t     * This is a simple example of a custom type that encodes and decodes items from an\n\t     * array, using the array index as the URL-encoded value:\n\t     */\n\t    UrlMatcherFactory.prototype.type = function (name, definition, definitionFn) {\n\t        var type = paramTypes_1.paramTypes.type(name, definition, definitionFn);\n\t        return !predicates_1.isDefined(definition) ? type : this;\n\t    };\n\t    ;\n\t    /** @hidden */\n\t    UrlMatcherFactory.prototype.$get = function () {\n\t        paramTypes_1.paramTypes.enqueue = false;\n\t        paramTypes_1.paramTypes._flushTypeQueue();\n\t        return this;\n\t    };\n\t    ;\n\t    return UrlMatcherFactory;\n\t}());\n\texports.UrlMatcherFactory = UrlMatcherFactory;\n\n\n/***/ },\n/* 28 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module url */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar param_1 = __webpack_require__(22);\n\tvar paramTypes_1 = __webpack_require__(25);\n\tvar predicates_2 = __webpack_require__(4);\n\tvar param_2 = __webpack_require__(22);\n\tvar common_2 = __webpack_require__(3);\n\tvar common_3 = __webpack_require__(3);\n\t/** @hidden */\n\tfunction quoteRegExp(string, param) {\n\t    var surroundPattern = ['', ''], result = string.replace(/[\\\\\\[\\]\\^$*+?.()|{}]/g, \"\\\\$&\");\n\t    if (!param)\n\t        return result;\n\t    switch (param.squash) {\n\t        case false:\n\t            surroundPattern = ['(', ')' + (param.isOptional ? '?' : '')];\n\t            break;\n\t        case true:\n\t            result = result.replace(/\\/$/, '');\n\t            surroundPattern = ['(?:\\/(', ')|\\/)?'];\n\t            break;\n\t        default:\n\t            surroundPattern = [(\"(\" + param.squash + \"|\"), ')?'];\n\t            break;\n\t    }\n\t    return result + surroundPattern[0] + param.type.pattern.source + surroundPattern[1];\n\t}\n\t/** @hidden */\n\tvar memoizeTo = function (obj, prop, fn) { return obj[prop] = obj[prop] || fn(); };\n\t/**\n\t * Matches URLs against patterns.\n\t *\n\t * Matches URLs against patterns and extracts named parameters from the path or the search\n\t * part of the URL.\n\t *\n\t * A URL pattern consists of a path pattern, optionally followed by '?' and a list of search (query)\n\t * parameters. Multiple search parameter names are separated by '&'. Search parameters\n\t * do not influence whether or not a URL is matched, but their values are passed through into\n\t * the matched parameters returned by [[UrlMatcher.exec]].\n\t *\n\t * - *Path parameters* are defined using curly brace placeholders (`/somepath/{param}`)\n\t * or colon placeholders (`/somePath/:param`).\n\t *\n\t * - *A parameter RegExp* may be defined for a param after a colon\n\t * (`/somePath/{param:[a-zA-Z0-9]+}`) in a curly brace placeholder.\n\t * The regexp must match for the url to be matched.\n\t * Should the regexp itself contain curly braces, they must be in matched pairs or escaped with a backslash.\n\t *\n\t * - *Custom parameter types* may also be specified after a colon (`/somePath/{param:int}`)\n\t * in curly brace parameters.  See [[UrlMatcherFactory.type]] for more information.\n\t *\n\t * - *Catch-all parameters* are defined using an asterisk placeholder (`/somepath/*catchallparam`).  A catch-all\n\t * parameter value will contain the remainder of the URL.\n\t *\n\t * ---\n\t *\n\t * Parameter names may contain only word characters (latin letters, digits, and underscore) and\n\t * must be unique within the pattern (across both path and search parameters).\n\t * A path parameter matches any number of characters other than '/'. For catch-all\n\t * placeholders the path parameter matches any number of characters.\n\t *\n\t * Examples:\n\t *\n\t * * `'/hello/'` - Matches only if the path is exactly '/hello/'. There is no special treatment for\n\t *   trailing slashes, and patterns have to match the entire path, not just a prefix.\n\t * * `'/user/:id'` - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or\n\t *   '/user/bob/details'. The second path segment will be captured as the parameter 'id'.\n\t * * `'/user/{id}'` - Same as the previous example, but using curly brace syntax.\n\t * * `'/user/{id:[^/]*}'` - Same as the previous example.\n\t * * `'/user/{id:[0-9a-fA-F]{1,8}}'` - Similar to the previous example, but only matches if the id\n\t *   parameter consists of 1 to 8 hex digits.\n\t * * `'/files/{path:.*}'` - Matches any URL starting with '/files/' and captures the rest of the\n\t *   path into the parameter 'path'.\n\t * * `'/files/*path'` - ditto.\n\t * * `'/calendar/{start:date}'` - Matches \"/calendar/2014-11-12\" (because the pattern defined\n\t *   in the built-in  `date` ParamType matches `2014-11-12`) and provides a Date object in $stateParams.start\n\t *\n\t */\n\tvar UrlMatcher = (function () {\n\t    /**\n\t     * @param pattern The pattern to compile into a matcher.\n\t     * @param config  A configuration object hash\n\t     * * `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`.\n\t     * * `strict` - `false` if matching against a URL with a trailing slash should be treated as equivalent to a URL without a trailing slash, the default value is `true`.\n\t     *\n\t     * @property {string} pattern  The pattern that was passed into the constructor\n\t     */\n\t    function UrlMatcher(pattern, config) {\n\t        var _this = this;\n\t        this.config = config;\n\t        /** @hidden */\n\t        this._cache = { path: [], pattern: null };\n\t        /** @hidden */\n\t        this._children = [];\n\t        /** @hidden */\n\t        this._params = [];\n\t        /** @hidden */\n\t        this._segments = [];\n\t        /** @hidden */\n\t        this._compiled = [];\n\t        this.pattern = pattern;\n\t        this.config = common_1.defaults(this.config, {\n\t            params: {},\n\t            strict: true,\n\t            caseInsensitive: false,\n\t            paramMap: common_1.identity\n\t        });\n\t        // Find all placeholders and create a compiled pattern, using either classic or curly syntax:\n\t        //   '*' name\n\t        //   ':' name\n\t        //   '{' name '}'\n\t        //   '{' name ':' regexp '}'\n\t        // The regular expression is somewhat complicated due to the need to allow curly braces\n\t        // inside the regular expression. The placeholder regexp breaks down as follows:\n\t        //    ([:*])([\\w\\[\\]]+)              - classic placeholder ($1 / $2) (search version has - for snake-case)\n\t        //    \\{([\\w\\[\\]]+)(?:\\:\\s*( ... ))?\\}  - curly brace placeholder ($3) with optional regexp/type ... ($4) (search version has - for snake-case\n\t        //    (?: ... | ... | ... )+         - the regexp consists of any number of atoms, an atom being either\n\t        //    [^{}\\\\]+                       - anything other than curly braces or backslash\n\t        //    \\\\.                            - a backslash escape\n\t        //    \\{(?:[^{}\\\\]+|\\\\.)*\\}          - a matched set of curly braces containing other atoms\n\t        var placeholder = /([:*])([\\w\\[\\]]+)|\\{([\\w\\[\\]]+)(?:\\:\\s*((?:[^{}\\\\]+|\\\\.|\\{(?:[^{}\\\\]+|\\\\.)*\\})+))?\\}/g, searchPlaceholder = /([:]?)([\\w\\[\\].-]+)|\\{([\\w\\[\\].-]+)(?:\\:\\s*((?:[^{}\\\\]+|\\\\.|\\{(?:[^{}\\\\]+|\\\\.)*\\})+))?\\}/g, last = 0, m, patterns = [];\n\t        var checkParamErrors = function (id) {\n\t            if (!UrlMatcher.nameValidator.test(id))\n\t                throw new Error(\"Invalid parameter name '\" + id + \"' in pattern '\" + pattern + \"'\");\n\t            if (common_1.find(_this._params, hof_1.propEq('id', id)))\n\t                throw new Error(\"Duplicate parameter name '\" + id + \"' in pattern '\" + pattern + \"'\");\n\t        };\n\t        // Split into static segments separated by path parameter placeholders.\n\t        // The number of segments is always 1 more than the number of parameters.\n\t        var matchDetails = function (m, isSearch) {\n\t            // IE[78] returns '' for unmatched groups instead of null\n\t            var id = m[2] || m[3], regexp = isSearch ? m[4] : m[4] || (m[1] === '*' ? '.*' : null);\n\t            return {\n\t                id: id,\n\t                regexp: regexp,\n\t                cfg: _this.config.params[id],\n\t                segment: pattern.substring(last, m.index),\n\t                type: !regexp ? null : paramTypes_1.paramTypes.type(regexp || \"string\") || common_1.inherit(paramTypes_1.paramTypes.type(\"string\"), {\n\t                    pattern: new RegExp(regexp, _this.config.caseInsensitive ? 'i' : undefined)\n\t                })\n\t            };\n\t        };\n\t        var p, segment;\n\t        while ((m = placeholder.exec(pattern))) {\n\t            p = matchDetails(m, false);\n\t            if (p.segment.indexOf('?') >= 0)\n\t                break; // we're into the search part\n\t            checkParamErrors(p.id);\n\t            this._params.push(param_1.Param.fromPath(p.id, p.type, this.config.paramMap(p.cfg, false)));\n\t            this._segments.push(p.segment);\n\t            patterns.push([p.segment, common_1.tail(this._params)]);\n\t            last = placeholder.lastIndex;\n\t        }\n\t        segment = pattern.substring(last);\n\t        // Find any search parameter names and remove them from the last segment\n\t        var i = segment.indexOf('?');\n\t        if (i >= 0) {\n\t            var search = segment.substring(i);\n\t            segment = segment.substring(0, i);\n\t            if (search.length > 0) {\n\t                last = 0;\n\t                while ((m = searchPlaceholder.exec(search))) {\n\t                    p = matchDetails(m, true);\n\t                    checkParamErrors(p.id);\n\t                    this._params.push(param_1.Param.fromSearch(p.id, p.type, this.config.paramMap(p.cfg, true)));\n\t                    last = placeholder.lastIndex;\n\t                }\n\t            }\n\t        }\n\t        this._segments.push(segment);\n\t        common_1.extend(this, {\n\t            _compiled: patterns.map(function (pattern) { return quoteRegExp.apply(null, pattern); }).concat(quoteRegExp(segment)),\n\t            prefix: this._segments[0]\n\t        });\n\t        Object.freeze(this);\n\t    }\n\t    /**\n\t     * Creates a new concatenated UrlMatcher\n\t     *\n\t     * Builds a new UrlMatcher by appending another UrlMatcher to this one.\n\t     *\n\t     * @param url A `UrlMatcher` instance to append as a child of the current `UrlMatcher`.\n\t     */\n\t    UrlMatcher.prototype.append = function (url) {\n\t        this._children.push(url);\n\t        common_1.forEach(url._cache, function (val, key) { return url._cache[key] = predicates_1.isArray(val) ? [] : null; });\n\t        url._cache.path = this._cache.path.concat(this);\n\t        return url;\n\t    };\n\t    /** @hidden */\n\t    UrlMatcher.prototype.isRoot = function () {\n\t        return this._cache.path.length === 0;\n\t    };\n\t    /** Returns the input pattern string */\n\t    UrlMatcher.prototype.toString = function () {\n\t        return this.pattern;\n\t    };\n\t    /**\n\t     * Tests the specified url/path against this matcher.\n\t     *\n\t     * Tests if the given url matches this matcher's pattern, and returns an object containing the captured\n\t     * parameter values.  Returns null if the path does not match.\n\t     *\n\t     * The returned object contains the values\n\t     * of any search parameters that are mentioned in the pattern, but their value may be null if\n\t     * they are not present in `search`. This means that search parameters are always treated\n\t     * as optional.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', {\n\t     *   x: '1', q: 'hello'\n\t     * });\n\t     * // returns { id: 'bob', q: 'hello', r: null }\n\t     * ```\n\t     *\n\t     * @param path    The URL path to match, e.g. `$location.path()`.\n\t     * @param search  URL search parameters, e.g. `$location.search()`.\n\t     * @param hash    URL hash e.g. `$location.hash()`.\n\t     * @param options\n\t     *\n\t     * @returns The captured parameter values.\n\t     */\n\t    UrlMatcher.prototype.exec = function (path, search, hash, options) {\n\t        var _this = this;\n\t        if (search === void 0) { search = {}; }\n\t        if (options === void 0) { options = {}; }\n\t        var match = memoizeTo(this._cache, 'pattern', function () {\n\t            return new RegExp([\n\t                '^',\n\t                common_1.unnest(_this._cache.path.concat(_this).map(hof_1.prop('_compiled'))).join(''),\n\t                _this.config.strict === false ? '\\/?' : '',\n\t                '$'\n\t            ].join(''), _this.config.caseInsensitive ? 'i' : undefined);\n\t        }).exec(path);\n\t        if (!match)\n\t            return null;\n\t        //options = defaults(options, { isolate: false });\n\t        var allParams = this.parameters(), pathParams = allParams.filter(function (param) { return !param.isSearch(); }), searchParams = allParams.filter(function (param) { return param.isSearch(); }), nPathSegments = this._cache.path.concat(this).map(function (urlm) { return urlm._segments.length - 1; }).reduce(function (a, x) { return a + x; }), values = {};\n\t        if (nPathSegments !== match.length - 1)\n\t            throw new Error(\"Unbalanced capture group in route '\" + this.pattern + \"'\");\n\t        function decodePathArray(string) {\n\t            var reverseString = function (str) { return str.split(\"\").reverse().join(\"\"); };\n\t            var unquoteDashes = function (str) { return str.replace(/\\\\-/g, \"-\"); };\n\t            var split = reverseString(string).split(/-(?!\\\\)/);\n\t            var allReversed = common_1.map(split, reverseString);\n\t            return common_1.map(allReversed, unquoteDashes).reverse();\n\t        }\n\t        for (var i = 0; i < nPathSegments; i++) {\n\t            var param = pathParams[i];\n\t            var value = match[i + 1];\n\t            // if the param value matches a pre-replace pair, replace the value before decoding.\n\t            for (var j = 0; j < param.replace.length; j++) {\n\t                if (param.replace[j].from === value)\n\t                    value = param.replace[j].to;\n\t            }\n\t            if (value && param.array === true)\n\t                value = decodePathArray(value);\n\t            if (predicates_2.isDefined(value))\n\t                value = param.type.decode(value);\n\t            values[param.id] = param.value(value);\n\t        }\n\t        common_1.forEach(searchParams, function (param) {\n\t            var value = search[param.id];\n\t            for (var j = 0; j < param.replace.length; j++) {\n\t                if (param.replace[j].from === value)\n\t                    value = param.replace[j].to;\n\t            }\n\t            if (predicates_2.isDefined(value))\n\t                value = param.type.decode(value);\n\t            values[param.id] = param.value(value);\n\t        });\n\t        if (hash)\n\t            values[\"#\"] = hash;\n\t        return values;\n\t    };\n\t    /**\n\t     * @hidden\n\t     * Returns all the [[Param]] objects of all path and search parameters of this pattern in order of appearance.\n\t     *\n\t     * @returns {Array.<Param>}  An array of [[Param]] objects. Must be treated as read-only. If the\n\t     *    pattern has no parameters, an empty array is returned.\n\t     */\n\t    UrlMatcher.prototype.parameters = function (opts) {\n\t        if (opts === void 0) { opts = {}; }\n\t        if (opts.inherit === false)\n\t            return this._params;\n\t        return common_1.unnest(this._cache.path.concat(this).map(hof_1.prop('_params')));\n\t    };\n\t    /**\n\t     * @hidden\n\t     * Returns a single parameter from this UrlMatcher by id\n\t     *\n\t     * @param id\n\t     * @param opts\n\t     * @returns {T|Param|any|boolean|UrlMatcher|null}\n\t     */\n\t    UrlMatcher.prototype.parameter = function (id, opts) {\n\t        if (opts === void 0) { opts = {}; }\n\t        var parent = common_1.tail(this._cache.path);\n\t        return (common_1.find(this._params, hof_1.propEq('id', id)) ||\n\t            (opts.inherit !== false && parent && parent.parameter(id)) ||\n\t            null);\n\t    };\n\t    /**\n\t     * Validates the input parameter values against this UrlMatcher\n\t     *\n\t     * Checks an object hash of parameters to validate their correctness according to the parameter\n\t     * types of this `UrlMatcher`.\n\t     *\n\t     * @param params The object hash of parameters to validate.\n\t     * @returns Returns `true` if `params` validates, otherwise `false`.\n\t     */\n\t    UrlMatcher.prototype.validates = function (params) {\n\t        var _this = this;\n\t        var validParamVal = function (param, val) { return !param || param.validates(val); };\n\t        return common_1.pairs(params || {}).map(function (_a) {\n\t            var key = _a[0], val = _a[1];\n\t            return validParamVal(_this.parameter(key), val);\n\t        }).reduce(common_1.allTrueR, true);\n\t    };\n\t    /**\n\t     * Given a set of parameter values, creates a URL from this UrlMatcher.\n\t     *\n\t     * Creates a URL that matches this pattern by substituting the specified values\n\t     * for the path and search parameters.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });\n\t     * // returns '/user/bob?q=yes'\n\t     * ```\n\t     *\n\t     * @param values  the values to substitute for the parameters in this pattern.\n\t     * @returns the formatted URL (path and optionally search part).\n\t     */\n\t    UrlMatcher.prototype.format = function (values) {\n\t        if (values === void 0) { values = {}; }\n\t        if (!this.validates(values))\n\t            return null;\n\t        // Build the full path of UrlMatchers (including all parent UrlMatchers)\n\t        var urlMatchers = this._cache.path.slice().concat(this);\n\t        // Extract all the static segments and Params into an ordered array\n\t        var pathSegmentsAndParams = urlMatchers.map(UrlMatcher.pathSegmentsAndParams).reduce(common_2.unnestR, []);\n\t        // Extract the query params into a separate array\n\t        var queryParams = urlMatchers.map(UrlMatcher.queryParams).reduce(common_2.unnestR, []);\n\t        /**\n\t         * Given a Param,\n\t         * Applies the parameter value, then returns details about it\n\t         */\n\t        function getDetails(param) {\n\t            // Normalize to typed value\n\t            var value = param.value(values[param.id]);\n\t            var isDefaultValue = param.isDefaultValue(value);\n\t            // Check if we're in squash mode for the parameter\n\t            var squash = isDefaultValue ? param.squash : false;\n\t            // Allow the Parameter's Type to encode the value\n\t            var encoded = param.type.encode(value);\n\t            return { param: param, value: value, isDefaultValue: isDefaultValue, squash: squash, encoded: encoded };\n\t        }\n\t        // Build up the path-portion from the list of static segments and parameters\n\t        var pathString = pathSegmentsAndParams.reduce(function (acc, x) {\n\t            // The element is a static segment (a raw string); just append it\n\t            if (predicates_1.isString(x))\n\t                return acc + x;\n\t            // Otherwise, it's a Param.  Fetch details about the parameter value\n\t            var _a = getDetails(x), squash = _a.squash, encoded = _a.encoded, param = _a.param;\n\t            // If squash is === true, try to remove a slash from the path\n\t            if (squash === true)\n\t                return (acc.match(/\\/$/)) ? acc.slice(0, -1) : acc;\n\t            // If squash is a string, use the string for the param value\n\t            if (predicates_1.isString(squash))\n\t                return acc + squash;\n\t            if (squash !== false)\n\t                return acc; // ?\n\t            if (encoded == null)\n\t                return acc;\n\t            // If this parameter value is an array, encode the value using encodeDashes\n\t            if (predicates_1.isArray(encoded))\n\t                return acc + common_1.map(encoded, UrlMatcher.encodeDashes).join(\"-\");\n\t            // If the parameter type is \"raw\", then do not encodeURIComponent\n\t            if (param.type.raw)\n\t                return acc + encoded;\n\t            // Encode the value\n\t            return acc + encodeURIComponent(encoded);\n\t        }, \"\");\n\t        // Build the query string by applying parameter values (array or regular)\n\t        // then mapping to key=value, then flattening and joining using \"&\"\n\t        var queryString = queryParams.map(function (param) {\n\t            var _a = getDetails(param), squash = _a.squash, encoded = _a.encoded, isDefaultValue = _a.isDefaultValue;\n\t            if (encoded == null || (isDefaultValue && squash !== false))\n\t                return;\n\t            if (!predicates_1.isArray(encoded))\n\t                encoded = [encoded];\n\t            if (encoded.length === 0)\n\t                return;\n\t            if (!param.type.raw)\n\t                encoded = common_1.map(encoded, encodeURIComponent);\n\t            return encoded.map(function (val) { return (param.id + \"=\" + val); });\n\t        }).filter(common_1.identity).reduce(common_2.unnestR, []).join(\"&\");\n\t        // Concat the pathstring with the queryString (if exists) and the hashString (if exists)\n\t        return pathString + (queryString ? \"?\" + queryString : \"\") + (values[\"#\"] ? \"#\" + values[\"#\"] : \"\");\n\t    };\n\t    /** @hidden */\n\t    UrlMatcher.encodeDashes = function (str) {\n\t        return encodeURIComponent(str).replace(/-/g, function (c) { return (\"%5C%\" + c.charCodeAt(0).toString(16).toUpperCase()); });\n\t    };\n\t    /** @hidden Given a matcher, return an array with the matcher's path segments and path params, in order */\n\t    UrlMatcher.pathSegmentsAndParams = function (matcher) {\n\t        var staticSegments = matcher._segments;\n\t        var pathParams = matcher._params.filter(function (p) { return p.location === param_2.DefType.PATH; });\n\t        return common_3.arrayTuples(staticSegments, pathParams.concat(undefined)).reduce(common_2.unnestR, []).filter(function (x) { return x !== \"\" && predicates_2.isDefined(x); });\n\t    };\n\t    /** @hidden Given a matcher, return an array with the matcher's query params */\n\t    UrlMatcher.queryParams = function (matcher) {\n\t        return matcher._params.filter(function (p) { return p.location === param_2.DefType.SEARCH; });\n\t    };\n\t    /** @hidden */\n\t    UrlMatcher.nameValidator = /^\\w+([-.]+\\w+)*(?:\\[\\])?$/;\n\t    return UrlMatcher;\n\t}());\n\texports.UrlMatcher = UrlMatcher;\n\n\n/***/ },\n/* 29 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module url */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\t/** @hidden */\n\tvar $location = coreservices_1.services.location;\n\t/** @hidden Returns a string that is a prefix of all strings matching the RegExp */\n\tfunction regExpPrefix(re) {\n\t    var prefix = /^\\^((?:\\\\[^a-zA-Z0-9]|[^\\\\\\[\\]\\^$*+?.()|{}]+)*)/.exec(re.source);\n\t    return (prefix != null) ? prefix[1].replace(/\\\\(.)/g, \"$1\") : '';\n\t}\n\t/** @hidden Interpolates matched values into a String.replace()-style pattern */\n\tfunction interpolate(pattern, match) {\n\t    return pattern.replace(/\\$(\\$|\\d{1,2})/, function (m, what) {\n\t        return match[what === '$' ? 0 : Number(what)];\n\t    });\n\t}\n\t/** @hidden */\n\tfunction handleIfMatch($injector, $stateParams, handler, match) {\n\t    if (!match)\n\t        return false;\n\t    var result = $injector.invoke(handler, handler, { $match: match, $stateParams: $stateParams });\n\t    return predicates_1.isDefined(result) ? result : true;\n\t}\n\t/** @hidden */\n\tfunction appendBasePath(url, isHtml5, absolute) {\n\t    var baseHref = coreservices_1.services.locationConfig.baseHref();\n\t    if (baseHref === '/')\n\t        return url;\n\t    if (isHtml5)\n\t        return baseHref.slice(0, -1) + url;\n\t    if (absolute)\n\t        return baseHref.slice(1) + url;\n\t    return url;\n\t}\n\t// TODO: Optimize groups of rules with non-empty prefix into some sort of decision tree\n\t/** @hidden */\n\tfunction update(rules, otherwiseFn, evt) {\n\t    if (evt && evt.defaultPrevented)\n\t        return;\n\t    function check(rule) {\n\t        var handled = rule(coreservices_1.services.$injector, $location);\n\t        if (!handled)\n\t            return false;\n\t        if (predicates_1.isString(handled)) {\n\t            $location.replace();\n\t            $location.url(handled);\n\t        }\n\t        return true;\n\t    }\n\t    var n = rules.length, i;\n\t    for (i = 0; i < n; i++) {\n\t        if (check(rules[i]))\n\t            return;\n\t    }\n\t    // always check otherwise last to allow dynamic updates to the set of rules\n\t    if (otherwiseFn)\n\t        check(otherwiseFn);\n\t}\n\t/**\n\t * Manages rules for client-side URL\n\t *\n\t * This class manages the router rules for what to do when the URL changes.\n\t */\n\tvar UrlRouterProvider = (function () {\n\t    function UrlRouterProvider($urlMatcherFactory, $stateParams) {\n\t        /** @hidden */\n\t        this.rules = [];\n\t        /** @hidden */\n\t        this.interceptDeferred = false;\n\t        this.$urlMatcherFactory = $urlMatcherFactory;\n\t        this.$stateParams = $stateParams;\n\t    }\n\t    /**\n\t     * Registers a url handler function.\n\t     *\n\t     * Registers a low level url handler (a `rule`). A rule detects specific URL patterns and returns\n\t     * a redirect, or performs some action.\n\t     *\n\t     * If a rule returns a string, the URL is replaced with the string, and all rules are fired again.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * var app = angular.module('app', ['ui.router.router']);\n\t     *\n\t     * app.config(function ($urlRouterProvider) {\n\t     *   // Here's an example of how you might allow case insensitive urls\n\t     *   $urlRouterProvider.rule(function ($injector, $location) {\n\t     *     var path = $location.path(),\n\t     *         normalized = path.toLowerCase();\n\t     *\n\t     *     if (path !== normalized) {\n\t     *       return normalized;\n\t     *     }\n\t     *   });\n\t     * });\n\t     * ```\n\t     *\n\t     * @param rule\n\t     * Handler function that takes `$injector` and `$location` services as arguments.\n\t     * You can use them to detect a url and return a different url as a string.\n\t     *\n\t     * @return [[$urlRouterProvider]] (`this`)\n\t     */\n\t    UrlRouterProvider.prototype.rule = function (rule) {\n\t        if (!predicates_1.isFunction(rule))\n\t            throw new Error(\"'rule' must be a function\");\n\t        this.rules.push(rule);\n\t        return this;\n\t    };\n\t    ;\n\t    /**\n\t     * Defines the path or behavior to use when no url can be matched.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * var app = angular.module('app', ['ui.router.router']);\n\t     *\n\t     * app.config(function ($urlRouterProvider) {\n\t     *   // if the path doesn't match any of the urls you configured\n\t     *   // otherwise will take care of routing the user to the\n\t     *   // specified url\n\t     *   $urlRouterProvider.otherwise('/index');\n\t     *\n\t     *   // Example of using function rule as param\n\t     *   $urlRouterProvider.otherwise(function ($injector, $location) {\n\t     *     return '/a/valid/url';\n\t     *   });\n\t     * });\n\t     * ```\n\t     *\n\t     * @param rule\n\t     * The url path you want to redirect to or a function rule that returns the url path or performs a `$state.go()`.\n\t     * The function version is passed two params: `$injector` and `$location` services, and should return a url string.\n\t     *\n\t     * @return {object} `$urlRouterProvider` - `$urlRouterProvider` instance\n\t     */\n\t    UrlRouterProvider.prototype.otherwise = function (rule) {\n\t        if (!predicates_1.isFunction(rule) && !predicates_1.isString(rule))\n\t            throw new Error(\"'rule' must be a string or function\");\n\t        this.otherwiseFn = predicates_1.isString(rule) ? function () { return rule; } : rule;\n\t        return this;\n\t    };\n\t    ;\n\t    /**\n\t     * Registers a handler for a given url matching.\n\t     *\n\t     * If the handler is a string, it is\n\t     * treated as a redirect, and is interpolated according to the syntax of match\n\t     * (i.e. like `String.replace()` for `RegExp`, or like a `UrlMatcher` pattern otherwise).\n\t     *\n\t     * If the handler is a function, it is injectable.\n\t     * It gets invoked if `$location` matches.\n\t     * You have the option of inject the match object as `$match`.\n\t     *\n\t     * The handler can return\n\t     *\n\t     * - **falsy** to indicate that the rule didn't match after all, then `$urlRouter`\n\t     *   will continue trying to find another one that matches.\n\t     * - **string** which is treated as a redirect and passed to `$location.url()`\n\t     * - **void** or any **truthy** value tells `$urlRouter` that the url was handled.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * var app = angular.module('app', ['ui.router.router']);\n\t     *\n\t     * app.config(function ($urlRouterProvider) {\n\t     *   $urlRouterProvider.when($state.url, function ($match, $stateParams) {\n\t     *     if ($state.$current.navigable !== state ||\n\t     *         !equalForKeys($match, $stateParams) {\n\t     *      $state.transitionTo(state, $match, false);\n\t     *     }\n\t     *   });\n\t     * });\n\t     * ```\n\t     *\n\t     * @param what A pattern string to match, compiled as a [[UrlMatcher]].\n\t     * @param handler The path (or function that returns a path) that you want to redirect your user to.\n\t     *\n\t     * Note: the handler may also invoke arbitrary code, such as `$state.go()`\n\t     */\n\t    UrlRouterProvider.prototype.when = function (what, handler) {\n\t        var _a = this, $urlMatcherFactory = _a.$urlMatcherFactory, $stateParams = _a.$stateParams;\n\t        var redirect, handlerIsString = predicates_1.isString(handler);\n\t        // @todo Queue this\n\t        if (predicates_1.isString(what))\n\t            what = $urlMatcherFactory.compile(what);\n\t        if (!handlerIsString && !predicates_1.isFunction(handler) && !predicates_1.isArray(handler))\n\t            throw new Error(\"invalid 'handler' in when()\");\n\t        var strategies = {\n\t            matcher: function (_what, _handler) {\n\t                if (handlerIsString) {\n\t                    redirect = $urlMatcherFactory.compile(_handler);\n\t                    _handler = ['$match', redirect.format.bind(redirect)];\n\t                }\n\t                return common_1.extend(function () {\n\t                    return handleIfMatch(coreservices_1.services.$injector, $stateParams, _handler, _what.exec($location.path(), $location.search(), $location.hash()));\n\t                }, {\n\t                    prefix: predicates_1.isString(_what.prefix) ? _what.prefix : ''\n\t                });\n\t            },\n\t            regex: function (_what, _handler) {\n\t                if (_what.global || _what.sticky)\n\t                    throw new Error(\"when() RegExp must not be global or sticky\");\n\t                if (handlerIsString) {\n\t                    redirect = _handler;\n\t                    _handler = ['$match', function ($match) { return interpolate(redirect, $match); }];\n\t                }\n\t                return common_1.extend(function () {\n\t                    return handleIfMatch(coreservices_1.services.$injector, $stateParams, _handler, _what.exec($location.path()));\n\t                }, {\n\t                    prefix: regExpPrefix(_what)\n\t                });\n\t            }\n\t        };\n\t        var check = {\n\t            matcher: $urlMatcherFactory.isMatcher(what),\n\t            regex: what instanceof RegExp\n\t        };\n\t        for (var n in check) {\n\t            if (check[n])\n\t                return this.rule(strategies[n](what, handler));\n\t        }\n\t        throw new Error(\"invalid 'what' in when()\");\n\t    };\n\t    ;\n\t    /**\n\t     * Disables monitoring of the URL.\n\t     *\n\t     * Call this method before UI-Router has bootstrapped.\n\t     * It will stop UI-Router from performing the initial url sync.\n\t     *\n\t     * This can be useful to perform some asynchronous initialization before the router starts.\n\t     * Once the initialization is complete, call [[listen]] to tell UI-Router to start watching and synchronizing the URL.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * var app = angular.module('app', ['ui.router']);\n\t     *\n\t     * app.config(function ($urlRouterProvider) {\n\t     *   // Prevent $urlRouter from automatically intercepting URL changes;\n\t     *   $urlRouterProvider.deferIntercept();\n\t     * })\n\t     *\n\t     * app.run(function (MyService, $urlRouter, $http) {\n\t     *   $http.get(\"/stuff\").then(function(resp) {\n\t     *     MyService.doStuff(resp.data);\n\t     *     $urlRouter.listen();\n\t     *     $urlRouter.sync();\n\t     *   });\n\t     * });\n\t     * ```\n\t     *\n\t     * @param defer Indicates whether to defer location change interception. Passing\n\t     *        no parameter is equivalent to `true`.\n\t     */\n\t    UrlRouterProvider.prototype.deferIntercept = function (defer) {\n\t        if (defer === undefined)\n\t            defer = true;\n\t        this.interceptDeferred = defer;\n\t    };\n\t    ;\n\t    return UrlRouterProvider;\n\t}());\n\texports.UrlRouterProvider = UrlRouterProvider;\n\tvar UrlRouter = (function () {\n\t    /** @hidden */\n\t    function UrlRouter(urlRouterProvider) {\n\t        this.urlRouterProvider = urlRouterProvider;\n\t        common_1.bindFunctions(UrlRouter.prototype, this, this);\n\t    }\n\t    /**\n\t     * Checks the current URL for a matching rule\n\t     *\n\t     * Triggers an update; the same update that happens when the address bar url changes, aka `$locationChangeSuccess`.\n\t     * This method is useful when you need to use `preventDefault()` on the `$locationChangeSuccess` event,\n\t     * perform some custom logic (route protection, auth, config, redirection, etc) and then finally proceed\n\t     * with the transition by calling `$urlRouter.sync()`.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * angular.module('app', ['ui.router'])\n\t     *   .run(function($rootScope, $urlRouter) {\n\t     *     $rootScope.$on('$locationChangeSuccess', function(evt) {\n\t     *       // Halt state change from even starting\n\t     *       evt.preventDefault();\n\t     *       // Perform custom logic\n\t     *       var meetsRequirement = ...\n\t     *       // Continue with the update and state transition if logic allows\n\t     *       if (meetsRequirement) $urlRouter.sync();\n\t     *     });\n\t     * });\n\t     * ```\n\t     */\n\t    UrlRouter.prototype.sync = function () {\n\t        update(this.urlRouterProvider.rules, this.urlRouterProvider.otherwiseFn);\n\t    };\n\t    /**\n\t     * Starts listening for URL changes\n\t     *\n\t     * Call this sometime after calling [[deferIntercept]] to start monitoring the url.\n\t     * This causes [[UrlRouter]] to start listening for changes to the URL, if it wasn't already listening.\n\t     */\n\t    UrlRouter.prototype.listen = function () {\n\t        var _this = this;\n\t        return this.listener = this.listener || $location.onChange(function (evt) { return update(_this.urlRouterProvider.rules, _this.urlRouterProvider.otherwiseFn, evt); });\n\t    };\n\t    /**\n\t     * Internal API.\n\t     */\n\t    UrlRouter.prototype.update = function (read) {\n\t        if (read) {\n\t            this.location = $location.url();\n\t            return;\n\t        }\n\t        if ($location.url() === this.location)\n\t            return;\n\t        $location.url(this.location);\n\t        $location.replace();\n\t    };\n\t    /**\n\t     * Internal API.\n\t     *\n\t     * Pushes a new location to the browser history.\n\t     *\n\t     * @param urlMatcher\n\t     * @param params\n\t     * @param options\n\t     */\n\t    UrlRouter.prototype.push = function (urlMatcher, params, options) {\n\t        $location.url(urlMatcher.format(params || {}));\n\t        if (options && options.replace)\n\t            $location.replace();\n\t    };\n\t    /**\n\t     * Builds and returns a URL with interpolated parameters\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * $bob = $urlRouter.href(new UrlMatcher(\"/about/:person\"), {\n\t     *   person: \"bob\"\n\t     * });\n\t     * // $bob == \"/about/bob\";\n\t     * ```\n\t     *\n\t     * @param urlMatcher The [[UrlMatcher]] object which is used as the template of the URL to generate.\n\t     * @param params An object of parameter values to fill the matcher's required parameters.\n\t     * @param options Options object. The options are:\n\t     *\n\t     * - **`absolute`** - {boolean=false},  If true will generate an absolute url, e.g. \"http://www.example.com/fullurl\".\n\t     *\n\t     * @returns Returns the fully compiled URL, or `null` if `params` fail validation against `urlMatcher`\n\t     */\n\t    UrlRouter.prototype.href = function (urlMatcher, params, options) {\n\t        if (!urlMatcher.validates(params))\n\t            return null;\n\t        var url = urlMatcher.format(params);\n\t        options = options || { absolute: false };\n\t        var cfg = coreservices_1.services.locationConfig;\n\t        var isHtml5 = cfg.html5Mode();\n\t        if (!isHtml5 && url !== null) {\n\t            url = \"#\" + cfg.hashPrefix() + url;\n\t        }\n\t        url = appendBasePath(url, isHtml5, options.absolute);\n\t        if (!options.absolute || !url) {\n\t            return url;\n\t        }\n\t        var slash = (!isHtml5 && url ? '/' : ''), port = cfg.port();\n\t        port = (port === 80 || port === 443 ? '' : ':' + port);\n\t        return [cfg.protocol(), '://', cfg.host(), port, slash, url].join('');\n\t    };\n\t    return UrlRouter;\n\t}());\n\texports.UrlRouter = UrlRouter;\n\n\n/***/ },\n/* 30 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** for typedoc */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar common_1 = __webpack_require__(3);\n\t/**\n\t * @ngdoc object\n\t * @name ui.router.state.$stateProvider\n\t *\n\t * @requires ui.router.router.$urlRouterProvider\n\t * @requires ui.router.util.$urlMatcherFactoryProvider\n\t *\n\t * @description\n\t * The new `$stateProvider` works similar to Angular's v1 router, but it focuses purely\n\t * on state.\n\t *\n\t * A state corresponds to a \"place\" in the application in terms of the overall UI and\n\t * navigation. A state describes (via the controller / template / view properties) what\n\t * the UI looks like and does at that place.\n\t *\n\t * States often have things in common, and the primary way of factoring out these\n\t * commonalities in this model is via the state hierarchy, i.e. parent/child states aka\n\t * nested states.\n\t *\n\t * The `$stateProvider` provides interfaces to declare these states for your app.\n\t */\n\tvar StateProvider = (function () {\n\t    function StateProvider(stateRegistry) {\n\t        this.stateRegistry = stateRegistry;\n\t        this.invalidCallbacks = [];\n\t        common_1.bindFunctions(StateProvider.prototype, this, this);\n\t    }\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$stateProvider#decorator\n\t     * @methodOf ui.router.state.$stateProvider\n\t     *\n\t     * @description\n\t     * Allows you to extend (carefully) or override (at your own peril) the\n\t     * `stateBuilder` object used internally by `$stateProvider`. This can be used\n\t     * to add custom functionality to ui-router, for example inferring templateUrl\n\t     * based on the state name.\n\t     *\n\t     * When passing only a name, it returns the current (original or decorated) builder\n\t     * function that matches `name`.\n\t     *\n\t     * The builder functions that can be decorated are listed below. Though not all\n\t     * necessarily have a good use case for decoration, that is up to you to decide.\n\t     *\n\t     * In addition, users can attach custom decorators, which will generate new\n\t     * properties within the state's internal definition. There is currently no clear\n\t     * use-case for this beyond accessing internal states (i.e. $state.$current),\n\t     * however, expect this to become increasingly relevant as we introduce additional\n\t     * meta-programming features.\n\t     *\n\t     * **Warning**: Decorators should not be interdependent because the order of\n\t     * execution of the builder functions in non-deterministic. Builder functions\n\t     * should only be dependent on the state definition object and super function.\n\t     *\n\t     *\n\t     * Existing builder functions and current return values:\n\t     *\n\t     * - **parent** `{object}` - returns the parent state object.\n\t     * - **data** `{object}` - returns state data, including any inherited data that is not\n\t     *   overridden by own values (if any).\n\t     * - **url** `{object}` - returns a {@link ui.router.util.type:UrlMatcher UrlMatcher}\n\t     *   or `null`.\n\t     * - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is\n\t     *   navigable).\n\t     * - **params** `{object}` - returns an array of state params that are ensured to\n\t     *   be a super-set of parent's params.\n\t     * - **views** `{object}` - returns a views object where each key is an absolute view\n\t     *   name (i.e. \"viewName@stateName\") and each value is the config object\n\t     *   (template, controller) for the view. Even when you don't use the views object\n\t     *   explicitly on a state config, one is still created for you internally.\n\t     *   So by decorating this builder function you have access to decorating template\n\t     *   and controller properties.\n\t     * - **ownParams** `{object}` - returns an array of params that belong to the state,\n\t     *   not including any params defined by ancestor states.\n\t     * - **path** `{string}` - returns the full path from the root down to this state.\n\t     *   Needed for state activation.\n\t     * - **includes** `{object}` - returns an object that includes every state that\n\t     *   would pass a `$state.includes()` test.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * // Override the internal 'views' builder with a function that takes the state\n\t     * // definition, and a reference to the internal function being overridden:\n\t     * $stateProvider.decorator('views', function (state, parent) {\n\t     *   let result = {},\n\t     *       views = parent(state);\n\t     *\n\t     *   angular.forEach(views, function (config, name) {\n\t     *     let autoName = (state.name + '.' + name).replace('.', '/');\n\t     *     config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html';\n\t     *     result[name] = config;\n\t     *   });\n\t     *   return result;\n\t     * });\n\t     *\n\t     * $stateProvider.state('home', {\n\t     *   views: {\n\t     *     'contact.list': { controller: 'ListController' },\n\t     *     'contact.item': { controller: 'ItemController' }\n\t     *   }\n\t     * });\n\t     *\n\t     * // ...\n\t     *\n\t     * $state.go('home');\n\t     * // Auto-populates list and item views with /partials/home/contact/list.html,\n\t     * // and /partials/home/contact/item.html, respectively.\n\t     * </pre>\n\t     *\n\t     * @param {string} name The name of the builder function to decorate.\n\t     * @param {object} func A function that is responsible for decorating the original\n\t     * builder function. The function receives two parameters:\n\t     *\n\t     *   - `{object}` - state - The state config object.\n\t     *   - `{object}` - super - The original builder function.\n\t     *\n\t     * @return {object} $stateProvider - $stateProvider instance\n\t     */\n\t    StateProvider.prototype.decorator = function (name, func) {\n\t        return this.stateRegistry.decorator(name, func) || this;\n\t    };\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$stateProvider#state\n\t     * @methodOf ui.router.state.$stateProvider\n\t     *\n\t     * @description\n\t     * Registers a state configuration under a given state name. The stateConfig object\n\t     * has the following acceptable properties.\n\t     *\n\t     * <a id='template'></a>\n\t     *\n\t     * - **`template`** - {string|function=} - html template as a string or a function that returns\n\t     *   an html template as a string which should be used by the uiView directives. This property\n\t     *   takes precedence over templateUrl.\n\t     *\n\t     *   If `template` is a function, it will be called with the following parameters:\n\t     *\n\t     *   - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by\n\t     *     applying the current state\n\t     *\n\t     * <a id='templateUrl'></a>\n\t     *\n\t     * - **`templateUrl`** - {string|function=} - path or function that returns a path to an html\n\t     *   template that should be used by uiView.\n\t     *\n\t     *   If `templateUrl` is a function, it will be called with the following parameters:\n\t     *\n\t     *   - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by\n\t     *     applying the current state\n\t     *\n\t     * <a id='templateProvider'></a>\n\t     *\n\t     * - **`templateProvider`** - {function=} - Provider function that returns HTML content\n\t     *   string.\n\t     *\n\t     * <a id='controller'></a>\n\t     *\n\t     * - **`controller`** - {string|function=} -  Controller fn that should be associated with newly\n\t     *   related scope or the name of a registered controller if passed as a string.\n\t     *\n\t     * <a id='controllerProvider'></a>\n\t     *\n\t     * - **`controllerProvider`** - {function=} - Injectable provider function that returns\n\t     *   the actual controller or string.\n\t     *\n\t     * <a id='controllerAs'></a>\n\t     *\n\t     * - **`controllerAs`** – {string=} – A controller alias name. If present the controller will be\n\t     *   published to scope under the controllerAs name.\n\t     *\n\t     * <a id='resolve'></a>\n\t     *\n\t     * - **`resolve`** - {object.&lt;string, function&gt;=} - An optional map of dependencies which\n\t     *   should be injected into the controller. If any of these dependencies are promises,\n\t     *   the router will wait for them all to be resolved or one to be rejected before the\n\t     *   controller is instantiated. If all the promises are resolved successfully, the values\n\t     *   of the resolved promises are injected and $stateChangeSuccess event is fired. If any\n\t     *   of the promises are rejected the $stateChangeError event is fired. The map object is:\n\t     *\n\t     *   - key - {string}: name of dependency to be injected into controller\n\t     *   - factory - {string|function}: If string then it is alias for service. Otherwise if function,\n\t     *     it is injected and return value it treated as dependency. If result is a promise, it is\n\t     *     resolved before its value is injected into controller.\n\t     *\n\t     * <a id='url'></a>\n\t     *\n\t     * - **`url`** - {string=} - A url with optional parameters. When a state is navigated or\n\t     *   transitioned to, the `$stateParams` service will be populated with any\n\t     *   parameters that were passed.\n\t     *\n\t     * <a id='params'></a>\n\t     *\n\t     * - **`params`** - {object=} - An array of parameter names or regular expressions. Only\n\t     *   use this within a state if you are not using url. Otherwise you can specify your\n\t     *   parameters within the url. When a state is navigated or transitioned to, the\n\t     *   $stateParams service will be populated with any parameters that were passed.\n\t     *\n\t     * <a id='views'></a>\n\t     *\n\t     * - **`views`** - {object=} - Use the views property to set up multiple views or to target views\n\t     *   manually/explicitly.\n\t     *\n\t     * <a id='abstract'></a>\n\t     *\n\t     * - **`abstract`** - {boolean=} - An abstract state will never be directly activated,\n\t     *   but can provide inherited properties to its common children states.\n\t     *\n\t     * <a id='onEnter'></a>\n\t     *\n\t     * - **`onEnter`** - {object=} - Callback function for when a state is entered. Good way\n\t     *   to trigger an action or dispatch an event, such as opening a dialog.\n\t     * If minifying your scripts, make sure to use the `['injection1', 'injection2', function(injection1, injection2){}]` syntax.\n\t     *\n\t     * <a id='onExit'></a>\n\t     *\n\t     * - **`onExit`** - {object=} - Callback function for when a state is exited. Good way to\n\t     *   trigger an action or dispatch an event, such as opening a dialog.\n\t     * If minifying your scripts, make sure to use the `['injection1', 'injection2', function(injection1, injection2){}]` syntax.\n\t     *\n\t     * <a id='reloadOnSearch'></a>\n\t     *\n\t     * - **`reloadOnSearch = true`** - {boolean=} - If `false`, will not retrigger the same state\n\t     *   just because a search/query parameter has changed (via $location.search() or $location.hash()).\n\t     *   Useful for when you'd like to modify $location.search() without triggering a reload.\n\t     *\n\t     * <a id='data'></a>\n\t     *\n\t     * - **`data`** - {object=} - Arbitrary data object, useful for custom configuration.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * // Some state name examples\n\t     *\n\t     * // stateName can be a single top-level name (must be unique).\n\t     * $stateProvider.state(\"home\", {});\n\t     *\n\t     * // Or it can be a nested state name. This state is a child of the\n\t     * // above \"home\" state.\n\t     * $stateProvider.state(\"home.newest\", {});\n\t     *\n\t     * // Nest states as deeply as needed.\n\t     * $stateProvider.state(\"home.newest.abc.xyz.inception\", {});\n\t     *\n\t     * // state() returns $stateProvider, so you can chain state declarations.\n\t     * $stateProvider\n\t     *   .state(\"home\", {})\n\t     *   .state(\"about\", {})\n\t     *   .state(\"contacts\", {});\n\t     * </pre>\n\t     *\n\t     * @param {string} name A unique state name, e.g. \"home\", \"about\", \"contacts\".\n\t     * To create a parent/child state use a dot, e.g. \"about.sales\", \"home.newest\".\n\t     * @param {object} definition State configuration object.\n\t     */\n\t    StateProvider.prototype.state = function (name, definition) {\n\t        if (predicates_1.isObject(name)) {\n\t            definition = name;\n\t        }\n\t        else {\n\t            definition.name = name;\n\t        }\n\t        this.stateRegistry.register(definition);\n\t        return this;\n\t    };\n\t    /**\n\t     * Registers an invalid state handler\n\t     *\n\t     * Registers a function to be injected and invoked when [[StateService.transitionTo]] has been called with an invalid\n\t     * state reference parameter\n\t     *\n\t     * This function can be injected with one some special values:\n\t     * - **`$to$`**: TargetState\n\t     * - **`$from$`**: TargetState\n\t     *\n\t     * Note: This API is subject to change.\n\t     * Replacement of dependency injection support with some alternative is likely.\n\t     *\n\t     * @param {function} callback\n\t     *   The function which will be injected and invoked, when a matching transition is started.\n\t     *   The function may optionally return a {TargetState} or a Promise for a TargetState.  If one\n\t     *   is returned, it is treated as a redirect.\n\t     */\n\t    StateProvider.prototype.onInvalid = function (callback) {\n\t        this.invalidCallbacks.push(callback);\n\t    };\n\t    return StateProvider;\n\t}());\n\texports.StateProvider = StateProvider;\n\n\n/***/ },\n/* 31 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tvar transition_1 = __webpack_require__(11);\n\tvar hookRegistry_1 = __webpack_require__(15);\n\tvar resolve_1 = __webpack_require__(32);\n\tvar views_1 = __webpack_require__(33);\n\tvar url_1 = __webpack_require__(34);\n\tvar redirectTo_1 = __webpack_require__(35);\n\tvar onEnterExitRetain_1 = __webpack_require__(36);\n\tvar hof_1 = __webpack_require__(5);\n\t/**\n\t * The default [[Transition]] options.\n\t *\n\t * Include this object when applying custom defaults:\n\t * let reloadOpts = { reload: true, notify: true }\n\t * let options = defaults(theirOpts, customDefaults, defaultOptions);\n\t */\n\texports.defaultTransOpts = {\n\t    location: true,\n\t    relative: null,\n\t    inherit: false,\n\t    notify: true,\n\t    reload: false,\n\t    custom: {},\n\t    current: function () { return null; }\n\t};\n\t/**\n\t * This class provides services related to Transitions.\n\t *\n\t * - Most importantly, it allows global Transition Hooks to be registered.\n\t * - It allows the default transition error handler to be set.\n\t * - It also has a factory function for creating new [[Transition]] objects, (used internally by the [[StateService]]).\n\t *\n\t * At bootstrap, [[UIRouter]] creates a single instance (singleton) of this class.\n\t */\n\tvar TransitionService = (function () {\n\t    function TransitionService(_router) {\n\t        this._router = _router;\n\t        this.$view = _router.viewService;\n\t        hookRegistry_1.HookRegistry.mixin(new hookRegistry_1.HookRegistry(), this);\n\t        this._deregisterHookFns = {};\n\t        this.registerTransitionHooks();\n\t    }\n\t    /** @hidden */\n\t    TransitionService.prototype.registerTransitionHooks = function () {\n\t        var fns = this._deregisterHookFns;\n\t        // Wire up redirectTo hook\n\t        fns.redirectTo = this.onStart({ to: function (state) { return !!state.redirectTo; } }, redirectTo_1.redirectToHook);\n\t        // Wire up onExit/Retain/Enter state hooks\n\t        fns.onExit = this.onExit({ exiting: function (state) { return !!state.onExit; } }, onEnterExitRetain_1.onExitHook);\n\t        fns.onRetain = this.onRetain({ retained: function (state) { return !!state.onRetain; } }, onEnterExitRetain_1.onRetainHook);\n\t        fns.onEnter = this.onEnter({ entering: function (state) { return !!state.onEnter; } }, onEnterExitRetain_1.onEnterHook);\n\t        // Wire up Resolve hooks\n\t        fns.eagerResolve = this.onStart({}, resolve_1.eagerResolvePath, { priority: 1000 });\n\t        fns.lazyResolve = this.onEnter({ entering: hof_1.val(true) }, resolve_1.lazyResolveState, { priority: 1000 });\n\t        // Wire up the View management hooks\n\t        fns.loadViews = this.onStart({}, views_1.loadEnteringViews);\n\t        fns.activateViews = this.onSuccess({}, views_1.activateViews);\n\t        // After globals.current is updated at priority: 10000\n\t        fns.updateUrl = this.onSuccess({}, url_1.updateUrl, { priority: 9999 });\n\t    };\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onBefore = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onStart = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onExit = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onRetain = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onEnter = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onFinish = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onSuccess = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onError = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /**\n\t     * Creates a new [[Transition]] object\n\t     *\n\t     * This is a factory function for creating new Transition objects.\n\t     * It is used internally by the [[StateService]] and should generally not be called by application code.\n\t     *\n\t     * @param fromPath the path to the current state (the from state)\n\t     * @param targetState the target state (destination)\n\t     * @returns a Transition\n\t     */\n\t    TransitionService.prototype.create = function (fromPath, targetState) {\n\t        return new transition_1.Transition(fromPath, targetState, this._router);\n\t    };\n\t    return TransitionService;\n\t}());\n\texports.TransitionService = TransitionService;\n\n\n/***/ },\n/* 32 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module hooks */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar resolveContext_1 = __webpack_require__(17);\n\t/**\n\t * A [[TransitionHookFn]] which resolves all EAGER Resolvables in the To Path\n\t *\n\t * Registered using `transitionService.onStart({}, eagerResolvePath);`\n\t *\n\t * When a Transition starts, this hook resolves all the EAGER Resolvables, which the transition then waits for.\n\t *\n\t * See [[StateDeclaration.resolve]]\n\t */\n\texports.eagerResolvePath = function (trans) {\n\t    return new resolveContext_1.ResolveContext(trans.treeChanges().to)\n\t        .resolvePath(\"EAGER\", trans)\n\t        .then(common_1.noop);\n\t};\n\t/**\n\t * A [[TransitionHookFn]] which resolves all LAZY Resolvables for the state (and all its ancestors) in the To Path\n\t *\n\t * Registered using `transitionService.onEnter({ entering: () => true }, lazyResolveState);`\n\t *\n\t * When a State is being entered, this hook resolves all the Resolvables for this state, which the transition then waits for.\n\t *\n\t * See [[StateDeclaration.resolve]]\n\t */\n\texports.lazyResolveState = function (trans, state) {\n\t    return new resolveContext_1.ResolveContext(trans.treeChanges().to)\n\t        .subContext(state)\n\t        .resolvePath(\"LAZY\", trans)\n\t        .then(common_1.noop);\n\t};\n\n\n/***/ },\n/* 33 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module hooks */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar coreservices_1 = __webpack_require__(6);\n\t/**\n\t * A [[TransitionHookFn]] which waits for the views to load\n\t *\n\t * Registered using `transitionService.onStart({}, loadEnteringViews);`\n\t *\n\t * Allows the views to do async work in [[ViewConfig.load]] before the transition continues.\n\t * In angular 1, this includes loading the templates.\n\t */\n\tfunction loadEnteringViews(transition) {\n\t    var enteringViews = transition.views(\"entering\");\n\t    if (!enteringViews.length)\n\t        return;\n\t    return coreservices_1.services.$q.all(enteringViews.map(function (view) { return view.load(); })).then(common_1.noop);\n\t}\n\texports.loadEnteringViews = loadEnteringViews;\n\t/**\n\t * A [[TransitionHookFn]] which activates the new views when a transition is successful.\n\t *\n\t * Registered using `transitionService.onSuccess({}, activateViews);`\n\t *\n\t * After a transition is complete, this hook deactivates the old views from the previous state,\n\t * and activates the new views from the destination state.\n\t *\n\t * See [[ViewService]]\n\t */\n\tfunction activateViews(transition) {\n\t    var enteringViews = transition.views(\"entering\");\n\t    var exitingViews = transition.views(\"exiting\");\n\t    if (!enteringViews.length && !exitingViews.length)\n\t        return;\n\t    var $view = transition.router.viewService;\n\t    exitingViews.forEach(function (vc) { return $view.deactivateViewConfig(vc); });\n\t    enteringViews.forEach(function (vc) { return $view.activateViewConfig(vc); });\n\t    $view.sync();\n\t}\n\texports.activateViews = activateViews;\n\n\n/***/ },\n/* 34 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t/**\n\t * A [[TransitionHookFn]] which updates the URL after a successful transition\n\t *\n\t * Registered using `transitionService.onSuccess({}, updateUrl);`\n\t */\n\tfunction updateUrl(transition) {\n\t    var options = transition.options();\n\t    var $state = transition.router.stateService;\n\t    var $urlRouter = transition.router.urlRouter;\n\t    if (options.location && $state.$current.navigable) {\n\t        var urlOptions = { replace: options.location === 'replace' };\n\t        $urlRouter.push($state.$current.navigable.url, $state.params, urlOptions);\n\t    }\n\t    $urlRouter.update(true);\n\t}\n\texports.updateUrl = updateUrl;\n\n\n/***/ },\n/* 35 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module hooks */ /** */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar targetState_1 = __webpack_require__(14);\n\t/**\n\t * A [[TransitionHookFn]] that redirects to a different state or params\n\t *\n\t * Registered using `transitionService.onStart({ to: (state) => !!state.redirectTo }, redirectHook);`\n\t *\n\t * See [[StateDeclaration.redirectTo]]\n\t */\n\texports.redirectToHook = function (trans) {\n\t    var redirect = trans.to().redirectTo;\n\t    if (!redirect)\n\t        return;\n\t    function handleResult(result) {\n\t        var $state = trans.router.stateService;\n\t        if (result instanceof targetState_1.TargetState)\n\t            return result;\n\t        if (predicates_1.isString(result))\n\t            return $state.target(result, trans.params(), trans.options());\n\t        if (result['state'] || result['params'])\n\t            return $state.target(result['state'] || trans.to(), result['params'] || trans.params(), trans.options());\n\t    }\n\t    if (predicates_1.isFunction(redirect)) {\n\t        return coreservices_1.services.$q.when(redirect(trans)).then(handleResult);\n\t    }\n\t    return handleResult(redirect);\n\t};\n\n\n/***/ },\n/* 36 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t/**\n\t * A factory which creates an onEnter, onExit or onRetain transition hook function\n\t *\n\t * The returned function invokes the (for instance) state.onEnter hook when the\n\t * state is being entered.\n\t *\n\t * @hidden\n\t */\n\tfunction makeEnterExitRetainHook(hookName) {\n\t    return function (transition, state) {\n\t        return state[hookName](transition, state);\n\t    };\n\t}\n\t/**\n\t * The [[TransitionStateHookFn]] for onExit\n\t *\n\t * When the state is being exited, the state's .onExit function is invoked.\n\t *\n\t * Registered using `transitionService.onExit({ exiting: (state) => !!state.onExit }, onExitHook);`\n\t */\n\texports.onExitHook = makeEnterExitRetainHook('onExit');\n\t/**\n\t * The [[TransitionStateHookFn]] for onRetain\n\t *\n\t * When the state is being exited, the state's .onRetain function is invoked.\n\t *\n\t * Registered using `transitionService.onRetain({ retained: (state) => !!state.onRetain }, onRetainHook);`\n\t */\n\texports.onRetainHook = makeEnterExitRetainHook('onRetain');\n\t/**\n\t * The [[TransitionStateHookFn]] for onEnter\n\t *\n\t * When the state is being exited, the state's .onEnter function is invoked.\n\t *\n\t * Registered using `transitionService.onEnter({ entering: (state) => !!state.onEnter }, onEnterHook);`\n\t */\n\texports.onEnterHook = makeEnterExitRetainHook('onEnter');\n\n\n/***/ },\n/* 37 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module view */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar trace_1 = __webpack_require__(12);\n\tvar match = function (obj1) {\n\t    var keys = [];\n\t    for (var _i = 1; _i < arguments.length; _i++) {\n\t        keys[_i - 1] = arguments[_i];\n\t    }\n\t    return function (obj2) { return keys.reduce(function (memo, key) { return memo && obj1[key] === obj2[key]; }, true); };\n\t};\n\t/**\n\t * The View service\n\t */\n\tvar ViewService = (function () {\n\t    function ViewService() {\n\t        var _this = this;\n\t        this.uiViews = [];\n\t        this.viewConfigs = [];\n\t        this._viewConfigFactories = {};\n\t        this.sync = function () {\n\t            var uiViewsByFqn = _this.uiViews.map(function (uiv) { return [uiv.fqn, uiv]; }).reduce(common_1.applyPairs, {});\n\t            /**\n\t             * Given a ui-view and a ViewConfig, determines if they \"match\".\n\t             *\n\t             * A ui-view has a fully qualified name (fqn) and a context object.  The fqn is built from its overall location in\n\t             * the DOM, describing its nesting relationship to any parent ui-view tags it is nested inside of.\n\t             *\n\t             * A ViewConfig has a target ui-view name and a context anchor.  The ui-view name can be a simple name, or\n\t             * can be a segmented ui-view path, describing a portion of a ui-view fqn.\n\t             *\n\t             * In order for a ui-view to match ViewConfig, ui-view's $type must match the ViewConfig's $type\n\t             *\n\t             * If the ViewConfig's target ui-view name is a simple name (no dots), then a ui-view matches if:\n\t             * - the ui-view's name matches the ViewConfig's target name\n\t             * - the ui-view's context matches the ViewConfig's anchor\n\t             *\n\t             * If the ViewConfig's target ui-view name is a segmented name (with dots), then a ui-view matches if:\n\t             * - There exists a parent ui-view where:\n\t             *    - the parent ui-view's name matches the first segment (index 0) of the ViewConfig's target name\n\t             *    - the parent ui-view's context matches the ViewConfig's anchor\n\t             * - And the remaining segments (index 1..n) of the ViewConfig's target name match the tail of the ui-view's fqn\n\t             *\n\t             * Example:\n\t             *\n\t             * DOM:\n\t             * <div ui-view>                        <!-- created in the root context (name: \"\") -->\n\t             *   <div ui-view=\"foo\">                <!-- created in the context named: \"A\"      -->\n\t             *     <div ui-view>                    <!-- created in the context named: \"A.B\"    -->\n\t             *       <div ui-view=\"bar\">            <!-- created in the context named: \"A.B.C\"  -->\n\t             *       </div>\n\t             *     </div>\n\t             *   </div>\n\t             * </div>\n\t             *\n\t             * uiViews: [\n\t             *  { fqn: \"$default\",                  creationContext: { name: \"\" } },\n\t             *  { fqn: \"$default.foo\",              creationContext: { name: \"A\" } },\n\t             *  { fqn: \"$default.foo.$default\",     creationContext: { name: \"A.B\" } }\n\t             *  { fqn: \"$default.foo.$default.bar\", creationContext: { name: \"A.B.C\" } }\n\t             * ]\n\t             *\n\t             * These four view configs all match the ui-view with the fqn: \"$default.foo.$default.bar\":\n\t             *\n\t             * - ViewConfig1: { uiViewName: \"bar\",                       uiViewContextAnchor: \"A.B.C\" }\n\t             * - ViewConfig2: { uiViewName: \"$default.bar\",              uiViewContextAnchor: \"A.B\" }\n\t             * - ViewConfig3: { uiViewName: \"foo.$default.bar\",          uiViewContextAnchor: \"A\" }\n\t             * - ViewConfig4: { uiViewName: \"$default.foo.$default.bar\", uiViewContextAnchor: \"\" }\n\t             *\n\t             * Using ViewConfig3 as an example, it matches the ui-view with fqn \"$default.foo.$default.bar\" because:\n\t             * - The ViewConfig's segmented target name is: [ \"foo\", \"$default\", \"bar\" ]\n\t             * - There exists a parent ui-view (which has fqn: \"$default.foo\") where:\n\t             *    - the parent ui-view's name \"foo\" matches the first segment \"foo\" of the ViewConfig's target name\n\t             *    - the parent ui-view's context \"A\" matches the ViewConfig's anchor context \"A\"\n\t             * - And the remaining segments [ \"$default\", \"bar\" ].join(\".\"_ of the ViewConfig's target name match\n\t             *   the tail of the ui-view's fqn \"default.bar\"\n\t             */\n\t            var matches = function (uiView) { return function (viewConfig) {\n\t                // Don't supply an ng1 ui-view with an ng2 ViewConfig, etc\n\t                if (uiView.$type !== viewConfig.viewDecl.$type)\n\t                    return false;\n\t                // Split names apart from both viewConfig and uiView into segments\n\t                var vc = viewConfig.viewDecl;\n\t                var vcSegments = vc.$uiViewName.split(\".\");\n\t                var uivSegments = uiView.fqn.split(\".\");\n\t                // Check if the tails of the segment arrays match. ex, these arrays' tails match:\n\t                // vc: [\"foo\", \"bar\"], uiv fqn: [\"$default\", \"foo\", \"bar\"]\n\t                if (!common_1.equals(vcSegments, uivSegments.slice(0 - vcSegments.length)))\n\t                    return false;\n\t                // Now check if the fqn ending at the first segment of the viewConfig matches the context:\n\t                // [\"$default\", \"foo\"].join(\".\") == \"$default.foo\", does the ui-view $default.foo context match?\n\t                var negOffset = (1 - vcSegments.length) || undefined;\n\t                var fqnToFirstSegment = uivSegments.slice(0, negOffset).join(\".\");\n\t                var uiViewContext = uiViewsByFqn[fqnToFirstSegment].creationContext;\n\t                return vc.$uiViewContextAnchor === (uiViewContext && uiViewContext.name);\n\t            }; };\n\t            // Return the number of dots in the fully qualified name\n\t            function uiViewDepth(uiView) {\n\t                return uiView.fqn.split(\".\").length;\n\t            }\n\t            // Return the ViewConfig's context's depth in the context tree.\n\t            function viewConfigDepth(config) {\n\t                var context = config.viewDecl.$context, count = 0;\n\t                while (++count && context.parent)\n\t                    context = context.parent;\n\t                return count;\n\t            }\n\t            // Given a depth function, returns a compare function which can return either ascending or descending order\n\t            var depthCompare = hof_1.curry(function (depthFn, posNeg, left, right) { return posNeg * (depthFn(left) - depthFn(right)); });\n\t            var matchingConfigPair = function (uiView) {\n\t                var matchingConfigs = _this.viewConfigs.filter(matches(uiView));\n\t                if (matchingConfigs.length > 1)\n\t                    matchingConfigs.sort(depthCompare(viewConfigDepth, -1)); // descending\n\t                return [uiView, matchingConfigs[0]];\n\t            };\n\t            var configureUIView = function (_a) {\n\t                var uiView = _a[0], viewConfig = _a[1];\n\t                // If a parent ui-view is reconfigured, it could destroy child ui-views.\n\t                // Before configuring a child ui-view, make sure it's still in the active uiViews array.\n\t                if (_this.uiViews.indexOf(uiView) !== -1)\n\t                    uiView.configUpdated(viewConfig);\n\t            };\n\t            _this.uiViews.sort(depthCompare(uiViewDepth, 1)).map(matchingConfigPair).forEach(configureUIView);\n\t        };\n\t    }\n\t    ViewService.prototype.rootContext = function (context) {\n\t        return this._rootContext = context || this._rootContext;\n\t    };\n\t    ;\n\t    ViewService.prototype.viewConfigFactory = function (viewType, factory) {\n\t        this._viewConfigFactories[viewType] = factory;\n\t    };\n\t    ViewService.prototype.createViewConfig = function (path, decl) {\n\t        var cfgFactory = this._viewConfigFactories[decl.$type];\n\t        if (!cfgFactory)\n\t            throw new Error(\"ViewService: No view config factory registered for type \" + decl.$type);\n\t        var cfgs = cfgFactory(path, decl);\n\t        return predicates_1.isArray(cfgs) ? cfgs : [cfgs];\n\t    };\n\t    /**\n\t     * De-registers a ViewConfig.\n\t     *\n\t     * @param viewConfig The ViewConfig view to deregister.\n\t     */\n\t    ViewService.prototype.deactivateViewConfig = function (viewConfig) {\n\t        trace_1.trace.traceViewServiceEvent(\"<- Removing\", viewConfig);\n\t        common_1.removeFrom(this.viewConfigs, viewConfig);\n\t    };\n\t    ;\n\t    ViewService.prototype.activateViewConfig = function (viewConfig) {\n\t        trace_1.trace.traceViewServiceEvent(\"-> Registering\", viewConfig);\n\t        this.viewConfigs.push(viewConfig);\n\t    };\n\t    ;\n\t    /**\n\t     * Allows a `ui-view` element to register its canonical name with a callback that allows it to\n\t     * be updated with a template, controller, and local variables.\n\t     *\n\t     * @param {String} name The fully-qualified name of the `ui-view` object being registered.\n\t     * @param {Function} configUpdatedCallback A callback that receives updates to the content & configuration\n\t     *                   of the view.\n\t     * @return {Function} Returns a de-registration function used when the view is destroyed.\n\t     */\n\t    ViewService.prototype.registerUIView = function (uiView) {\n\t        trace_1.trace.traceViewServiceUIViewEvent(\"-> Registering\", uiView);\n\t        var uiViews = this.uiViews;\n\t        var fqnMatches = function (uiv) { return uiv.fqn === uiView.fqn; };\n\t        if (uiViews.filter(fqnMatches).length)\n\t            trace_1.trace.traceViewServiceUIViewEvent(\"!!!! duplicate uiView named:\", uiView);\n\t        uiViews.push(uiView);\n\t        this.sync();\n\t        return function () {\n\t            var idx = uiViews.indexOf(uiView);\n\t            if (idx <= 0) {\n\t                trace_1.trace.traceViewServiceUIViewEvent(\"Tried removing non-registered uiView\", uiView);\n\t                return;\n\t            }\n\t            trace_1.trace.traceViewServiceUIViewEvent(\"<- Deregistering\", uiView);\n\t            common_1.removeFrom(uiViews)(uiView);\n\t        };\n\t    };\n\t    ;\n\t    /**\n\t     * Returns the list of views currently available on the page, by fully-qualified name.\n\t     *\n\t     * @return {Array} Returns an array of fully-qualified view names.\n\t     */\n\t    ViewService.prototype.available = function () {\n\t        return this.uiViews.map(hof_1.prop(\"fqn\"));\n\t    };\n\t    /**\n\t     * Returns the list of views on the page containing loaded content.\n\t     *\n\t     * @return {Array} Returns an array of fully-qualified view names.\n\t     */\n\t    ViewService.prototype.active = function () {\n\t        return this.uiViews.filter(hof_1.prop(\"$config\")).map(hof_1.prop(\"name\"));\n\t    };\n\t    /**\n\t     * Normalizes a view's name from a state.views configuration block.\n\t     *\n\t     * @param context the context object (state declaration) that the view belongs to\n\t     * @param rawViewName the name of the view, as declared in the [[StateDeclaration.views]]\n\t     *\n\t     * @returns the normalized uiViewName and uiViewContextAnchor that the view targets\n\t     */\n\t    ViewService.normalizeUIViewTarget = function (context, rawViewName) {\n\t        if (rawViewName === void 0) { rawViewName = \"\"; }\n\t        // TODO: Validate incoming view name with a regexp to allow:\n\t        // ex: \"view.name@foo.bar\" , \"^.^.view.name\" , \"view.name@^.^\" , \"\" ,\n\t        // \"@\" , \"$default@^\" , \"!$default.$default\" , \"!foo.bar\"\n\t        var viewAtContext = rawViewName.split(\"@\");\n\t        var uiViewName = viewAtContext[0] || \"$default\"; // default to unnamed view\n\t        var uiViewContextAnchor = predicates_1.isString(viewAtContext[1]) ? viewAtContext[1] : \"^\"; // default to parent context\n\t        // Handle relative view-name sugar syntax.\n\t        // Matches rawViewName \"^.^.^.foo.bar\" into array: [\"^.^.^.foo.bar\", \"^.^.^\", \"foo.bar\"],\n\t        var relativeViewNameSugar = /^(\\^(?:\\.\\^)*)\\.(.*$)/.exec(uiViewName);\n\t        if (relativeViewNameSugar) {\n\t            // Clobbers existing contextAnchor (rawViewName validation will fix this)\n\t            uiViewContextAnchor = relativeViewNameSugar[1]; // set anchor to \"^.^.^\"\n\t            uiViewName = relativeViewNameSugar[2]; // set view-name to \"foo.bar\"\n\t        }\n\t        if (uiViewName.charAt(0) === '!') {\n\t            uiViewName = uiViewName.substr(1);\n\t            uiViewContextAnchor = \"\"; // target absolutely from root\n\t        }\n\t        // handle parent relative targeting \"^.^.^\"\n\t        var relativeMatch = /^(\\^(?:\\.\\^)*)$/;\n\t        if (relativeMatch.exec(uiViewContextAnchor)) {\n\t            var anchor = uiViewContextAnchor.split(\".\").reduce((function (anchor, x) { return anchor.parent; }), context);\n\t            uiViewContextAnchor = anchor.name;\n\t        }\n\t        return { uiViewName: uiViewName, uiViewContextAnchor: uiViewContextAnchor };\n\t    };\n\t    return ViewService;\n\t}());\n\texports.ViewService = ViewService;\n\n\n/***/ },\n/* 38 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module state */ /** for typedoc */\n\t\"use strict\";\n\tvar stateMatcher_1 = __webpack_require__(39);\n\tvar stateBuilder_1 = __webpack_require__(40);\n\tvar stateQueueManager_1 = __webpack_require__(41);\n\tvar StateRegistry = (function () {\n\t    function StateRegistry(urlMatcherFactory, urlRouterProvider) {\n\t        this.states = {};\n\t        this.matcher = new stateMatcher_1.StateMatcher(this.states);\n\t        this.builder = new stateBuilder_1.StateBuilder(this.matcher, urlMatcherFactory);\n\t        this.stateQueue = new stateQueueManager_1.StateQueueManager(this.states, this.builder, urlRouterProvider);\n\t        var rootStateDef = {\n\t            name: '',\n\t            url: '^',\n\t            views: null,\n\t            params: {\n\t                '#': { value: null, type: 'hash', dynamic: true }\n\t            },\n\t            abstract: true\n\t        };\n\t        var _root = this._root = this.stateQueue.register(rootStateDef);\n\t        _root.navigable = null;\n\t    }\n\t    StateRegistry.prototype.root = function () {\n\t        return this._root;\n\t    };\n\t    StateRegistry.prototype.register = function (stateDefinition) {\n\t        return this.stateQueue.register(stateDefinition);\n\t    };\n\t    StateRegistry.prototype.get = function (stateOrName, base) {\n\t        var _this = this;\n\t        if (arguments.length === 0)\n\t            return Object.keys(this.states).map(function (name) { return _this.states[name].self; });\n\t        var found = this.matcher.find(stateOrName, base);\n\t        return found && found.self || null;\n\t    };\n\t    StateRegistry.prototype.decorator = function (name, func) {\n\t        return this.builder.builder(name, func);\n\t    };\n\t    return StateRegistry;\n\t}());\n\texports.StateRegistry = StateRegistry;\n\n\n/***/ },\n/* 39 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** for typedoc */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar StateMatcher = (function () {\n\t    function StateMatcher(_states) {\n\t        this._states = _states;\n\t    }\n\t    StateMatcher.prototype.isRelative = function (stateName) {\n\t        stateName = stateName || \"\";\n\t        return stateName.indexOf(\".\") === 0 || stateName.indexOf(\"^\") === 0;\n\t    };\n\t    StateMatcher.prototype.find = function (stateOrName, base) {\n\t        if (!stateOrName && stateOrName !== \"\")\n\t            return undefined;\n\t        var isStr = predicates_1.isString(stateOrName);\n\t        var name = isStr ? stateOrName : stateOrName.name;\n\t        if (this.isRelative(name))\n\t            name = this.resolvePath(name, base);\n\t        var state = this._states[name];\n\t        if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) {\n\t            return state;\n\t        }\n\t        return undefined;\n\t    };\n\t    StateMatcher.prototype.resolvePath = function (name, base) {\n\t        if (!base)\n\t            throw new Error(\"No reference point given for path '\" + name + \"'\");\n\t        var baseState = this.find(base);\n\t        var splitName = name.split(\".\"), i = 0, pathLength = splitName.length, current = baseState;\n\t        for (; i < pathLength; i++) {\n\t            if (splitName[i] === \"\" && i === 0) {\n\t                current = baseState;\n\t                continue;\n\t            }\n\t            if (splitName[i] === \"^\") {\n\t                if (!current.parent)\n\t                    throw new Error(\"Path '\" + name + \"' not valid for state '\" + baseState.name + \"'\");\n\t                current = current.parent;\n\t                continue;\n\t            }\n\t            break;\n\t        }\n\t        var relName = splitName.slice(i).join(\".\");\n\t        return current.name + (current.name && relName ? \".\" : \"\") + relName;\n\t    };\n\t    return StateMatcher;\n\t}());\n\texports.StateMatcher = StateMatcher;\n\n\n/***/ },\n/* 40 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar strings_1 = __webpack_require__(9);\n\tvar hof_1 = __webpack_require__(5);\n\tvar param_1 = __webpack_require__(22);\n\tvar resolvable_1 = __webpack_require__(19);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar parseUrl = function (url) {\n\t    if (!predicates_1.isString(url))\n\t        return false;\n\t    var root = url.charAt(0) === '^';\n\t    return { val: root ? url.substring(1) : url, root: root };\n\t};\n\tfunction selfBuilder(state) {\n\t    state.self.$$state = function () { return state; };\n\t    return state.self;\n\t}\n\tfunction dataBuilder(state) {\n\t    if (state.parent && state.parent.data) {\n\t        state.data = state.self.data = common_1.inherit(state.parent.data, state.data);\n\t    }\n\t    return state.data;\n\t}\n\tvar getUrlBuilder = function ($urlMatcherFactoryProvider, root) {\n\t    return function urlBuilder(state) {\n\t        var stateDec = state;\n\t        var parsed = parseUrl(stateDec.url), parent = state.parent;\n\t        var url = !parsed ? stateDec.url : $urlMatcherFactoryProvider.compile(parsed.val, {\n\t            params: state.params || {},\n\t            paramMap: function (paramConfig, isSearch) {\n\t                if (stateDec.reloadOnSearch === false && isSearch)\n\t                    paramConfig = common_1.extend(paramConfig || {}, { dynamic: true });\n\t                return paramConfig;\n\t            }\n\t        });\n\t        if (!url)\n\t            return null;\n\t        if (!$urlMatcherFactoryProvider.isMatcher(url))\n\t            throw new Error(\"Invalid url '\" + url + \"' in state '\" + state + \"'\");\n\t        return (parsed && parsed.root) ? url : ((parent && parent.navigable) || root()).url.append(url);\n\t    };\n\t};\n\tvar getNavigableBuilder = function (isRoot) {\n\t    return function navigableBuilder(state) {\n\t        return !isRoot(state) && state.url ? state : (state.parent ? state.parent.navigable : null);\n\t    };\n\t};\n\tfunction paramsBuilder(state) {\n\t    var makeConfigParam = function (config, id) { return param_1.Param.fromConfig(id, null, config); };\n\t    var urlParams = (state.url && state.url.parameters({ inherit: false })) || [];\n\t    var nonUrlParams = common_1.values(common_1.map(common_1.omit(state.params || {}, urlParams.map(hof_1.prop('id'))), makeConfigParam));\n\t    return urlParams.concat(nonUrlParams).map(function (p) { return [p.id, p]; }).reduce(common_1.applyPairs, {});\n\t}\n\tfunction pathBuilder(state) {\n\t    return state.parent ? state.parent.path.concat(state) : [state];\n\t}\n\tfunction includesBuilder(state) {\n\t    var includes = state.parent ? common_1.extend({}, state.parent.includes) : {};\n\t    includes[state.name] = true;\n\t    return includes;\n\t}\n\t/**\n\t * This is a [[StateBuilder.builder]] function for the `resolve:` block on a [[StateDeclaration]].\n\t *\n\t * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder\n\t * validates the `resolve` property and converts it to a [[Resolvable]] array.\n\t *\n\t * resolve: input value can be:\n\t *\n\t * {\n\t *   // analyzed but not injected\n\t *   myFooResolve: function() { return \"myFooData\"; },\n\t *\n\t *   // function.toString() parsed, \"DependencyName\" dep as string (not min-safe)\n\t *   myBarResolve: function(DependencyName) { return DependencyName.fetchSomethingAsPromise() },\n\t *\n\t *   // Array split; \"DependencyName\" dep as string\n\t *   myBazResolve: [ \"DependencyName\", function(dep) { return dep.fetchSomethingAsPromise() },\n\t *\n\t *   // Array split; DependencyType dep as token (compared using ===)\n\t *   myQuxResolve: [ DependencyType, function(dep) { return dep.fetchSometingAsPromise() },\n\t *\n\t *   // val.$inject used as deps\n\t *   // where:\n\t *   //     corgeResolve.$inject = [\"DependencyName\"];\n\t *   //     function corgeResolve(dep) { dep.fetchSometingAsPromise() }\n\t *   // then \"DependencyName\" dep as string\n\t *   myCorgeResolve: corgeResolve,\n\t *\n\t *  // inject service by name\n\t *  // When a string is found, desugar creating a resolve that injects the named service\n\t *   myGraultResolve: \"SomeService\"\n\t * }\n\t *\n\t * or:\n\t *\n\t * [\n\t *   new Resolvable(\"myFooResolve\", function() { return \"myFooData\" }),\n\t *   new Resolvable(\"myBarResolve\", function(dep) { return dep.fetchSomethingAsPromise() }, [ \"DependencyName\" ]),\n\t *   { provide: \"myBazResolve\", useFactory: function(dep) { dep.fetchSomethingAsPromise() }, deps: [ \"DependencyName\" ] }\n\t * ]\n\t */\n\tfunction resolvablesBuilder(state) {\n\t    /** convert a resolve: {} object to an array of tuples */\n\t    var obj2Tuples = function (obj) { return Object.keys(obj || {}).map(function (token) { return ({ token: token, val: obj[token], deps: undefined }); }); };\n\t    /** fetch DI annotations from a function or ng1-style array */\n\t    var annotate = function (fn) { return fn.$inject || coreservices_1.services.$injector.annotate(fn, coreservices_1.services.$injector.strictDi); };\n\t    /** true if the object has both `token` and `resolveFn`, and is probably a [[ResolveLiteral]] */\n\t    var isResolveLiteral = function (obj) { return !!(obj.token && obj.resolveFn); };\n\t    /** true if the object looks like a provide literal, or a ng2 Provider */\n\t    var isLikeNg2Provider = function (obj) { return !!((obj.provide || obj.token) && (obj.useValue || obj.useFactory || obj.useExisting || obj.useClass)); };\n\t    /** true if the object looks like a tuple from obj2Tuples */\n\t    var isTupleFromObj = function (obj) { return !!(obj && obj.val && (predicates_1.isString(obj.val) || predicates_1.isArray(obj.val) || predicates_1.isFunction(obj.val))); };\n\t    /** extracts the token from a Provider or provide literal */\n\t    var token = function (p) { return p.provide || p.token; };\n\t    /** Given a literal resolve or provider object, returns a Resolvable */\n\t    var literal2Resolvable = hof_1.pattern([\n\t        [hof_1.prop('resolveFn'), function (p) { return new resolvable_1.Resolvable(token(p), p.resolveFn, p.deps, p.policy); }],\n\t        [hof_1.prop('useFactory'), function (p) { return new resolvable_1.Resolvable(token(p), p.useFactory, (p.deps || p.dependencies), p.policy); }],\n\t        [hof_1.prop('useClass'), function (p) { return new resolvable_1.Resolvable(token(p), function () { return new p.useClass(); }, [], p.policy); }],\n\t        [hof_1.prop('useValue'), function (p) { return new resolvable_1.Resolvable(token(p), function () { return p.useValue; }, [], p.policy, p.useValue); }],\n\t        [hof_1.prop('useExisting'), function (p) { return new resolvable_1.Resolvable(token(p), function (x) { return x; }, [p.useExisting], p.policy); }],\n\t    ]);\n\t    var tuple2Resolvable = hof_1.pattern([\n\t        [hof_1.pipe(hof_1.prop(\"val\"), predicates_1.isString), function (tuple) { return new resolvable_1.Resolvable(tuple.token, function (x) { return x; }, [tuple.val], tuple.policy); }],\n\t        [hof_1.pipe(hof_1.prop(\"val\"), predicates_1.isArray), function (tuple) { return new resolvable_1.Resolvable(tuple.token, common_1.tail(tuple.val), tuple.val.slice(0, -1), tuple.policy); }],\n\t        [hof_1.pipe(hof_1.prop(\"val\"), predicates_1.isFunction), function (tuple) { return new resolvable_1.Resolvable(tuple.token, tuple.val, annotate(tuple.val), tuple.policy); }],\n\t    ]);\n\t    var item2Resolvable = hof_1.pattern([\n\t        [hof_1.is(resolvable_1.Resolvable), function (r) { return r; }],\n\t        [isResolveLiteral, literal2Resolvable],\n\t        [isLikeNg2Provider, literal2Resolvable],\n\t        [isTupleFromObj, tuple2Resolvable],\n\t        [hof_1.val(true), function (tuple) { throw new Error(\"Invalid resolve value: \" + strings_1.stringify(tuple)); }]\n\t    ]);\n\t    // If resolveBlock is already an array, use it as-is.\n\t    // Otherwise, assume it's an object and convert to an Array of tuples\n\t    var decl = state.resolve;\n\t    var items = predicates_1.isArray(decl) ? decl : obj2Tuples(decl);\n\t    return items.map(item2Resolvable);\n\t}\n\texports.resolvablesBuilder = resolvablesBuilder;\n\t/**\n\t * @internalapi A internal global service\n\t *\n\t * StateBuilder is a factory for the internal [[State]] objects.\n\t *\n\t * When you register a state with the [[StateRegistry]], you register a plain old javascript object which\n\t * conforms to the [[StateDeclaration]] interface.  This factory takes that object and builds the corresponding\n\t * [[State]] object, which has an API and is used internally.\n\t *\n\t * Custom properties or API may be added to the internal [[State]] object by registering a decorator function\n\t * using the [[builder]] method.\n\t */\n\tvar StateBuilder = (function () {\n\t    function StateBuilder(matcher, $urlMatcherFactoryProvider) {\n\t        this.matcher = matcher;\n\t        var self = this;\n\t        var root = function () { return matcher.find(\"\"); };\n\t        var isRoot = function (state) { return state.name === \"\"; };\n\t        function parentBuilder(state) {\n\t            if (isRoot(state))\n\t                return null;\n\t            return matcher.find(self.parentName(state)) || root();\n\t        }\n\t        this.builders = {\n\t            self: [selfBuilder],\n\t            parent: [parentBuilder],\n\t            data: [dataBuilder],\n\t            // Build a URLMatcher if necessary, either via a relative or absolute URL\n\t            url: [getUrlBuilder($urlMatcherFactoryProvider, root)],\n\t            // Keep track of the closest ancestor state that has a URL (i.e. is navigable)\n\t            navigable: [getNavigableBuilder(isRoot)],\n\t            params: [paramsBuilder],\n\t            // Each framework-specific ui-router implementation should define its own `views` builder\n\t            // e.g., src/ng1/statebuilders/views.ts\n\t            views: [],\n\t            // Keep a full path from the root down to this state as this is needed for state activation.\n\t            path: [pathBuilder],\n\t            // Speed up $state.includes() as it's used a lot\n\t            includes: [includesBuilder],\n\t            resolvables: [resolvablesBuilder]\n\t        };\n\t    }\n\t    /**\n\t     * Registers a [[BuilderFunction]] for a specific [[State]] property (e.g., `parent`, `url`, or `path`).\n\t     * More than one BuilderFunction can be registered for a given property.\n\t     *\n\t     * The BuilderFunction(s) will be used to define the property on any subsequently built [[State]] objects.\n\t     *\n\t     * @param name The name of the State property being registered for.\n\t     * @param fn The BuilderFunction which will be used to build the State property\n\t     * @returns a function which deregisters the BuilderFunction\n\t     */\n\t    StateBuilder.prototype.builder = function (name, fn) {\n\t        var builders = this.builders;\n\t        var array = builders[name] || [];\n\t        // Backwards compat: if only one builder exists, return it, else return whole arary.\n\t        if (predicates_1.isString(name) && !predicates_1.isDefined(fn))\n\t            return array.length > 1 ? array : array[0];\n\t        if (!predicates_1.isString(name) || !predicates_1.isFunction(fn))\n\t            return;\n\t        builders[name] = array;\n\t        builders[name].push(fn);\n\t        return function () { return builders[name].splice(builders[name].indexOf(fn, 1)) && null; };\n\t    };\n\t    /**\n\t     * Builds all of the properties on an essentially blank State object, returning a State object which has all its\n\t     * properties and API built.\n\t     *\n\t     * @param state an uninitialized State object\n\t     * @returns the built State object\n\t     */\n\t    StateBuilder.prototype.build = function (state) {\n\t        var _a = this, matcher = _a.matcher, builders = _a.builders;\n\t        var parent = this.parentName(state);\n\t        if (parent && !matcher.find(parent))\n\t            return null;\n\t        for (var key in builders) {\n\t            if (!builders.hasOwnProperty(key))\n\t                continue;\n\t            var chain = builders[key].reduce(function (parentFn, step) { return function (_state) { return step(_state, parentFn); }; }, common_1.noop);\n\t            state[key] = chain(state);\n\t        }\n\t        return state;\n\t    };\n\t    StateBuilder.prototype.parentName = function (state) {\n\t        var name = state.name || \"\";\n\t        if (name.indexOf('.') !== -1)\n\t            return name.substring(0, name.lastIndexOf('.'));\n\t        if (!state.parent)\n\t            return \"\";\n\t        return predicates_1.isString(state.parent) ? state.parent : state.parent.name;\n\t    };\n\t    StateBuilder.prototype.name = function (state) {\n\t        var name = state.name;\n\t        if (name.indexOf('.') !== -1 || !state.parent)\n\t            return name;\n\t        var parentName = predicates_1.isString(state.parent) ? state.parent : state.parent.name;\n\t        return parentName ? parentName + \".\" + name : name;\n\t    };\n\t    return StateBuilder;\n\t}());\n\texports.StateBuilder = StateBuilder;\n\n\n/***/ },\n/* 41 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar stateObject_1 = __webpack_require__(42);\n\tvar StateQueueManager = (function () {\n\t    function StateQueueManager(states, builder, $urlRouterProvider) {\n\t        this.states = states;\n\t        this.builder = builder;\n\t        this.$urlRouterProvider = $urlRouterProvider;\n\t        this.queue = [];\n\t    }\n\t    StateQueueManager.prototype.register = function (config) {\n\t        var _a = this, states = _a.states, queue = _a.queue, $state = _a.$state;\n\t        // Wrap a new object around the state so we can store our private details easily.\n\t        // @TODO: state = new State(extend({}, config, { ... }))\n\t        var state = common_1.inherit(new stateObject_1.State(), common_1.extend({}, config, {\n\t            self: config,\n\t            resolve: config.resolve || [],\n\t            toString: function () { return config.name; }\n\t        }));\n\t        if (!predicates_1.isString(state.name))\n\t            throw new Error(\"State must have a valid name\");\n\t        if (states.hasOwnProperty(state.name) || common_1.pluck(queue, 'name').indexOf(state.name) !== -1)\n\t            throw new Error(\"State '\" + state.name + \"' is already defined\");\n\t        queue.push(state);\n\t        if (this.$state) {\n\t            this.flush($state);\n\t        }\n\t        return state;\n\t    };\n\t    StateQueueManager.prototype.flush = function ($state) {\n\t        var _a = this, queue = _a.queue, states = _a.states, builder = _a.builder;\n\t        var result, state, orphans = [], orphanIdx, previousQueueLength = {};\n\t        while (queue.length > 0) {\n\t            state = queue.shift();\n\t            result = builder.build(state);\n\t            orphanIdx = orphans.indexOf(state);\n\t            if (result) {\n\t                if (states.hasOwnProperty(state.name))\n\t                    throw new Error(\"State '\" + name + \"' is already defined\");\n\t                states[state.name] = state;\n\t                this.attachRoute($state, state);\n\t                if (orphanIdx >= 0)\n\t                    orphans.splice(orphanIdx, 1);\n\t                continue;\n\t            }\n\t            var prev = previousQueueLength[state.name];\n\t            previousQueueLength[state.name] = queue.length;\n\t            if (orphanIdx >= 0 && prev === queue.length) {\n\t                // Wait until two consecutive iterations where no additional states were dequeued successfully.\n\t                // throw new Error(`Cannot register orphaned state '${state.name}'`);\n\t                return states;\n\t            }\n\t            else if (orphanIdx < 0) {\n\t                orphans.push(state);\n\t            }\n\t            queue.push(state);\n\t        }\n\t        return states;\n\t    };\n\t    StateQueueManager.prototype.autoFlush = function ($state) {\n\t        this.$state = $state;\n\t        this.flush($state);\n\t    };\n\t    StateQueueManager.prototype.attachRoute = function ($state, state) {\n\t        var $urlRouterProvider = this.$urlRouterProvider;\n\t        if (state[common_1.abstractKey] || !state.url)\n\t            return;\n\t        $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {\n\t                if ($state.$current.navigable !== state || !common_1.equalForKeys($match, $stateParams)) {\n\t                    $state.transitionTo(state, $match, { inherit: true, location: false });\n\t                }\n\t            }]);\n\t    };\n\t    return StateQueueManager;\n\t}());\n\texports.StateQueueManager = StateQueueManager;\n\n\n/***/ },\n/* 42 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module state */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\t/**\n\t * @ngdoc object\n\t * @name ui.router.state.type:State\n\t *\n\t * @description\n\t * Definition object for states. Includes methods for manipulating the state heirarchy.\n\t *\n\t * @param {Object} config  A configuration object hash that includes the results of user-supplied\n\t *        values, as well as values from `StateBuilder`.\n\t *\n\t * @returns {Object}  Returns a new `State` object.\n\t */\n\tvar State = (function () {\n\t    function State(config) {\n\t        common_1.extend(this, config);\n\t        // Object.freeze(this);\n\t    }\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.type:State#is\n\t     * @methodOf ui.router.state.type:State\n\t     *\n\t     * @description\n\t     * Compares the identity of the state against the passed value, which is either an object\n\t     * reference to the actual `State` instance, the original definition object passed to\n\t     * `$stateProvider.state()`, or the fully-qualified name.\n\t     *\n\t     * @param {Object} ref Can be one of (a) a `State` instance, (b) an object that was passed\n\t     *        into `$stateProvider.state()`, (c) the fully-qualified name of a state as a string.\n\t     * @returns {boolean} Returns `true` if `ref` matches the current `State` instance.\n\t     */\n\t    State.prototype.is = function (ref) {\n\t        return this === ref || this.self === ref || this.fqn() === ref;\n\t    };\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.type:State#fqn\n\t     * @methodOf ui.router.state.type:State\n\t     *\n\t     * @description\n\t     * Returns the fully-qualified name of the state, based on its current position in the tree.\n\t     *\n\t     * @returns {string} Returns a dot-separated name of the state.\n\t     */\n\t    State.prototype.fqn = function () {\n\t        if (!this.parent || !(this.parent instanceof this.constructor))\n\t            return this.name;\n\t        var name = this.parent.fqn();\n\t        return name ? name + \".\" + this.name : this.name;\n\t    };\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.type:State#root\n\t     * @methodOf ui.router.state.type:State\n\t     *\n\t     * @description\n\t     * Returns the root node of this state's tree.\n\t     *\n\t     * @returns {State} The root of this state's tree.\n\t     */\n\t    State.prototype.root = function () {\n\t        return this.parent && this.parent.root() || this;\n\t    };\n\t    State.prototype.parameters = function (opts) {\n\t        opts = common_1.defaults(opts, { inherit: true });\n\t        var inherited = opts.inherit && this.parent && this.parent.parameters() || [];\n\t        return inherited.concat(common_1.values(this.params));\n\t    };\n\t    State.prototype.parameter = function (id, opts) {\n\t        if (opts === void 0) { opts = {}; }\n\t        return (this.url && this.url.parameter(id, opts) ||\n\t            common_1.find(common_1.values(this.params), hof_1.propEq('id', id)) ||\n\t            opts.inherit && this.parent && this.parent.parameter(id));\n\t    };\n\t    State.prototype.toString = function () {\n\t        return this.fqn();\n\t    };\n\t    return State;\n\t}());\n\texports.State = State;\n\n\n/***/ },\n/* 43 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar queue_1 = __webpack_require__(8);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar pathFactory_1 = __webpack_require__(20);\n\tvar node_1 = __webpack_require__(21);\n\tvar transitionService_1 = __webpack_require__(31);\n\tvar rejectFactory_1 = __webpack_require__(10);\n\tvar targetState_1 = __webpack_require__(14);\n\tvar param_1 = __webpack_require__(22);\n\tvar glob_1 = __webpack_require__(7);\n\tvar common_2 = __webpack_require__(3);\n\tvar common_3 = __webpack_require__(3);\n\tvar StateService = (function () {\n\t    /** @hidden */\n\t    function StateService(router) {\n\t        this.router = router;\n\t        /** @hidden */\n\t        this._defaultErrorHandler = function $defaultErrorHandler($error$) {\n\t            if ($error$ instanceof Error && $error$.stack) {\n\t                console.error($error$.stack);\n\t            }\n\t            else if ($error$ instanceof rejectFactory_1.Rejection) {\n\t                console.error($error$);\n\t                if ($error$.detail && $error$.detail.stack)\n\t                    console.error($error$.detail.stack);\n\t            }\n\t            else {\n\t                console.error($error$);\n\t            }\n\t        };\n\t        var getters = ['current', '$current', 'params', 'transition'];\n\t        var boundFns = Object.keys(StateService.prototype).filter(function (key) { return getters.indexOf(key) === -1; });\n\t        common_3.bindFunctions(StateService.prototype, this, this, boundFns);\n\t    }\n\t    Object.defineProperty(StateService.prototype, \"transition\", {\n\t        get: function () { return this.router.globals.transition; },\n\t        enumerable: true,\n\t        configurable: true\n\t    });\n\t    Object.defineProperty(StateService.prototype, \"params\", {\n\t        get: function () { return this.router.globals.params; },\n\t        enumerable: true,\n\t        configurable: true\n\t    });\n\t    Object.defineProperty(StateService.prototype, \"current\", {\n\t        get: function () { return this.router.globals.current; },\n\t        enumerable: true,\n\t        configurable: true\n\t    });\n\t    Object.defineProperty(StateService.prototype, \"$current\", {\n\t        get: function () { return this.router.globals.$current; },\n\t        enumerable: true,\n\t        configurable: true\n\t    });\n\t    /**\n\t     * Handler for when [[transitionTo]] is called with an invalid state.\n\t     *\n\t     * Invokes the [[onInvalid]] callbacks, in natural order.\n\t     * Each callback's return value is checked in sequence until one of them returns an instance of TargetState.\n\t     * The results of the callbacks are wrapped in $q.when(), so the callbacks may return promises.\n\t     *\n\t     * If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and the result returned.\n\t     */\n\t    StateService.prototype._handleInvalidTargetState = function (fromPath, $to$) {\n\t        var _this = this;\n\t        var globals = this.router.globals;\n\t        var latestThing = function () { return globals.transitionHistory.peekTail(); };\n\t        var latest = latestThing();\n\t        var $from$ = pathFactory_1.PathFactory.makeTargetState(fromPath);\n\t        var callbackQueue = new queue_1.Queue([].concat(this.router.stateProvider.invalidCallbacks));\n\t        var $q = coreservices_1.services.$q, $injector = coreservices_1.services.$injector;\n\t        var invokeCallback = function (callback) { return $q.when($injector.invoke(callback, null, { $to$: $to$, $from$: $from$ })); };\n\t        var checkForRedirect = function (result) {\n\t            if (!(result instanceof targetState_1.TargetState)) {\n\t                return;\n\t            }\n\t            var target = result;\n\t            // Recreate the TargetState, in case the state is now defined.\n\t            target = _this.target(target.identifier(), target.params(), target.options());\n\t            if (!target.valid())\n\t                return rejectFactory_1.Rejection.invalid(target.error()).toPromise();\n\t            if (latestThing() !== latest)\n\t                return rejectFactory_1.Rejection.superseded().toPromise();\n\t            return _this.transitionTo(target.identifier(), target.params(), target.options());\n\t        };\n\t        function invokeNextCallback() {\n\t            var nextCallback = callbackQueue.dequeue();\n\t            if (nextCallback === undefined)\n\t                return rejectFactory_1.Rejection.invalid($to$.error()).toPromise();\n\t            return invokeCallback(nextCallback).then(checkForRedirect).then(function (result) { return result || invokeNextCallback(); });\n\t        }\n\t        return invokeNextCallback();\n\t    };\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#reload\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * A method that force reloads the current state, or a partial state hierarchy. All resolves are re-resolved,\n\t     * controllers reinstantiated, and events re-fired.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * let app angular.module('app', ['ui.router']);\n\t     *\n\t     * app.controller('ctrl', function ($scope, $state) {\n\t     *   $scope.reload = function(){\n\t     *     $state.reload();\n\t     *   }\n\t     * });\n\t     * </pre>\n\t     *\n\t     * `reload()` is just an alias for:\n\t     * <pre>\n\t     * $state.transitionTo($state.current, $stateParams, {\n\t     *   reload: true, inherit: false, notify: true\n\t     * });\n\t     * </pre>\n\t     *\n\t     * @param {string=|object=} reloadState - A state name or a state object, which is the root of the resolves to be re-resolved.\n\t     * @example\n\t     * <pre>\n\t     * //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'\n\t     * //and current state is 'contacts.detail.item'\n\t     * let app angular.module('app', ['ui.router']);\n\t     *\n\t     * app.controller('ctrl', function ($scope, $state) {\n\t     *   $scope.reload = function(){\n\t     *     //will reload 'contact.detail' and nested 'contact.detail.item' states\n\t     *     $state.reload('contact.detail');\n\t     *   }\n\t     * });\n\t     * </pre>\n\t     *\n\t     * @returns {promise} A promise representing the state of the new transition. See\n\t     * {@link ui.router.state.$state#methods_go $state.go}.\n\t     */\n\t    StateService.prototype.reload = function (reloadState) {\n\t        return this.transitionTo(this.current, this.params, {\n\t            reload: predicates_1.isDefined(reloadState) ? reloadState : true,\n\t            inherit: false,\n\t            notify: false\n\t        });\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#go\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * Convenience method for transitioning to a new state. `$state.go` calls\n\t     * `$state.transitionTo` internally but automatically sets options to\n\t     * `{ location: true, inherit: true, relative: $state.$current, notify: true }`.\n\t     * This allows you to easily use an absolute or relative to path and specify\n\t     * only the parameters you'd like to update (while letting unspecified parameters\n\t     * inherit from the currently active ancestor states).\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * let app = angular.module('app', ['ui.router']);\n\t     *\n\t     * app.controller('ctrl', function ($scope, $state) {\n\t     *   $scope.changeState = function () {\n\t     *     $state.go('contact.detail');\n\t     *   };\n\t     * });\n\t     * </pre>\n\t     * <img src='../ngdoc_assets/StateGoExamples.png'/>\n\t     *\n\t     * @param {string} to Absolute state name or relative state path. Some examples:\n\t     *\n\t     * - `$state.go('contact.detail')` - will go to the `contact.detail` state\n\t     * - `$state.go('^')` - will go to a parent state\n\t     * - `$state.go('^.sibling')` - will go to a sibling state\n\t     * - `$state.go('.child.grandchild')` - will go to grandchild state\n\t     *\n\t     * @param {object=} params A map of the parameters that will be sent to the state,\n\t     * will populate $stateParams. Any parameters that are not specified will be inherited from currently\n\t     * defined parameters. This allows, for example, going to a sibling state that shares parameters\n\t     * specified in a parent state. Parameter inheritance only works between common ancestor states, I.e.\n\t     * transitioning to a sibling will get you the parameters for all parents, transitioning to a child\n\t     * will get you all current parameters, etc.\n\t     * @param {object=} options Options object. The options are:\n\t     *\n\t     * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`\n\t     *    will not. If string, must be `\"replace\"`, which will update url and also replace last history record.\n\t     * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.\n\t     * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),\n\t     *    defines which state to be relative from.\n\t     * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.\n\t     * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params\n\t     *    have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd\n\t     *    use this when you want to force a reload when *everything* is the same, including search params.\n\t     *\n\t     * @returns {promise} A promise representing the state of the new transition.\n\t     *\n\t     * Possible success values:\n\t     *\n\t     * - $state.current\n\t     *\n\t     * <br/>Possible rejection values:\n\t     *\n\t     * - 'transition superseded' - when a newer transition has been started after this one\n\t     * - 'transition prevented' - when `event.preventDefault()` has been called in a `$stateChangeStart` listener\n\t     * - 'transition aborted' - when `event.preventDefault()` has been called in a `$stateNotFound` listener or\n\t     *   when a `$stateNotFound` `event.retry` promise errors.\n\t     * - 'transition failed' - when a state has been unsuccessfully found after 2 tries.\n\t     * - *resolve error* - when an error has occurred with a `resolve`\n\t     *\n\t     */\n\t    StateService.prototype.go = function (to, params, options) {\n\t        var defautGoOpts = { relative: this.$current, inherit: true };\n\t        var transOpts = common_1.defaults(options, defautGoOpts, transitionService_1.defaultTransOpts);\n\t        return this.transitionTo(to, params, transOpts);\n\t    };\n\t    ;\n\t    /** Factory method for creating a TargetState */\n\t    StateService.prototype.target = function (identifier, params, options) {\n\t        if (options === void 0) { options = {}; }\n\t        // If we're reloading, find the state object to reload from\n\t        if (predicates_1.isObject(options.reload) && !options.reload.name)\n\t            throw new Error('Invalid reload state object');\n\t        var reg = this.router.stateRegistry;\n\t        options.reloadState = options.reload === true ? reg.root() : reg.matcher.find(options.reload, options.relative);\n\t        if (options.reload && !options.reloadState)\n\t            throw new Error(\"No such reload state '\" + (predicates_1.isString(options.reload) ? options.reload : options.reload.name) + \"'\");\n\t        var stateDefinition = reg.matcher.find(identifier, options.relative);\n\t        return new targetState_1.TargetState(identifier, stateDefinition, params, options);\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#transitionTo\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * Low-level method for transitioning to a new state. {@link ui.router.state.$state#methods_go $state.go}\n\t     * uses `transitionTo` internally. `$state.go` is recommended in most situations.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * let app = angular.module('app', ['ui.router']);\n\t     *\n\t     * app.controller('ctrl', function ($scope, $state) {\n\t     *   $scope.changeState = function () {\n\t     *     $state.transitionTo('contact.detail');\n\t     *   };\n\t     * });\n\t     * </pre>\n\t     *\n\t     * @param {string} to State name.\n\t     * @param {object=} toParams A map of the parameters that will be sent to the state,\n\t     * will populate $stateParams.\n\t     * @param {object=} options Options object. The options are:\n\t     *\n\t     * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`\n\t     *    will not. If string, must be `\"replace\"`, which will update url and also replace last history record.\n\t     * - **`inherit`** - {boolean=false}, If `true` will inherit url parameters from current url.\n\t     * - **`relative`** - {object=}, When transitioning with relative path (e.g '^'),\n\t     *    defines which state to be relative from.\n\t     * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.\n\t     * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params\n\t     *    have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd\n\t     *    use this when you want to force a reload when *everything* is the same, including search params.\n\t     *\n\t     * @returns {promise} A promise representing the state of the new transition. See\n\t     * {@link ui.router.state.$state#methods_go $state.go}.\n\t     */\n\t    StateService.prototype.transitionTo = function (to, toParams, options) {\n\t        var _this = this;\n\t        if (toParams === void 0) { toParams = {}; }\n\t        if (options === void 0) { options = {}; }\n\t        var router = this.router;\n\t        var globals = router.globals;\n\t        var transHistory = globals.transitionHistory;\n\t        options = common_1.defaults(options, transitionService_1.defaultTransOpts);\n\t        options = common_1.extend(options, { current: transHistory.peekTail.bind(transHistory) });\n\t        var ref = this.target(to, toParams, options);\n\t        var latestSuccess = globals.successfulTransitions.peekTail();\n\t        var rootPath = function () { return [new node_1.PathNode(_this.router.stateRegistry.root())]; };\n\t        var currentPath = latestSuccess ? latestSuccess.treeChanges().to : rootPath();\n\t        if (!ref.exists())\n\t            return this._handleInvalidTargetState(currentPath, ref);\n\t        if (!ref.valid())\n\t            return common_1.silentRejection(ref.error());\n\t        /**\n\t         * Special handling for Ignored, Aborted, and Redirected transitions\n\t         *\n\t         * The semantics for the transition.run() promise and the StateService.transitionTo()\n\t         * promise differ. For instance, the run() promise may be rejected because it was\n\t         * IGNORED, but the transitionTo() promise is resolved because from the user perspective\n\t         * no error occurred.  Likewise, the transition.run() promise may be rejected because of\n\t         * a Redirect, but the transitionTo() promise is chained to the new Transition's promise.\n\t         */\n\t        var rejectedTransitionHandler = function (transition) { return function (error) {\n\t            if (error instanceof rejectFactory_1.Rejection) {\n\t                if (error.type === rejectFactory_1.RejectType.IGNORED) {\n\t                    router.urlRouter.update();\n\t                    return globals.current;\n\t                }\n\t                if (error.type === rejectFactory_1.RejectType.SUPERSEDED && error.redirected && error.detail instanceof targetState_1.TargetState) {\n\t                    var redirect = transition.redirect(error.detail);\n\t                    return redirect.run().catch(rejectedTransitionHandler(redirect));\n\t                }\n\t                if (error.type === rejectFactory_1.RejectType.ABORTED) {\n\t                    router.urlRouter.update();\n\t                    return coreservices_1.services.$q.reject(error);\n\t                }\n\t            }\n\t            var errorHandler = _this.defaultErrorHandler();\n\t            errorHandler(error);\n\t            return coreservices_1.services.$q.reject(error);\n\t        }; };\n\t        var transition = this.router.transitionService.create(currentPath, ref);\n\t        var transitionToPromise = transition.run().catch(rejectedTransitionHandler(transition));\n\t        common_1.silenceUncaughtInPromise(transitionToPromise); // issue #2676\n\t        // Return a promise for the transition, which also has the transition object on it.\n\t        return common_1.extend(transitionToPromise, { transition: transition });\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#is\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * Similar to {@link ui.router.state.$state#methods_includes $state.includes},\n\t     * but only checks for the full state name. If params is supplied then it will be\n\t     * tested for strict equality against the current active params object, so all params\n\t     * must match with none missing and no extras.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * $state.$current.name = 'contacts.details.item';\n\t     *\n\t     * // absolute name\n\t     * $state.is('contact.details.item'); // returns true\n\t     * $state.is(contactDetailItemStateObject); // returns true\n\t     *\n\t     * // relative name (. and ^), typically from a template\n\t     * // E.g. from the 'contacts.details' template\n\t     * <div ng-class=\"{highlighted: $state.is('.item')}\">Item</div>\n\t     * </pre>\n\t     *\n\t     * @param {string|object} stateOrName The state name (absolute or relative) or state object you'd like to check.\n\t     * @param {object=} params A param object, e.g. `{sectionId: section.id}`, that you'd like\n\t     * to test against the current active state.\n\t     * @param {object=} options An options object.  The options are:\n\t     *\n\t     * - **`relative`** - {string|object} -  If `stateOrName` is a relative state name and `options.relative` is set, .is will\n\t     * test relative to `options.relative` state (or name).\n\t     *\n\t     * @returns {boolean} Returns true if it is the state.\n\t     */\n\t    StateService.prototype.is = function (stateOrName, params, options) {\n\t        options = common_1.defaults(options, { relative: this.$current });\n\t        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative);\n\t        if (!predicates_1.isDefined(state))\n\t            return undefined;\n\t        if (this.$current !== state)\n\t            return false;\n\t        return predicates_1.isDefined(params) && params !== null ? param_1.Param.equals(state.parameters(), this.params, params) : true;\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#includes\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * A method to determine if the current active state is equal to or is the child of the\n\t     * state stateName. If any params are passed then they will be tested for a match as well.\n\t     * Not all the parameters need to be passed, just the ones you'd like to test for equality.\n\t     *\n\t     * @example\n\t     * Partial and relative names\n\t     * <pre>\n\t     * $state.$current.name = 'contacts.details.item';\n\t     *\n\t     * // Using partial names\n\t     * $state.includes(\"contacts\"); // returns true\n\t     * $state.includes(\"contacts.details\"); // returns true\n\t     * $state.includes(\"contacts.details.item\"); // returns true\n\t     * $state.includes(\"contacts.list\"); // returns false\n\t     * $state.includes(\"about\"); // returns false\n\t     *\n\t     * // Using relative names (. and ^), typically from a template\n\t     * // E.g. from the 'contacts.details' template\n\t     * <div ng-class=\"{highlighted: $state.includes('.item')}\">Item</div>\n\t     * </pre>\n\t     *\n\t     * Basic globbing patterns\n\t     * <pre>\n\t     * $state.$current.name = 'contacts.details.item.url';\n\t     *\n\t     * $state.includes(\"*.details.*.*\"); // returns true\n\t     * $state.includes(\"*.details.**\"); // returns true\n\t     * $state.includes(\"**.item.**\"); // returns true\n\t     * $state.includes(\"*.details.item.url\"); // returns true\n\t     * $state.includes(\"*.details.*.url\"); // returns true\n\t     * $state.includes(\"*.details.*\"); // returns false\n\t     * $state.includes(\"item.**\"); // returns false\n\t     * </pre>\n\t     *\n\t     * @param {string} stateOrName A partial name, relative name, or glob pattern\n\t     * to be searched for within the current state name.\n\t     * @param {object=} params A param object, e.g. `{sectionId: section.id}`,\n\t     * that you'd like to test against the current active state.\n\t     * @param {object=} options An options object.  The options are:\n\t     *\n\t     * - **`relative`** - {string|object=} -  If `stateOrName` is a relative state reference and `options.relative` is set,\n\t     * .includes will test relative to `options.relative` state (or name).\n\t     *\n\t     * @returns {boolean} Returns true if it does include the state\n\t     */\n\t    StateService.prototype.includes = function (stateOrName, params, options) {\n\t        options = common_1.defaults(options, { relative: this.$current });\n\t        var glob = predicates_1.isString(stateOrName) && glob_1.Glob.fromString(stateOrName);\n\t        if (glob) {\n\t            if (!glob.matches(this.$current.name))\n\t                return false;\n\t            stateOrName = this.$current.name;\n\t        }\n\t        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative), include = this.$current.includes;\n\t        if (!predicates_1.isDefined(state))\n\t            return undefined;\n\t        if (!predicates_1.isDefined(include[state.name]))\n\t            return false;\n\t        // @TODO Replace with Param.equals() ?\n\t        return params ? common_2.equalForKeys(param_1.Param.values(state.parameters(), params), this.params, Object.keys(params)) : true;\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#href\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * A url generation method that returns the compiled url for the given state populated with the given params.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * expect($state.href(\"about.person\", { person: \"bob\" })).toEqual(\"/about/bob\");\n\t     * </pre>\n\t     *\n\t     * @param {string|object} stateOrName The state name or state object you'd like to generate a url from.\n\t     * @param {object=} params An object of parameter values to fill the state's required parameters.\n\t     * @param {object=} options Options object. The options are:\n\t     *\n\t     * - **`lossy`** - {boolean=true} -  If true, and if there is no url associated with the state provided in the\n\t     *    first parameter, then the constructed href url will be built from the first navigable ancestor (aka\n\t     *    ancestor with a valid url).\n\t     * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.\n\t     * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),\n\t     *    defines which state to be relative from.\n\t     * - **`absolute`** - {boolean=false},  If true will generate an absolute url, e.g. \"http://www.example.com/fullurl\".\n\t     *\n\t     * @returns {string} compiled state url\n\t     */\n\t    StateService.prototype.href = function (stateOrName, params, options) {\n\t        var defaultHrefOpts = {\n\t            lossy: true,\n\t            inherit: true,\n\t            absolute: false,\n\t            relative: this.$current\n\t        };\n\t        options = common_1.defaults(options, defaultHrefOpts);\n\t        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative);\n\t        if (!predicates_1.isDefined(state))\n\t            return null;\n\t        if (options.inherit)\n\t            params = this.params.$inherit(params || {}, this.$current, state);\n\t        var nav = (state && options.lossy) ? state.navigable : state;\n\t        if (!nav || nav.url === undefined || nav.url === null) {\n\t            return null;\n\t        }\n\t        return this.router.urlRouter.href(nav.url, param_1.Param.values(state.parameters(), params), {\n\t            absolute: options.absolute\n\t        });\n\t    };\n\t    ;\n\t    /**\n\t     * Sets or gets the default [[transitionTo]] error handler.\n\t     *\n\t     * The error handler is called when a [[Transition]] is rejected or when any error occurred during the Transition.\n\t     * This includes errors caused by resolves and transition hooks.\n\t     *\n\t     * The built-in default error handler logs the error to the console.\n\t     *\n\t     * You can provide your own custom handler.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * stateService.defaultErrorHandler(function() {\n\t     *   // Do not log transitionTo errors\n\t     * });\n\t     * ```\n\t     *\n\t     * @param handler a global error handler function\n\t     * @returns the current global error handler\n\t     */\n\t    StateService.prototype.defaultErrorHandler = function (handler) {\n\t        return this._defaultErrorHandler = handler || this._defaultErrorHandler;\n\t    };\n\t    StateService.prototype.get = function (stateOrName, base) {\n\t        var reg = this.router.stateRegistry;\n\t        if (arguments.length === 0)\n\t            return reg.get();\n\t        return reg.get(stateOrName, base || this.$current);\n\t    };\n\t    return StateService;\n\t}());\n\texports.StateService = StateService;\n\n\n/***/ },\n/* 44 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module core */ /** */\n\tvar stateParams_1 = __webpack_require__(45);\n\tvar queue_1 = __webpack_require__(8);\n\tvar common_1 = __webpack_require__(3);\n\t/**\n\t * Global mutable state\n\t */\n\tvar Globals = (function () {\n\t    function Globals(transitionService) {\n\t        var _this = this;\n\t        this.params = new stateParams_1.StateParams();\n\t        this.transitionHistory = new queue_1.Queue([], 1);\n\t        this.successfulTransitions = new queue_1.Queue([], 1);\n\t        var beforeNewTransition = function ($transition$) {\n\t            _this.transition = $transition$;\n\t            _this.transitionHistory.enqueue($transition$);\n\t            var updateGlobalState = function () {\n\t                _this.successfulTransitions.enqueue($transition$);\n\t                _this.$current = $transition$.$to();\n\t                _this.current = _this.$current.self;\n\t                common_1.copy($transition$.params(), _this.params);\n\t            };\n\t            $transition$.onSuccess({}, updateGlobalState, { priority: 10000 });\n\t            var clearCurrentTransition = function () { if (_this.transition === $transition$)\n\t                _this.transition = null; };\n\t            $transition$.promise.then(clearCurrentTransition, clearCurrentTransition);\n\t        };\n\t        transitionService.onBefore({}, beforeNewTransition);\n\t    }\n\t    return Globals;\n\t}());\n\texports.Globals = Globals;\n\n\n/***/ },\n/* 45 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module params */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar StateParams = (function () {\n\t    function StateParams(params) {\n\t        if (params === void 0) { params = {}; }\n\t        common_1.extend(this, params);\n\t    }\n\t    /**\n\t     * Merges a set of parameters with all parameters inherited between the common parents of the\n\t     * current state and a given destination state.\n\t     *\n\t     * @param {Object} newParams The set of parameters which will be composited with inherited params.\n\t     * @param {Object} $current Internal definition of object representing the current state.\n\t     * @param {Object} $to Internal definition of object representing state to transition to.\n\t     */\n\t    StateParams.prototype.$inherit = function (newParams, $current, $to) {\n\t        var parents = common_1.ancestors($current, $to), parentParams, inherited = {}, inheritList = [];\n\t        for (var i in parents) {\n\t            if (!parents[i] || !parents[i].params)\n\t                continue;\n\t            parentParams = Object.keys(parents[i].params);\n\t            if (!parentParams.length)\n\t                continue;\n\t            for (var j in parentParams) {\n\t                if (inheritList.indexOf(parentParams[j]) >= 0)\n\t                    continue;\n\t                inheritList.push(parentParams[j]);\n\t                inherited[parentParams[j]] = this[parentParams[j]];\n\t            }\n\t        }\n\t        return common_1.extend({}, inherited, newParams);\n\t    };\n\t    ;\n\t    return StateParams;\n\t}());\n\texports.StateParams = StateParams;\n\n\n/***/ },\n/* 46 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/**\n\t * This module contains code for State Parameters.\n\t *\n\t * See [[ParamDeclaration]]\n\t * @module params\n\t * @preferred doc\n\t */\n\t/** for typedoc */\n\t__export(__webpack_require__(22));\n\t__export(__webpack_require__(25));\n\t__export(__webpack_require__(45));\n\t__export(__webpack_require__(24));\n\n\n/***/ },\n/* 47 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module path */ /** for typedoc */\n\t__export(__webpack_require__(21));\n\t__export(__webpack_require__(20));\n\n\n/***/ },\n/* 48 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module resolve */ /** for typedoc */\n\t__export(__webpack_require__(18));\n\t__export(__webpack_require__(19));\n\t__export(__webpack_require__(17));\n\n\n/***/ },\n/* 49 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module state */ /** for typedoc */\n\t__export(__webpack_require__(30));\n\t__export(__webpack_require__(40));\n\t__export(__webpack_require__(42));\n\t__export(__webpack_require__(39));\n\t__export(__webpack_require__(41));\n\t__export(__webpack_require__(38));\n\t__export(__webpack_require__(43));\n\t__export(__webpack_require__(14));\n\n\n/***/ },\n/* 50 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/**\n\t * This module contains APIs related to a Transition.\n\t *\n\t * See [[Transition]], [[$transitions]]\n\t *\n\t * @module transition\n\t * @preferred\n\t */\n\t/** for typedoc */\n\t__export(__webpack_require__(16));\n\t__export(__webpack_require__(15));\n\t__export(__webpack_require__(10));\n\t__export(__webpack_require__(11));\n\t__export(__webpack_require__(13));\n\t__export(__webpack_require__(31));\n\n\n/***/ },\n/* 51 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module url */ /** for typedoc */\n\t__export(__webpack_require__(28));\n\t__export(__webpack_require__(23));\n\t__export(__webpack_require__(27));\n\t__export(__webpack_require__(29));\n\n\n/***/ },\n/* 52 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module view */ /** for typedoc */\n\t__export(__webpack_require__(37));\n\n\n/***/ },\n/* 53 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * # UI-Router for Angular 1\n\t *\n\t * - Provides an implementation for the [[CoreServices]] API, based on angular 1 services.\n\t * - Also registers some services with the angular 1 injector.\n\t * - Creates and bootstraps a new [[UIRouter]] object.  Ties it to the the angular 1 lifecycle.\n\t *\n\t * @module ng1\n\t * @preferred\n\t */\n\t\"use strict\";\n\t/** for typedoc */\n\tvar router_1 = __webpack_require__(26);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar resolveService_1 = __webpack_require__(54);\n\tvar trace_1 = __webpack_require__(12);\n\tvar views_1 = __webpack_require__(55);\n\tvar templateFactory_1 = __webpack_require__(56);\n\tvar onEnterExitRetain_1 = __webpack_require__(57);\n\t/** @hidden */\n\tvar app = angular.module(\"ui.router.angular1\", []);\n\t/**\n\t * @ngdoc overview\n\t * @name ui.router.util\n\t *\n\t * @description\n\t * # ui.router.util sub-module\n\t *\n\t * This module is a dependency of other sub-modules. Do not include this module as a dependency\n\t * in your angular app (use {@link ui.router} module instead).\n\t *\n\t */\n\tangular.module('ui.router.util', ['ng', 'ui.router.init']);\n\t/**\n\t * @ngdoc overview\n\t * @name ui.router.router\n\t *\n\t * @requires ui.router.util\n\t *\n\t * @description\n\t * # ui.router.router sub-module\n\t *\n\t * This module is a dependency of other sub-modules. Do not include this module as a dependency\n\t * in your angular app (use {@link ui.router} module instead).\n\t */\n\tangular.module('ui.router.router', ['ui.router.util']);\n\t/**\n\t * @ngdoc overview\n\t * @name ui.router.state\n\t *\n\t * @requires ui.router.router\n\t * @requires ui.router.util\n\t *\n\t * @description\n\t * # ui.router.state sub-module\n\t *\n\t * This module is a dependency of the main ui.router module. Do not include this module as a dependency\n\t * in your angular app (use {@link ui.router} module instead).\n\t *\n\t */\n\tangular.module('ui.router.state', ['ui.router.router', 'ui.router.util', 'ui.router.angular1']);\n\t/**\n\t * @ngdoc overview\n\t * @name ui.router\n\t *\n\t * @requires ui.router.state\n\t *\n\t * @description\n\t * # ui.router\n\t *\n\t * ## The main module for ui.router\n\t * There are several sub-modules included with the ui.router module, however only this module is needed\n\t * as a dependency within your angular app. The other modules are for organization purposes.\n\t *\n\t * The modules are:\n\t * * ui.router - the main \"umbrella\" module\n\t * * ui.router.router -\n\t *\n\t * *You'll need to include **only** this module as the dependency within your angular app.*\n\t *\n\t * <pre>\n\t * <!doctype html>\n\t * <html ng-app=\"myApp\">\n\t * <head>\n\t *   <script src=\"js/angular.js\"></script>\n\t *   <!-- Include the ui-router script -->\n\t *   <script src=\"js/angular-ui-router.min.js\"></script>\n\t *   <script>\n\t *     // ...and add 'ui.router' as a dependency\n\t *     var myApp = angular.module('myApp', ['ui.router']);\n\t *   </script>\n\t * </head>\n\t * <body>\n\t * </body>\n\t * </html>\n\t * </pre>\n\t */\n\tangular.module('ui.router', ['ui.router.init', 'ui.router.state', 'ui.router.angular1']);\n\tangular.module('ui.router.compat', ['ui.router']);\n\t/**\n\t * Annotates a controller expression (may be a controller function(), a \"controllername\",\n\t * or \"controllername as name\")\n\t *\n\t * - Temporarily decorates $injector.instantiate.\n\t * - Invokes $controller() service\n\t *   - Calls $injector.instantiate with controller constructor\n\t * - Annotate constructor\n\t * - Undecorate $injector\n\t *\n\t * returns an array of strings, which are the arguments of the controller expression\n\t */\n\tfunction annotateController(controllerExpression) {\n\t    var $injector = coreservices_1.services.$injector;\n\t    var $controller = $injector.get(\"$controller\");\n\t    var oldInstantiate = $injector.instantiate;\n\t    try {\n\t        var deps_1;\n\t        $injector.instantiate = function fakeInstantiate(constructorFunction) {\n\t            $injector.instantiate = oldInstantiate; // Un-decorate ASAP\n\t            deps_1 = $injector.annotate(constructorFunction);\n\t        };\n\t        $controller(controllerExpression, { $scope: {} });\n\t        return deps_1;\n\t    }\n\t    finally {\n\t        $injector.instantiate = oldInstantiate;\n\t    }\n\t}\n\texports.annotateController = annotateController;\n\trunBlock.$inject = ['$injector', '$q'];\n\tfunction runBlock($injector, $q) {\n\t    coreservices_1.services.$injector = $injector;\n\t    coreservices_1.services.$q = $q;\n\t}\n\tapp.run(runBlock);\n\tvar router = null;\n\tng1UIRouter.$inject = ['$locationProvider'];\n\t/** This angular 1 provider instantiates a Router and exposes its services via the angular injector */\n\tfunction ng1UIRouter($locationProvider) {\n\t    // Create a new instance of the Router when the ng1UIRouterProvider is initialized\n\t    router = new router_1.UIRouter();\n\t    // Apply ng1 specific StateBuilder code for `views`, `resolve`, and `onExit/Retain/Enter` properties\n\t    router.stateRegistry.decorator(\"views\", views_1.ng1ViewsBuilder);\n\t    router.stateRegistry.decorator(\"onExit\", onEnterExitRetain_1.getStateHookBuilder(\"onExit\"));\n\t    router.stateRegistry.decorator(\"onRetain\", onEnterExitRetain_1.getStateHookBuilder(\"onRetain\"));\n\t    router.stateRegistry.decorator(\"onEnter\", onEnterExitRetain_1.getStateHookBuilder(\"onEnter\"));\n\t    router.viewService.viewConfigFactory('ng1', views_1.ng1ViewConfigFactory);\n\t    // Bind LocationConfig.hashPrefix to $locationProvider.hashPrefix\n\t    common_1.bindFunctions($locationProvider, coreservices_1.services.locationConfig, $locationProvider, ['hashPrefix']);\n\t    // Create a LocationService.onChange registry\n\t    var urlListeners = [];\n\t    coreservices_1.services.location.onChange = function (callback) {\n\t        urlListeners.push(callback);\n\t        return function () { return common_1.removeFrom(urlListeners)(callback); };\n\t    };\n\t    this.$get = $get;\n\t    $get.$inject = ['$location', '$browser', '$sniffer', '$rootScope', '$http', '$templateCache'];\n\t    function $get($location, $browser, $sniffer, $rootScope, $http, $templateCache) {\n\t        // Bind $locationChangeSuccess to the listeners registered in LocationService.onChange\n\t        $rootScope.$on(\"$locationChangeSuccess\", function (evt) { return urlListeners.forEach(function (fn) { return fn(evt); }); });\n\t        // Bind LocationConfig.html5Mode to $locationProvider.html5Mode and $sniffer.history\n\t        coreservices_1.services.locationConfig.html5Mode = function () {\n\t            var html5Mode = $locationProvider.html5Mode();\n\t            html5Mode = predicates_1.isObject(html5Mode) ? html5Mode.enabled : html5Mode;\n\t            return html5Mode && $sniffer.history;\n\t        };\n\t        coreservices_1.services.template.get = function (url) {\n\t            return $http.get(url, { cache: $templateCache, headers: { Accept: 'text/html' } }).then(hof_1.prop(\"data\"));\n\t        };\n\t        // Bind these LocationService functions to $location\n\t        common_1.bindFunctions($location, coreservices_1.services.location, $location, [\"replace\", \"url\", \"path\", \"search\", \"hash\"]);\n\t        // Bind these LocationConfig functions to $location\n\t        common_1.bindFunctions($location, coreservices_1.services.locationConfig, $location, ['port', 'protocol', 'host']);\n\t        // Bind these LocationConfig functions to $browser\n\t        common_1.bindFunctions($browser, coreservices_1.services.locationConfig, $browser, ['baseHref']);\n\t        return router;\n\t    }\n\t}\n\tfunction $stateParamsFactory(ng1UIRouter) {\n\t    return ng1UIRouter.globals.params;\n\t}\n\t// The 'ui.router' ng1 module depends on 'ui.router.init' module.\n\tangular.module('ui.router.init', []).provider(\"ng1UIRouter\", ng1UIRouter);\n\t// This effectively calls $get() to init when we enter runtime\n\tangular.module('ui.router.init').run(['ng1UIRouter', function (ng1UIRouter) { }]);\n\t// $urlMatcherFactory service and $urlMatcherFactoryProvider\n\tangular.module('ui.router.util').provider('$urlMatcherFactory', ['ng1UIRouterProvider', function () { return router.urlMatcherFactory; }]);\n\tangular.module('ui.router.util').run(['$urlMatcherFactory', function ($urlMatcherFactory) { }]);\n\t// $urlRouter service and $urlRouterProvider\n\tfunction getUrlRouterProvider() {\n\t    router.urlRouterProvider[\"$get\"] = function () {\n\t        router.urlRouter.update(true);\n\t        if (!this.interceptDeferred)\n\t            router.urlRouter.listen();\n\t        return router.urlRouter;\n\t    };\n\t    return router.urlRouterProvider;\n\t}\n\tangular.module('ui.router.router').provider('$urlRouter', ['ng1UIRouterProvider', getUrlRouterProvider]);\n\tangular.module('ui.router.router').run(['$urlRouter', function ($urlRouter) { }]);\n\t// $state service and $stateProvider\n\t// $urlRouter service and $urlRouterProvider\n\tfunction getStateProvider() {\n\t    router.stateProvider[\"$get\"] = function () {\n\t        // Autoflush once we are in runtime\n\t        router.stateRegistry.stateQueue.autoFlush(router.stateService);\n\t        return router.stateService;\n\t    };\n\t    return router.stateProvider;\n\t}\n\tangular.module('ui.router.state').provider('$state', ['ng1UIRouterProvider', getStateProvider]);\n\tangular.module('ui.router.state').run(['$state', function ($state) { }]);\n\t// $stateParams service\n\tangular.module('ui.router.state').factory('$stateParams', ['ng1UIRouter', function (ng1UIRouter) {\n\t        return ng1UIRouter.globals.params;\n\t    }]);\n\t// $transitions service and $transitionsProvider\n\tfunction getTransitionsProvider() {\n\t    router.transitionService[\"$get\"] = function () { return router.transitionService; };\n\t    return router.transitionService;\n\t}\n\tangular.module('ui.router.state').provider('$transitions', ['ng1UIRouterProvider', getTransitionsProvider]);\n\t// $templateFactory service\n\tangular.module('ui.router.util').factory('$templateFactory', ['ng1UIRouter', function () { return new templateFactory_1.TemplateFactory(); }]);\n\t// The $view service\n\tangular.module('ui.router').factory('$view', function () { return router.viewService; });\n\t// The old $resolve service\n\tangular.module('ui.router').factory('$resolve', resolveService_1.resolveFactory);\n\t// $trace service\n\tangular.module(\"ui.router\").service(\"$trace\", function () { return trace_1.trace; });\n\twatchDigests.$inject = ['$rootScope'];\n\tfunction watchDigests($rootScope) {\n\t    $rootScope.$watch(function () { trace_1.trace.approximateDigests++; });\n\t}\n\texports.watchDigests = watchDigests;\n\tangular.module(\"ui.router\").run(watchDigests);\n\texports.getLocals = function (ctx) {\n\t    var tokens = ctx.getTokens().filter(predicates_1.isString);\n\t    var tuples = tokens.map(function (key) { return [key, ctx.getResolvable(key).data]; });\n\t    return tuples.reduce(common_1.applyPairs, {});\n\t};\n\t/** Injectable services */\n\t/**\n\t * An injectable service object which has the current state parameters\n\t *\n\t * This angular service (singleton object) holds the current state parameters.\n\t * The values in `$stateParams` are not updated until *after* a [[Transition]] successfully completes.\n\t *\n\t * This object can be injected into other services.\n\t *\n\t * @example\n\t * ```js\n\t *\n\t * SomeService.$inject = ['$http', '$stateParams'];\n\t * function SomeService($http, $stateParams) {\n\t *   return {\n\t *     getUser: function() {\n\t *       return $http.get('/api/users/' + $stateParams.username);\n\t *     }\n\t *   }\n\t * };\n\t * angular.service('SomeService', SomeService);\n\t * ```\n\t *\n\t * ### Deprecation warning:\n\t *\n\t * When `$stateParams` is injected into transition hooks, resolves and view controllers, they receive a different\n\t * object than this global service object.  In those cases, the injected object has the parameter values for the\n\t * *pending* Transition.\n\t *\n\t * Because of these confusing details, this service is deprecated.\n\t *\n\t * @deprecated Instead of using `$stateParams, inject the current [[Transition]] as `$transition$` and use [[Transition.params]]\n\t * ```js\n\t * MyController.$inject = ['$transition$'];\n\t * function MyController($transition$) {\n\t *   var username = $transition$.params().username;\n\t *   // .. do something with username\n\t * }\n\t * ```\n\t */\n\tvar $stateParams;\n\t/**\n\t * An injectable service primarily used to register transition hooks\n\t *\n\t * This angular service exposes the [[TransitionService]] singleton, which is primarily used to add transition hooks.\n\t *\n\t * The same object is also exposed as [[$transitionsProvider]] for injection during angular config time.\n\t */\n\tvar $transitions;\n\t/**\n\t * A config-time injectable provider primarily used to register transition hooks\n\t *\n\t * This angular provider exposes the [[TransitionService]] singleton, which is primarily used to add transition hooks.\n\t *\n\t * The same object is also exposed as [[$transitions]] for injection at runtime.\n\t */\n\tvar $transitionsProvider;\n\t/**\n\t * An injectable service used to query for current state information.\n\t *\n\t * This angular service exposes the [[StateService]] singleton.\n\t */\n\tvar $state;\n\t/**\n\t * A config-time injectable provider used to register states.\n\t *\n\t * This angular service exposes the [[StateProvider]] singleton.\n\t */\n\tvar $stateProvider;\n\t/**\n\t * A config-time injectable provider used to manage the URL.\n\t *\n\t * This angular service exposes the [[UrlRouterProvider]] singleton.\n\t */\n\tvar $urlRouterProvider;\n\t/**\n\t * An injectable service used to configure URL redirects.\n\t *\n\t * This angular service exposes the [[UrlRouter]] singleton.\n\t */\n\tvar $urlRouter;\n\t/**\n\t * An injectable service used to configure the URL.\n\t *\n\t * This service is used to set url mapping options, and create [[UrlMatcher]] objects.\n\t *\n\t * This angular service exposes the [[UrlMatcherFactory]] singleton.\n\t * The singleton is also exposed at config-time as the [[$urlMatcherFactoryProvider]].\n\t */\n\tvar $urlMatcherFactory;\n\t/**\n\t * An injectable service used to configure the URL.\n\t *\n\t * This service is used to set url mapping options, and create [[UrlMatcher]] objects.\n\t *\n\t * This angular service exposes the [[UrlMatcherFactory]] singleton at config-time.\n\t * The singleton is also exposed at runtime as the [[$urlMatcherFactory]].\n\t */\n\tvar $urlMatcherFactoryProvider;\n\n\n/***/ },\n/* 54 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module ng1 */ /** */\n\tvar stateObject_1 = __webpack_require__(42);\n\tvar node_1 = __webpack_require__(21);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar common_1 = __webpack_require__(3);\n\tvar stateBuilder_1 = __webpack_require__(40);\n\t/**\n\t * Implementation of the legacy `$resolve` service for angular 1.\n\t */\n\tvar $resolve = {\n\t    /**\n\t     * Asynchronously injects a resolve block.\n\t     *\n\t     * This emulates most of the behavior of the ui-router 0.2.x $resolve.resolve() service API.\n\t     *\n\t     * Given an object `invocables`, where keys are strings and values are injectable functions,\n\t     * injects each function, and waits for the resulting promise to resolve.\n\t     * When all resulting promises are resolved, returns the results as an object.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * let invocables = {\n\t     *   foo: [ '$http', ($http) =>\n\t     *            $http.get('/api/foo').then(resp => resp.data) ],\n\t     *   bar: [ 'foo', '$http', (foo, $http) =>\n\t     *            $http.get('/api/bar/' + foo.barId).then(resp => resp.data) ]\n\t     * }\n\t     * $resolve.resolve(invocables)\n\t     *     .then(results => console.log(results.foo, results.bar))\n\t     * // Logs foo and bar:\n\t     * // { id: 123, barId: 456, fooData: 'foo data' }\n\t     * // { id: 456, barData: 'bar data' }\n\t     * ```\n\t     *\n\t     * @param invocables an object which looks like an [[StateDefinition.resolve]] object; keys are resolve names and values are injectable functions\n\t     * @param locals key/value pre-resolved data (locals)\n\t     * @param parent a promise for a \"parent resolve\"\n\t     */\n\t    resolve: function (invocables, locals, parent) {\n\t        if (locals === void 0) { locals = {}; }\n\t        var parentNode = new node_1.PathNode(new stateObject_1.State({ params: {}, resolvables: [] }));\n\t        var node = new node_1.PathNode(new stateObject_1.State({ params: {}, resolvables: [] }));\n\t        var context = new resolveContext_1.ResolveContext([parentNode, node]);\n\t        context.addResolvables(stateBuilder_1.resolvablesBuilder({ resolve: invocables }), node.state);\n\t        var resolveData = function (parentLocals) {\n\t            var rewrap = function (_locals) { return stateBuilder_1.resolvablesBuilder({ resolve: common_1.map(_locals, function (local) { return function () { return local; }; }) }); };\n\t            context.addResolvables(rewrap(parentLocals), parentNode.state);\n\t            context.addResolvables(rewrap(locals), node.state);\n\t            var tuples2ObjR = function (acc, tuple) {\n\t                acc[tuple.token] = tuple.value;\n\t                return acc;\n\t            };\n\t            return context.resolvePath().then(function (results) { return results.reduce(tuples2ObjR, {}); });\n\t        };\n\t        return parent ? parent.then(resolveData) : resolveData({});\n\t    }\n\t};\n\t/** @hidden */\n\texports.resolveFactory = function () { return $resolve; };\n\n\n/***/ },\n/* 55 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar strings_1 = __webpack_require__(9);\n\tvar view_1 = __webpack_require__(37);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar trace_1 = __webpack_require__(12);\n\tvar templateFactory_1 = __webpack_require__(56);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar resolvable_1 = __webpack_require__(19);\n\texports.ng1ViewConfigFactory = function (path, view) { return new Ng1ViewConfig(path, view); };\n\t/**\n\t * This is a [[StateBuilder.builder]] function for angular1 `views`.\n\t *\n\t * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder\n\t * handles the `views` property with logic specific to angular-ui-router (ng1).\n\t *\n\t * If no `views: {}` property exists on the [[StateDeclaration]], then it creates the `views` object\n\t * and applies the state-level configuration to a view named `$default`.\n\t */\n\tfunction ng1ViewsBuilder(state) {\n\t    var tplKeys = ['templateProvider', 'templateUrl', 'template', 'notify', 'async'], ctrlKeys = ['controller', 'controllerProvider', 'controllerAs', 'resolveAs'], compKeys = ['component', 'bindings'], nonCompKeys = tplKeys.concat(ctrlKeys), allKeys = compKeys.concat(nonCompKeys);\n\t    var views = {}, viewsObject = state.views || { \"$default\": common_1.pick(state, allKeys) };\n\t    common_1.forEach(viewsObject, function (config, name) {\n\t        // Account for views: { \"\": { template... } }\n\t        name = name || \"$default\";\n\t        // Account for views: { header: \"headerComponent\" }\n\t        if (predicates_1.isString(config))\n\t            config = { component: config };\n\t        if (!Object.keys(config).length)\n\t            return;\n\t        // Configure this view for routing to an angular 1.5+ style .component (or any directive, really)\n\t        if (config.component) {\n\t            if (nonCompKeys.map(function (key) { return predicates_1.isDefined(config[key]); }).reduce(common_1.anyTrueR, false)) {\n\t                throw new Error(\"Cannot combine: \" + compKeys.join(\"|\") + \" with: \" + nonCompKeys.join(\"|\") + \" in stateview: 'name@\" + state.name + \"'\");\n\t            }\n\t            // Dynamically build a template like \"<component-name input1='::$resolve.foo'></component-name>\"\n\t            config.templateProvider = ['$injector', function ($injector) {\n\t                    var resolveFor = function (key) { return config.bindings && config.bindings[key] || key; };\n\t                    var prefix = angular.version.minor >= 3 ? \"::\" : \"\";\n\t                    var attributeTpl = function (input) {\n\t                        var attrName = strings_1.kebobString(input.name);\n\t                        var resolveName = resolveFor(input.name);\n\t                        if (input.type === '@')\n\t                            return attrName + \"='{{\" + prefix + \"$resolve.\" + resolveName + \"}}'\";\n\t                        return attrName + \"='\" + prefix + \"$resolve.\" + resolveName + \"'\";\n\t                    };\n\t                    var attrs = getComponentInputs($injector, config.component).map(attributeTpl).join(\" \");\n\t                    var kebobName = strings_1.kebobString(config.component);\n\t                    return \"<\" + kebobName + \" \" + attrs + \"></\" + kebobName + \">\";\n\t                }];\n\t        }\n\t        config.resolveAs = config.resolveAs || '$resolve';\n\t        config.$type = \"ng1\";\n\t        config.$context = state;\n\t        config.$name = name;\n\t        var normalized = view_1.ViewService.normalizeUIViewTarget(config.$context, config.$name);\n\t        config.$uiViewName = normalized.uiViewName;\n\t        config.$uiViewContextAnchor = normalized.uiViewContextAnchor;\n\t        views[name] = config;\n\t    });\n\t    return views;\n\t}\n\texports.ng1ViewsBuilder = ng1ViewsBuilder;\n\t// for ng 1.2 style, process the scope: { input: \"=foo\" }\n\t// for ng 1.3 through ng 1.5, process the component's bindToController: { input: \"=foo\" } object\n\tvar scopeBindings = function (bindingsObj) { return Object.keys(bindingsObj || {})\n\t    .map(function (key) { return [key, /^([=<@])[?]?(.*)/.exec(bindingsObj[key])]; }) // [ 'input', [ '=foo', '=', 'foo' ] ]\n\t    .filter(function (tuple) { return predicates_1.isDefined(tuple) && predicates_1.isDefined(tuple[1]); }) // skip malformed values\n\t    .map(function (tuple) { return ({ name: tuple[1][2] || tuple[0], type: tuple[1][1] }); }); }; // { name: ('foo' || 'input'), type: '=' }\n\t// Given a directive definition, find its object input attributes\n\t// Use different properties, depending on the type of directive (component, bindToController, normal)\n\tvar getBindings = function (def) {\n\t    if (predicates_1.isObject(def.bindToController))\n\t        return scopeBindings(def.bindToController);\n\t    return scopeBindings(def.scope);\n\t};\n\t// Gets all the directive(s)' inputs ('@', '=', and '<')\n\tfunction getComponentInputs($injector, name) {\n\t    var cmpDefs = $injector.get(name + \"Directive\"); // could be multiple\n\t    if (!cmpDefs || !cmpDefs.length)\n\t        throw new Error(\"Unable to find component named '\" + name + \"'\");\n\t    return cmpDefs.map(getBindings).reduce(common_1.unnestR, []);\n\t}\n\tvar id = 0;\n\tvar Ng1ViewConfig = (function () {\n\t    function Ng1ViewConfig(path, viewDecl) {\n\t        this.path = path;\n\t        this.viewDecl = viewDecl;\n\t        this.$id = id++;\n\t        this.loaded = false;\n\t    }\n\t    Ng1ViewConfig.prototype.load = function () {\n\t        var _this = this;\n\t        var $q = coreservices_1.services.$q;\n\t        if (!this.hasTemplate())\n\t            throw new Error(\"No template configuration specified for '\" + this.viewDecl.$uiViewName + \"@\" + this.viewDecl.$uiViewContextAnchor + \"'\");\n\t        var context = new resolveContext_1.ResolveContext(this.path);\n\t        var params = this.path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {});\n\t        var promises = {\n\t            template: $q.when(this.getTemplate(params, new templateFactory_1.TemplateFactory(), context)),\n\t            controller: $q.when(this.getController(context))\n\t        };\n\t        return $q.all(promises).then(function (results) {\n\t            trace_1.trace.traceViewServiceEvent(\"Loaded\", _this);\n\t            _this.controller = results.controller;\n\t            _this.template = results.template;\n\t        });\n\t    };\n\t    /**\n\t     * Checks a view configuration to ensure that it specifies a template.\n\t     *\n\t     * @return {boolean} Returns `true` if the configuration contains a valid template, otherwise `false`.\n\t     */\n\t    Ng1ViewConfig.prototype.hasTemplate = function () {\n\t        return !!(this.viewDecl.template || this.viewDecl.templateUrl || this.viewDecl.templateProvider);\n\t    };\n\t    Ng1ViewConfig.prototype.getTemplate = function (params, $factory, context) {\n\t        return $factory.fromConfig(this.viewDecl, params, context);\n\t    };\n\t    /**\n\t     * Gets the controller for a view configuration.\n\t     *\n\t     * @returns {Function|Promise.<Function>} Returns a controller, or a promise that resolves to a controller.\n\t     */\n\t    Ng1ViewConfig.prototype.getController = function (context) {\n\t        var provider = this.viewDecl.controllerProvider;\n\t        if (!predicates_1.isInjectable(provider))\n\t            return this.viewDecl.controller;\n\t        var deps = coreservices_1.services.$injector.annotate(provider);\n\t        var providerFn = predicates_1.isArray(provider) ? common_1.tail(provider) : provider;\n\t        var resolvable = new resolvable_1.Resolvable(\"\", providerFn, deps);\n\t        return resolvable.get(context);\n\t    };\n\t    return Ng1ViewConfig;\n\t}());\n\texports.Ng1ViewConfig = Ng1ViewConfig;\n\n\n/***/ },\n/* 56 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module view */ /** for typedoc */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar common_1 = __webpack_require__(3);\n\tvar resolvable_1 = __webpack_require__(19);\n\t/**\n\t * Service which manages loading of templates from a ViewConfig.\n\t */\n\tvar TemplateFactory = (function () {\n\t    function TemplateFactory() {\n\t    }\n\t    /**\n\t     * Creates a template from a configuration object.\n\t     *\n\t     * @param config Configuration object for which to load a template.\n\t     * The following properties are search in the specified order, and the first one\n\t     * that is defined is used to create the template:\n\t     *\n\t     * @param params  Parameters to pass to the template function.\n\t     * @param context The resolve context associated with the template's view\n\t     *\n\t     * @return {string|object}  The template html as a string, or a promise for\n\t     * that string,or `null` if no template is configured.\n\t     */\n\t    TemplateFactory.prototype.fromConfig = function (config, params, context) {\n\t        return (predicates_1.isDefined(config.template) ? this.fromString(config.template, params) :\n\t            predicates_1.isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :\n\t                predicates_1.isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, context) :\n\t                    null);\n\t    };\n\t    ;\n\t    /**\n\t     * Creates a template from a string or a function returning a string.\n\t     *\n\t     * @param template html template as a string or function that returns an html template as a string.\n\t     * @param params Parameters to pass to the template function.\n\t     *\n\t     * @return {string|object} The template html as a string, or a promise for that\n\t     * string.\n\t     */\n\t    TemplateFactory.prototype.fromString = function (template, params) {\n\t        return predicates_1.isFunction(template) ? template(params) : template;\n\t    };\n\t    ;\n\t    /**\n\t     * Loads a template from the a URL via `$http` and `$templateCache`.\n\t     *\n\t     * @param {string|Function} url url of the template to load, or a function\n\t     * that returns a url.\n\t     * @param {Object} params Parameters to pass to the url function.\n\t     * @return {string|Promise.<string>} The template html as a string, or a promise\n\t     * for that string.\n\t     */\n\t    TemplateFactory.prototype.fromUrl = function (url, params) {\n\t        if (predicates_1.isFunction(url))\n\t            url = url(params);\n\t        if (url == null)\n\t            return null;\n\t        return coreservices_1.services.template.get(url);\n\t    };\n\t    ;\n\t    /**\n\t     * Creates a template by invoking an injectable provider function.\n\t     *\n\t     * @param provider Function to invoke via `locals`\n\t     * @param {Function} injectFn a function used to invoke the template provider\n\t     * @return {string|Promise.<string>} The template html as a string, or a promise\n\t     * for that string.\n\t     */\n\t    TemplateFactory.prototype.fromProvider = function (provider, params, context) {\n\t        var deps = coreservices_1.services.$injector.annotate(provider);\n\t        var providerFn = predicates_1.isArray(provider) ? common_1.tail(provider) : provider;\n\t        var resolvable = new resolvable_1.Resolvable(\"\", providerFn, deps);\n\t        return resolvable.get(context);\n\t    };\n\t    ;\n\t    return TemplateFactory;\n\t}());\n\texports.TemplateFactory = TemplateFactory;\n\n\n/***/ },\n/* 57 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar services_1 = __webpack_require__(53);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar common_1 = __webpack_require__(3);\n\t/**\n\t * This is a [[StateBuilder.builder]] function for angular1 `onEnter`, `onExit`,\n\t * `onRetain` callback hooks on a [[Ng1StateDeclaration]].\n\t *\n\t * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder\n\t * ensures that those hooks are injectable for angular-ui-router (ng1).\n\t */\n\texports.getStateHookBuilder = function (hookName) {\n\t    return function stateHookBuilder(state, parentFn) {\n\t        var hook = state[hookName];\n\t        function decoratedNg1Hook(trans, state) {\n\t            var resolveContext = new resolveContext_1.ResolveContext(trans.treeChanges().to);\n\t            return coreservices_1.services.$injector.invoke(hook, this, common_1.extend({ $state$: state }, services_1.getLocals(resolveContext)));\n\t        }\n\t        return hook ? decoratedNg1Hook : undefined;\n\t    };\n\t};\n\n\n/***/ },\n/* 58 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/**\n\t * These are the UI-Router angular 1 directives.\n\t *\n\t * These directives are used in templates to create viewports and navigate to states\n\t *\n\t * @preferred @module ng1_directives\n\t */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\t/** @hidden */\n\tfunction parseStateRef(ref, current) {\n\t    var preparsed = ref.match(/^\\s*({[^}]*})\\s*$/), parsed;\n\t    if (preparsed)\n\t        ref = current + '(' + preparsed[1] + ')';\n\t    parsed = ref.replace(/\\n/g, \" \").match(/^([^(]+?)\\s*(\\((.*)\\))?$/);\n\t    if (!parsed || parsed.length !== 4)\n\t        throw new Error(\"Invalid state ref '\" + ref + \"'\");\n\t    return { state: parsed[1], paramExpr: parsed[3] || null };\n\t}\n\t/** @hidden */\n\tfunction stateContext(el) {\n\t    var $uiView = el.parent().inheritedData('$uiView');\n\t    var path = hof_1.parse('$cfg.path')($uiView);\n\t    return path ? common_1.tail(path).state.name : undefined;\n\t}\n\t/** @hidden */\n\tfunction getTypeInfo(el) {\n\t    // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.\n\t    var isSvg = Object.prototype.toString.call(el.prop('href')) === '[object SVGAnimatedString]';\n\t    var isForm = el[0].nodeName === \"FORM\";\n\t    return {\n\t        attr: isForm ? \"action\" : (isSvg ? 'xlink:href' : 'href'),\n\t        isAnchor: el.prop(\"tagName\").toUpperCase() === \"A\",\n\t        clickable: !isForm\n\t    };\n\t}\n\t/** @hidden */\n\tfunction clickHook(el, $state, $timeout, type, current) {\n\t    return function (e) {\n\t        var button = e.which || e.button, target = current();\n\t        if (!(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || el.attr('target'))) {\n\t            // HACK: This is to allow ng-clicks to be processed before the transition is initiated:\n\t            var transition = $timeout(function () {\n\t                $state.go(target.state, target.params, target.options);\n\t            });\n\t            e.preventDefault();\n\t            // if the state has no URL, ignore one preventDefault from the <a> directive.\n\t            var ignorePreventDefaultCount = type.isAnchor && !target.href ? 1 : 0;\n\t            e.preventDefault = function () {\n\t                if (ignorePreventDefaultCount-- <= 0)\n\t                    $timeout.cancel(transition);\n\t            };\n\t        }\n\t    };\n\t}\n\t/** @hidden */\n\tfunction defaultOpts(el, $state) {\n\t    return { relative: stateContext(el) || $state.$current, inherit: true };\n\t}\n\t/**\n\t * `ui-sref`: A directive for linking to a state\n\t *\n\t * A directive that binds a link (`<a>` tag) to a state.\n\t * If the state has an associated URL, the directive will automatically generate and\n\t * update the `href` attribute via the [[StateService.href]]  method.\n\t * Clicking the link will trigger a state transition with optional parameters.\n\t *\n\t * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be\n\t * handled natively by the browser.\n\t *\n\t * You can also use relative state paths within ui-sref, just like the relative\n\t * paths passed to `$state.go()`.\n\t * You just need to be aware that the path is relative to the state that the link lives in.\n\t * In other words, the state that created the view containing the link.\n\t *\n\t * You can specify options to pass to [[StateService.go]] using the `ui-sref-opts` attribute.\n\t * Options are restricted to `location`, `inherit`, and `reload`.\n\t *\n\t * Here's an example of how you'd use ui-sref and how it would compile.\n\t * If you have the following template:\n\t *\n\t * @example\n\t * ```html\n\t *\n\t * <pre>\n\t * <a ui-sref=\"home\">Home</a> | <a ui-sref=\"about\">About</a> | <a ui-sref=\"{page: 2}\">Next page</a>\n\t *\n\t * <ul>\n\t *     <li ng-repeat=\"contact in contacts\">\n\t *         <a ui-sref=\"contacts.detail({ id: contact.id })\">{{ contact.name }}</a>\n\t *     </li>\n\t * </ul>\n\t * </pre>\n\t * ```\n\t *\n\t * Then the compiled html would be (assuming Html5Mode is off and current state is contacts):\n\t *\n\t * ```html\n\t *\n\t * <pre>\n\t * <a href=\"#/home\" ui-sref=\"home\">Home</a> | <a href=\"#/about\" ui-sref=\"about\">About</a> | <a href=\"#/contacts?page=2\" ui-sref=\"{page: 2}\">Next page</a>\n\t *\n\t * <ul>\n\t *     <li ng-repeat=\"contact in contacts\">\n\t *         <a href=\"#/contacts/1\" ui-sref=\"contacts.detail({ id: contact.id })\">Joe</a>\n\t *     </li>\n\t *     <li ng-repeat=\"contact in contacts\">\n\t *         <a href=\"#/contacts/2\" ui-sref=\"contacts.detail({ id: contact.id })\">Alice</a>\n\t *     </li>\n\t *     <li ng-repeat=\"contact in contacts\">\n\t *         <a href=\"#/contacts/3\" ui-sref=\"contacts.detail({ id: contact.id })\">Bob</a>\n\t *     </li>\n\t * </ul>\n\t *\n\t * <a ui-sref=\"home\" ui-sref-opts=\"{reload: true}\">Home</a>\n\t * </pre>\n\t * ```\n\t *\n\t * @param {string} ui-sref 'stateName' can be any valid absolute or relative state\n\t * @param {Object} ui-sref-opts options to pass to [[StateService.go]]\n\t */\n\tvar uiSref = ['$state', '$timeout',\n\t    function $StateRefDirective($state, $timeout) {\n\t        return {\n\t            restrict: 'A',\n\t            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],\n\t            link: function (scope, element, attrs, uiSrefActive) {\n\t                var ref = parseStateRef(attrs.uiSref, $state.current.name);\n\t                var def = { state: ref.state, href: null, params: null, options: null };\n\t                var type = getTypeInfo(element);\n\t                var active = uiSrefActive[1] || uiSrefActive[0];\n\t                var unlinkInfoFn = null;\n\t                def.options = common_1.extend(defaultOpts(element, $state), attrs.uiSrefOpts ? scope.$eval(attrs.uiSrefOpts) : {});\n\t                var update = function (val) {\n\t                    if (val)\n\t                        def.params = angular.copy(val);\n\t                    def.href = $state.href(ref.state, def.params, def.options);\n\t                    if (unlinkInfoFn)\n\t                        unlinkInfoFn();\n\t                    if (active)\n\t                        unlinkInfoFn = active.$$addStateInfo(ref.state, def.params);\n\t                    if (def.href !== null)\n\t                        attrs.$set(type.attr, def.href);\n\t                };\n\t                if (ref.paramExpr) {\n\t                    scope.$watch(ref.paramExpr, function (val) { if (val !== def.params)\n\t                        update(val); }, true);\n\t                    def.params = angular.copy(scope.$eval(ref.paramExpr));\n\t                }\n\t                update();\n\t                if (!type.clickable)\n\t                    return;\n\t                element.bind(\"click\", clickHook(element, $state, $timeout, type, function () { return def; }));\n\t            }\n\t        };\n\t    }];\n\t/**\n\t * `ui-state`: A dynamic version of `ui-sref`\n\t *\n\t * Much like ui-sref, but will accept named $scope properties to evaluate for a state definition,\n\t * params and override options.\n\t *\n\t * @example\n\t * ```html\n\t *\n\t * <li ng-repeat=\"nav in navlinks\">\n\t *   <a ui-state=\"nav.statename\">{{nav.description}}</a>\n\t * </li>\n\t *\n\t * @param {string} ui-state 'stateName' can be any valid absolute or relative state\n\t * @param {Object} ui-state-params params to pass to [[StateService.href]]\n\t * @param {Object} ui-state-opts options to pass to [[StateService.go]]\n\t */\n\tvar uiState = ['$state', '$timeout',\n\t    function $StateRefDynamicDirective($state, $timeout) {\n\t        return {\n\t            restrict: 'A',\n\t            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],\n\t            link: function (scope, element, attrs, uiSrefActive) {\n\t                var type = getTypeInfo(element);\n\t                var active = uiSrefActive[1] || uiSrefActive[0];\n\t                var group = [attrs.uiState, attrs.uiStateParams || null, attrs.uiStateOpts || null];\n\t                var watch = '[' + group.map(function (val) { return val || 'null'; }).join(', ') + ']';\n\t                var def = { state: null, params: null, options: null, href: null };\n\t                var unlinkInfoFn = null;\n\t                function runStateRefLink(group) {\n\t                    def.state = group[0];\n\t                    def.params = group[1];\n\t                    def.options = group[2];\n\t                    def.href = $state.href(def.state, def.params, def.options);\n\t                    if (unlinkInfoFn)\n\t                        unlinkInfoFn();\n\t                    if (active)\n\t                        unlinkInfoFn = active.$$addStateInfo(def.state, def.params);\n\t                    if (def.href)\n\t                        attrs.$set(type.attr, def.href);\n\t                }\n\t                scope.$watch(watch, runStateRefLink, true);\n\t                runStateRefLink(scope.$eval(watch));\n\t                if (!type.clickable)\n\t                    return;\n\t                element.bind(\"click\", clickHook(element, $state, $timeout, type, function () { return def; }));\n\t            }\n\t        };\n\t    }];\n\t/**\n\t * `ui-sref-active` and `ui-sref-active-eq`: A directive that adds a CSS class when a `ui-sref` is active\n\t *\n\t * A directive working alongside ui-sref to add classes to an element when the\n\t * related ui-sref directive's state is active, and removing them when it is inactive.\n\t * The primary use-case is to simplify the special appearance of navigation menus\n\t * relying on `ui-sref`, by having the \"active\" state's menu button appear different,\n\t * distinguishing it from the inactive menu items.\n\t *\n\t * ui-sref-active can live on the same element as ui-sref or on a parent element. The first\n\t * ui-sref-active found at the same level or above the ui-sref will be used.\n\t *\n\t * Will activate when the ui-sref's target state or any child state is active. If you\n\t * need to activate only when the ui-sref target state is active and *not* any of\n\t * it's children, then you will use ui-sref-active-eq\n\t *\n\t * Given the following template:\n\t * @example\n\t * ```html\n\t *\n\t * <pre>\n\t * <ul>\n\t *   <li ui-sref-active=\"active\" class=\"item\">\n\t *     <a href ui-sref=\"app.user({user: 'bilbobaggins'})\">@bilbobaggins</a>\n\t *   </li>\n\t * </ul>\n\t * </pre>\n\t * ```\n\t *\n\t *\n\t * When the app state is \"app.user\" (or any children states), and contains the state parameter \"user\" with value \"bilbobaggins\",\n\t * the resulting HTML will appear as (note the 'active' class):\n\t *\n\t * ```html\n\t *\n\t * <pre>\n\t * <ul>\n\t *   <li ui-sref-active=\"active\" class=\"item active\">\n\t *     <a ui-sref=\"app.user({user: 'bilbobaggins'})\" href=\"/users/bilbobaggins\">@bilbobaggins</a>\n\t *   </li>\n\t * </ul>\n\t * </pre>\n\t * ```\n\t *\n\t * The class name is interpolated **once** during the directives link time (any further changes to the\n\t * interpolated value are ignored).\n\t *\n\t * Multiple classes may be specified in a space-separated format:\n\t *\n\t * ```html\n\t * <pre>\n\t * <ul>\n\t *   <li ui-sref-active='class1 class2 class3'>\n\t *     <a ui-sref=\"app.user\">link</a>\n\t *   </li>\n\t * </ul>\n\t * </pre>\n\t * ```\n\t *\n\t * It is also possible to pass ui-sref-active an expression that evaluates\n\t * to an object hash, whose keys represent active class names and whose\n\t * values represent the respective state names/globs.\n\t * ui-sref-active will match if the current active state **includes** any of\n\t * the specified state names/globs, even the abstract ones.\n\t *\n\t * Given the following template, with \"admin\" being an abstract state:\n\t * @example\n\t * ```html\n\t *\n\t * <pre>\n\t * <div ui-sref-active=\"{'active': 'admin.*'}\">\n\t *   <a ui-sref-active=\"active\" ui-sref=\"admin.roles\">Roles</a>\n\t * </div>\n\t * </pre>\n\t * ```\n\t *\n\t * When the current state is \"admin.roles\" the \"active\" class will be applied\n\t * to both the <div> and <a> elements. It is important to note that the state\n\t * names/globs passed to ui-sref-active shadow the state provided by ui-sref.\n\t */\n\tvar uiSrefActive = ['$state', '$stateParams', '$interpolate', '$transitions',\n\t    function $StateRefActiveDirective($state, $stateParams, $interpolate, $transitions) {\n\t        return {\n\t            restrict: \"A\",\n\t            controller: ['$scope', '$element', '$attrs', '$timeout', function ($scope, $element, $attrs, $timeout) {\n\t                    var states = [], activeClasses = {}, activeEqClass, uiSrefActive;\n\t                    // There probably isn't much point in $observing this\n\t                    // uiSrefActive and uiSrefActiveEq share the same directive object with some\n\t                    // slight difference in logic routing\n\t                    activeEqClass = $interpolate($attrs.uiSrefActiveEq || '', false)($scope);\n\t                    try {\n\t                        uiSrefActive = $scope.$eval($attrs.uiSrefActive);\n\t                    }\n\t                    catch (e) {\n\t                    }\n\t                    uiSrefActive = uiSrefActive || $interpolate($attrs.uiSrefActive || '', false)($scope);\n\t                    if (predicates_1.isObject(uiSrefActive)) {\n\t                        common_1.forEach(uiSrefActive, function (stateOrName, activeClass) {\n\t                            if (predicates_1.isString(stateOrName)) {\n\t                                var ref = parseStateRef(stateOrName, $state.current.name);\n\t                                addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);\n\t                            }\n\t                        });\n\t                    }\n\t                    // Allow uiSref to communicate with uiSrefActive[Equals]\n\t                    this.$$addStateInfo = function (newState, newParams) {\n\t                        // we already got an explicit state provided by ui-sref-active, so we\n\t                        // shadow the one that comes from ui-sref\n\t                        if (predicates_1.isObject(uiSrefActive) && states.length > 0) {\n\t                            return;\n\t                        }\n\t                        var deregister = addState(newState, newParams, uiSrefActive);\n\t                        update();\n\t                        return deregister;\n\t                    };\n\t                    $scope.$on('$stateChangeSuccess', update);\n\t                    $scope.$on('$destroy', $transitions.onStart({}, function (trans) { return trans.promise.then(update) && null; }));\n\t                    function addState(stateName, stateParams, activeClass) {\n\t                        var state = $state.get(stateName, stateContext($element));\n\t                        var stateHash = createStateHash(stateName, stateParams);\n\t                        var stateInfo = {\n\t                            state: state || { name: stateName },\n\t                            params: stateParams,\n\t                            hash: stateHash\n\t                        };\n\t                        states.push(stateInfo);\n\t                        activeClasses[stateHash] = activeClass;\n\t                        return function removeState() {\n\t                            var idx = states.indexOf(stateInfo);\n\t                            if (idx !== -1)\n\t                                states.splice(idx, 1);\n\t                        };\n\t                    }\n\t                    /**\n\t                     * @param {string} state\n\t                     * @param {Object|string} [params]\n\t                     * @return {string}\n\t                     */\n\t                    function createStateHash(state, params) {\n\t                        if (!predicates_1.isString(state)) {\n\t                            throw new Error('state should be a string');\n\t                        }\n\t                        if (predicates_1.isObject(params)) {\n\t                            return state + common_1.toJson(params);\n\t                        }\n\t                        params = $scope.$eval(params);\n\t                        if (predicates_1.isObject(params)) {\n\t                            return state + common_1.toJson(params);\n\t                        }\n\t                        return state;\n\t                    }\n\t                    // Update route state\n\t                    function update() {\n\t                        for (var i = 0; i < states.length; i++) {\n\t                            if (anyMatch(states[i].state, states[i].params)) {\n\t                                addClass($element, activeClasses[states[i].hash]);\n\t                            }\n\t                            else {\n\t                                removeClass($element, activeClasses[states[i].hash]);\n\t                            }\n\t                            if (exactMatch(states[i].state, states[i].params)) {\n\t                                addClass($element, activeEqClass);\n\t                            }\n\t                            else {\n\t                                removeClass($element, activeEqClass);\n\t                            }\n\t                        }\n\t                    }\n\t                    function addClass(el, className) { $timeout(function () { el.addClass(className); }); }\n\t                    function removeClass(el, className) { el.removeClass(className); }\n\t                    function anyMatch(state, params) { return $state.includes(state.name, params); }\n\t                    function exactMatch(state, params) { return $state.is(state.name, params); }\n\t                    update();\n\t                }]\n\t        };\n\t    }];\n\tangular.module('ui.router.state')\n\t    .directive('uiSref', uiSref)\n\t    .directive('uiSrefActive', uiSrefActive)\n\t    .directive('uiSrefActiveEq', uiSrefActive)\n\t    .directive('uiState', uiState);\n\n\n/***/ },\n/* 59 */\n/***/ function(module, exports) {\n\n\t/** @module state */ /** for typedoc */\n\t\"use strict\";\n\t/**\n\t * @ngdoc filter\n\t * @name ui.router.state.filter:isState\n\t *\n\t * @requires ui.router.state.$state\n\t *\n\t * @description\n\t * Translates to {@link ui.router.state.$state#methods_is $state.is(\"stateName\")}.\n\t */\n\t$IsStateFilter.$inject = ['$state'];\n\tfunction $IsStateFilter($state) {\n\t    var isFilter = function (state, params, options) {\n\t        return $state.is(state, params, options);\n\t    };\n\t    isFilter.$stateful = true;\n\t    return isFilter;\n\t}\n\texports.$IsStateFilter = $IsStateFilter;\n\t/**\n\t * @ngdoc filter\n\t * @name ui.router.state.filter:includedByState\n\t *\n\t * @requires ui.router.state.$state\n\t *\n\t * @description\n\t * Translates to {@link ui.router.state.$state#methods_includes $state.includes('fullOrPartialStateName')}.\n\t */\n\t$IncludedByStateFilter.$inject = ['$state'];\n\tfunction $IncludedByStateFilter($state) {\n\t    var includesFilter = function (state, params, options) {\n\t        return $state.includes(state, params, options);\n\t    };\n\t    includesFilter.$stateful = true;\n\t    return includesFilter;\n\t}\n\texports.$IncludedByStateFilter = $IncludedByStateFilter;\n\tangular.module('ui.router.state')\n\t    .filter('isState', $IsStateFilter)\n\t    .filter('includedByState', $IncludedByStateFilter);\n\n\n/***/ },\n/* 60 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module ng1_directives */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar trace_1 = __webpack_require__(12);\n\tvar views_1 = __webpack_require__(55);\n\tvar hof_1 = __webpack_require__(5);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar strings_1 = __webpack_require__(9);\n\tvar services_1 = __webpack_require__(53);\n\t/**\n\t * `ui-view`: A viewport directive which is filled in by a view from the active state.\n\t *\n\t * @param {string=} name A view name. The name should be unique amongst the other views in the\n\t * same state. You can have views of the same name that live in different states.\n\t *\n\t * @param {string=} autoscroll It allows you to set the scroll behavior of the browser window\n\t * when a view is populated. By default, $anchorScroll is overridden by ui-router's custom scroll\n\t * service, {@link ui.router.state.$uiViewScroll}. This custom service let's you\n\t * scroll ui-view elements into view when they are populated during a state activation.\n\t *\n\t * *Note: To revert back to old [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll)\n\t * functionality, call `$uiViewScrollProvider.useAnchorScroll()`.*\n\t *\n\t * @param {string=} onload Expression to evaluate whenever the view updates.\n\t *\n\t * A view can be unnamed or named.\n\t * @example\n\t * ```html\n\t *\n\t * <!-- Unnamed -->\n\t * <div ui-view></div>\n\t *\n\t * <!-- Named -->\n\t * <div ui-view=\"viewName\"></div>\n\t * ```\n\t *\n\t * You can only have one unnamed view within any template (or root html). If you are only using a\n\t * single view and it is unnamed then you can populate it like so:\n\t * ```\n\t *\n\t * <div ui-view></div>\n\t * $stateProvider.state(\"home\", {\n\t *   template: \"<h1>HELLO!</h1>\"\n\t * })\n\t * ```\n\t *\n\t * The above is a convenient shortcut equivalent to specifying your view explicitly with the {@link ui.router.state.$stateProvider#views `views`}\n\t * config property, by name, in this case an empty name:\n\t * ```js\n\t *\n\t * $stateProvider.state(\"home\", {\n\t *   views: {\n\t *     \"\": {\n\t *       template: \"<h1>HELLO!</h1>\"\n\t *     }\n\t *   }\n\t * })\n\t * ```\n\t *\n\t * But typically you'll only use the views property if you name your view or have more than one view\n\t * in the same template. There's not really a compelling reason to name a view if its the only one,\n\t * but you could if you wanted, like so:\n\t *\n\t * ```html\n\t *\n\t * <div ui-view=\"main\"></div>\n\t * ```\n\t *\n\t * ```js\n\t *\n\t * $stateProvider.state(\"home\", {\n\t *   views: {\n\t *     \"main\": {\n\t *       template: \"<h1>HELLO!</h1>\"\n\t *     }\n\t *   }\n\t * })\n\t * ```\n\t *\n\t * Really though, you'll use views to set up multiple views:\n\t * ```html\n\t *\n\t * <div ui-view></div>\n\t * <div ui-view=\"chart\"></div>\n\t * <div ui-view=\"data\"></div>\n\t * ```\n\t *\n\t * ```js\n\t * $stateProvider.state(\"home\", {\n\t *   views: {\n\t *     \"\": {\n\t *       template: \"<h1>HELLO!</h1>\"\n\t *     },\n\t *     \"chart\": {\n\t *       template: \"<chart_thing/>\"\n\t *     },\n\t *     \"data\": {\n\t *       template: \"<data_thing/>\"\n\t *     }\n\t *   }\n\t * })\n\t * ```\n\t *\n\t * Examples for `autoscroll`:\n\t *\n\t * ```html\n\t *\n\t * <!-- If autoscroll present with no expression,\n\t *      then scroll ui-view into view -->\n\t * <ui-view autoscroll/>\n\t *\n\t * <!-- If autoscroll present with valid expression,\n\t *      then scroll ui-view into view if expression evaluates to true -->\n\t * <ui-view autoscroll='true'/>\n\t * <ui-view autoscroll='false'/>\n\t * <ui-view autoscroll='scopeVariable'/>\n\t * ```\n\t *\n\t * Resolve data:\n\t *\n\t * The resolved data from the state's `resolve` block is placed on the scope as `$resolve` (this\n\t * can be customized using [[ViewDeclaration.resolveAs]]).  This can be then accessed from the template.\n\t *\n\t * Note that when `controllerAs` is being used, `$resolve` is set on the controller instance *after* the\n\t * controller is instantiated.  The `$onInit()` hook can be used to perform initialization code which\n\t * depends on `$resolve` data.\n\t *\n\t * @example\n\t * ```js\n\t *\n\t * $stateProvider.state('home', {\n\t *   template: '<my-component user=\"$resolve.user\"></my-component>',\n\t *   resolve: {\n\t *     user: function(UserService) { return UserService.fetchUser(); }\n\t *   }\n\t * });\n\t * ```\n\t */\n\tvar uiView = ['$view', '$animate', '$uiViewScroll', '$interpolate', '$q',\n\t    function $ViewDirective($view, $animate, $uiViewScroll, $interpolate, $q) {\n\t        function getRenderer(attrs, scope) {\n\t            return {\n\t                enter: function (element, target, cb) {\n\t                    if (angular.version.minor > 2) {\n\t                        $animate.enter(element, null, target).then(cb);\n\t                    }\n\t                    else {\n\t                        $animate.enter(element, null, target, cb);\n\t                    }\n\t                },\n\t                leave: function (element, cb) {\n\t                    if (angular.version.minor > 2) {\n\t                        $animate.leave(element).then(cb);\n\t                    }\n\t                    else {\n\t                        $animate.leave(element, cb);\n\t                    }\n\t                }\n\t            };\n\t        }\n\t        function configsEqual(config1, config2) {\n\t            return config1 === config2;\n\t        }\n\t        var rootData = {\n\t            $cfg: { viewDecl: { $context: $view.rootContext() } },\n\t            $uiView: {}\n\t        };\n\t        var directive = {\n\t            count: 0,\n\t            restrict: 'ECA',\n\t            terminal: true,\n\t            priority: 400,\n\t            transclude: 'element',\n\t            compile: function (tElement, tAttrs, $transclude) {\n\t                return function (scope, $element, attrs) {\n\t                    var previousEl, currentEl, currentScope, unregister, onloadExp = attrs.onload || '', autoScrollExp = attrs.autoscroll, renderer = getRenderer(attrs, scope), viewConfig = undefined, inherited = $element.inheritedData('$uiView') || rootData, name = $interpolate(attrs.uiView || attrs.name || '')(scope) || '$default';\n\t                    var activeUIView = {\n\t                        $type: 'ng1',\n\t                        id: directive.count++,\n\t                        name: name,\n\t                        fqn: inherited.$uiView.fqn ? inherited.$uiView.fqn + \".\" + name : name,\n\t                        config: null,\n\t                        configUpdated: configUpdatedCallback,\n\t                        get creationContext() {\n\t                            return hof_1.parse('$cfg.viewDecl.$context')(inherited);\n\t                        }\n\t                    };\n\t                    trace_1.trace.traceUIViewEvent(\"Linking\", activeUIView);\n\t                    function configUpdatedCallback(config) {\n\t                        if (config && !(config instanceof views_1.Ng1ViewConfig))\n\t                            return;\n\t                        if (configsEqual(viewConfig, config))\n\t                            return;\n\t                        trace_1.trace.traceUIViewConfigUpdated(activeUIView, config && config.viewDecl && config.viewDecl.$context);\n\t                        viewConfig = config;\n\t                        updateView(config);\n\t                    }\n\t                    $element.data('$uiView', { $uiView: activeUIView });\n\t                    updateView();\n\t                    unregister = $view.registerUIView(activeUIView);\n\t                    scope.$on(\"$destroy\", function () {\n\t                        trace_1.trace.traceUIViewEvent(\"Destroying/Unregistering\", activeUIView);\n\t                        unregister();\n\t                    });\n\t                    function cleanupLastView() {\n\t                        if (previousEl) {\n\t                            trace_1.trace.traceUIViewEvent(\"Removing (previous) el\", previousEl.data('$uiView'));\n\t                            previousEl.remove();\n\t                            previousEl = null;\n\t                        }\n\t                        if (currentScope) {\n\t                            trace_1.trace.traceUIViewEvent(\"Destroying scope\", activeUIView);\n\t                            currentScope.$destroy();\n\t                            currentScope = null;\n\t                        }\n\t                        if (currentEl) {\n\t                            var _viewData_1 = currentEl.data('$uiView');\n\t                            trace_1.trace.traceUIViewEvent(\"Animate out\", _viewData_1);\n\t                            renderer.leave(currentEl, function () {\n\t                                _viewData_1.$$animLeave.resolve();\n\t                                previousEl = null;\n\t                            });\n\t                            previousEl = currentEl;\n\t                            currentEl = null;\n\t                        }\n\t                    }\n\t                    function updateView(config) {\n\t                        var newScope = scope.$new();\n\t                        trace_1.trace.traceUIViewScopeCreated(activeUIView, newScope);\n\t                        var animEnter = $q.defer(), animLeave = $q.defer();\n\t                        var $uiViewData = {\n\t                            $cfg: config,\n\t                            $uiView: activeUIView,\n\t                            $animEnter: animEnter.promise,\n\t                            $animLeave: animLeave.promise,\n\t                            $$animLeave: animLeave\n\t                        };\n\t                        var cloned = $transclude(newScope, function (clone) {\n\t                            renderer.enter(clone.data('$uiView', $uiViewData), $element, function onUIViewEnter() {\n\t                                animEnter.resolve();\n\t                                if (currentScope)\n\t                                    currentScope.$emit('$viewContentAnimationEnded');\n\t                                if (predicates_1.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) {\n\t                                    $uiViewScroll(clone);\n\t                                }\n\t                            });\n\t                            cleanupLastView();\n\t                        });\n\t                        currentEl = cloned;\n\t                        currentScope = newScope;\n\t                        /**\n\t                         * @ngdoc event\n\t                         * @name ui.router.state.directive:ui-view#$viewContentLoaded\n\t                         * @eventOf ui.router.state.directive:ui-view\n\t                         * @eventType emits on ui-view directive scope\n\t                         * @description           *\n\t                         * Fired once the view is **loaded**, *after* the DOM is rendered.\n\t                         *\n\t                         * @param {Object} event Event object.\n\t                         */\n\t                        currentScope.$emit('$viewContentLoaded', config || viewConfig);\n\t                        currentScope.$eval(onloadExp);\n\t                    }\n\t                };\n\t            }\n\t        };\n\t        return directive;\n\t    }];\n\t$ViewDirectiveFill.$inject = ['$compile', '$controller', '$transitions', '$view', '$timeout'];\n\t/** @hidden */\n\tfunction $ViewDirectiveFill($compile, $controller, $transitions, $view, $timeout) {\n\t    var getControllerAs = hof_1.parse('viewDecl.controllerAs');\n\t    var getResolveAs = hof_1.parse('viewDecl.resolveAs');\n\t    return {\n\t        restrict: 'ECA',\n\t        priority: -400,\n\t        compile: function (tElement) {\n\t            var initial = tElement.html();\n\t            return function (scope, $element) {\n\t                var data = $element.data('$uiView');\n\t                if (!data)\n\t                    return;\n\t                var cfg = data.$cfg || { viewDecl: {} };\n\t                $element.html(cfg.template || initial);\n\t                trace_1.trace.traceUIViewFill(data.$uiView, $element.html());\n\t                var link = $compile($element.contents());\n\t                var controller = cfg.controller;\n\t                var controllerAs = getControllerAs(cfg);\n\t                var resolveAs = getResolveAs(cfg);\n\t                var resolveCtx = cfg.path && new resolveContext_1.ResolveContext(cfg.path);\n\t                var locals = resolveCtx && services_1.getLocals(resolveCtx);\n\t                scope[resolveAs] = locals;\n\t                if (controller) {\n\t                    var controllerInstance = $controller(controller, common_1.extend({}, locals, { $scope: scope, $element: $element }));\n\t                    if (controllerAs) {\n\t                        scope[controllerAs] = controllerInstance;\n\t                        scope[controllerAs][resolveAs] = locals;\n\t                    }\n\t                    // TODO: Use $view service as a central point for registering component-level hooks\n\t                    // Then, when a component is created, tell the $view service, so it can invoke hooks\n\t                    // $view.componentLoaded(controllerInstance, { $scope: scope, $element: $element });\n\t                    // scope.$on('$destroy', () => $view.componentUnloaded(controllerInstance, { $scope: scope, $element: $element }));\n\t                    $element.data('$ngControllerController', controllerInstance);\n\t                    $element.children().data('$ngControllerController', controllerInstance);\n\t                    registerControllerCallbacks($transitions, controllerInstance, scope, cfg);\n\t                }\n\t                // Wait for the component to appear in the DOM\n\t                if (predicates_1.isString(cfg.viewDecl.component)) {\n\t                    var cmp_1 = cfg.viewDecl.component;\n\t                    var kebobName_1 = strings_1.kebobString(cmp_1);\n\t                    var getComponentController = function () {\n\t                        var directiveEl = [].slice.call($element[0].children)\n\t                            .filter(function (el) { return el && el.tagName && el.tagName.toLowerCase() === kebobName_1; });\n\t                        return directiveEl && angular.element(directiveEl).data(\"$\" + cmp_1 + \"Controller\");\n\t                    };\n\t                    var deregisterWatch_1 = scope.$watch(getComponentController, function (ctrlInstance) {\n\t                        if (!ctrlInstance)\n\t                            return;\n\t                        registerControllerCallbacks($transitions, ctrlInstance, scope, cfg);\n\t                        deregisterWatch_1();\n\t                    });\n\t                }\n\t                link(scope);\n\t            };\n\t        }\n\t    };\n\t}\n\t/** @hidden */\n\tvar hasComponentImpl = typeof angular.module('ui.router')['component'] === 'function';\n\t/** @hidden TODO: move these callbacks to $view and/or `/hooks/components.ts` or something */\n\tfunction registerControllerCallbacks($transitions, controllerInstance, $scope, cfg) {\n\t    // Call $onInit() ASAP\n\t    if (predicates_1.isFunction(controllerInstance.$onInit) && !(cfg.viewDecl.component && hasComponentImpl))\n\t        controllerInstance.$onInit();\n\t    var viewState = common_1.tail(cfg.path).state.self;\n\t    var hookOptions = { bind: controllerInstance };\n\t    // Add component-level hook for onParamsChange\n\t    if (predicates_1.isFunction(controllerInstance.uiOnParamsChanged)) {\n\t        var resolveContext = new resolveContext_1.ResolveContext(cfg.path);\n\t        var viewCreationTrans_1 = resolveContext.getResolvable('$transition$').data;\n\t        // Fire callback on any successful transition\n\t        var paramsUpdated = function ($transition$) {\n\t            // Exit early if the $transition$ is the same as the view was created within.\n\t            // Exit early if the $transition$ will exit the state the view is for.\n\t            if ($transition$ === viewCreationTrans_1 || $transition$.exiting().indexOf(viewState) !== -1)\n\t                return;\n\t            var toParams = $transition$.params(\"to\");\n\t            var fromParams = $transition$.params(\"from\");\n\t            var toSchema = $transition$.treeChanges().to.map(function (node) { return node.paramSchema; }).reduce(common_1.unnestR, []);\n\t            var fromSchema = $transition$.treeChanges().from.map(function (node) { return node.paramSchema; }).reduce(common_1.unnestR, []);\n\t            // Find the to params that have different values than the from params\n\t            var changedToParams = toSchema.filter(function (param) {\n\t                var idx = fromSchema.indexOf(param);\n\t                return idx === -1 || !fromSchema[idx].type.equals(toParams[param.id], fromParams[param.id]);\n\t            });\n\t            // Only trigger callback if a to param has changed or is new\n\t            if (changedToParams.length) {\n\t                var changedKeys_1 = changedToParams.map(function (x) { return x.id; });\n\t                // Filter the params to only changed/new to params.  `$transition$.params()` may be used to get all params.\n\t                controllerInstance.uiOnParamsChanged(common_1.filter(toParams, function (val, key) { return changedKeys_1.indexOf(key) !== -1; }), $transition$);\n\t            }\n\t        };\n\t        $scope.$on('$destroy', $transitions.onSuccess({}, paramsUpdated, hookOptions));\n\t    }\n\t    // Add component-level hook for uiCanExit\n\t    if (predicates_1.isFunction(controllerInstance.uiCanExit)) {\n\t        var criteria = { exiting: viewState.name };\n\t        $scope.$on('$destroy', $transitions.onBefore(criteria, controllerInstance.uiCanExit, hookOptions));\n\t    }\n\t}\n\tangular.module('ui.router.state').directive('uiView', uiView);\n\tangular.module('ui.router.state').directive('uiView', $ViewDirectiveFill);\n\n\n/***/ },\n/* 61 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t/**\n\t * @ngdoc object\n\t * @name ui.router.state.$uiViewScrollProvider\n\t *\n\t * @description\n\t * Provider that returns the {@link ui.router.state.$uiViewScroll} service function.\n\t */\n\tfunction $ViewScrollProvider() {\n\t    var useAnchorScroll = false;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$uiViewScrollProvider#useAnchorScroll\n\t     * @methodOf ui.router.state.$uiViewScrollProvider\n\t     *\n\t     * @description\n\t     * Reverts back to using the core [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll) service for\n\t     * scrolling based on the url anchor.\n\t     */\n\t    this.useAnchorScroll = function () {\n\t        useAnchorScroll = true;\n\t    };\n\t    /**\n\t     * @ngdoc object\n\t     * @name ui.router.state.$uiViewScroll\n\t     *\n\t     * @requires $anchorScroll\n\t     * @requires $timeout\n\t     *\n\t     * @description\n\t     * When called with a jqLite element, it scrolls the element into view (after a\n\t     * `$timeout` so the DOM has time to refresh).\n\t     *\n\t     * If you prefer to rely on `$anchorScroll` to scroll the view to the anchor,\n\t     * this can be enabled by calling {@link ui.router.state.$uiViewScrollProvider#methods_useAnchorScroll `$uiViewScrollProvider.useAnchorScroll()`}.\n\t     */\n\t    this.$get = ['$anchorScroll', '$timeout', function ($anchorScroll, $timeout) {\n\t            if (useAnchorScroll) {\n\t                return $anchorScroll;\n\t            }\n\t            return function ($element) {\n\t                return $timeout(function () {\n\t                    $element[0].scrollIntoView();\n\t                }, 0, false);\n\t            };\n\t        }];\n\t}\n\tangular.module('ui.router.state').provider('$uiViewScroll', $ViewScrollProvider);\n\n\n/***/ }\n/******/ ])\n});\n;\n//# sourceMappingURL=angular-ui-router.js.map\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-ui-router/release/angular-ui-router.js\n// module id = 3\n// module chunks = 0","\n/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nlet self;\n\nclass ElineSide {\n\n  static $inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];\n\n  constructor(\n    private XosSidePanel: any,\n    private XosModelStore: any,\n    private $http: any,\n    private $log: any,\n    private toastr: any,\n  ) {\n    self = this;\n  }\n\n  public saveEline(item: any) {\n    let path = item.path;\n    delete item.path;\n    item.$save().then((res) => {\n      item.path = path;\n      this.toastr.success(`${item.name} successfully saved!`);\n    })\n      .catch((error) => {\n        this.toastr.error(`Error while saving ${item.name}: ${error.specific_error}`);\n      });\n  }\n\n  public deleteEline(item: any) {\n    let name = item.name;\n    item.$delete().then((res) => {\n      this.toastr.success(`${name} successfully deleted!`);\n    })\n    .catch((error) => {\n        this.toastr.error(`Error while deleting ${name}: ${error.specific_error}`);\n      });\n  }\n\n\n}\n\nexport const elineSide: angular.IComponentOptions = {\n  template: require('./eline-side.component.html'),\n  controllerAs: 'vm',\n  controller: ElineSide,\n  bindings: {\n    eng: '='\n  }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./~/tslint-loader!./src/app/components/eline-side.component.ts","/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\"use strict\";\nexports.__esModule = true;\nvar self;\nvar ElineSide = (function () {\n    function ElineSide(XosSidePanel, XosModelStore, $http, $log, toastr) {\n        this.XosSidePanel = XosSidePanel;\n        this.XosModelStore = XosModelStore;\n        this.$http = $http;\n        this.$log = $log;\n        this.toastr = toastr;\n        self = this;\n    }\n    ElineSide.prototype.saveEline = function (item) {\n        var _this = this;\n        var path = item.path;\n        delete item.path;\n        item.$save().then(function (res) {\n            item.path = path;\n            _this.toastr.success(item.name + \" successfully saved!\");\n        })[\"catch\"](function (error) {\n            _this.toastr.error(\"Error while saving \" + item.name + \": \" + error.specific_error);\n        });\n    };\n    ElineSide.prototype.deleteEline = function (item) {\n        var _this = this;\n        var name = item.name;\n        item.$delete().then(function (res) {\n            _this.toastr.success(name + \" successfully deleted!\");\n        })[\"catch\"](function (error) {\n            _this.toastr.error(\"Error while deleting \" + name + \": \" + error.specific_error);\n        });\n    };\n    return ElineSide;\n}());\nElineSide.$inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];\nexports.elineSide = {\n    template: require('./eline-side.component.html'),\n    controllerAs: 'vm',\n    controller: ElineSide,\n    bindings: {\n        eng: '='\n    }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/components/eline-side.component.ts","\n/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nimport {NgMap} from 'ngmap';\nimport {Subscription} from 'rxjs/Subscription';\nimport * as _ from 'lodash';\n\ndeclare var google;\n\nlet self;\n\nexport class EngMap {\n\n  static $inject = [\n    'NgMap',\n    'XosModelStore',\n    'AppConfig',\n    '$resource',\n    'XosSidePanel',\n    'XosModelDiscoverer',\n    'ModelRest',\n    'MapConfig',\n  ];\n\n  public unis = [];\n  public elines = [];\n  public cpilatlng = new Map();\n  public paths = [];\n  public bwps = [];\n  public map;\n  public panelOpen = false;\n  public createMode = false;\n  public canCreateEline = true;\n  public eline;\n  public current_uni;\n  public mapStyles = [{'featureType': 'administrative', 'elementType': 'labels.text.fill', 'stylers': [{'color': '#444444'}]}, {'featureType': 'landscape', 'elementType': 'all', 'stylers': [{'color': '#f2f2f2'}]}, {'featureType': 'poi', 'elementType': 'all', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'road', 'elementType': 'all', 'stylers': [{'saturation': -100}, {'lightness': 45}]}, {'featureType': 'road.highway', 'elementType': 'all', 'stylers': [{'visibility': 'simplified'}]}, {'featureType': 'road.arterial', 'elementType': 'labels.icon', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'transit', 'elementType': 'all', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'water', 'elementType': 'all', 'stylers': [{'color': '#9ce1fc'}, {'visibility': 'on'}]}];\n\n  private uniSubscription: Subscription;\n  private elineSubscription: Subscription;\n  private bwpSubscription: Subscription;\n\n  constructor(\n    private NgMap: any,\n    private XosModelStore: any,\n    private AppConfig: any,\n    private $resource: any,\n    private XosSidePanel: any,\n    private XosModelDiscoverer: any,\n    private ModelRest: any,\n    private MapConfig: any,\n  ) {\n    self = this;\n  }\n\n  $onInit() {\n    this.NgMap.getMap().then(map => {\n      this.map = map;\n      this.uniSubscription = this.XosModelStore.query('UserNetworkInterface', '/vnaas/usernetworkinterfaces/').subscribe(\n        res => {\n          this.unis = res;\n          this.renderMap(map);\n        }\n      );\n      this.elineSubscription = this.XosModelStore.query('ELine', '/vnaas/elines/').subscribe(\n        res => {\n          this.elines = res;\n          this.createPaths();\n          this.renderMap(map);\n        }\n      );\n      this.bwpSubscription = this.XosModelStore.query('BandwidthProfile', '/vnaas/bandwidthprofiles/').subscribe(\n        res => {\n          this.bwps = res;\n        }\n      );\n    });\n  }\n\n  $onDestroy() {\n    if (this.uniSubscription) {\n      this.uniSubscription.unsubscribe();\n    }\n  }\n\n  public renderMap(map: NgMap) {\n\n    let bounds = new google.maps.LatLngBounds();\n\n    for (let i = 0; i < self.unis.length; i++) {\n      self.unis[i].eline_start = false;\n      let curr = JSON.parse(self.unis[i].latlng);\n      this.cpilatlng.set(self.unis[i].cpe_id, curr);\n      let latlng = new google.maps.LatLng(curr[0], curr[1]);\n      bounds.extend(latlng);\n    }\n    map.setCenter(bounds.getCenter());\n    map.fitBounds(bounds);\n\n  }\n\n  public createPaths() {\n    this.elines.forEach((eline: any) => {\n      let latlng_start = this.cpilatlng.get(eline.connect_point_1_id);\n      let latlng_end = this.cpilatlng.get(eline.connect_point_2_id);\n      eline.path = [latlng_start, latlng_end];\n    });\n\n  }\n\n  public colorLine(eline_status : any) {\n    let status = parseInt(eline_status, 10);\n    switch (status) {\n      case 0:\n        return '#f39c12';\n      case 1:\n        return '#2ecc71';\n      default:\n        return '#e74c3c';\n    }\n\n  }\n\n  public showUni(e: any, uni: any) {\n    self.current_uni = uni;\n    self.map.showInfoWindow('uni-info', this);\n  }\n\n  // do not display backend status or ID in create mode\n\n  public elinePanel(e: any, eline: any, exists: boolean) {\n    self.panelOpen = !self.panelOpen;\n    if (exists) {\n      self.eline = _.find(self.elines, {id: eline.id});\n    }\n    self.XosSidePanel.toggleComponent('elineSide', {eline: self.eline, bwplist: self.bwps, eng: self}, false);\n    if (!self.panelOpen && self.createMode) {\n      self.createMode = false;\n      self.canCreateEline = true;\n      self.current_uni.eline_start = false;\n    }\n\n  }\n\n  public createConnection(uni: any) {\n    return () => {\n      self.canCreateEline = false;\n      self.createMode = true;\n      uni.eline_start = true;\n      self.current_uni = uni;\n      self.eline = {\n        name: uni.name,\n        uni1name: uni.name,\n        connect_point_1_id: uni.cpe_id,\n      };\n      self.elinePanel({}, self.eline, false);\n    };\n\n  }\n\n  public finishConnection(uni: any) {\n    self.eline.connect_point_2_id = uni.cpe_id;\n    if (self.eline.name === self.eline.uni1name) {\n      self.eline.name = self.eline.name + uni.name;\n    }\n    delete self.eline.uni1name;\n    const resource = this.ModelRest.getResource('/vnaas/elines/');\n    let res = new resource({});\n    for (let attr in self.eline) {\n      if (true) {\n        res[attr] = self.eline[attr];\n      }\n\n    }\n    self.eline = res;\n  }\n\n}\n\nexport const engMap: angular.IComponentOptions = {\n  template: require('./engMap.component.html'),\n  controllerAs: 'vm',\n  controller: EngMap,\n};\n\n\n\n// WEBPACK FOOTER //\n// ./~/tslint-loader!./src/app/components/engMap.component.ts","/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\"use strict\";\nexports.__esModule = true;\nvar _ = require(\"lodash\");\nvar self;\nvar EngMap = (function () {\n    function EngMap(NgMap, XosModelStore, AppConfig, $resource, XosSidePanel, XosModelDiscoverer, ModelRest, MapConfig) {\n        this.NgMap = NgMap;\n        this.XosModelStore = XosModelStore;\n        this.AppConfig = AppConfig;\n        this.$resource = $resource;\n        this.XosSidePanel = XosSidePanel;\n        this.XosModelDiscoverer = XosModelDiscoverer;\n        this.ModelRest = ModelRest;\n        this.MapConfig = MapConfig;\n        this.unis = [];\n        this.elines = [];\n        this.cpilatlng = new Map();\n        this.paths = [];\n        this.bwps = [];\n        this.panelOpen = false;\n        this.createMode = false;\n        this.canCreateEline = true;\n        this.mapStyles = [{ 'featureType': 'administrative', 'elementType': 'labels.text.fill', 'stylers': [{ 'color': '#444444' }] }, { 'featureType': 'landscape', 'elementType': 'all', 'stylers': [{ 'color': '#f2f2f2' }] }, { 'featureType': 'poi', 'elementType': 'all', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'road', 'elementType': 'all', 'stylers': [{ 'saturation': -100 }, { 'lightness': 45 }] }, { 'featureType': 'road.highway', 'elementType': 'all', 'stylers': [{ 'visibility': 'simplified' }] }, { 'featureType': 'road.arterial', 'elementType': 'labels.icon', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'transit', 'elementType': 'all', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'water', 'elementType': 'all', 'stylers': [{ 'color': '#9ce1fc' }, { 'visibility': 'on' }] }];\n        self = this;\n    }\n    EngMap.prototype.$onInit = function () {\n        var _this = this;\n        this.NgMap.getMap().then(function (map) {\n            _this.map = map;\n            _this.uniSubscription = _this.XosModelStore.query('UserNetworkInterface', '/vnaas/usernetworkinterfaces/').subscribe(function (res) {\n                _this.unis = res;\n                _this.renderMap(map);\n            });\n            _this.elineSubscription = _this.XosModelStore.query('ELine', '/vnaas/elines/').subscribe(function (res) {\n                _this.elines = res;\n                _this.createPaths();\n                _this.renderMap(map);\n            });\n            _this.bwpSubscription = _this.XosModelStore.query('BandwidthProfile', '/vnaas/bandwidthprofiles/').subscribe(function (res) {\n                _this.bwps = res;\n            });\n        });\n    };\n    EngMap.prototype.$onDestroy = function () {\n        if (this.uniSubscription) {\n            this.uniSubscription.unsubscribe();\n        }\n    };\n    EngMap.prototype.renderMap = function (map) {\n        var bounds = new google.maps.LatLngBounds();\n        for (var i = 0; i < self.unis.length; i++) {\n            self.unis[i].eline_start = false;\n            var curr = JSON.parse(self.unis[i].latlng);\n            this.cpilatlng.set(self.unis[i].cpe_id, curr);\n            var latlng = new google.maps.LatLng(curr[0], curr[1]);\n            bounds.extend(latlng);\n        }\n        map.setCenter(bounds.getCenter());\n        map.fitBounds(bounds);\n    };\n    EngMap.prototype.createPaths = function () {\n        var _this = this;\n        this.elines.forEach(function (eline) {\n            var latlng_start = _this.cpilatlng.get(eline.connect_point_1_id);\n            var latlng_end = _this.cpilatlng.get(eline.connect_point_2_id);\n            eline.path = [latlng_start, latlng_end];\n        });\n    };\n    EngMap.prototype.colorLine = function (eline_status) {\n        var status = parseInt(eline_status, 10);\n        switch (status) {\n            case 0:\n                return '#f39c12';\n            case 1:\n                return '#2ecc71';\n            default:\n                return '#e74c3c';\n        }\n    };\n    EngMap.prototype.showUni = function (e, uni) {\n        self.current_uni = uni;\n        self.map.showInfoWindow('uni-info', this);\n    };\n    // do not display backend status or ID in create mode\n    EngMap.prototype.elinePanel = function (e, eline, exists) {\n        self.panelOpen = !self.panelOpen;\n        if (exists) {\n            self.eline = _.find(self.elines, { id: eline.id });\n        }\n        self.XosSidePanel.toggleComponent('elineSide', { eline: self.eline, bwplist: self.bwps, eng: self }, false);\n        if (!self.panelOpen && self.createMode) {\n            self.createMode = false;\n            self.canCreateEline = true;\n            self.current_uni.eline_start = false;\n        }\n    };\n    EngMap.prototype.createConnection = function (uni) {\n        return function () {\n            self.canCreateEline = false;\n            self.createMode = true;\n            uni.eline_start = true;\n            self.current_uni = uni;\n            self.eline = {\n                name: uni.name,\n                uni1name: uni.name,\n                connect_point_1_id: uni.cpe_id\n            };\n            self.elinePanel({}, self.eline, false);\n        };\n    };\n    EngMap.prototype.finishConnection = function (uni) {\n        self.eline.connect_point_2_id = uni.cpe_id;\n        if (self.eline.name === self.eline.uni1name) {\n            self.eline.name = self.eline.name + uni.name;\n        }\n        delete self.eline.uni1name;\n        var resource = this.ModelRest.getResource('/vnaas/elines/');\n        var res = new resource({});\n        for (var attr in self.eline) {\n            if (true) {\n                res[attr] = self.eline[attr];\n            }\n        }\n        self.eline = res;\n    };\n    return EngMap;\n}());\nEngMap.$inject = [\n    'NgMap',\n    'XosModelStore',\n    'AppConfig',\n    '$resource',\n    'XosSidePanel',\n    'XosModelDiscoverer',\n    'ModelRest',\n    'MapConfig',\n];\nexports.EngMap = EngMap;\nexports.engMap = {\n    template: require('./engMap.component.html'),\n    controllerAs: 'vm',\n    controller: EngMap\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/components/engMap.component.ts","\n/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nexport default routesConfig;\n\nfunction routesConfig($stateProvider: angular.ui.IStateProvider, $locationProvider: angular.ILocationProvider) {\n  $locationProvider.html5Mode(false).hashPrefix('');\n\n  $stateProvider\n    .state('xos.vnaasgui', {\n      url: 'vnaasgui',\n      parent: 'xos',\n      component: 'engMap'\n    });\n}\n\n\n\n// WEBPACK FOOTER //\n// ./~/tslint-loader!./src/routes.ts","/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\"use strict\";\nexports.__esModule = true;\nexports[\"default\"] = routesConfig;\nfunction routesConfig($stateProvider, $locationProvider) {\n    $locationProvider.html5Mode(false).hashPrefix('');\n    $stateProvider\n        .state('xos.vnaasgui', {\n        url: 'vnaasgui',\n        parent: 'xos',\n        component: 'engMap'\n    });\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/routes.ts","(function(root, factory) {\r\nif (typeof exports === \"object\") {\r\nmodule.exports = factory(require('angular'));\r\n} else if (typeof define === \"function\" && define.amd) {\r\ndefine(['angular'], factory);\r\n} else{\r\nfactory(root.angular);\r\n}\r\n}(this, function(angular) {\r\n/**\n * AngularJS Google Maps Ver. 1.18.3\n *\n * The MIT License (MIT)\n * \n * Copyright (c) 2014, 2015, 1016 Allen Kim\n * \n * Permission is hereby granted, free of charge, to any person obtaining a copy of\n * this software and associated documentation files (the \"Software\"), to deal in\n * the Software without restriction, including without limitation the rights to\n * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n * the Software, and to permit persons to whom the Software is furnished to do so,\n * subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\nangular.module('ngMap', []);\n\n/**\n * @ngdoc controller\n * @name MapController\n */\n(function() {\n  'use strict';\n  var Attr2MapOptions;\n\n  var __MapController = function(\n      $scope, $element, $attrs, $parse, $interpolate, _Attr2MapOptions_, NgMap, NgMapPool, escapeRegExp\n    ) {\n    Attr2MapOptions = _Attr2MapOptions_;\n    var vm = this;\n    var exprStartSymbol = $interpolate.startSymbol();\n    var exprEndSymbol = $interpolate.endSymbol();\n\n    vm.mapOptions; /** @memberof __MapController */\n    vm.mapEvents;  /** @memberof __MapController */\n    vm.eventListeners;  /** @memberof __MapController */\n\n    /**\n     * Add an object to the collection of group\n     * @memberof __MapController\n     * @function addObject\n     * @param groupName the name of collection that object belongs to\n     * @param obj  an object to add into a collection, i.e. marker, shape\n     */\n    vm.addObject = function(groupName, obj) {\n      if (vm.map) {\n        vm.map[groupName] = vm.map[groupName] || {};\n        var len = Object.keys(vm.map[groupName]).length;\n        vm.map[groupName][obj.id || len] = obj;\n\n        if (vm.map instanceof google.maps.Map) {\n          //infoWindow.setMap works like infoWindow.open\n          if (groupName != \"infoWindows\" && obj.setMap) {\n            obj.setMap && obj.setMap(vm.map);\n          }\n          if (obj.centered && obj.position) {\n            vm.map.setCenter(obj.position);\n          }\n          (groupName == 'markers') && vm.objectChanged('markers');\n          (groupName == 'customMarkers') && vm.objectChanged('customMarkers');\n        }\n      }\n    };\n\n    /**\n     * Delete an object from the collection and remove from map\n     * @memberof __MapController\n     * @function deleteObject\n     * @param {Array} objs the collection of objects. i.e., map.markers\n     * @param {Object} obj the object to be removed. i.e., marker\n     */\n    vm.deleteObject = function(groupName, obj) {\n      /* delete from group */\n      if (obj.map) {\n        var objs = obj.map[groupName];\n        for (var name in objs) {\n          if (objs[name] === obj) {\n            void 0;\n            google.maps.event.clearInstanceListeners(obj);\n            delete objs[name];\n          }\n        }\n\n        /* delete from map */\n        obj.map && obj.setMap && obj.setMap(null);\n\n        (groupName == 'markers') && vm.objectChanged('markers');\n        (groupName == 'customMarkers') && vm.objectChanged('customMarkers');\n      }\n    };\n\n    /**\n     * @memberof __MapController\n     * @function observeAttrSetObj\n     * @param {Hash} orgAttrs attributes before its initialization\n     * @param {Hash} attrs    attributes after its initialization\n     * @param {Object} obj    map object that an action is to be done\n     * @description watch changes of attribute values and\n     * do appropriate action based on attribute name\n     */\n    vm.observeAttrSetObj = function(orgAttrs, attrs, obj) {\n      if (attrs.noWatcher) {\n        return false;\n      }\n      var attrsToObserve = Attr2MapOptions.getAttrsToObserve(orgAttrs);\n      for (var i=0; i<attrsToObserve.length; i++) {\n        var attrName = attrsToObserve[i];\n        attrs.$observe(attrName, NgMap.observeAndSet(attrName, obj));\n      }\n    };\n\n    /**\n     * @memberof __MapController\n     * @function zoomToIncludeMarkers\n     */\n    vm.zoomToIncludeMarkers = function() {\n      // Only fit to bounds if we have any markers\n      // object.keys is supported in all major browsers (IE9+)\n      if ((vm.map.markers != null && Object.keys(vm.map.markers).length > 0) || (vm.map.customMarkers != null && Object.keys(vm.map.customMarkers).length > 0)) {\n        var bounds = new google.maps.LatLngBounds();\n        for (var k1 in vm.map.markers) {\n          bounds.extend(vm.map.markers[k1].getPosition());\n        }\n        for (var k2 in vm.map.customMarkers) {\n          bounds.extend(vm.map.customMarkers[k2].getPosition());\n        }\n    \t  if (vm.mapOptions.maximumZoom) {\n    \t\t  vm.enableMaximumZoomCheck = true; //enable zoom check after resizing for markers\n    \t  }\n        vm.map.fitBounds(bounds);\n      }\n    };\n\n    /**\n     * @memberof __MapController\n     * @function objectChanged\n     * @param {String} group name of group e.g., markers\n     */\n    vm.objectChanged = function(group) {\n      if ( vm.map &&\n        (group == 'markers' || group == 'customMarkers') &&\n        vm.map.zoomToIncludeMarkers == 'auto'\n      ) {\n        vm.zoomToIncludeMarkers();\n      }\n    };\n\n    /**\n     * @memberof __MapController\n     * @function initializeMap\n     * @description\n     *  . initialize Google map on <div> tag\n     *  . set map options, events, and observers\n     *  . reset zoom to include all (custom)markers\n     */\n    vm.initializeMap = function() {\n      var mapOptions = vm.mapOptions,\n          mapEvents = vm.mapEvents;\n\n      var lazyInitMap = vm.map; //prepared for lazy init\n      vm.map = NgMapPool.getMapInstance($element[0]);\n      NgMap.setStyle($element[0]);\n\n      // set objects for lazyInit\n      if (lazyInitMap) {\n\n        /**\n         * rebuild mapOptions for lazyInit\n         * because attributes values might have been changed\n         */\n        var filtered = Attr2MapOptions.filter($attrs);\n        var options = Attr2MapOptions.getOptions(filtered);\n        var controlOptions = Attr2MapOptions.getControlOptions(filtered);\n        mapOptions = angular.extend(options, controlOptions);\n        void 0;\n\n        for (var group in lazyInitMap) {\n          var groupMembers = lazyInitMap[group]; //e.g. markers\n          if (typeof groupMembers == 'object') {\n            for (var id in groupMembers) {\n              vm.addObject(group, groupMembers[id]);\n            }\n          }\n        }\n        vm.map.showInfoWindow = vm.showInfoWindow;\n        vm.map.hideInfoWindow = vm.hideInfoWindow;\n      }\n\n      // set options\n      mapOptions.zoom = mapOptions.zoom || 15;\n      var center = mapOptions.center;\n      var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '.*' + escapeRegExp(exprEndSymbol));\n\n      if (!mapOptions.center ||\n        ((typeof center === 'string') && center.match(exprRegExp))\n      ) {\n        mapOptions.center = new google.maps.LatLng(0, 0);\n      } else if( (typeof center === 'string') && center.match(/^[0-9.-]*,[0-9.-]*$/) ){\n        var lat = parseFloat(center.split(',')[0]);\n        var lng = parseFloat(center.split(',')[1]);\n        mapOptions.center = new google.maps.LatLng(lat, lng);\n      } else if (!(center instanceof google.maps.LatLng)) {\n        var geoCenter = mapOptions.center;\n        delete mapOptions.center;\n        NgMap.getGeoLocation(geoCenter, mapOptions.geoLocationOptions).\n          then(function (latlng) {\n            vm.map.setCenter(latlng);\n            var geoCallback = mapOptions.geoCallback;\n            geoCallback && $parse(geoCallback)($scope);\n          }, function () {\n            if (mapOptions.geoFallbackCenter) {\n              vm.map.setCenter(mapOptions.geoFallbackCenter);\n            }\n          });\n      }\n      vm.map.setOptions(mapOptions);\n\n      // set events\n      for (var eventName in mapEvents) {\n        var event = mapEvents[eventName];\n        var listener = google.maps.event.addListener(vm.map, eventName, event);\n        vm.eventListeners[eventName] = listener;\n      }\n\n      // set observers\n      vm.observeAttrSetObj(orgAttrs, $attrs, vm.map);\n      vm.singleInfoWindow = mapOptions.singleInfoWindow;\n\n      google.maps.event.trigger(vm.map, 'resize');\n\n      google.maps.event.addListenerOnce(vm.map, \"idle\", function () {\n        NgMap.addMap(vm);\n        if (mapOptions.zoomToIncludeMarkers) {\n          vm.zoomToIncludeMarkers();\n        }\n        //TODO: it's for backward compatibiliy. will be removed\n        $scope.map = vm.map;\n        $scope.$emit('mapInitialized', vm.map);\n\n        //callback\n        if ($attrs.mapInitialized) {\n          $parse($attrs.mapInitialized)($scope, {map: vm.map});\n        }\n      });\n\n\t  //add maximum zoom listeners if zoom-to-include-markers and and maximum-zoom are valid attributes\n\t  if (mapOptions.zoomToIncludeMarkers && mapOptions.maximumZoom) {\n\t    google.maps.event.addListener(vm.map, 'zoom_changed', function() {\n          if (vm.enableMaximumZoomCheck == true) {\n\t\t\tvm.enableMaximumZoomCheck = false;\n\t        google.maps.event.addListenerOnce(vm.map, 'bounds_changed', function() {\n\t\t      vm.map.setZoom(Math.min(mapOptions.maximumZoom, vm.map.getZoom()));\n\t\t    });\n\t  \t  }\n\t    });\n\t  }\n    };\n\n    $scope.google = google; //used by $scope.eval to avoid eval()\n\n    /**\n     * get map options and events\n     */\n    var orgAttrs = Attr2MapOptions.orgAttributes($element);\n    var filtered = Attr2MapOptions.filter($attrs);\n    var options = Attr2MapOptions.getOptions(filtered, {scope: $scope});\n    var controlOptions = Attr2MapOptions.getControlOptions(filtered);\n    var mapOptions = angular.extend(options, controlOptions);\n    var mapEvents = Attr2MapOptions.getEvents($scope, filtered);\n    void 0;\n    Object.keys(mapEvents).length && void 0;\n\n    vm.mapOptions = mapOptions;\n    vm.mapEvents = mapEvents;\n    vm.eventListeners = {};\n\n    if (options.lazyInit) { // allows controlled initialization\n      // parse angular expression for dynamic ids\n      if (!!$attrs.id &&\n      \t  // starts with, at position 0\n\t  $attrs.id.indexOf(exprStartSymbol, 0) === 0 &&\n\t  // ends with\n\t  $attrs.id.indexOf(exprEndSymbol, $attrs.id.length - exprEndSymbol.length) !== -1) {\n        var idExpression = $attrs.id.slice(2,-2);\n        var mapId = $parse(idExpression)($scope);\n      } else {\n        var mapId = $attrs.id;\n      }\n      vm.map = {id: mapId}; //set empty, not real, map\n      NgMap.addMap(vm);\n    } else {\n      vm.initializeMap();\n    }\n\n    //Trigger Resize\n    if(options.triggerResize) {\n      google.maps.event.trigger(vm.map, 'resize');\n    }\n\n    $element.bind('$destroy', function() {\n      NgMapPool.returnMapInstance(vm.map);\n      NgMap.deleteMap(vm);\n    });\n  }; // __MapController\n\n  __MapController.$inject = [\n    '$scope', '$element', '$attrs', '$parse', '$interpolate', 'Attr2MapOptions', 'NgMap', 'NgMapPool', 'escapeRegexpFilter'\n  ];\n  angular.module('ngMap').controller('__MapController', __MapController);\n})();\n\n/**\n * @ngdoc directive\n * @name bicycling-layer\n * @param Attr2Options {service}\n *   convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n *\n *   <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *     <bicycling-layer></bicycling-layer>\n *    </map>\n */\n(function() {\n  'use strict';\n  var parser;\n\n  var linkFunc = function(scope, element, attrs, mapController) {\n    mapController = mapController[0]||mapController[1];\n    var orgAttrs = parser.orgAttributes(element);\n    var filtered = parser.filter(attrs);\n    var options = parser.getOptions(filtered, {scope: scope});\n    var events = parser.getEvents(scope, filtered);\n\n    void 0;\n\n    var layer = getLayer(options, events);\n    mapController.addObject('bicyclingLayers', layer);\n    mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers\n    element.bind('$destroy', function() {\n      mapController.deleteObject('bicyclingLayers', layer);\n    });\n  };\n\n  var getLayer = function(options, events) {\n    var layer = new google.maps.BicyclingLayer(options);\n    for (var eventName in events) {\n      google.maps.event.addListener(layer, eventName, events[eventName]);\n    }\n    return layer;\n  };\n\n  var bicyclingLayer= function(Attr2MapOptions) {\n    parser = Attr2MapOptions;\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n     };\n  };\n  bicyclingLayer.$inject = ['Attr2MapOptions'];\n\n  angular.module('ngMap').directive('bicyclingLayer', bicyclingLayer);\n})();\n\n/**\n * @ngdoc directive\n * @name custom-control\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @param $compile {service} AngularJS $compile service\n * @description\n *   Build custom control and set to the map with position\n *\n *   Requires:  map directive\n *\n *   Restrict To:  Element\n *\n * @attr {String} position position of this control\n *        i.e. TOP_RIGHT\n * @attr {Number} index index of the control\n * @example\n *\n * Example:\n *  <map center=\"41.850033,-87.6500523\" zoom=\"3\">\n *    <custom-control id=\"home\" position=\"TOP_LEFT\" index=\"1\">\n *      <div style=\"background-color: white;\">\n *        <b>Home</b>\n *      </div>\n *    </custom-control>\n *  </map>\n *\n */\n(function() {\n  'use strict';\n  var parser, NgMap;\n\n  var linkFunc = function(scope, element, attrs, mapController, $transclude) {\n    mapController = mapController[0]||mapController[1];\n    var filtered = parser.filter(attrs);\n    var options = parser.getOptions(filtered, {scope: scope});\n    var events = parser.getEvents(scope, filtered);\n\n    /**\n     * build a custom control element\n     */\n    var customControlEl = element[0].parentElement.removeChild(element[0]);\n    var content = $transclude();\n    angular.element(customControlEl).append(content);\n\n    /**\n     * set events\n     */\n    for (var eventName in events) {\n      google.maps.event.addDomListener(customControlEl, eventName, events[eventName]);\n    }\n\n    mapController.addObject('customControls', customControlEl);\n    var position = options.position;\n    mapController.map.controls[google.maps.ControlPosition[position]].push(customControlEl);\n\n    element.bind('$destroy', function() {\n      mapController.deleteObject('customControls', customControlEl);\n    });\n  };\n\n  var customControl =  function(Attr2MapOptions, _NgMap_)  {\n    parser = Attr2MapOptions, NgMap = _NgMap_;\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc,\n      transclude: true\n    }; // return\n  };\n  customControl.$inject = ['Attr2MapOptions', 'NgMap'];\n\n  angular.module('ngMap').directive('customControl', customControl);\n})();\n\n/**\n * @ngdoc directive\n * @memberof ngmap\n * @name custom-marker\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @param $timeout {service} AngularJS $timeout\n * @description\n *   Marker with html\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @attr {String} position required, position on map\n * @attr {Number} z-index optional\n * @attr {Boolean} visible optional\n * @example\n *\n * Example:\n *   <map center=\"41.850033,-87.6500523\" zoom=\"3\">\n *     <custom-marker position=\"41.850033,-87.6500523\">\n *       <div>\n *         <b>Home</b>\n *       </div>\n *     </custom-marker>\n *   </map>\n *\n */\n/* global document */\n(function() {\n  'use strict';\n  var parser, $timeout, $compile, NgMap;\n\n  var CustomMarker = function(options) {\n    options = options || {};\n\n    this.el = document.createElement('div');\n    this.el.style.display = 'inline-block';\n    this.el.style.visibility = \"hidden\";\n    this.visible = true;\n    for (var key in options) { /* jshint ignore:line */\n     this[key] = options[key];\n    }\n  };\n\n  var setCustomMarker = function() {\n\n    CustomMarker.prototype = new google.maps.OverlayView();\n\n    CustomMarker.prototype.setContent = function(html, scope) {\n      this.el.innerHTML = html;\n      this.el.style.position = 'absolute';\n      if (scope) {\n        $compile(angular.element(this.el).contents())(scope);\n      }\n    };\n\n    CustomMarker.prototype.getDraggable = function() {\n      return this.draggable;\n    };\n\n    CustomMarker.prototype.setDraggable = function(draggable) {\n      this.draggable = draggable;\n    };\n\n    CustomMarker.prototype.getPosition = function() {\n      return this.position;\n    };\n\n    CustomMarker.prototype.setPosition = function(position) {\n      position && (this.position = position); /* jshint ignore:line */\n      var _this = this;\n      if (this.getProjection() && typeof this.position.lng == 'function') {\n        void 0;\n        var setPosition = function() {\n          if (!_this.getProjection()) { return; }\n          var posPixel = _this.getProjection().fromLatLngToDivPixel(_this.position);\n          var x = Math.round(posPixel.x - (_this.el.offsetWidth/2));\n          var y = Math.round(posPixel.y - _this.el.offsetHeight - 10); // 10px for anchor\n          _this.el.style.left = x + \"px\";\n          _this.el.style.top = y + \"px\";\n          _this.el.style.visibility = \"visible\";\n        };\n        if (_this.el.offsetWidth && _this.el.offsetHeight) {\n          setPosition();\n        } else {\n          //delayed left/top calculation when width/height are not set instantly\n          $timeout(setPosition, 300);\n        }\n      }\n    };\n\n    CustomMarker.prototype.setZIndex = function(zIndex) {\n      zIndex && (this.zIndex = zIndex); /* jshint ignore:line */\n      this.el.style.zIndex = this.zIndex;\n    };\n\n    CustomMarker.prototype.getVisible = function() {\n      return this.visible;\n    };\n\n    CustomMarker.prototype.setVisible = function(visible) {\n      this.el.style.display = visible ? 'inline-block' : 'none';\n      this.visible = visible;\n    };\n\n    CustomMarker.prototype.addClass = function(className) {\n      var classNames = this.el.className.trim().split(' ');\n      (classNames.indexOf(className) == -1) && classNames.push(className); /* jshint ignore:line */\n      this.el.className = classNames.join(' ');\n    };\n\n    CustomMarker.prototype.removeClass = function(className) {\n      var classNames = this.el.className.split(' ');\n      var index = classNames.indexOf(className);\n      (index > -1) && classNames.splice(index, 1); /* jshint ignore:line */\n      this.el.className = classNames.join(' ');\n    };\n\n    CustomMarker.prototype.onAdd = function() {\n      this.getPanes().overlayMouseTarget.appendChild(this.el);\n    };\n\n    CustomMarker.prototype.draw = function() {\n      this.setPosition();\n      this.setZIndex(this.zIndex);\n      this.setVisible(this.visible);\n    };\n\n    CustomMarker.prototype.onRemove = function() {\n      this.el.parentNode.removeChild(this.el);\n      //this.el = null;\n    };\n  };\n\n  var linkFunc = function(orgHtml, varsToWatch) {\n    //console.log('orgHtml', orgHtml, 'varsToWatch', varsToWatch);\n\n    return function(scope, element, attrs, mapController) {\n      mapController = mapController[0]||mapController[1];\n      var orgAttrs = parser.orgAttributes(element);\n\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var events = parser.getEvents(scope, filtered);\n\n      /**\n       * build a custom marker element\n       */\n      element[0].style.display = 'none';\n      void 0;\n      var customMarker = new CustomMarker(options);\n\n      $timeout(function() { //apply contents, class, and location after it is compiled\n\n        scope.$watch('[' + varsToWatch.join(',') + ']', function() {\n          customMarker.setContent(orgHtml, scope);\n        }, true);\n\n        customMarker.setContent(element[0].innerHTML, scope);\n        var classNames = element[0].firstElementChild.className;\n        customMarker.addClass('custom-marker');\n        customMarker.addClass(classNames);\n        void 0;\n\n        if (!(options.position instanceof google.maps.LatLng)) {\n          NgMap.getGeoLocation(options.position).then(\n                function(latlng) {\n                  customMarker.setPosition(latlng);\n                }\n          );\n        }\n\n      });\n\n      void 0;\n      for (var eventName in events) { /* jshint ignore:line */\n        google.maps.event.addDomListener(\n          customMarker.el, eventName, events[eventName]);\n      }\n      mapController.addObject('customMarkers', customMarker);\n\n      //set observers\n      mapController.observeAttrSetObj(orgAttrs, attrs, customMarker);\n\n      element.bind('$destroy', function() {\n        //Is it required to remove event listeners when DOM is removed?\n        mapController.deleteObject('customMarkers', customMarker);\n      });\n\n    }; // linkFunc\n  };\n\n\n  var customMarkerDirective = function(\n      _$timeout_, _$compile_, $interpolate, Attr2MapOptions, _NgMap_, escapeRegExp\n    )  {\n    parser = Attr2MapOptions;\n    $timeout = _$timeout_;\n    $compile = _$compile_;\n    NgMap = _NgMap_;\n\n    var exprStartSymbol = $interpolate.startSymbol();\n    var exprEndSymbol = $interpolate.endSymbol();\n    var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '([^' + exprEndSymbol.substring(0, 1) + ']+)' + escapeRegExp(exprEndSymbol), 'g');\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      compile: function(element) {\n        setCustomMarker();\n        element[0].style.display ='none';\n        var orgHtml = element.html();\n        var matches = orgHtml.match(exprRegExp);\n        var varsToWatch = [];\n        //filter out that contains '::', 'this.'\n        (matches || []).forEach(function(match) {\n          var toWatch = match.replace(exprStartSymbol,'').replace(exprEndSymbol,'');\n          if (match.indexOf('::') == -1 &&\n            match.indexOf('this.') == -1 &&\n            varsToWatch.indexOf(toWatch) == -1) {\n            varsToWatch.push(match.replace(exprStartSymbol,'').replace(exprEndSymbol,''));\n          }\n        });\n\n        return linkFunc(orgHtml, varsToWatch);\n      }\n    }; // return\n  };// function\n  customMarkerDirective.$inject =\n    ['$timeout', '$compile', '$interpolate', 'Attr2MapOptions', 'NgMap', 'escapeRegexpFilter'];\n\n  angular.module('ngMap').directive('customMarker', customMarkerDirective);\n})();\n\n/**\n * @ngdoc directive\n * @name directions\n * @description\n *   Enable directions on map.\n *   e.g., origin, destination, draggable, waypoints, etc\n *\n *   Requires:  map directive\n *\n *   Restrict To:  Element\n *\n * @attr {String} DirectionsRendererOptions\n *   [Any DirectionsRendererOptions](https://developers.google.com/maps/documentation/javascript/reference#DirectionsRendererOptions)\n * @attr {String} DirectionsRequestOptions\n *   [Any DirectionsRequest options](https://developers.google.com/maps/documentation/javascript/reference#DirectionsRequest)\n * @example\n *  <map zoom=\"14\" center=\"37.7699298, -122.4469157\">\n *    <directions\n *      draggable=\"true\"\n *      panel=\"directions-panel\"\n *      travel-mode=\"{{travelMode}}\"\n *      waypoints=\"[{location:'kingston', stopover:true}]\"\n *      origin=\"{{origin}}\"\n *      destination=\"{{destination}}\">\n *    </directions>\n *  </map>\n */\n/* global document */\n(function() {\n  'use strict';\n  var NgMap, $timeout, NavigatorGeolocation;\n\n  var getDirectionsRenderer = function(options, events) {\n    if (options.panel) {\n      options.panel = document.getElementById(options.panel) ||\n        document.querySelector(options.panel);\n    }\n    var renderer = new google.maps.DirectionsRenderer(options);\n    for (var eventName in events) {\n      google.maps.event.addListener(renderer, eventName, events[eventName]);\n    }\n    return renderer;\n  };\n\n  var updateRoute = function(renderer, options) {\n    var directionsService = new google.maps.DirectionsService();\n\n    /* filter out valid keys only for DirectionsRequest object*/\n    var request = options;\n    request.travelMode = request.travelMode || 'DRIVING';\n    var validKeys = [\n      'origin', 'destination', 'travelMode', 'transitOptions', 'unitSystem',\n      'durationInTraffic', 'waypoints', 'optimizeWaypoints', \n      'provideRouteAlternatives', 'avoidHighways', 'avoidTolls', 'region'\n    ];\n    for(var key in request){\n      (validKeys.indexOf(key) === -1) && (delete request[key]);\n    }\n\n    if(request.waypoints) {\n      // Check fo valid values\n      if(request.waypoints == \"[]\" || request.waypoints === \"\") {\n        delete request.waypoints;\n      }\n    }\n\n    var showDirections = function(request) {\n      directionsService.route(request, function(response, status) {\n        if (status == google.maps.DirectionsStatus.OK) {\n          $timeout(function() {\n            renderer.setDirections(response);\n          });\n        }\n      });\n    };\n\n    if (request.origin && request.destination) {\n      if (request.origin == 'current-location') {\n        NavigatorGeolocation.getCurrentPosition().then(function(ll) {\n          request.origin = new google.maps.LatLng(ll.coords.latitude, ll.coords.longitude);\n          showDirections(request);\n        });\n      } else if (request.destination == 'current-location') {\n        NavigatorGeolocation.getCurrentPosition().then(function(ll) {\n          request.destination = new google.maps.LatLng(ll.coords.latitude, ll.coords.longitude);\n          showDirections(request);\n        });\n      } else {\n        showDirections(request);\n      }\n    }\n  };\n\n  var directions = function(\n      Attr2MapOptions, _$timeout_, _NavigatorGeolocation_, _NgMap_) {\n    var parser = Attr2MapOptions;\n    NgMap = _NgMap_;\n    $timeout = _$timeout_;\n    NavigatorGeolocation = _NavigatorGeolocation_;\n\n    var linkFunc = function(scope, element, attrs, mapController) {\n      mapController = mapController[0]||mapController[1];\n\n      var orgAttrs = parser.orgAttributes(element);\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var events = parser.getEvents(scope, filtered);\n      var attrsToObserve = parser.getAttrsToObserve(orgAttrs);\n\n      var renderer = getDirectionsRenderer(options, events);\n      mapController.addObject('directionsRenderers', renderer);\n\n      attrsToObserve.forEach(function(attrName) {\n        (function(attrName) {\n          attrs.$observe(attrName, function(val) {\n            if (attrName == 'panel') {\n              $timeout(function(){\n                var panel =\n                  document.getElementById(val) || document.querySelector(val);\n                void 0;\n                panel && renderer.setPanel(panel);\n              });\n            } else if (options[attrName] !== val) { //apply only if changed\n              var optionValue = parser.toOptionValue(val, {key: attrName});\n              void 0;\n              options[attrName] = optionValue;\n              updateRoute(renderer, options);\n            }\n          });\n        })(attrName);\n      });\n\n      NgMap.getMap().then(function() {\n        updateRoute(renderer, options);\n      });\n      element.bind('$destroy', function() {\n        mapController.deleteObject('directionsRenderers', renderer);\n      });\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n    };\n  }; // var directions\n  directions.$inject =\n    ['Attr2MapOptions', '$timeout', 'NavigatorGeolocation', 'NgMap'];\n\n  angular.module('ngMap').directive('directions', directions);\n})();\n\n\n/**\n * @ngdoc directive\n * @name drawing-manager\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n *  <map zoom=\"13\" center=\"37.774546, -122.433523\" map-type-id=\"SATELLITE\">\n *    <drawing-manager\n *      on-overlaycomplete=\"onMapOverlayCompleted()\"\n *      position=\"ControlPosition.TOP_CENTER\"\n *      drawingModes=\"POLYGON,CIRCLE\"\n *      drawingControl=\"true\"\n *      circleOptions=\"fillColor: '#FFFF00';fillOpacity: 1;strokeWeight: 5;clickable: false;zIndex: 1;editable: true;\" >\n *    </drawing-manager>\n *  </map>\n *\n *  TODO: Add remove button.\n *  currently, for our solution, we have the shapes/markers in our own\n *  controller, and we use some css classes to change the shape button\n *  to a remove button (<div>X</div>) and have the remove operation in our own controller.\n */\n(function() {\n  'use strict';\n  angular.module('ngMap').directive('drawingManager', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var controlOptions = parser.getControlOptions(filtered);\n        var events = parser.getEvents(scope, filtered);\n\n        /**\n         * set options\n         */\n        var drawingManager = new google.maps.drawing.DrawingManager({\n          drawingMode: options.drawingmode,\n          drawingControl: options.drawingcontrol,\n          drawingControlOptions: controlOptions.drawingControlOptions,\n          circleOptions:options.circleoptions,\n          markerOptions:options.markeroptions,\n          polygonOptions:options.polygonoptions,\n          polylineOptions:options.polylineoptions,\n          rectangleOptions:options.rectangleoptions\n        });\n\n        //Observers\n        attrs.$observe('drawingControlOptions', function (newValue) {\n          drawingManager.drawingControlOptions = parser.getControlOptions({drawingControlOptions: newValue}).drawingControlOptions;\n          drawingManager.setDrawingMode(null);\n          drawingManager.setMap(mapController.map);\n        });\n\n\n        /**\n         * set events\n         */\n        for (var eventName in events) {\n          google.maps.event.addListener(drawingManager, eventName, events[eventName]);\n        }\n\n        mapController.addObject('mapDrawingManager', drawingManager);\n\n        element.bind('$destroy', function() {\n          mapController.deleteObject('mapDrawingManager', drawingManager);\n        });\n      }\n    }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name dynamic-maps-engine-layer\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *   <map zoom=\"14\" center=\"[59.322506, 18.010025]\">\n *     <dynamic-maps-engine-layer\n *       layer-id=\"06673056454046135537-08896501997766553811\">\n *     </dynamic-maps-engine-layer>\n *    </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('dynamicMapsEngineLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getDynamicMapsEngineLayer = function(options, events) {\n      var layer = new google.maps.visualization.DynamicMapsEngineLayer(options);\n\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered, events);\n\n        var layer = getDynamicMapsEngineLayer(options, events);\n        mapController.addObject('mapsEngineLayers', layer);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name fusion-tables-layer\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *   <map zoom=\"11\" center=\"41.850033, -87.6500523\">\n *     <fusion-tables-layer query=\"{\n *       select: 'Geocodable address',\n *       from: '1mZ53Z70NsChnBMm-qEYmSDOvLXgrreLTkQUvvg'}\">\n *     </fusion-tables-layer>\n *   </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('fusionTablesLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getLayer = function(options, events) {\n      var layer = new google.maps.FusionTablesLayer(options);\n\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered, events);\n        void 0;\n\n        var layer = getLayer(options, events);\n        mapController.addObject('fusionTablesLayers', layer);\n        element.bind('$destroy', function() {\n          mapController.deleteObject('fusionTablesLayers', layer);\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name heatmap-layer\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n *\n * <map zoom=\"11\" center=\"[41.875696,-87.624207]\">\n *   <heatmap-layer data=\"taxiData\"></heatmap-layer>\n * </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('heatmapLayer', [\n    'Attr2MapOptions', '$window', function(Attr2MapOptions, $window) {\n    var parser = Attr2MapOptions;\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n\n        /**\n         * set options\n         */\n        var options = parser.getOptions(filtered, {scope: scope});\n        options.data = $window[attrs.data] || scope[attrs.data];\n        if (options.data instanceof Array) {\n          options.data = new google.maps.MVCArray(options.data);\n        } else {\n          throw \"invalid heatmap data\";\n        }\n        var layer = new google.maps.visualization.HeatmapLayer(options);\n\n        /**\n         * set events\n         */\n        var events = parser.getEvents(scope, filtered);\n        void 0;\n\n        mapController.addObject('heatmapLayers', layer);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name info-window\n * @param Attr2MapOptions {service}\n *   convert html attribute to Google map api options\n * @param $compile {service} $compile service\n * @description\n *  Defines infoWindow and provides compile method\n *\n *  Requires:  map directive\n *\n *  Restrict To:  Element\n *\n *  NOTE: this directive should **NOT** be used with `ng-repeat`\n *  because InfoWindow itself is a template, and a template must be\n *  reused by each marker, thus, should not be redefined repeatedly\n *  by `ng-repeat`.\n *\n * @attr {Boolean} visible\n *   Indicates to show it when map is initialized\n * @attr {Boolean} visible-on-marker\n *   Indicates to show it on a marker when map is initialized\n * @attr {Expression} geo-callback\n *   if position is an address, the expression is will be performed\n *   when geo-lookup is successful. e.g., geo-callback=\"showDetail()\"\n * @attr {String} &lt;InfoWindowOption> Any InfoWindow options,\n *   https://developers.google.com/maps/documentation/javascript/reference?csw=1#InfoWindowOptions\n * @attr {String} &lt;InfoWindowEvent> Any InfoWindow events,\n *   https://developers.google.com/maps/documentation/javascript/reference\n * @example\n * Usage:\n *   <map MAP_ATTRIBUTES>\n *    <info-window id=\"foo\" ANY_OPTIONS ANY_EVENTS\"></info-window>\n *   </map>\n *\n * Example:\n *  <map center=\"41.850033,-87.6500523\" zoom=\"3\">\n *    <info-window id=\"1\" position=\"41.850033,-87.6500523\" >\n *      <div ng-non-bindable>\n *        Chicago, IL<br/>\n *        LatLng: {{chicago.lat()}}, {{chicago.lng()}}, <br/>\n *        World Coordinate: {{worldCoordinate.x}}, {{worldCoordinate.y}}, <br/>\n *        Pixel Coordinate: {{pixelCoordinate.x}}, {{pixelCoordinate.y}}, <br/>\n *        Tile Coordinate: {{tileCoordinate.x}}, {{tileCoordinate.y}} at Zoom Level {{map.getZoom()}}\n *      </div>\n *    </info-window>\n *  </map>\n */\n/* global google */\n(function() {\n  'use strict';\n\n  var infoWindow = function(Attr2MapOptions, $compile, $q, $templateRequest, $timeout, $parse, NgMap)  {\n    var parser = Attr2MapOptions;\n\n    var getInfoWindow = function(options, events, element) {\n      var infoWindow;\n\n      /**\n       * set options\n       */\n      if (options.position && !(options.position instanceof google.maps.LatLng)) {\n        delete options.position;\n      }\n      infoWindow = new google.maps.InfoWindow(options);\n\n      /**\n       * set events\n       */\n      for (var eventName in events) {\n        if (eventName) {\n          google.maps.event.addListener(infoWindow, eventName, events[eventName]);\n        }\n      }\n\n      /**\n       * set template and template-related functions\n       * it must have a container element with ng-non-bindable\n       */\n      var templatePromise = $q(function(resolve) {\n        if (angular.isString(element)) {\n          $templateRequest(element).then(function (requestedTemplate) {\n            resolve(angular.element(requestedTemplate).wrap('<div>').parent());\n          }, function(message) {\n            throw \"info-window template request failed: \" + message;\n          });\n        }\n        else {\n          resolve(element);\n        }\n      }).then(function(resolvedTemplate) {\n        var template = resolvedTemplate.html().trim();\n        if (angular.element(template).length != 1) {\n          throw \"info-window working as a template must have a container\";\n        }\n        infoWindow.__template = template.replace(/\\s?ng-non-bindable[='\"]+/,\"\");\n      });\n\n      infoWindow.__open = function(map, scope, anchor) {\n        templatePromise.then(function() {\n          $timeout(function() {\n            anchor && (scope.anchor = anchor);\n            var el = $compile(infoWindow.__template)(scope);\n            infoWindow.setContent(el[0]);\n            scope.$apply();\n            if (anchor && anchor.getPosition) {\n              infoWindow.open(map, anchor);\n            } else if (anchor && anchor instanceof google.maps.LatLng) {\n              infoWindow.open(map);\n              infoWindow.setPosition(anchor);\n            } else {\n              infoWindow.open(map);\n            }\n            var infoWindowContainerEl = infoWindow.content.parentElement.parentElement.parentElement;\n            infoWindowContainerEl.className = \"ng-map-info-window\";\n          });\n        });\n      };\n\n      return infoWindow;\n    };\n\n    var linkFunc = function(scope, element, attrs, mapController) {\n      mapController = mapController[0]||mapController[1];\n\n      element.css('display','none');\n\n      var orgAttrs = parser.orgAttributes(element);\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var events = parser.getEvents(scope, filtered);\n\n      var infoWindow = getInfoWindow(options, events, options.template || element);\n      var address;\n      if (options.position && !(options.position instanceof google.maps.LatLng)) {\n        address = options.position;\n      }\n      if (address) {\n        NgMap.getGeoLocation(address).then(function(latlng) {\n          infoWindow.setPosition(latlng);\n          infoWindow.__open(mapController.map, scope, latlng);\n          var geoCallback = attrs.geoCallback;\n          geoCallback && $parse(geoCallback)(scope);\n        });\n      }\n\n      mapController.addObject('infoWindows', infoWindow);\n      mapController.observeAttrSetObj(orgAttrs, attrs, infoWindow);\n\n      mapController.showInfoWindow =\n      mapController.map.showInfoWindow = mapController.showInfoWindow ||\n        function(p1, p2, p3) { //event, id, marker\n          var id = typeof p1 == 'string' ? p1 : p2;\n          var marker = typeof p1 == 'string' ? p2 : p3;\n          if (typeof marker == 'string') {\n            //Check if markers if defined to avoid odd 'undefined' errors\n            if (\n              typeof mapController.map.markers != \"undefined\"\n              && typeof mapController.map.markers[marker] != \"undefined\") {\n                marker = mapController.map.markers[marker];\n            } else if (\n              //additionally check if that marker is a custom marker\n              typeof mapController.map.customMarkers !== \"undefined\"\n              && typeof mapController.map.customMarkers[marker] !== \"undefined\") {\n                marker = mapController.map.customMarkers[marker];\n            } else {\n              //Better error output if marker with that id is not defined\n              throw new Error(\"Cant open info window for id \" + marker + \". Marker or CustomMarker is not defined\")\n            }\n          }\n\n          var infoWindow = mapController.map.infoWindows[id];\n          var anchor = marker ? marker : (this.getPosition ? this : null);\n          infoWindow.__open(mapController.map, scope, anchor);\n          if(mapController.singleInfoWindow) {\n            if(mapController.lastInfoWindow) {\n              scope.hideInfoWindow(mapController.lastInfoWindow);\n            }\n            mapController.lastInfoWindow = id;\n          }\n        };\n\n      mapController.hideInfoWindow =\n      mapController.map.hideInfoWindow = mapController.hideInfoWindow ||\n        function(p1, p2) {\n          var id = typeof p1 == 'string' ? p1 : p2;\n          var infoWindow = mapController.map.infoWindows[id];\n          infoWindow.close();\n        };\n\n      //TODO DEPRECATED\n      scope.showInfoWindow = mapController.map.showInfoWindow;\n      scope.hideInfoWindow = mapController.map.hideInfoWindow;\n\n      var map = infoWindow.mapId ? {id:infoWindow.mapId} : 0;\n      NgMap.getMap(map).then(function(map) {\n        infoWindow.visible && infoWindow.__open(map, scope);\n        if (infoWindow.visibleOnMarker) {\n          var markerId = infoWindow.visibleOnMarker;\n          infoWindow.__open(map, scope, map.markers[markerId]);\n        }\n      });\n\n    }; //link\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n    };\n\n  }; // infoWindow\n  infoWindow.$inject =\n    ['Attr2MapOptions', '$compile', '$q', '$templateRequest', '$timeout', '$parse', 'NgMap'];\n\n  angular.module('ngMap').directive('infoWindow', infoWindow);\n})();\n\n/**\n * @ngdoc directive\n * @name kml-layer\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   renders Kml layer on a map\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @attr {Url} url url of the kml layer\n * @attr {KmlLayerOptions} KmlLayerOptions\n *   (https://developers.google.com/maps/documentation/javascript/reference#KmlLayerOptions) \n * @attr {String} &lt;KmlLayerEvent> Any KmlLayer events,\n *   https://developers.google.com/maps/documentation/javascript/reference\n * @example\n * Usage:\n *   <map MAP_ATTRIBUTES>\n *    <kml-layer ANY_KML_LAYER ANY_KML_LAYER_EVENTS\"></kml-layer>\n *   </map>\n *\n * Example:\n *\n * <map zoom=\"11\" center=\"[41.875696,-87.624207]\">\n *   <kml-layer url=\"https://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml\" >\n *   </kml-layer>\n * </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('kmlLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getKmlLayer = function(options, events) {\n      var kmlLayer = new google.maps.KmlLayer(options);\n      for (var eventName in events) {\n        google.maps.event.addListener(kmlLayer, eventName, events[eventName]);\n      }\n      return kmlLayer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var orgAttrs = parser.orgAttributes(element);\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered);\n        void 0;\n\n        var kmlLayer = getKmlLayer(options, events);\n        mapController.addObject('kmlLayers', kmlLayer);\n        mapController.observeAttrSetObj(orgAttrs, attrs, kmlLayer);  //observers\n        element.bind('$destroy', function() {\n          mapController.deleteObject('kmlLayers', kmlLayer);\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name map-data\n * @param Attr2MapOptions {service}\n *   convert html attribute to Google map api options\n * @description\n *   set map data\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @wn {String} method-name, run map.data[method-name] with attribute value\n * @example\n * Example:\n *\n *  <map zoom=\"11\" center=\"[41.875696,-87.624207]\">\n *    <map-data load-geo-json=\"https://storage.googleapis.com/maps-devrel/google.json\"></map-data>\n *   </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('mapData', [\n    'Attr2MapOptions', 'NgMap', function(Attr2MapOptions, NgMap) {\n    var parser = Attr2MapOptions;\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0] || mapController[1];\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered, events);\n\n        void 0;\n        NgMap.getMap(mapController.map.id).then(function(map) {\n          //options\n          for (var key in options) {\n            var val = options[key];\n            if (typeof scope[val] === \"function\") {\n              map.data[key](scope[val]);\n            } else {\n              map.data[key](val);\n            }\n          }\n\n          //events\n          for (var eventName in events) {\n            map.data.addListener(eventName, events[eventName]);\n          }\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name map-lazy-load\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @description\n *  Requires: Delay the initialization of map directive\n *    until the map is ready to be rendered\n *  Restrict To: Attribute\n *\n * @attr {String} map-lazy-load\n *    Maps api script source file location.\n *    Example:\n *      'https://maps.google.com/maps/api/js'\n * @attr {String} map-lazy-load-params\n *   Maps api script source file location via angular scope variable.\n *   Also requires the map-lazy-load attribute to be present in the directive.\n *   Example: In your controller, set\n *     $scope.googleMapsURL = 'https://maps.google.com/maps/api/js?v=3.20&client=XXXXXenter-api-key-hereXXXX'\n *\n * @example\n * Example:\n *\n *   <div map-lazy-load=\"http://maps.google.com/maps/api/js\">\n *     <map center=\"Brampton\" zoom=\"10\">\n *       <marker position=\"Brampton\"></marker>\n *     </map>\n *   </div>\n *\n *   <div map-lazy-load=\"http://maps.google.com/maps/api/js\"\n *        map-lazy-load-params=\"{{googleMapsUrl}}\">\n *     <map center=\"Brampton\" zoom=\"10\">\n *       <marker position=\"Brampton\"></marker>\n *     </map>\n *   </div>\n */\n/* global window, document */\n(function() {\n  'use strict';\n  var $timeout, $compile, src, savedHtml = [], elements = [];\n\n  var preLinkFunc = function(scope, element, attrs) {\n    var mapsUrl = attrs.mapLazyLoadParams || attrs.mapLazyLoad;\n\n    if(window.google === undefined || window.google.maps === undefined) {\n      elements.push({\n        scope: scope,\n        element: element,\n        savedHtml: savedHtml[elements.length],\n      });\n\n      window.lazyLoadCallback = function() {\n        void 0;\n        $timeout(function() { /* give some time to load */\n          elements.forEach(function(elm) {\n              elm.element.html(elm.savedHtml);\n              $compile(elm.element.contents())(elm.scope);\n          });\n        }, 100);\n      };\n\n      var scriptEl = document.createElement('script');\n      void 0;\n\n      scriptEl.src = mapsUrl +\n        (mapsUrl.indexOf('?') > -1 ? '&' : '?') +\n        'callback=lazyLoadCallback';\n\n        if (!document.querySelector('script[src=\"' + scriptEl.src + '\"]')) {\n          document.body.appendChild(scriptEl);\n        }\n    } else {\n      element.html(savedHtml);\n      $compile(element.contents())(scope);\n    }\n  };\n\n  var compileFunc = function(tElement, tAttrs) {\n\n    (!tAttrs.mapLazyLoad) && void 0;\n    savedHtml.push(tElement.html());\n    src = tAttrs.mapLazyLoad;\n\n    /**\n     * if already loaded, stop processing it\n     */\n    if(window.google !== undefined && window.google.maps !== undefined) {\n      return false;\n    }\n\n    tElement.html('');  // will compile again after script is loaded\n\n    return {\n      pre: preLinkFunc\n    };\n  };\n\n  var mapLazyLoad = function(_$compile_, _$timeout_) {\n    $compile = _$compile_, $timeout = _$timeout_;\n    return {\n      compile: compileFunc\n    };\n  };\n  mapLazyLoad.$inject = ['$compile','$timeout'];\n\n  angular.module('ngMap').directive('mapLazyLoad', mapLazyLoad);\n})();\n\n/**\n * @ngdoc directive\n * @name map-type\n * @param Attr2MapOptions {service} \n *   convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n *   <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *     <map-type name=\"coordinate\" object=\"coordinateMapType\"></map-type>\n *   </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('mapType', ['$parse', 'NgMap',\n    function($parse, NgMap) {\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var mapTypeName = attrs.name, mapTypeObject;\n        if (!mapTypeName) {\n          throw \"invalid map-type name\";\n        }\n        mapTypeObject = $parse(attrs.object)(scope);\n        if (!mapTypeObject) {\n          throw \"invalid map-type object\";\n        }\n\n        NgMap.getMap().then(function(map) {\n          map.mapTypes.set(mapTypeName, mapTypeObject);\n        });\n        mapController.addObject('mapTypes', mapTypeObject);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @memberof ngMap\n * @name ng-map\n * @param Attr2Options {service}\n *  convert html attribute to Google map api options\n * @description\n * Implementation of {@link __MapController}\n * Initialize a Google map within a `<div>` tag\n *   with given options and register events\n *\n * @attr {Expression} map-initialized\n *   callback function when map is initialized\n *   e.g., map-initialized=\"mycallback(map)\"\n * @attr {Expression} geo-callback if center is an address or current location,\n *   the expression is will be executed when geo-lookup is successful.\n *   e.g., geo-callback=\"showMyStoreInfo()\"\n * @attr {Array} geo-fallback-center\n *   The center of map incase geolocation failed. i.e. [0,0]\n * @attr {Object} geo-location-options\n *  The navigator geolocation options.\n *  e.g., { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }.\n *  If none specified, { timeout: 5000 }.\n *  If timeout not specified, timeout: 5000 added\n * @attr {Boolean} zoom-to-include-markers\n *  When true, map boundary will be changed automatially\n *  to include all markers when initialized\n * @attr {Boolean} default-style\n *  When false, the default styling,\n *  `display:block;height:300px`, will be ignored.\n * @attr {String} &lt;MapOption> Any Google map options,\n *  https://developers.google.com/maps/documentation/javascript/reference?csw=1#MapOptions\n * @attr {String} &lt;MapEvent> Any Google map events,\n *  https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/map_events.html\n * @attr {Boolean} single-info-window\n *  When true the map will only display one info window at the time,\n *  if not set or false,\n *  everytime an info window is open it will be displayed with the othe one.\n * @attr {Boolean} trigger-resize\n *  Default to false.  Set to true to trigger resize of the map.  Needs to be done anytime you resize the map\n * @example\n * Usage:\n *   <map MAP_OPTIONS_OR_MAP_EVENTS ..>\n *     ... Any children directives\n *   </map>\n *\n * Example:\n *   <map center=\"[40.74, -74.18]\" on-click=\"doThat()\">\n *   </map>\n *\n *   <map geo-fallback-center=\"[40.74, -74.18]\" zoom-to-inlude-markers=\"true\">\n *   </map>\n */\n(function () {\n  'use strict';\n\n  var mapDirective = function () {\n    return {\n      restrict: 'AE',\n      controller: '__MapController',\n      controllerAs: 'ngmap'\n    };\n  };\n\n  angular.module('ngMap').directive('map', [mapDirective]);\n  angular.module('ngMap').directive('ngMap', [mapDirective]);\n})();\n\n/**\n * @ngdoc directive\n * @name maps-engine-layer\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *  <map zoom=\"14\" center=\"[59.322506, 18.010025]\">\n *    <maps-engine-layer layer-id=\"06673056454046135537-08896501997766553811\">\n *    </maps-engine-layer>\n *  </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('mapsEngineLayer', ['Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getMapsEngineLayer = function(options, events) {\n      var layer = new google.maps.visualization.MapsEngineLayer(options);\n\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered, events);\n        void 0;\n\n        var layer = getMapsEngineLayer(options, events);\n        mapController.addObject('mapsEngineLayers', layer);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name marker\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @param NavigatorGeolocation It is used to find the current location\n * @description\n *  Draw a Google map marker on a map with given options and register events\n *\n *  Requires:  map directive\n *\n *  Restrict To:  Element\n *\n * @attr {String} position address, 'current', or [latitude, longitude]\n *  example:\n *    '1600 Pennsylvania Ave, 20500  Washingtion DC',\n *    'current position',\n *    '[40.74, -74.18]'\n * @attr {Boolean} centered if set, map will be centered with this marker\n * @attr {Expression} geo-callback if position is an address,\n *   the expression is will be performed when geo-lookup is successful.\n *   e.g., geo-callback=\"showStoreInfo()\"\n * @attr {Boolean} no-watcher if true, no attribute observer is added.\n *   Useful for many ng-repeat\n * @attr {String} &lt;MarkerOption>\n *   [Any Marker options](https://developers.google.com/maps/documentation/javascript/reference?csw=1#MarkerOptions)\n * @attr {String} &lt;MapEvent>\n *   [Any Marker events](https://developers.google.com/maps/documentation/javascript/reference)\n * @example\n * Usage:\n *   <map MAP_ATTRIBUTES>\n *    <marker ANY_MARKER_OPTIONS ANY_MARKER_EVENTS\"></MARKER>\n *   </map>\n *\n * Example:\n *   <map center=\"[40.74, -74.18]\">\n *    <marker position=\"[40.74, -74.18]\" on-click=\"myfunc()\"></div>\n *   </map>\n *\n *   <map center=\"the cn tower\">\n *    <marker position=\"the cn tower\" on-click=\"myfunc()\"></div>\n *   </map>\n */\n/* global google */\n(function() {\n  'use strict';\n  var parser, $parse, NgMap;\n\n  var getMarker = function(options, events) {\n    var marker;\n\n    if (NgMap.defaultOptions.marker) {\n      for (var key in NgMap.defaultOptions.marker) {\n        if (typeof options[key] == 'undefined') {\n          void 0;\n          options[key] = NgMap.defaultOptions.marker[key];\n        }\n      }\n    }\n\n    if (!(options.position instanceof google.maps.LatLng)) {\n      options.position = new google.maps.LatLng(0,0);\n    }\n    marker = new google.maps.Marker(options);\n\n    /**\n     * set events\n     */\n    if (Object.keys(events).length > 0) {\n      void 0;\n    }\n    for (var eventName in events) {\n      if (eventName) {\n        google.maps.event.addListener(marker, eventName, events[eventName]);\n      }\n    }\n\n    return marker;\n  };\n\n  var linkFunc = function(scope, element, attrs, mapController) {\n    mapController = mapController[0]||mapController[1];\n\n    var orgAttrs = parser.orgAttributes(element);\n    var filtered = parser.filter(attrs);\n    var markerOptions = parser.getOptions(filtered, scope, {scope: scope});\n    var markerEvents = parser.getEvents(scope, filtered);\n    void 0;\n\n    var address;\n    if (!(markerOptions.position instanceof google.maps.LatLng)) {\n      address = markerOptions.position;\n    }\n    var marker = getMarker(markerOptions, markerEvents);\n    mapController.addObject('markers', marker);\n    if (address) {\n      NgMap.getGeoLocation(address).then(function(latlng) {\n        marker.setPosition(latlng);\n        markerOptions.centered && marker.map.setCenter(latlng);\n        var geoCallback = attrs.geoCallback;\n        geoCallback && $parse(geoCallback)(scope);\n      });\n    }\n\n    //set observers\n    mapController.observeAttrSetObj(orgAttrs, attrs, marker); /* observers */\n\n    element.bind('$destroy', function() {\n      mapController.deleteObject('markers', marker);\n    });\n  };\n\n  var marker = function(Attr2MapOptions, _$parse_, _NgMap_) {\n    parser = Attr2MapOptions;\n    $parse = _$parse_;\n    NgMap = _NgMap_;\n\n    return {\n      restrict: 'E',\n      require: ['^?map','?^ngMap'],\n      link: linkFunc\n    };\n  };\n\n  marker.$inject = ['Attr2MapOptions', '$parse', 'NgMap'];\n  angular.module('ngMap').directive('marker', marker);\n\n})();\n\n/**\n * @ngdoc directive\n * @name overlay-map-type\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @param $window {service}\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n * <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *   <overlay-map-type index=\"0\" object=\"coordinateMapType\"></map-type>\n * </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('overlayMapType', [\n    'NgMap', function(NgMap) {\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var initMethod = attrs.initMethod || \"insertAt\";\n        var overlayMapTypeObject = scope[attrs.object];\n\n        NgMap.getMap().then(function(map) {\n          if (initMethod == \"insertAt\") {\n            var index = parseInt(attrs.index, 10);\n            map.overlayMapTypes.insertAt(index, overlayMapTypeObject);\n          } else if (initMethod == \"push\") {\n            map.overlayMapTypes.push(overlayMapTypeObject);\n          }\n        });\n        mapController.addObject('overlayMapTypes', overlayMapTypeObject);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name places-auto-complete\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Provides address auto complete feature to an input element\n *   Requires: input tag\n *   Restrict To: Attribute\n *\n * @attr {AutoCompleteOptions}\n *   [Any AutocompleteOptions](https://developers.google.com/maps/documentation/javascript/3.exp/reference#AutocompleteOptions)\n *\n * @example\n * Example:\n *   <script src=\"https://maps.googleapis.com/maps/api/js?libraries=places\"></script>\n *   <input places-auto-complete types=\"['geocode']\" on-place-changed=\"myCallback(place)\" component-restrictions=\"{country:'au'}\"/>\n */\n/* global google */\n(function() {\n  'use strict';\n\n  var placesAutoComplete = function(Attr2MapOptions, $timeout) {\n    var parser = Attr2MapOptions;\n\n    var linkFunc = function(scope, element, attrs, ngModelCtrl) {\n      if (attrs.placesAutoComplete ==='false') {\n        return false;\n      }\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var events = parser.getEvents(scope, filtered);\n      var autocomplete = new google.maps.places.Autocomplete(element[0], options);\n      for (var eventName in events) {\n        google.maps.event.addListener(autocomplete, eventName, events[eventName]);\n      }\n\n      var updateModel = function() {\n        $timeout(function(){\n          ngModelCtrl && ngModelCtrl.$setViewValue(element.val());\n        },100);\n      };\n      google.maps.event.addListener(autocomplete, 'place_changed', updateModel);\n      element[0].addEventListener('change', updateModel);\n\n      attrs.$observe('types', function(val) {\n        if (val) {\n          var optionValue = parser.toOptionValue(val, {key: 'types'});\n          autocomplete.setTypes(optionValue);\n        }\n      });\n\t  \n\t  attrs.$observe('componentRestrictions', function (val) {\n\t\t if (val) {\n\t\t   autocomplete.setComponentRestrictions(scope.$eval(val));\n\t\t }\n\t   });\n    };\n\t\n    return {\n      restrict: 'A',\n      require: '?ngModel',\n      link: linkFunc\n    };\n  };\n\n  placesAutoComplete.$inject = ['Attr2MapOptions', '$timeout'];\n  angular.module('ngMap').directive('placesAutoComplete', placesAutoComplete);\n})();\n\n/**\n * @ngdoc directive\n * @name shape\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Initialize a Google map shape in map with given options and register events\n *   The shapes are:\n *     . circle\n *     . polygon\n *     . polyline\n *     . rectangle\n *     . groundOverlay(or image)\n *\n *   Requires:  map directive\n *\n *   Restrict To:  Element\n *\n * @attr {Boolean} centered if set, map will be centered with this marker\n * @attr {Expression} geo-callback if shape is a circle and the center is\n *   an address, the expression is will be performed when geo-lookup\n *   is successful. e.g., geo-callback=\"showDetail()\"\n * @attr {String} &lt;OPTIONS>\n *   For circle, [any circle options](https://developers.google.com/maps/documentation/javascript/reference#CircleOptions)\n *   For polygon, [any polygon options](https://developers.google.com/maps/documentation/javascript/reference#PolygonOptions)\n *   For polyline, [any polyline options](https://developers.google.com/maps/documentation/javascript/reference#PolylineOptions)\n *   For rectangle, [any rectangle options](https://developers.google.com/maps/documentation/javascript/reference#RectangleOptions)\n *   For image, [any groundOverlay options](https://developers.google.com/maps/documentation/javascript/reference#GroundOverlayOptions)\n * @attr {String} &lt;MapEvent> [Any Shape events](https://developers.google.com/maps/documentation/javascript/reference)\n * @example\n * Usage:\n *   <map MAP_ATTRIBUTES>\n *    <shape name=SHAPE_NAME ANY_SHAPE_OPTIONS ANY_SHAPE_EVENTS\"></MARKER>\n *   </map>\n *\n * Example:\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"polyline\" name=\"polyline\" geodesic=\"true\"\n *       stroke-color=\"#FF0000\" stroke-opacity=\"1.0\" stroke-weight=\"2\"\n *       path=\"[[40.74,-74.18],[40.64,-74.10],[40.54,-74.05],[40.44,-74]]\" >\n *     </shape>\n *   </map>\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"polygon\" name=\"polygon\" stroke-color=\"#FF0000\"\n *       stroke-opacity=\"1.0\" stroke-weight=\"2\"\n *       paths=\"[[40.74,-74.18],[40.64,-74.18],[40.84,-74.08],[40.74,-74.18]]\" >\n *     </shape>\n *   </map>\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"rectangle\" name=\"rectangle\" stroke-color='#FF0000'\n *       stroke-opacity=\"0.8\" stroke-weight=\"2\"\n *       bounds=\"[[40.74,-74.18], [40.78,-74.14]]\" editable=\"true\" >\n *     </shape>\n *   </map>\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"circle\" name=\"circle\" stroke-color='#FF0000'\n *       stroke-opacity=\"0.8\"stroke-weight=\"2\"\n *       center=\"[40.70,-74.14]\" radius=\"4000\" editable=\"true\" >\n *     </shape>\n *   </map>\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"image\" name=\"image\"\n *       url=\"https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg\"\n *       bounds=\"[[40.71,-74.22],[40.77,-74.12]]\" opacity=\"0.7\"\n *       clickable=\"true\">\n *     </shape>\n *   </map>\n *\n *  For full-working example, please visit\n *    [shape example](https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/shape.html)\n */\n/* global google */\n(function() {\n  'use strict';\n\n  var getShape = function(options, events) {\n    var shape;\n\n    var shapeName = options.name;\n    delete options.name;  //remove name bcoz it's not for options\n    void 0;\n\n    /**\n     * set options\n     */\n    switch(shapeName) {\n      case \"circle\":\n        if (!(options.center instanceof google.maps.LatLng)) {\n          options.center = new google.maps.LatLng(0,0);\n        } \n        shape = new google.maps.Circle(options);\n        break;\n      case \"polygon\":\n        shape = new google.maps.Polygon(options);\n        break;\n      case \"polyline\":\n        shape = new google.maps.Polyline(options);\n        break;\n      case \"rectangle\":\n        shape = new google.maps.Rectangle(options);\n        break;\n      case \"groundOverlay\":\n      case \"image\":\n        var url = options.url;\n        var opts = {opacity: options.opacity, clickable: options.clickable, id:options.id};\n        shape = new google.maps.GroundOverlay(url, options.bounds, opts);\n        break;\n    }\n\n    /**\n     * set events\n     */\n    for (var eventName in events) {\n      if (events[eventName]) {\n        google.maps.event.addListener(shape, eventName, events[eventName]);\n      }\n    }\n    return shape;\n  };\n\n  var shape = function(Attr2MapOptions, $parse, NgMap) {\n    var parser = Attr2MapOptions;\n\n    var linkFunc = function(scope, element, attrs, mapController) {\n      mapController = mapController[0]||mapController[1];\n\n      var orgAttrs = parser.orgAttributes(element);\n      var filtered = parser.filter(attrs);\n      var shapeOptions = parser.getOptions(filtered, {scope: scope});\n      var shapeEvents = parser.getEvents(scope, filtered);\n\n      var address, shapeType;\n      shapeType = shapeOptions.name;\n      if (!(shapeOptions.center instanceof google.maps.LatLng)) {\n        address = shapeOptions.center;\n      }\n      var shape = getShape(shapeOptions, shapeEvents);\n      mapController.addObject('shapes', shape);\n\n      if (address && shapeType == 'circle') {\n        NgMap.getGeoLocation(address).then(function(latlng) {\n          shape.setCenter(latlng);\n          shape.centered && shape.map.setCenter(latlng);\n          var geoCallback = attrs.geoCallback;\n          geoCallback && $parse(geoCallback)(scope);\n        });\n      }\n\n      //set observers\n      mapController.observeAttrSetObj(orgAttrs, attrs, shape);\n      element.bind('$destroy', function() {\n        mapController.deleteObject('shapes', shape);\n      });\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n     }; // return\n  };\n  shape.$inject = ['Attr2MapOptions', '$parse', 'NgMap'];\n\n  angular.module('ngMap').directive('shape', shape);\n\n})();\n\n/**\n * @ngdoc directive\n * @name streetview-panorama\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @attr container Optional, id or css selector, if given, streetview will be in the given html element\n * @attr {String} &lt;StreetViewPanoramaOption>\n *   [Any Google StreetViewPanorama options](https://developers.google.com/maps/documentation/javascript/reference?csw=1#StreetViewPanoramaOptions)\n * @attr {String} &lt;StreetViewPanoramaEvent>\n *   [Any Google StreetViewPanorama events](https://developers.google.com/maps/documentation/javascript/reference#StreetViewPanorama)\n *\n * @example\n *   <map zoom=\"11\" center=\"[40.688738,-74.043871]\" >\n *     <street-view-panorama\n *       click-to-go=\"true\"\n *       disable-default-ui=\"true\"\n *       disable-double-click-zoom=\"true\"\n *       enable-close-button=\"true\"\n *       pano=\"my-pano\"\n *       position=\"40.688738,-74.043871\"\n *       pov=\"{heading:0, pitch: 90}\"\n *       scrollwheel=\"false\"\n *       visible=\"true\">\n *     </street-view-panorama>\n *   </map>\n */\n/* global google, document */\n(function() {\n  'use strict';\n\n  var streetViewPanorama = function(Attr2MapOptions, NgMap) {\n    var parser = Attr2MapOptions;\n\n    var getStreetViewPanorama = function(map, options, events) {\n      var svp, container;\n      if (options.container) {\n        container = document.getElementById(options.container);\n        container = container || document.querySelector(options.container);\n      }\n      if (container) {\n        svp = new google.maps.StreetViewPanorama(container, options);\n      } else {\n        svp = map.getStreetView();\n        svp.setOptions(options);\n      }\n\n      for (var eventName in events) {\n        eventName &&\n          google.maps.event.addListener(svp, eventName, events[eventName]);\n      }\n      return svp;\n    };\n\n    var linkFunc = function(scope, element, attrs) {\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var controlOptions = parser.getControlOptions(filtered);\n      var svpOptions = angular.extend(options, controlOptions);\n\n      var svpEvents = parser.getEvents(scope, filtered);\n      void 0;\n\n      NgMap.getMap().then(function(map) {\n        var svp = getStreetViewPanorama(map, svpOptions, svpEvents);\n\n        map.setStreetView(svp);\n        (!svp.getPosition()) && svp.setPosition(map.getCenter());\n        google.maps.event.addListener(svp, 'position_changed', function() {\n          if (svp.getPosition() !== map.getCenter()) {\n            map.setCenter(svp.getPosition());\n          }\n        });\n        //needed for geo-callback\n        var listener =\n          google.maps.event.addListener(map, 'center_changed', function() {\n            svp.setPosition(map.getCenter());\n            google.maps.event.removeListener(listener);\n          });\n      });\n\n    }; //link\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n    };\n\n  };\n  streetViewPanorama.$inject = ['Attr2MapOptions', 'NgMap'];\n\n  angular.module('ngMap').directive('streetViewPanorama', streetViewPanorama);\n})();\n\n/**\n * @ngdoc directive\n * @name traffic-layer\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n *   <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *     <traffic-layer></traffic-layer>\n *    </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('trafficLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getLayer = function(options, events) {\n      var layer = new google.maps.TrafficLayer(options);\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var orgAttrs = parser.orgAttributes(element);\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered);\n        void 0;\n\n        var layer = getLayer(options, events);\n        mapController.addObject('trafficLayers', layer);\n        mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers\n        element.bind('$destroy', function() {\n          mapController.deleteObject('trafficLayers', layer);\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name transit-layer\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n *  <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *    <transit-layer></transit-layer>\n *  </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('transitLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getLayer = function(options, events) {\n      var layer = new google.maps.TransitLayer(options);\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var orgAttrs = parser.orgAttributes(element);\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered);\n        void 0;\n\n        var layer = getLayer(options, events);\n        mapController.addObject('transitLayers', layer);\n        mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers\n        element.bind('$destroy', function() {\n          mapController.deleteObject('transitLayers', layer);\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc filter\n * @name camel-case\n * @description\n *   Converts string to camel cased\n */\n(function() {\n  'use strict';\n\n  var SPECIAL_CHARS_REGEXP = /([\\:\\-\\_]+(.))/g;\n  var MOZ_HACK_REGEXP = /^moz([A-Z])/;\n\n  var camelCaseFilter = function() {\n    return function(name) {\n      return name.\n        replace(SPECIAL_CHARS_REGEXP,\n          function(_, separator, letter, offset) {\n            return offset ? letter.toUpperCase() : letter;\n        }).\n        replace(MOZ_HACK_REGEXP, 'Moz$1');\n    };\n  };\n\n  angular.module('ngMap').filter('camelCase', camelCaseFilter);\n})();\n\n/**\n * @ngdoc filter\n * @name escape-regex\n * @description\n *   Escapes all regex special characters in a string\n */\n(function() {\n  'use strict';\n\n\n\n  var escapeRegexpFilter = function() {\n    return function(string) {\n\t\t\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n\t\t};\n  };\n\n  angular.module('ngMap').filter('escapeRegexp', escapeRegexpFilter);\n})();\n\n/**\n * @ngdoc filter\n * @name jsonize\n * @description\n *   Converts json-like string to json string\n */\n(function() {\n  'use strict';\n\n  var jsonizeFilter = function() {\n    return function(str) {\n      try {       // if parsable already, return as it is\n        JSON.parse(str);\n        return str;\n      } catch(e) { // if not parsable, change little\n        return str\n          // wrap keys without quote with valid double quote\n          .replace(/([\\$\\w]+)\\s*:/g,\n            function(_, $1) {\n              return '\"'+$1+'\":';\n            }\n          )\n          // replacing single quote wrapped ones to double quote\n          .replace(/'([^']+)'/g,\n            function(_, $1) {\n              return '\"'+$1+'\"';\n            }\n          )\n          .replace(/''/g, '\"\"');\n      }\n    };\n  };\n\n  angular.module('ngMap').filter('jsonize', jsonizeFilter);\n})();\n\n/**\n * @ngdoc service\n * @name Attr2MapOptions\n * @description\n *   Converts tag attributes to options used by google api v3 objects\n */\n/* global google */\n(function() {\n  'use strict';\n\n  //i.e. \"2015-08-12T06:12:40.858Z\"\n  var isoDateRE =\n    /^(\\d{4}\\-\\d\\d\\-\\d\\d([tT][\\d:\\.]*)?)([zZ]|([+\\-])(\\d\\d):?(\\d\\d))?$/;\n\n  var Attr2MapOptions = function(\n      $parse, $timeout, $log, $interpolate, NavigatorGeolocation, GeoCoder,\n      camelCaseFilter, jsonizeFilter, escapeRegExp\n    ) {\n\n    var exprStartSymbol = $interpolate.startSymbol();\n    var exprEndSymbol = $interpolate.endSymbol();\n\n    /**\n     * Returns the attributes of an element as hash\n     * @memberof Attr2MapOptions\n     * @param {HTMLElement} el html element\n     * @returns {Hash} attributes\n     */\n    var orgAttributes = function(el) {\n      (el.length > 0) && (el = el[0]);\n      var orgAttributes = {};\n      for (var i=0; i<el.attributes.length; i++) {\n        var attr = el.attributes[i];\n        orgAttributes[attr.name] = attr.value;\n      }\n      return orgAttributes;\n    };\n\n    var getJSON = function(input) {\n      var re =/^[\\+\\-]?[0-9\\.]+,[ ]*\\ ?[\\+\\-]?[0-9\\.]+$/; //lat,lng\n      if (input.match(re)) {\n        input = \"[\"+input+\"]\";\n      }\n      return JSON.parse(jsonizeFilter(input));\n    };\n    \n    var getLatLng = function(input) {\n      var output = input;\n      if (input[0].constructor == Array) { \n        if ((input[0][0].constructor == Array && input[0][0].length == 2) || input[0][0].constructor == Object) {\n            var preoutput;\n            var outputArray = [];\n            for (var i = 0; i < input.length; i++) {\n                preoutput = input[i].map(function(el){\n                    return new google.maps.LatLng(el[0], el[1]);\n                });\n                outputArray.push(preoutput);\n            }\n            output = outputArray;\n        } else {\n            output = input.map(function(el) {\n                return new google.maps.LatLng(el[0], el[1]);\n            });\n        }\n      } else if (!isNaN(parseFloat(input[0])) && isFinite(input[0])) {\n        output = new google.maps.LatLng(output[0], output[1]);\n      }\n      return output;\n    };\n\n    var toOptionValue = function(input, options) {\n      var output;\n      try { // 1. Number?\n        output = getNumber(input);\n      } catch(err) {\n        try { // 2. JSON?\n          var output = getJSON(input);\n          if (output instanceof Array) {\n            if (output[0].constructor == Object) {\n              output = output;\n            } else if (output[0] instanceof Array) {\n              if (output[0][0].constructor == Object) {\n                output = output;\n              } else {\n                output = getLatLng(output);\n              }\n            } else {\n                output = getLatLng(output);\n            }\n          }\n          // JSON is an object (not array or null)\n          else if (output === Object(output)) {\n            // check for nested hashes and convert to Google API options\n            var newOptions = options;\n            newOptions.doNotConverStringToNumber = true;\n            output = getOptions(output, newOptions);\n          }\n        } catch(err2) {\n          // 3. Google Map Object function Expression. i.e. LatLng(80,-49)\n          if (input.match(/^[A-Z][a-zA-Z0-9]+\\(.*\\)$/)) {\n            try {\n              var exp = \"new google.maps.\"+input;\n              output = eval(exp); /* jshint ignore:line */\n            } catch(e) {\n              output = input;\n            }\n          // 4. Google Map Object constant Expression. i.e. MayTypeId.HYBRID\n          } else if (input.match(/^([A-Z][a-zA-Z0-9]+)\\.([A-Z]+)$/)) {\n            try {\n              var matches = input.match(/^([A-Z][a-zA-Z0-9]+)\\.([A-Z]+)$/);\n              output = google.maps[matches[1]][matches[2]];\n            } catch(e) {\n              output = input;\n            }\n          // 5. Google Map Object constant Expression. i.e. HYBRID\n          } else if (input.match(/^[A-Z]+$/)) {\n            try {\n              var capitalizedKey = options.key.charAt(0).toUpperCase() +\n                options.key.slice(1);\n              if (options.key.match(/temperatureUnit|windSpeedUnit|labelColor/)) {\n                capitalizedKey = capitalizedKey.replace(/s$/,\"\");\n                output = google.maps.weather[capitalizedKey][input];\n              } else {\n                output = google.maps[capitalizedKey][input];\n              }\n            } catch(e) {\n              output = input;\n            }\n          // 6. Date Object as ISO String\n          } else if (input.match(isoDateRE)) {\n            try {\n              output = new Date(input);\n            } catch(e) {\n              output = input;\n            }\n          // 7. evaluate dynamically bound values\n        } else if (input.match(new RegExp('^' + escapeRegExp(exprStartSymbol))) && options.scope) {\n            try {\n              var expr = input.replace(new RegExp(escapeRegExp(exprStartSymbol)),'').replace(new RegExp(escapeRegExp(exprEndSymbol), 'g'),'');\n              output = options.scope.$eval(expr);\n            } catch (err) {\n              output = input;\n            }\n          } else {\n            output = input;\n          }\n        } // catch(err2)\n      } // catch(err)\n\n      // convert output more for center and position\n      if (\n        (options.key == 'center' || options.key == 'position') &&\n        output instanceof Array\n      ) {\n        output = new google.maps.LatLng(output[0], output[1]);\n      }\n\n      // convert output more for shape bounds\n      if (options.key == 'bounds' && output instanceof Array) {\n        output = new google.maps.LatLngBounds(output[0], output[1]);\n      }\n\n      // convert output more for shape icons\n      if (options.key == 'icons' && output instanceof Array) {\n\n        for (var i=0; i<output.length; i++) {\n          var el = output[i];\n          if (el.icon.path.match(/^[A-Z_]+$/)) {\n            el.icon.path =  google.maps.SymbolPath[el.icon.path];\n          }\n        }\n      }\n\n      // convert output more for marker icon\n      if (options.key == 'icon' && output instanceof Object) {\n        if ((\"\"+output.path).match(/^[A-Z_]+$/)) {\n          output.path = google.maps.SymbolPath[output.path];\n        }\n        for (var key in output) { //jshint ignore:line\n          var arr = output[key];\n          if (key == \"anchor\" || key == \"origin\" || key == \"labelOrigin\") {\n            output[key] = new google.maps.Point(arr[0], arr[1]);\n          } else if (key == \"size\" || key == \"scaledSize\") {\n            output[key] = new google.maps.Size(arr[0], arr[1]);\n          }\n        }\n      }\n\n      return output;\n    };\n\n    var getAttrsToObserve = function(attrs) {\n      var attrsToObserve = [];\n      var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '.*' + escapeRegExp(exprEndSymbol), 'g');\n\n      if (!attrs.noWatcher) {\n        for (var attrName in attrs) { //jshint ignore:line\n          var attrValue = attrs[attrName];\n          if (attrValue && attrValue.match(exprRegExp)) { // if attr value is {{..}}\n            attrsToObserve.push(camelCaseFilter(attrName));\n          }\n        }\n      }\n\n      return attrsToObserve;\n    };\n\n    /**\n     * filters attributes by skipping angularjs methods $.. $$..\n     * @memberof Attr2MapOptions\n     * @param {Hash} attrs tag attributes\n     * @returns {Hash} filterd attributes\n     */\n    var filter = function(attrs) {\n      var options = {};\n      for(var key in attrs) {\n        if (key.match(/^\\$/) || key.match(/^ng[A-Z]/)) {\n          void(0);\n        } else {\n          options[key] = attrs[key];\n        }\n      }\n      return options;\n    };\n\n    /**\n     * converts attributes hash to Google Maps API v3 options\n     * ```\n     *  . converts numbers to number\n     *  . converts class-like string to google maps instance\n     *    i.e. `LatLng(1,1)` to `new google.maps.LatLng(1,1)`\n     *  . converts constant-like string to google maps constant\n     *    i.e. `MapTypeId.HYBRID` to `google.maps.MapTypeId.HYBRID`\n     *    i.e. `HYBRID\"` to `google.maps.MapTypeId.HYBRID`\n     * ```\n     * @memberof Attr2MapOptions\n     * @param {Hash} attrs tag attributes\n     * @param {Hash} options\n     * @returns {Hash} options converted attributess\n     */\n    var getOptions = function(attrs, params) {\n      params = params || {};\n      var options = {};\n      for(var key in attrs) {\n        if (attrs[key] || attrs[key] === 0) {\n          if (key.match(/^on[A-Z]/)) { //skip events, i.e. on-click\n            continue;\n          } else if (key.match(/ControlOptions$/)) { // skip controlOptions\n            continue;\n          } else {\n            // nested conversions need to be typechecked\n            // (non-strings are fully converted)\n            if (typeof attrs[key] !== 'string') {\n              options[key] = attrs[key];\n            } else {\n              if (params.doNotConverStringToNumber &&\n                attrs[key].match(/^[0-9]+$/)\n              ) {\n                options[key] = attrs[key];\n              } else {\n                options[key] = toOptionValue(attrs[key], {key: key, scope: params.scope});\n              }\n            }\n          }\n        } // if (attrs[key])\n      } // for(var key in attrs)\n      return options;\n    };\n\n    /**\n     * converts attributes hash to scope-specific event function\n     * @memberof Attr2MapOptions\n     * @param {scope} scope angularjs scope\n     * @param {Hash} attrs tag attributes\n     * @returns {Hash} events converted events\n     */\n    var getEvents = function(scope, attrs) {\n      var events = {};\n      var toLowercaseFunc = function($1){\n        return \"_\"+$1.toLowerCase();\n      };\n      var EventFunc = function(attrValue) {\n        // funcName(argsStr)\n        var matches = attrValue.match(/([^\\(]+)\\(([^\\)]*)\\)/);\n        var funcName = matches[1];\n        var argsStr = matches[2].replace(/event[ ,]*/,'');  //remove string 'event'\n        var argsExpr = $parse(\"[\"+argsStr+\"]\"); //for perf when triggering event\n        return function(event) {\n          var args = argsExpr(scope); //get args here to pass updated model values\n          function index(obj,i) {return obj[i];}\n          var f = funcName.split('.').reduce(index, scope);\n          f && f.apply(this, [event].concat(args));\n          $timeout( function() {\n            scope.$apply();\n          });\n        };\n      };\n\n      for(var key in attrs) {\n        if (attrs[key]) {\n          if (!key.match(/^on[A-Z]/)) { //skip if not events\n            continue;\n          }\n\n          //get event name as underscored. i.e. zoom_changed\n          var eventName = key.replace(/^on/,'');\n          eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1);\n          eventName = eventName.replace(/([A-Z])/g, toLowercaseFunc);\n\n          var attrValue = attrs[key];\n          events[eventName] = new EventFunc(attrValue);\n        }\n      }\n      return events;\n    };\n\n    /**\n     * control means map controls, i.e streetview, pan, etc, not a general control\n     * @memberof Attr2MapOptions\n     * @param {Hash} filtered filtered tag attributes\n     * @returns {Hash} Google Map options\n     */\n    var getControlOptions = function(filtered) {\n      var controlOptions = {};\n      if (typeof filtered != 'object') {\n        return false;\n      }\n\n      for (var attr in filtered) {\n        if (filtered[attr]) {\n          if (!attr.match(/(.*)ControlOptions$/)) {\n            continue; // if not controlOptions, skip it\n          }\n\n          //change invalid json to valid one, i.e. {foo:1} to {\"foo\": 1}\n          var orgValue = filtered[attr];\n          var newValue = orgValue.replace(/'/g, '\"');\n          newValue = newValue.replace(/([^\"]+)|(\"[^\"]+\")/g, function($0, $1, $2) {\n            if ($1) {\n              return $1.replace(/([a-zA-Z0-9]+?):/g, '\"$1\":');\n            } else {\n              return $2;\n            }\n          });\n          try {\n            var options = JSON.parse(newValue);\n            for (var key in options) { //assign the right values\n              if (options[key]) {\n                var value = options[key];\n                if (typeof value === 'string') {\n                  value = value.toUpperCase();\n                } else if (key === \"mapTypeIds\") {\n                  value = value.map( function(str) {\n                    if (str.match(/^[A-Z]+$/)) { // if constant\n                      return google.maps.MapTypeId[str.toUpperCase()];\n                    } else { // else, custom map-type\n                      return str;\n                    }\n                  });\n                }\n\n                if (key === \"style\") {\n                  var str = attr.charAt(0).toUpperCase() + attr.slice(1);\n                  var objName = str.replace(/Options$/,'')+\"Style\";\n                  options[key] = google.maps[objName][value];\n                } else if (key === \"position\") {\n                  options[key] = google.maps.ControlPosition[value];\n                } else {\n                  options[key] = value;\n                }\n              }\n            }\n            controlOptions[attr] = options;\n          } catch (e) {\n            void 0;\n          }\n        }\n      } // for\n\n      return controlOptions;\n    };\n\n    return {\n      filter: filter,\n      getOptions: getOptions,\n      getEvents: getEvents,\n      getControlOptions: getControlOptions,\n      toOptionValue: toOptionValue,\n      getAttrsToObserve: getAttrsToObserve,\n      orgAttributes: orgAttributes\n    }; // return\n\n  };\n  Attr2MapOptions.$inject= [\n    '$parse', '$timeout', '$log', '$interpolate', 'NavigatorGeolocation', 'GeoCoder',\n    'camelCaseFilter', 'jsonizeFilter', 'escapeRegexpFilter'\n  ];\n\n  angular.module('ngMap').service('Attr2MapOptions', Attr2MapOptions);\n})();\n\n/**\n * @ngdoc service\n * @name GeoCoder\n * @description\n *   Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)\n *   service for Google Geocoder service\n */\n(function() {\n  'use strict';\n  var $q;\n  /**\n   * @memberof GeoCoder\n   * @param {Hash} options\n   *   https://developers.google.com/maps/documentation/geocoding/#geocoding\n   * @example\n   * ```\n   *   GeoCoder.geocode({address: 'the cn tower'}).then(function(result) {\n   *     //... do something with result\n   *   });\n   * ```\n   * @returns {HttpPromise} Future object\n   */\n  var geocodeFunc = function(options) {\n    var deferred = $q.defer();\n    var geocoder = new google.maps.Geocoder();\n    geocoder.geocode(options, function (results, status) {\n      if (status == google.maps.GeocoderStatus.OK) {\n        deferred.resolve(results);\n      } else {\n        deferred.reject(status);\n      }\n    });\n    return deferred.promise;\n  };\n\n  var GeoCoder = function(_$q_) {\n    $q = _$q_;\n    return {\n      geocode : geocodeFunc\n    };\n  };\n  GeoCoder.$inject = ['$q'];\n\n  angular.module('ngMap').service('GeoCoder', GeoCoder);\n})();\n\n/**\n * @ngdoc service\n * @name GoogleMapsApi\n * @description\n *   Load Google Maps API Service\n */\n(function() {\n  'use strict';\n  var $q;\n  var $timeout;\n\n  var GoogleMapsApi = function(_$q_, _$timeout_) {\n    $q = _$q_;\n    $timeout = _$timeout_;\n\n    return {\n\n      /**\n       * Load google maps into document by creating a script tag\n       * @memberof GoogleMapsApi\n       * @param {string} mapsUrl\n       * @example\n       *   GoogleMapsApi.load(myUrl).then(function() {\n       *     console.log('google map has been loaded')\n       *   });\n       */\n      load: function (mapsUrl) {\n\n        var deferred = $q.defer();\n\n        if (window.google === undefined || window.google.maps === undefined) {\n\n          window.lazyLoadCallback = function() {\n            $timeout(function() { /* give some time to load */\n              deferred.resolve(window.google)\n            }, 100);\n          };\n\n          var scriptEl = document.createElement('script');\n          scriptEl.src = mapsUrl +\n            (mapsUrl.indexOf('?') > -1 ? '&' : '?') +\n            'callback=lazyLoadCallback';\n\n          if (!document.querySelector('script[src=\"' + scriptEl.src + '\"]')) {\n            document.body.appendChild(scriptEl);\n          }\n        } else {\n          deferred.resolve(window.google)\n        }\n\n        return deferred.promise;\n      }\n\n    }\n  }\n  GoogleMapsApi.$inject = ['$q', '$timeout'];\n\n  angular.module('ngMap').service('GoogleMapsApi', GoogleMapsApi);\n})();\n\n\n\n/**\n * @ngdoc service\n * @name NavigatorGeolocation\n * @description\n *  Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)\n *  service for navigator.geolocation methods\n */\n/* global google */\n(function() {\n  'use strict';\n  var $q;\n\n  /**\n   * @memberof NavigatorGeolocation\n   * @param {Object} geoLocationOptions the navigator geolocations options.\n   *  i.e. { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }.\n   *  If none specified, { timeout: 5000 }. \n   *  If timeout not specified, timeout: 5000 added\n   * @param {function} success success callback function\n   * @param {function} failure failure callback function\n   * @example\n   * ```\n   *  NavigatorGeolocation.getCurrentPosition()\n   *    .then(function(position) {\n   *      var lat = position.coords.latitude, lng = position.coords.longitude;\n   *      .. do something lat and lng\n   *    });\n   * ```\n   * @returns {HttpPromise} Future object\n   */\n  var getCurrentPosition = function(geoLocationOptions) {\n    var deferred = $q.defer();\n    if (navigator.geolocation) {\n\n      if (geoLocationOptions === undefined) {\n        geoLocationOptions = { timeout: 5000 };\n      }\n      else if (geoLocationOptions.timeout === undefined) {\n        geoLocationOptions.timeout = 5000;\n      }\n\n      navigator.geolocation.getCurrentPosition(\n        function(position) {\n          deferred.resolve(position);\n        }, function(evt) {\n          void 0;\n          deferred.reject(evt);\n        },\n        geoLocationOptions\n      );\n    } else {\n      deferred.reject(\"Browser Geolocation service failed.\");\n    }\n    return deferred.promise;\n  };\n\n  var NavigatorGeolocation = function(_$q_) {\n    $q = _$q_;\n    return {\n      getCurrentPosition: getCurrentPosition\n    };\n  };\n  NavigatorGeolocation.$inject = ['$q'];\n\n  angular.module('ngMap').\n    service('NavigatorGeolocation', NavigatorGeolocation);\n})();\n\n/**\n * @ngdoc factory\n * @name NgMapPool\n * @description\n *   Provide map instance to avoid memory leak\n */\n(function() {\n  'use strict';\n  /**\n   * @memberof NgMapPool\n   * @desc map instance pool\n   */\n  var mapInstances = [];\n  var $window, $document, $timeout;\n\n  var add = function(el) {\n    var mapDiv = $document.createElement(\"div\");\n    mapDiv.style.width = \"100%\";\n    mapDiv.style.height = \"100%\";\n    el.appendChild(mapDiv);\n    var map = new $window.google.maps.Map(mapDiv, {});\n    mapInstances.push(map);\n    return map;\n  };\n\n  var findById = function(el, id) {\n    var notInUseMap;\n    for (var i=0; i<mapInstances.length; i++) {\n      var map = mapInstances[i];\n      if (map.id == id && !map.inUse) {\n        var mapDiv = map.getDiv();\n        el.appendChild(mapDiv);\n        notInUseMap = map;\n        break;\n      }\n    }\n    return notInUseMap;\n  };\n\n  var findUnused = function(el) { //jshint ignore:line\n    var notInUseMap;\n    for (var i=0; i<mapInstances.length; i++) {\n      var map = mapInstances[i];\n      if (map.id) {\n        continue;\n      }\n      if (!map.inUse) {\n        var mapDiv = map.getDiv();\n        el.appendChild(mapDiv);\n        notInUseMap = map;\n        break;\n      }\n    }\n    return notInUseMap;\n  };\n\n  /**\n   * @memberof NgMapPool\n   * @function getMapInstance\n   * @param {HtmlElement} el map container element\n   * @return map instance for the given element\n   */\n  var getMapInstance = function(el) {\n    var map = findById(el, el.id) || findUnused(el);\n    if (!map) {\n      map = add(el);\n    } else {\n      /* firing map idle event, which is used by map controller */\n      $timeout(function() {\n        google.maps.event.trigger(map, 'idle');\n      }, 100);\n    }\n    map.inUse = true;\n    return map;\n  };\n\n  /**\n   * @memberof NgMapPool\n   * @function returnMapInstance\n   * @param {Map} an instance of google.maps.Map\n   * @desc sets the flag inUse of the given map instance to false, so that it \n   * can be reused later\n   */\n  var returnMapInstance = function(map) {\n    map.inUse = false;\n  };\n  \n  /**\n   * @memberof NgMapPool\n   * @function resetMapInstances\n   * @desc resets mapInstance array\n   */\n  var resetMapInstances = function() {\n    for(var i = 0;i < mapInstances.length;i++) {\n        mapInstances[i] = null;\n    }\n    mapInstances = [];\n  };\n  \n  /**\n   * @memberof NgMapPool\n   * @function deleteMapInstance\n   * @desc delete a mapInstance\n   */\n  var deleteMapInstance= function(mapId) {\n\t  for( var i=0; i<mapInstances.length; i++ ) {\n\t\t  if( (mapInstances[i] !== null) && (mapInstances[i].id == mapId)) {\n\t\t\t  mapInstances[i]= null;\n\t\t\t  mapInstances.splice( i, 1 );\n\t\t  }\n\t  }\n  };\n\n  var NgMapPool = function(_$document_, _$window_, _$timeout_) {\n    $document = _$document_[0], $window = _$window_, $timeout = _$timeout_;\n\n    return {\n\t  mapInstances: mapInstances,\n      resetMapInstances: resetMapInstances,\n      getMapInstance: getMapInstance,\n      returnMapInstance: returnMapInstance,\n      deleteMapInstance: deleteMapInstance\n    };\n  };\n\n  NgMapPool.$inject = [ '$document', '$window', '$timeout'];\n\n  angular.module('ngMap').factory('NgMapPool', NgMapPool);\n\n})();\n\n/**\n * @ngdoc provider\n * @name NgMap\n * @description\n *  common utility service for ng-map\n */\n(function() {\n  'use strict';\n  var $window, $document, $q;\n  var NavigatorGeolocation, Attr2MapOptions, GeoCoder, camelCaseFilter, NgMapPool;\n\n  var mapControllers = {};\n\n  var getStyle = function(el, styleProp) {\n    var y;\n    if (el.currentStyle) {\n      y = el.currentStyle[styleProp];\n    } else if ($window.getComputedStyle) {\n      y = $document.defaultView.\n        getComputedStyle(el, null).\n        getPropertyValue(styleProp);\n    }\n    return y;\n  };\n\n  /**\n   * @memberof NgMap\n   * @function initMap\n   * @param id optional, id of the map. default 0\n   */\n  var initMap = function(id) {\n    var ctrl = mapControllers[id || 0];\n    if (!(ctrl.map instanceof google.maps.Map)) {\n      ctrl.initializeMap();\n      return ctrl.map;\n    } else {\n      void 0;\n    }\n  };\n\n  /**\n   * @memberof NgMap\n   * @function getMap\n   * @param {String} optional, id e.g., 'foo'\n   * @returns promise\n   */\n  var getMap = function(id, options) {\n    options = options || {};\n    id = typeof id === 'object' ? id.id : id;\n\n    var deferred = $q.defer();\n    var timeout = options.timeout || 10000;\n\n    function waitForMap(timeElapsed){\n      var keys = Object.keys(mapControllers);\n      var theFirstController = mapControllers[keys[0]];\n      if(id && mapControllers[id]){\n        deferred.resolve(mapControllers[id].map);\n      } else if (!id && theFirstController && theFirstController.map) {\n        deferred.resolve(theFirstController.map);\n      } else if (timeElapsed > timeout) {\n        deferred.reject('could not find map');\n      } else {\n        $window.setTimeout( function(){\n          waitForMap(timeElapsed+100);\n        }, 100);\n      }\n    }\n    waitForMap(0);\n\n    return deferred.promise;\n  };\n\n  /**\n   * @memberof NgMap\n   * @function addMap\n   * @param mapController {__MapContoller} a map controller\n   * @returns promise\n   */\n  var addMap = function(mapCtrl) {\n    if (mapCtrl.map) {\n      var len = Object.keys(mapControllers).length;\n      mapControllers[mapCtrl.map.id || len] = mapCtrl;\n    }\n  };\n\n  /**\n   * @memberof NgMap\n   * @function deleteMap\n   * @param mapController {__MapContoller} a map controller\n   */\n  var deleteMap = function(mapCtrl) {\n    var len = Object.keys(mapControllers).length - 1;\n    var mapId = mapCtrl.map.id || len;\n    if (mapCtrl.map) {\n      for (var eventName in mapCtrl.eventListeners) {\n        void 0;\n        var listener = mapCtrl.eventListeners[eventName];\n        google.maps.event.removeListener(listener);\n      }\n      if (mapCtrl.map.controls) {\n        mapCtrl.map.controls.forEach(function(ctrl) {\n          ctrl.clear();\n        });\n      }\n    }\n\n    //Remove Heatmap Layers\n    if (mapCtrl.map.heatmapLayers) {\n      Object.keys(mapCtrl.map.heatmapLayers).forEach(function (layer) {\n        mapCtrl.deleteObject('heatmapLayers', mapCtrl.map.heatmapLayers[layer]);\n      });\n    }\n\n    NgMapPool.deleteMapInstance(mapId);\n\n    delete mapControllers[mapId];\n  };\n\n  /**\n   * @memberof NgMap\n   * @function getGeoLocation\n   * @param {String} address\n   * @param {Hash} options geo options\n   * @returns promise\n   */\n  var getGeoLocation = function(string, options) {\n    var deferred = $q.defer();\n    if (!string || string.match(/^current/i)) { // current location\n      NavigatorGeolocation.getCurrentPosition(options).then(\n        function(position) {\n          var lat = position.coords.latitude;\n          var lng = position.coords.longitude;\n          var latLng = new google.maps.LatLng(lat,lng);\n          deferred.resolve(latLng);\n        },\n        function(error) {\n          deferred.reject(error);\n        }\n      );\n    } else {\n      GeoCoder.geocode({address: string}).then(\n        function(results) {\n          deferred.resolve(results[0].geometry.location);\n        },\n        function(error) {\n          deferred.reject(error);\n        }\n      );\n      // var geocoder = new google.maps.Geocoder();\n      // geocoder.geocode(options, function (results, status) {\n      //   if (status == google.maps.GeocoderStatus.OK) {\n      //     deferred.resolve(results);\n      //   } else {\n      //     deferred.reject(status);\n      //   }\n      // });\n    }\n\n    return deferred.promise;\n  };\n\n  /**\n   * @memberof NgMap\n   * @function observeAndSet\n   * @param {String} attrName attribute name\n   * @param {Object} object A Google maps object to be changed\n   * @returns attribue observe function\n   */\n  var observeAndSet = function(attrName, object) {\n    void 0;\n    return function(val) {\n      if (val) {\n        var setMethod = camelCaseFilter('set-'+attrName);\n        var optionValue = Attr2MapOptions.toOptionValue(val, {key: attrName});\n        if (object[setMethod]) { //if set method does exist\n          void 0;\n          /* if an location is being observed */\n          if (attrName.match(/center|position/) &&\n            typeof optionValue == 'string') {\n            getGeoLocation(optionValue).then(function(latlng) {\n              object[setMethod](latlng);\n            });\n          } else {\n            object[setMethod](optionValue);\n          }\n        }\n      }\n    };\n  };\n\n  /**\n   * @memberof NgMap\n   * @function setStyle\n   * @param {HtmlElement} map contriner element\n   * @desc set display, width, height of map container element\n   */\n  var setStyle = function(el) {\n    //if style is not given to the map element, set display and height\n    var defaultStyle = el.getAttribute('default-style');\n    if (defaultStyle == \"true\") {\n      el.style.display = 'block';\n      el.style.height = '300px';\n    } else {\n      if (getStyle(el, 'display') != \"block\") {\n        el.style.display = 'block';\n      }\n      if (getStyle(el, 'height').match(/^(0|auto)/)) {\n        el.style.height = '300px';\n      }\n    }\n  };\n\n  angular.module('ngMap').provider('NgMap', function() {\n    var defaultOptions = {};\n\n    /**\n     * @memberof NgMap\n     * @function setDefaultOptions\n     * @param {Hash} options\n     * @example\n     *  app.config(function(NgMapProvider) {\n     *    NgMapProvider.setDefaultOptions({\n     *      marker: {\n     *        optimized: false\n     *      }\n     *    });\n     *  });\n     */\n    this.setDefaultOptions = function(options) {\n      defaultOptions = options;\n    };\n\n    var NgMap = function(\n        _$window_, _$document_, _$q_,\n        _NavigatorGeolocation_, _Attr2MapOptions_,\n        _GeoCoder_, _camelCaseFilter_, _NgMapPool_\n      ) {\n      $window = _$window_;\n      $document = _$document_[0];\n      $q = _$q_;\n      NavigatorGeolocation = _NavigatorGeolocation_;\n      Attr2MapOptions = _Attr2MapOptions_;\n      GeoCoder = _GeoCoder_;\n      camelCaseFilter = _camelCaseFilter_;\n      NgMapPool = _NgMapPool_;\n\n      return {\n        defaultOptions: defaultOptions,\n        addMap: addMap,\n        deleteMap: deleteMap,\n        getMap: getMap,\n        initMap: initMap,\n        setStyle: setStyle,\n        getGeoLocation: getGeoLocation,\n        observeAndSet: observeAndSet\n      };\n    };\n    NgMap.$inject = [\n      '$window', '$document', '$q',\n      'NavigatorGeolocation', 'Attr2MapOptions',\n      'GeoCoder', 'camelCaseFilter', 'NgMapPool'\n    ];\n\n    this.$get = NgMap;\n  });\n})();\n\n/**\n * @ngdoc service\n * @name StreetView\n * @description\n *  Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)\n *  service for [Google StreetViewService]\n *  (https://developers.google.com/maps/documentation/javascript/streetview)\n */\n(function() {\n  'use strict';\n  var $q;\n\n  /**\n   * Retrieves panorama id from the given map (and or position)\n   * @memberof StreetView\n   * @param {map} map Google map instance\n   * @param {LatLng} latlng Google LatLng instance\n   *   default: the center of the map\n   * @example\n   *   StreetView.getPanorama(map).then(function(panoId) {\n   *     $scope.panoId = panoId;\n   *   });\n   * @returns {HttpPromise} Future object\n   */\n  var getPanorama = function(map, latlng) {\n    latlng = latlng || map.getCenter();\n    var deferred = $q.defer();\n    var svs = new google.maps.StreetViewService();\n    svs.getPanoramaByLocation( (latlng||map.getCenter), 100,\n      function (data, status) {\n        // if streetView available\n        if (status === google.maps.StreetViewStatus.OK) {\n          deferred.resolve(data.location.pano);\n        } else {\n          // no street view available in this range, or some error occurred\n          deferred.resolve(false);\n          //deferred.reject('Geocoder failed due to: '+ status);\n        }\n      }\n    );\n    return deferred.promise;\n  };\n\n  /**\n   * Set panorama view on the given map with the panorama id\n   * @memberof StreetView\n   * @param {map} map Google map instance\n   * @param {String} panoId Panorama id fro getPanorama method\n   * @example\n   *   StreetView.setPanorama(map, panoId);\n   */\n  var setPanorama = function(map, panoId) {\n    var svp = new google.maps.StreetViewPanorama(\n      map.getDiv(), {enableCloseButton: true}\n    );\n    svp.setPano(panoId);\n  };\n\n  var StreetView = function(_$q_) {\n    $q = _$q_;\n\n    return {\n      getPanorama: getPanorama,\n      setPanorama: setPanorama\n    };\n  };\n  StreetView.$inject = ['$q'];\n\n  angular.module('ngMap').service('StreetView', StreetView);\n})();\n\r\nreturn 'ngMap';\r\n}));\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/ngmap/build/scripts/ng-map.js\n// module id = 7\n// module chunks = 0","/**\n * @license AngularJS v1.6.3\n * (c) 2010-2017 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window, angular) {'use strict';\n\n/**\n * @ngdoc module\n * @name ngCookies\n * @description\n *\n * # ngCookies\n *\n * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.\n *\n *\n * <div doc-module-components=\"ngCookies\"></div>\n *\n * See {@link ngCookies.$cookies `$cookies`} for usage.\n */\n\n\nangular.module('ngCookies', ['ng']).\n  info({ angularVersion: '1.6.3' }).\n  /**\n   * @ngdoc provider\n   * @name $cookiesProvider\n   * @description\n   * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.\n   * */\n   provider('$cookies', [/** @this */function $CookiesProvider() {\n    /**\n     * @ngdoc property\n     * @name $cookiesProvider#defaults\n     * @description\n     *\n     * Object containing default options to pass when setting cookies.\n     *\n     * The object may have following properties:\n     *\n     * - **path** - `{string}` - The cookie will be available only for this path and its\n     *   sub-paths. By default, this is the URL that appears in your `<base>` tag.\n     * - **domain** - `{string}` - The cookie will be available only for this domain and\n     *   its sub-domains. For security reasons the user agent will not accept the cookie\n     *   if the current domain is not a sub-domain of this domain or equal to it.\n     * - **expires** - `{string|Date}` - String of the form \"Wdy, DD Mon YYYY HH:MM:SS GMT\"\n     *   or a Date object indicating the exact date/time this cookie will expire.\n     * - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a\n     *   secured connection.\n     *\n     * Note: By default, the address that appears in your `<base>` tag will be used as the path.\n     * This is important so that cookies will be visible for all routes when html5mode is enabled.\n     *\n     * @example\n     *\n     * ```js\n     * angular.module('cookiesProviderExample', ['ngCookies'])\n     *   .config(['$cookiesProvider', function($cookiesProvider) {\n     *     // Setting default options\n     *     $cookiesProvider.defaults.domain = 'foo.com';\n     *     $cookiesProvider.defaults.secure = true;\n     *   }]);\n     * ```\n     **/\n    var defaults = this.defaults = {};\n\n    function calcOptions(options) {\n      return options ? angular.extend({}, defaults, options) : defaults;\n    }\n\n    /**\n     * @ngdoc service\n     * @name $cookies\n     *\n     * @description\n     * Provides read/write access to browser's cookies.\n     *\n     * <div class=\"alert alert-info\">\n     * Up until Angular 1.3, `$cookies` exposed properties that represented the\n     * current browser cookie values. In version 1.4, this behavior has changed, and\n     * `$cookies` now provides a standard api of getters, setters etc.\n     * </div>\n     *\n     * Requires the {@link ngCookies `ngCookies`} module to be installed.\n     *\n     * @example\n     *\n     * ```js\n     * angular.module('cookiesExample', ['ngCookies'])\n     *   .controller('ExampleController', ['$cookies', function($cookies) {\n     *     // Retrieving a cookie\n     *     var favoriteCookie = $cookies.get('myFavorite');\n     *     // Setting a cookie\n     *     $cookies.put('myFavorite', 'oatmeal');\n     *   }]);\n     * ```\n     */\n    this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {\n      return {\n        /**\n         * @ngdoc method\n         * @name $cookies#get\n         *\n         * @description\n         * Returns the value of given cookie key\n         *\n         * @param {string} key Id to use for lookup.\n         * @returns {string} Raw cookie value.\n         */\n        get: function(key) {\n          return $$cookieReader()[key];\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#getObject\n         *\n         * @description\n         * Returns the deserialized value of given cookie key\n         *\n         * @param {string} key Id to use for lookup.\n         * @returns {Object} Deserialized cookie value.\n         */\n        getObject: function(key) {\n          var value = this.get(key);\n          return value ? angular.fromJson(value) : value;\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#getAll\n         *\n         * @description\n         * Returns a key value object with all the cookies\n         *\n         * @returns {Object} All cookies\n         */\n        getAll: function() {\n          return $$cookieReader();\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#put\n         *\n         * @description\n         * Sets a value for given cookie key\n         *\n         * @param {string} key Id for the `value`.\n         * @param {string} value Raw value to be stored.\n         * @param {Object=} options Options object.\n         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}\n         */\n        put: function(key, value, options) {\n          $$cookieWriter(key, value, calcOptions(options));\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#putObject\n         *\n         * @description\n         * Serializes and sets a value for given cookie key\n         *\n         * @param {string} key Id for the `value`.\n         * @param {Object} value Value to be stored.\n         * @param {Object=} options Options object.\n         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}\n         */\n        putObject: function(key, value, options) {\n          this.put(key, angular.toJson(value), options);\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#remove\n         *\n         * @description\n         * Remove given cookie\n         *\n         * @param {string} key Id of the key-value pair to delete.\n         * @param {Object=} options Options object.\n         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}\n         */\n        remove: function(key, options) {\n          $$cookieWriter(key, undefined, calcOptions(options));\n        }\n      };\n    }];\n  }]);\n\nangular.module('ngCookies').\n/**\n * @ngdoc service\n * @name $cookieStore\n * @deprecated\n * sinceVersion=\"v1.4.0\"\n * Please use the {@link ngCookies.$cookies `$cookies`} service instead.\n *\n * @requires $cookies\n *\n * @description\n * Provides a key-value (string-object) storage, that is backed by session cookies.\n * Objects put or retrieved from this storage are automatically serialized or\n * deserialized by angular's toJson/fromJson.\n *\n * Requires the {@link ngCookies `ngCookies`} module to be installed.\n *\n * @example\n *\n * ```js\n * angular.module('cookieStoreExample', ['ngCookies'])\n *   .controller('ExampleController', ['$cookieStore', function($cookieStore) {\n *     // Put cookie\n *     $cookieStore.put('myFavorite','oatmeal');\n *     // Get cookie\n *     var favoriteCookie = $cookieStore.get('myFavorite');\n *     // Removing a cookie\n *     $cookieStore.remove('myFavorite');\n *   }]);\n * ```\n */\n factory('$cookieStore', ['$cookies', function($cookies) {\n\n    return {\n      /**\n       * @ngdoc method\n       * @name $cookieStore#get\n       *\n       * @description\n       * Returns the value of given cookie key\n       *\n       * @param {string} key Id to use for lookup.\n       * @returns {Object} Deserialized cookie value, undefined if the cookie does not exist.\n       */\n      get: function(key) {\n        return $cookies.getObject(key);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $cookieStore#put\n       *\n       * @description\n       * Sets a value for given cookie key\n       *\n       * @param {string} key Id for the `value`.\n       * @param {Object} value Value to be stored.\n       */\n      put: function(key, value) {\n        $cookies.putObject(key, value);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $cookieStore#remove\n       *\n       * @description\n       * Remove given cookie\n       *\n       * @param {string} key Id of the key-value pair to delete.\n       */\n      remove: function(key) {\n        $cookies.remove(key);\n      }\n    };\n\n  }]);\n\n/**\n * @name $$cookieWriter\n * @requires $document\n *\n * @description\n * This is a private service for writing cookies\n *\n * @param {string} name Cookie name\n * @param {string=} value Cookie value (if undefined, cookie will be deleted)\n * @param {Object=} options Object with options that need to be stored for the cookie.\n */\nfunction $$CookieWriter($document, $log, $browser) {\n  var cookiePath = $browser.baseHref();\n  var rawDocument = $document[0];\n\n  function buildCookieString(name, value, options) {\n    var path, expires;\n    options = options || {};\n    expires = options.expires;\n    path = angular.isDefined(options.path) ? options.path : cookiePath;\n    if (angular.isUndefined(value)) {\n      expires = 'Thu, 01 Jan 1970 00:00:00 GMT';\n      value = '';\n    }\n    if (angular.isString(expires)) {\n      expires = new Date(expires);\n    }\n\n    var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);\n    str += path ? ';path=' + path : '';\n    str += options.domain ? ';domain=' + options.domain : '';\n    str += expires ? ';expires=' + expires.toUTCString() : '';\n    str += options.secure ? ';secure' : '';\n\n    // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:\n    // - 300 cookies\n    // - 20 cookies per unique domain\n    // - 4096 bytes per cookie\n    var cookieLength = str.length + 1;\n    if (cookieLength > 4096) {\n      $log.warn('Cookie \\'' + name +\n        '\\' possibly not set or overflowed because it was too large (' +\n        cookieLength + ' > 4096 bytes)!');\n    }\n\n    return str;\n  }\n\n  return function(name, value, options) {\n    rawDocument.cookie = buildCookieString(name, value, options);\n  };\n}\n\n$$CookieWriter.$inject = ['$document', '$log', '$browser'];\n\nangular.module('ngCookies').provider('$$cookieWriter', /** @this */ function $$CookieWriterProvider() {\n  this.$get = $$CookieWriter;\n});\n\n\n})(window, window.angular);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-cookies/angular-cookies.js\n// module id = 8\n// module chunks = 0","/**\n * @license AngularJS v1.6.3\n * (c) 2010-2017 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window, angular) {'use strict';\n\nvar $resourceMinErr = angular.$$minErr('$resource');\n\n// Helper functions and regex to lookup a dotted path on an object\n// stopping at undefined/null.  The path must be composed of ASCII\n// identifiers (just like $parse)\nvar MEMBER_NAME_REGEX = /^(\\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;\n\nfunction isValidDottedPath(path) {\n  return (path != null && path !== '' && path !== 'hasOwnProperty' &&\n      MEMBER_NAME_REGEX.test('.' + path));\n}\n\nfunction lookupDottedPath(obj, path) {\n  if (!isValidDottedPath(path)) {\n    throw $resourceMinErr('badmember', 'Dotted member path \"@{0}\" is invalid.', path);\n  }\n  var keys = path.split('.');\n  for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {\n    var key = keys[i];\n    obj = (obj !== null) ? obj[key] : undefined;\n  }\n  return obj;\n}\n\n/**\n * Create a shallow copy of an object and clear other fields from the destination\n */\nfunction shallowClearAndCopy(src, dst) {\n  dst = dst || {};\n\n  angular.forEach(dst, function(value, key) {\n    delete dst[key];\n  });\n\n  for (var key in src) {\n    if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {\n      dst[key] = src[key];\n    }\n  }\n\n  return dst;\n}\n\n/**\n * @ngdoc module\n * @name ngResource\n * @description\n *\n * # ngResource\n *\n * The `ngResource` module provides interaction support with RESTful services\n * via the $resource service.\n *\n *\n * <div doc-module-components=\"ngResource\"></div>\n *\n * See {@link ngResource.$resourceProvider} and {@link ngResource.$resource} for usage.\n */\n\n/**\n * @ngdoc provider\n * @name $resourceProvider\n *\n * @description\n *\n * Use `$resourceProvider` to change the default behavior of the {@link ngResource.$resource}\n * service.\n *\n * ## Dependencies\n * Requires the {@link ngResource } module to be installed.\n *\n */\n\n/**\n * @ngdoc service\n * @name $resource\n * @requires $http\n * @requires ng.$log\n * @requires $q\n * @requires ng.$timeout\n *\n * @description\n * A factory which creates a resource object that lets you interact with\n * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.\n *\n * The returned resource object has action methods which provide high-level behaviors without\n * the need to interact with the low level {@link ng.$http $http} service.\n *\n * Requires the {@link ngResource `ngResource`} module to be installed.\n *\n * By default, trailing slashes will be stripped from the calculated URLs,\n * which can pose problems with server backends that do not expect that\n * behavior.  This can be disabled by configuring the `$resourceProvider` like\n * this:\n *\n * ```js\n     app.config(['$resourceProvider', function($resourceProvider) {\n       // Don't strip trailing slashes from calculated URLs\n       $resourceProvider.defaults.stripTrailingSlashes = false;\n     }]);\n * ```\n *\n * @param {string} url A parameterized URL template with parameters prefixed by `:` as in\n *   `/user/:username`. If you are using a URL with a port number (e.g.\n *   `http://example.com:8080/api`), it will be respected.\n *\n *   If you are using a url with a suffix, just add the suffix, like this:\n *   `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`\n *   or even `$resource('http://example.com/resource/:resource_id.:format')`\n *   If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be\n *   collapsed down to a single `.`.  If you need this sequence to appear and not collapse then you\n *   can escape it with `/\\.`.\n *\n * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in\n *   `actions` methods. If a parameter value is a function, it will be called every time\n *   a param value needs to be obtained for a request (unless the param was overridden). The function\n *   will be passed the current data value as an argument.\n *\n *   Each key value in the parameter object is first bound to url template if present and then any\n *   excess keys are appended to the url search query after the `?`.\n *\n *   Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in\n *   URL `/path/greet?salutation=Hello`.\n *\n *   If the parameter value is prefixed with `@`, then the value for that parameter will be\n *   extracted from the corresponding property on the `data` object (provided when calling a\n *   \"non-GET\" action method).\n *   For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of\n *   `someParam` will be `data.someProp`.\n *   Note that the parameter will be ignored, when calling a \"GET\" action method (i.e. an action\n *   method that does not accept a request body)\n *\n * @param {Object.<Object>=} actions Hash with declaration of custom actions that will be available\n *   in addition to the default set of resource actions (see below). If a custom action has the same\n *   key as a default action (e.g. `save`), then the default action will be *overwritten*, and not\n *   extended.\n *\n *   The declaration should be created in the format of {@link ng.$http#usage $http.config}:\n *\n *       {action1: {method:?, params:?, isArray:?, headers:?, ...},\n *        action2: {method:?, params:?, isArray:?, headers:?, ...},\n *        ...}\n *\n *   Where:\n *\n *   - **`action`** – {string} – The name of action. This name becomes the name of the method on\n *     your resource object.\n *   - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`,\n *     `DELETE`, `JSONP`, etc).\n *   - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of\n *     the parameter value is a function, it will be called every time when a param value needs to\n *     be obtained for a request (unless the param was overridden). The function will be passed the\n *     current data value as an argument.\n *   - **`url`** – {string} – action specific `url` override. The url templating is supported just\n *     like for the resource-level urls.\n *   - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,\n *     see `returns` section.\n *   - **`transformRequest`** –\n *     `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –\n *     transform function or an array of such functions. The transform function takes the http\n *     request body and headers and returns its transformed (typically serialized) version.\n *     By default, transformRequest will contain one function that checks if the request data is\n *     an object and serializes it using `angular.toJson`. To prevent this behavior, set\n *     `transformRequest` to an empty array: `transformRequest: []`\n *   - **`transformResponse`** –\n *     `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –\n *     transform function or an array of such functions. The transform function takes the http\n *     response body, headers and status and returns its transformed (typically deserialized)\n *     version.\n *     By default, transformResponse will contain one function that checks if the response looks\n *     like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior,\n *     set `transformResponse` to an empty array: `transformResponse: []`\n *   - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the\n *     GET request, otherwise if a cache instance built with\n *     {@link ng.$cacheFactory $cacheFactory} is supplied, this cache will be used for\n *     caching.\n *   - **`timeout`** – `{number}` – timeout in milliseconds.<br />\n *     **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are\n *     **not** supported in $resource, because the same value would be used for multiple requests.\n *     If you are looking for a way to cancel requests, you should use the `cancellable` option.\n *   - **`cancellable`** – `{boolean}` – if set to true, the request made by a \"non-instance\" call\n *     will be cancelled (if not already completed) by calling `$cancelRequest()` on the call's\n *     return value. Calling `$cancelRequest()` for a non-cancellable or an already\n *     completed/cancelled request will have no effect.<br />\n *   - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the\n *     XHR object. See\n *     [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)\n *     for more information.\n *   - **`responseType`** - `{string}` - see\n *     [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).\n *   - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -\n *     `response` and `responseError`. Both `response` and `responseError` interceptors get called\n *     with `http response` object. See {@link ng.$http $http interceptors}.\n *\n * @param {Object} options Hash with custom settings that should extend the\n *   default `$resourceProvider` behavior.  The supported options are:\n *\n *   - **`stripTrailingSlashes`** – {boolean} – If true then the trailing\n *   slashes from any calculated URL will be stripped. (Defaults to true.)\n *   - **`cancellable`** – {boolean} – If true, the request made by a \"non-instance\" call will be\n *   cancelled (if not already completed) by calling `$cancelRequest()` on the call's return value.\n *   This can be overwritten per action. (Defaults to false.)\n *\n * @returns {Object} A resource \"class\" object with methods for the default set of resource actions\n *   optionally extended with custom `actions`. The default set contains these actions:\n *   ```js\n *   { 'get':    {method:'GET'},\n *     'save':   {method:'POST'},\n *     'query':  {method:'GET', isArray:true},\n *     'remove': {method:'DELETE'},\n *     'delete': {method:'DELETE'} };\n *   ```\n *\n *   Calling these methods invoke an {@link ng.$http} with the specified http method,\n *   destination and parameters. When the data is returned from the server then the object is an\n *   instance of the resource class. The actions `save`, `remove` and `delete` are available on it\n *   as  methods with the `$` prefix. This allows you to easily perform CRUD operations (create,\n *   read, update, delete) on server-side data like this:\n *   ```js\n *   var User = $resource('/user/:userId', {userId:'@id'});\n *   var user = User.get({userId:123}, function() {\n *     user.abc = true;\n *     user.$save();\n *   });\n *   ```\n *\n *   It is important to realize that invoking a $resource object method immediately returns an\n *   empty reference (object or array depending on `isArray`). Once the data is returned from the\n *   server the existing reference is populated with the actual data. This is a useful trick since\n *   usually the resource is assigned to a model which is then rendered by the view. Having an empty\n *   object results in no rendering, once the data arrives from the server then the object is\n *   populated with the data and the view automatically re-renders itself showing the new data. This\n *   means that in most cases one never has to write a callback function for the action methods.\n *\n *   The action methods on the class object or instance object can be invoked with the following\n *   parameters:\n *\n *   - HTTP GET \"class\" actions: `Resource.action([parameters], [success], [error])`\n *   - non-GET \"class\" actions: `Resource.action([parameters], postData, [success], [error])`\n *   - non-GET instance actions:  `instance.$action([parameters], [success], [error])`\n *\n *\n *   Success callback is called with (value (Object|Array), responseHeaders (Function),\n *   status (number), statusText (string)) arguments, where the value is the populated resource\n *   instance or collection object. The error callback is called with (httpResponse) argument.\n *\n *   Class actions return empty instance (with additional properties below).\n *   Instance actions return promise of the action.\n *\n *   The Resource instances and collections have these additional properties:\n *\n *   - `$promise`: the {@link ng.$q promise} of the original server interaction that created this\n *     instance or collection.\n *\n *     On success, the promise is resolved with the same resource instance or collection object,\n *     updated with data from server. This makes it easy to use in\n *     {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view\n *     rendering until the resource(s) are loaded.\n *\n *     On failure, the promise is rejected with the {@link ng.$http http response} object, without\n *     the `resource` property.\n *\n *     If an interceptor object was provided, the promise will instead be resolved with the value\n *     returned by the interceptor.\n *\n *   - `$resolved`: `true` after first server interaction is completed (either with success or\n *      rejection), `false` before that. Knowing if the Resource has been resolved is useful in\n *      data-binding.\n *\n *   The Resource instances and collections have these additional methods:\n *\n *   - `$cancelRequest`: If there is a cancellable, pending request related to the instance or\n *      collection, calling this method will abort the request.\n *\n *   The Resource instances have these additional methods:\n *\n *   - `toJSON`: It returns a simple object without any of the extra properties added as part of\n *     the Resource API. This object can be serialized through {@link angular.toJson} safely\n *     without attaching Angular-specific fields. Notice that `JSON.stringify` (and\n *     `angular.toJson`) automatically use this method when serializing a Resource instance\n *     (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior)).\n *\n * @example\n *\n * # Credit card resource\n *\n * ```js\n     // Define CreditCard class\n     var CreditCard = $resource('/user/:userId/card/:cardId',\n      {userId:123, cardId:'@id'}, {\n       charge: {method:'POST', params:{charge:true}}\n      });\n\n     // We can retrieve a collection from the server\n     var cards = CreditCard.query(function() {\n       // GET: /user/123/card\n       // server returns: [ {id:456, number:'1234', name:'Smith'} ];\n\n       var card = cards[0];\n       // each item is an instance of CreditCard\n       expect(card instanceof CreditCard).toEqual(true);\n       card.name = \"J. Smith\";\n       // non GET methods are mapped onto the instances\n       card.$save();\n       // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}\n       // server returns: {id:456, number:'1234', name: 'J. Smith'};\n\n       // our custom method is mapped as well.\n       card.$charge({amount:9.99});\n       // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}\n     });\n\n     // we can create an instance as well\n     var newCard = new CreditCard({number:'0123'});\n     newCard.name = \"Mike Smith\";\n     newCard.$save();\n     // POST: /user/123/card {number:'0123', name:'Mike Smith'}\n     // server returns: {id:789, number:'0123', name: 'Mike Smith'};\n     expect(newCard.id).toEqual(789);\n * ```\n *\n * The object returned from this function execution is a resource \"class\" which has \"static\" method\n * for each action in the definition.\n *\n * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and\n * `headers`.\n *\n * @example\n *\n * # User resource\n *\n * When the data is returned from the server then the object is an instance of the resource type and\n * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD\n * operations (create, read, update, delete) on server-side data.\n\n   ```js\n     var User = $resource('/user/:userId', {userId:'@id'});\n     User.get({userId:123}, function(user) {\n       user.abc = true;\n       user.$save();\n     });\n   ```\n *\n * It's worth noting that the success callback for `get`, `query` and other methods gets passed\n * in the response that came from the server as well as $http header getter function, so one\n * could rewrite the above example and get access to http headers as:\n *\n   ```js\n     var User = $resource('/user/:userId', {userId:'@id'});\n     User.get({userId:123}, function(user, getResponseHeaders){\n       user.abc = true;\n       user.$save(function(user, putResponseHeaders) {\n         //user => saved user object\n         //putResponseHeaders => $http header getter\n       });\n     });\n   ```\n *\n * You can also access the raw `$http` promise via the `$promise` property on the object returned\n *\n   ```\n     var User = $resource('/user/:userId', {userId:'@id'});\n     User.get({userId:123})\n         .$promise.then(function(user) {\n           $scope.user = user;\n         });\n   ```\n *\n * @example\n *\n * # Creating a custom 'PUT' request\n *\n * In this example we create a custom method on our resource to make a PUT request\n * ```js\n *    var app = angular.module('app', ['ngResource', 'ngRoute']);\n *\n *    // Some APIs expect a PUT request in the format URL/object/ID\n *    // Here we are creating an 'update' method\n *    app.factory('Notes', ['$resource', function($resource) {\n *    return $resource('/notes/:id', null,\n *        {\n *            'update': { method:'PUT' }\n *        });\n *    }]);\n *\n *    // In our controller we get the ID from the URL using ngRoute and $routeParams\n *    // We pass in $routeParams and our Notes factory along with $scope\n *    app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',\n                                      function($scope, $routeParams, Notes) {\n *    // First get a note object from the factory\n *    var note = Notes.get({ id:$routeParams.id });\n *    $id = note.id;\n *\n *    // Now call update passing in the ID first then the object you are updating\n *    Notes.update({ id:$id }, note);\n *\n *    // This will PUT /notes/ID with the note object in the request payload\n *    }]);\n * ```\n *\n * @example\n *\n * # Cancelling requests\n *\n * If an action's configuration specifies that it is cancellable, you can cancel the request related\n * to an instance or collection (as long as it is a result of a \"non-instance\" call):\n *\n   ```js\n     // ...defining the `Hotel` resource...\n     var Hotel = $resource('/api/hotel/:id', {id: '@id'}, {\n       // Let's make the `query()` method cancellable\n       query: {method: 'get', isArray: true, cancellable: true}\n     });\n\n     // ...somewhere in the PlanVacationController...\n     ...\n     this.onDestinationChanged = function onDestinationChanged(destination) {\n       // We don't care about any pending request for hotels\n       // in a different destination any more\n       this.availableHotels.$cancelRequest();\n\n       // Let's query for hotels in '<destination>'\n       // (calls: /api/hotel?location=<destination>)\n       this.availableHotels = Hotel.query({location: destination});\n     };\n   ```\n *\n */\nangular.module('ngResource', ['ng']).\n  info({ angularVersion: '1.6.3' }).\n  provider('$resource', function ResourceProvider() {\n    var PROTOCOL_AND_IPV6_REGEX = /^https?:\\/\\/\\[[^\\]]*][^/]*/;\n\n    var provider = this;\n\n    /**\n     * @ngdoc property\n     * @name $resourceProvider#defaults\n     * @description\n     * Object containing default options used when creating `$resource` instances.\n     *\n     * The default values satisfy a wide range of usecases, but you may choose to overwrite any of\n     * them to further customize your instances. The available properties are:\n     *\n     * - **stripTrailingSlashes** – `{boolean}` – If true, then the trailing slashes from any\n     *   calculated URL will be stripped.<br />\n     *   (Defaults to true.)\n     * - **cancellable** – `{boolean}` – If true, the request made by a \"non-instance\" call will be\n     *   cancelled (if not already completed) by calling `$cancelRequest()` on the call's return\n     *   value. For more details, see {@link ngResource.$resource}. This can be overwritten per\n     *   resource class or action.<br />\n     *   (Defaults to false.)\n     * - **actions** - `{Object.<Object>}` - A hash with default actions declarations. Actions are\n     *   high-level methods corresponding to RESTful actions/methods on resources. An action may\n     *   specify what HTTP method to use, what URL to hit, if the return value will be a single\n     *   object or a collection (array) of objects etc. For more details, see\n     *   {@link ngResource.$resource}. The actions can also be enhanced or overwritten per resource\n     *   class.<br />\n     *   The default actions are:\n     *   ```js\n     *   {\n     *     get: {method: 'GET'},\n     *     save: {method: 'POST'},\n     *     query: {method: 'GET', isArray: true},\n     *     remove: {method: 'DELETE'},\n     *     delete: {method: 'DELETE'}\n     *   }\n     *   ```\n     *\n     * #### Example\n     *\n     * For example, you can specify a new `update` action that uses the `PUT` HTTP verb:\n     *\n     * ```js\n     *   angular.\n     *     module('myApp').\n     *     config(['$resourceProvider', function ($resourceProvider) {\n     *       $resourceProvider.defaults.actions.update = {\n     *         method: 'PUT'\n     *       };\n     *     });\n     * ```\n     *\n     * Or you can even overwrite the whole `actions` list and specify your own:\n     *\n     * ```js\n     *   angular.\n     *     module('myApp').\n     *     config(['$resourceProvider', function ($resourceProvider) {\n     *       $resourceProvider.defaults.actions = {\n     *         create: {method: 'POST'},\n     *         get:    {method: 'GET'},\n     *         getAll: {method: 'GET', isArray:true},\n     *         update: {method: 'PUT'},\n     *         delete: {method: 'DELETE'}\n     *       };\n     *     });\n     * ```\n     *\n     */\n    this.defaults = {\n      // Strip slashes by default\n      stripTrailingSlashes: true,\n\n      // Make non-instance requests cancellable (via `$cancelRequest()`)\n      cancellable: false,\n\n      // Default actions configuration\n      actions: {\n        'get': {method: 'GET'},\n        'save': {method: 'POST'},\n        'query': {method: 'GET', isArray: true},\n        'remove': {method: 'DELETE'},\n        'delete': {method: 'DELETE'}\n      }\n    };\n\n    this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) {\n\n      var noop = angular.noop,\n          forEach = angular.forEach,\n          extend = angular.extend,\n          copy = angular.copy,\n          isArray = angular.isArray,\n          isDefined = angular.isDefined,\n          isFunction = angular.isFunction,\n          isNumber = angular.isNumber,\n          encodeUriQuery = angular.$$encodeUriQuery,\n          encodeUriSegment = angular.$$encodeUriSegment;\n\n      function Route(template, defaults) {\n        this.template = template;\n        this.defaults = extend({}, provider.defaults, defaults);\n        this.urlParams = {};\n      }\n\n      Route.prototype = {\n        setUrlParams: function(config, params, actionUrl) {\n          var self = this,\n            url = actionUrl || self.template,\n            val,\n            encodedVal,\n            protocolAndIpv6 = '';\n\n          var urlParams = self.urlParams = Object.create(null);\n          forEach(url.split(/\\W/), function(param) {\n            if (param === 'hasOwnProperty') {\n              throw $resourceMinErr('badname', 'hasOwnProperty is not a valid parameter name.');\n            }\n            if (!(new RegExp('^\\\\d+$').test(param)) && param &&\n              (new RegExp('(^|[^\\\\\\\\]):' + param + '(\\\\W|$)').test(url))) {\n              urlParams[param] = {\n                isQueryParamValue: (new RegExp('\\\\?.*=:' + param + '(?:\\\\W|$)')).test(url)\n              };\n            }\n          });\n          url = url.replace(/\\\\:/g, ':');\n          url = url.replace(PROTOCOL_AND_IPV6_REGEX, function(match) {\n            protocolAndIpv6 = match;\n            return '';\n          });\n\n          params = params || {};\n          forEach(self.urlParams, function(paramInfo, urlParam) {\n            val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];\n            if (isDefined(val) && val !== null) {\n              if (paramInfo.isQueryParamValue) {\n                encodedVal = encodeUriQuery(val, true);\n              } else {\n                encodedVal = encodeUriSegment(val);\n              }\n              url = url.replace(new RegExp(':' + urlParam + '(\\\\W|$)', 'g'), function(match, p1) {\n                return encodedVal + p1;\n              });\n            } else {\n              url = url.replace(new RegExp('(/?):' + urlParam + '(\\\\W|$)', 'g'), function(match,\n                  leadingSlashes, tail) {\n                if (tail.charAt(0) === '/') {\n                  return tail;\n                } else {\n                  return leadingSlashes + tail;\n                }\n              });\n            }\n          });\n\n          // strip trailing slashes and set the url (unless this behavior is specifically disabled)\n          if (self.defaults.stripTrailingSlashes) {\n            url = url.replace(/\\/+$/, '') || '/';\n          }\n\n          // Collapse `/.` if found in the last URL path segment before the query.\n          // E.g. `http://url.com/id/.format?q=x` becomes `http://url.com/id.format?q=x`.\n          url = url.replace(/\\/\\.(?=\\w+($|\\?))/, '.');\n          // Replace escaped `/\\.` with `/.`.\n          // (If `\\.` comes from a param value, it will be encoded as `%5C.`.)\n          config.url = protocolAndIpv6 + url.replace(/\\/(\\\\|%5C)\\./, '/.');\n\n\n          // set params - delegate param encoding to $http\n          forEach(params, function(value, key) {\n            if (!self.urlParams[key]) {\n              config.params = config.params || {};\n              config.params[key] = value;\n            }\n          });\n        }\n      };\n\n\n      function resourceFactory(url, paramDefaults, actions, options) {\n        var route = new Route(url, options);\n\n        actions = extend({}, provider.defaults.actions, actions);\n\n        function extractParams(data, actionParams) {\n          var ids = {};\n          actionParams = extend({}, paramDefaults, actionParams);\n          forEach(actionParams, function(value, key) {\n            if (isFunction(value)) { value = value(data); }\n            ids[key] = value && value.charAt && value.charAt(0) === '@' ?\n              lookupDottedPath(data, value.substr(1)) : value;\n          });\n          return ids;\n        }\n\n        function defaultResponseInterceptor(response) {\n          return response.resource;\n        }\n\n        function Resource(value) {\n          shallowClearAndCopy(value || {}, this);\n        }\n\n        Resource.prototype.toJSON = function() {\n          var data = extend({}, this);\n          delete data.$promise;\n          delete data.$resolved;\n          delete data.$cancelRequest;\n          return data;\n        };\n\n        forEach(actions, function(action, name) {\n          var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);\n          var numericTimeout = action.timeout;\n          var cancellable = isDefined(action.cancellable) ?\n              action.cancellable : route.defaults.cancellable;\n\n          if (numericTimeout && !isNumber(numericTimeout)) {\n            $log.debug('ngResource:\\n' +\n                       '  Only numeric values are allowed as `timeout`.\\n' +\n                       '  Promises are not supported in $resource, because the same value would ' +\n                       'be used for multiple requests. If you are looking for a way to cancel ' +\n                       'requests, you should use the `cancellable` option.');\n            delete action.timeout;\n            numericTimeout = null;\n          }\n\n          Resource[name] = function(a1, a2, a3, a4) {\n            var params = {}, data, success, error;\n\n            switch (arguments.length) {\n              case 4:\n                error = a4;\n                success = a3;\n                // falls through\n              case 3:\n              case 2:\n                if (isFunction(a2)) {\n                  if (isFunction(a1)) {\n                    success = a1;\n                    error = a2;\n                    break;\n                  }\n\n                  success = a2;\n                  error = a3;\n                  // falls through\n                } else {\n                  params = a1;\n                  data = a2;\n                  success = a3;\n                  break;\n                }\n                // falls through\n              case 1:\n                if (isFunction(a1)) success = a1;\n                else if (hasBody) data = a1;\n                else params = a1;\n                break;\n              case 0: break;\n              default:\n                throw $resourceMinErr('badargs',\n                  'Expected up to 4 arguments [params, data, success, error], got {0} arguments',\n                  arguments.length);\n            }\n\n            var isInstanceCall = this instanceof Resource;\n            var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));\n            var httpConfig = {};\n            var responseInterceptor = action.interceptor && action.interceptor.response ||\n              defaultResponseInterceptor;\n            var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||\n              undefined;\n            var hasError = !!error;\n            var hasResponseErrorInterceptor = !!responseErrorInterceptor;\n            var timeoutDeferred;\n            var numericTimeoutPromise;\n\n            forEach(action, function(value, key) {\n              switch (key) {\n                default:\n                  httpConfig[key] = copy(value);\n                  break;\n                case 'params':\n                case 'isArray':\n                case 'interceptor':\n                case 'cancellable':\n                  break;\n              }\n            });\n\n            if (!isInstanceCall && cancellable) {\n              timeoutDeferred = $q.defer();\n              httpConfig.timeout = timeoutDeferred.promise;\n\n              if (numericTimeout) {\n                numericTimeoutPromise = $timeout(timeoutDeferred.resolve, numericTimeout);\n              }\n            }\n\n            if (hasBody) httpConfig.data = data;\n            route.setUrlParams(httpConfig,\n              extend({}, extractParams(data, action.params || {}), params),\n              action.url);\n\n            var promise = $http(httpConfig).then(function(response) {\n              var data = response.data;\n\n              if (data) {\n                // Need to convert action.isArray to boolean in case it is undefined\n                if (isArray(data) !== (!!action.isArray)) {\n                  throw $resourceMinErr('badcfg',\n                      'Error in resource configuration for action `{0}`. Expected response to ' +\n                      'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',\n                    isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);\n                }\n                if (action.isArray) {\n                  value.length = 0;\n                  forEach(data, function(item) {\n                    if (typeof item === 'object') {\n                      value.push(new Resource(item));\n                    } else {\n                      // Valid JSON values may be string literals, and these should not be converted\n                      // into objects. These items will not have access to the Resource prototype\n                      // methods, but unfortunately there\n                      value.push(item);\n                    }\n                  });\n                } else {\n                  var promise = value.$promise;     // Save the promise\n                  shallowClearAndCopy(data, value);\n                  value.$promise = promise;         // Restore the promise\n                }\n              }\n              response.resource = value;\n\n              return response;\n            });\n\n            promise = promise['finally'](function() {\n              value.$resolved = true;\n              if (!isInstanceCall && cancellable) {\n                value.$cancelRequest = noop;\n                $timeout.cancel(numericTimeoutPromise);\n                timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null;\n              }\n            });\n\n            promise = promise.then(\n              function(response) {\n                var value = responseInterceptor(response);\n                (success || noop)(value, response.headers, response.status, response.statusText);\n                return value;\n              },\n              (hasError || hasResponseErrorInterceptor) ?\n                function(response) {\n                  if (hasError && !hasResponseErrorInterceptor) {\n                    // Avoid `Possibly Unhandled Rejection` error,\n                    // but still fulfill the returned promise with a rejection\n                    promise.catch(noop);\n                  }\n                  if (hasError) error(response);\n                  return hasResponseErrorInterceptor ?\n                    responseErrorInterceptor(response) :\n                    $q.reject(response);\n                } :\n                undefined);\n\n            if (!isInstanceCall) {\n              // we are creating instance / collection\n              // - set the initial promise\n              // - return the instance / collection\n              value.$promise = promise;\n              value.$resolved = false;\n              if (cancellable) value.$cancelRequest = cancelRequest;\n\n              return value;\n            }\n\n            // instance call\n            return promise;\n\n            function cancelRequest(value) {\n              promise.catch(noop);\n              timeoutDeferred.resolve(value);\n            }\n          };\n\n\n          Resource.prototype['$' + name] = function(params, success, error) {\n            if (isFunction(params)) {\n              error = success; success = params; params = {};\n            }\n            var result = Resource[name].call(this, params, this, success, error);\n            return result.$promise || result;\n          };\n        });\n\n        Resource.bind = function(additionalParamDefaults) {\n          var extendedParamDefaults = extend({}, paramDefaults, additionalParamDefaults);\n          return resourceFactory(url, extendedParamDefaults, actions, options);\n        };\n\n        return Resource;\n      }\n\n      return resourceFactory;\n    }];\n  });\n\n\n})(window, window.angular);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-resource/angular-resource.js\n// module id = 9\n// module chunks = 0","/**\n * @license AngularJS v1.6.3\n * (c) 2010-2017 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window) {'use strict';\n\n/**\n * @description\n *\n * This object provides a utility for producing rich Error messages within\n * Angular. It can be called as follows:\n *\n * var exampleMinErr = minErr('example');\n * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);\n *\n * The above creates an instance of minErr in the example namespace. The\n * resulting error will have a namespaced error code of example.one.  The\n * resulting error will replace {0} with the value of foo, and {1} with the\n * value of bar. The object is not restricted in the number of arguments it can\n * take.\n *\n * If fewer arguments are specified than necessary for interpolation, the extra\n * interpolation markers will be preserved in the final string.\n *\n * Since data will be parsed statically during a build step, some restrictions\n * are applied with respect to how minErr instances are created and called.\n * Instances should have names of the form namespaceMinErr for a minErr created\n * using minErr('namespace') . Error codes, namespaces and template strings\n * should all be static strings, not variables or general expressions.\n *\n * @param {string} module The namespace to use for the new minErr instance.\n * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning\n *   error from returned function, for cases when a particular type of error is useful.\n * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance\n */\n\nfunction minErr(module, ErrorConstructor) {\n  ErrorConstructor = ErrorConstructor || Error;\n  return function() {\n    var code = arguments[0],\n      template = arguments[1],\n      message = '[' + (module ? module + ':' : '') + code + '] ',\n      templateArgs = sliceArgs(arguments, 2).map(function(arg) {\n        return toDebugString(arg, minErrConfig.objectMaxDepth);\n      }),\n      paramPrefix, i;\n\n    message += template.replace(/\\{\\d+\\}/g, function(match) {\n      var index = +match.slice(1, -1);\n\n      if (index < templateArgs.length) {\n        return templateArgs[index];\n      }\n\n      return match;\n    });\n\n    message += '\\nhttp://errors.angularjs.org/1.6.3/' +\n      (module ? module + '/' : '') + code;\n\n    for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {\n      message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]);\n    }\n\n    return new ErrorConstructor(message);\n  };\n}\n\n/* We need to tell ESLint what variables are being exported */\n/* exported\n  angular,\n  msie,\n  jqLite,\n  jQuery,\n  slice,\n  splice,\n  push,\n  toString,\n  minErrConfig,\n  errorHandlingConfig,\n  isValidObjectMaxDepth,\n  ngMinErr,\n  angularModule,\n  uid,\n  REGEX_STRING_REGEXP,\n  VALIDITY_STATE_PROPERTY,\n\n  lowercase,\n  uppercase,\n  manualLowercase,\n  manualUppercase,\n  nodeName_,\n  isArrayLike,\n  forEach,\n  forEachSorted,\n  reverseParams,\n  nextUid,\n  setHashKey,\n  extend,\n  toInt,\n  inherit,\n  merge,\n  noop,\n  identity,\n  valueFn,\n  isUndefined,\n  isDefined,\n  isObject,\n  isBlankObject,\n  isString,\n  isNumber,\n  isNumberNaN,\n  isDate,\n  isArray,\n  isFunction,\n  isRegExp,\n  isWindow,\n  isScope,\n  isFile,\n  isFormData,\n  isBlob,\n  isBoolean,\n  isPromiseLike,\n  trim,\n  escapeForRegexp,\n  isElement,\n  makeMap,\n  includes,\n  arrayRemove,\n  copy,\n  equals,\n  csp,\n  jq,\n  concat,\n  sliceArgs,\n  bind,\n  toJsonReplacer,\n  toJson,\n  fromJson,\n  convertTimezoneToLocal,\n  timezoneToOffset,\n  startingTag,\n  tryDecodeURIComponent,\n  parseKeyValue,\n  toKeyValue,\n  encodeUriSegment,\n  encodeUriQuery,\n  angularInit,\n  bootstrap,\n  getTestability,\n  snake_case,\n  bindJQuery,\n  assertArg,\n  assertArgFn,\n  assertNotHasOwnProperty,\n  getter,\n  getBlockNodes,\n  hasOwnProperty,\n  createMap,\n  stringify,\n\n  NODE_TYPE_ELEMENT,\n  NODE_TYPE_ATTRIBUTE,\n  NODE_TYPE_TEXT,\n  NODE_TYPE_COMMENT,\n  NODE_TYPE_DOCUMENT,\n  NODE_TYPE_DOCUMENT_FRAGMENT\n*/\n\n////////////////////////////////////\n\n/**\n * @ngdoc module\n * @name ng\n * @module ng\n * @installation\n * @description\n *\n * # ng (core module)\n * The ng module is loaded by default when an AngularJS application is started. The module itself\n * contains the essential components for an AngularJS application to function. The table below\n * lists a high level breakdown of each of the services/factories, filters, directives and testing\n * components available within this core module.\n *\n * <div doc-module-components=\"ng\"></div>\n */\n\nvar REGEX_STRING_REGEXP = /^\\/(.+)\\/([a-z]*)$/;\n\n// The name of a form control's ValidityState property.\n// This is used so that it's possible for internal tests to create mock ValidityStates.\nvar VALIDITY_STATE_PROPERTY = 'validity';\n\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar minErrConfig = {\n  objectMaxDepth: 5\n};\n\n /**\n * @ngdoc function\n * @name angular.errorHandlingConfig\n * @module ng\n * @kind function\n *\n * @description\n * Configure several aspects of error handling in AngularJS if used as a setter or return the\n * current configuration if used as a getter. The following options are supported:\n *\n * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.\n *\n * Omitted or undefined options will leave the corresponding configuration values unchanged.\n *\n * @param {Object=} config - The configuration object. May only contain the options that need to be\n *     updated. Supported keys:\n *\n * * `objectMaxDepth`  **{Number}** - The max depth for stringifying objects. Setting to a\n *   non-positive or non-numeric value, removes the max depth limit.\n *   Default: 5\n */\nfunction errorHandlingConfig(config) {\n  if (isObject(config)) {\n    if (isDefined(config.objectMaxDepth)) {\n      minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;\n    }\n  } else {\n    return minErrConfig;\n  }\n}\n\n/**\n * @private\n * @param {Number} maxDepth\n * @return {boolean}\n */\nfunction isValidObjectMaxDepth(maxDepth) {\n  return isNumber(maxDepth) && maxDepth > 0;\n}\n\n/**\n * @ngdoc function\n * @name angular.lowercase\n * @module ng\n * @kind function\n *\n * @deprecated\n * sinceVersion=\"1.5.0\"\n * removeVersion=\"1.7.0\"\n * Use [String.prototype.toLowerCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) instead.\n *\n * @description Converts the specified string to lowercase.\n * @param {string} string String to be converted to lowercase.\n * @returns {string} Lowercased string.\n */\nvar lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};\n\n/**\n * @ngdoc function\n * @name angular.uppercase\n * @module ng\n * @kind function\n *\n * @deprecated\n * sinceVersion=\"1.5.0\"\n * removeVersion=\"1.7.0\"\n * Use [String.prototype.toUpperCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) instead.\n *\n * @description Converts the specified string to uppercase.\n * @param {string} string String to be converted to uppercase.\n * @returns {string} Uppercased string.\n */\nvar uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};\n\n\nvar manualLowercase = function(s) {\n  /* eslint-disable no-bitwise */\n  return isString(s)\n      ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})\n      : s;\n  /* eslint-enable */\n};\nvar manualUppercase = function(s) {\n  /* eslint-disable no-bitwise */\n  return isString(s)\n      ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})\n      : s;\n  /* eslint-enable */\n};\n\n\n// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish\n// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods\n// with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387\nif ('i' !== 'I'.toLowerCase()) {\n  lowercase = manualLowercase;\n  uppercase = manualUppercase;\n}\n\n\nvar\n    msie,             // holds major version number for IE, or NaN if UA is not IE.\n    jqLite,           // delay binding since jQuery could be loaded after us.\n    jQuery,           // delay binding\n    slice             = [].slice,\n    splice            = [].splice,\n    push              = [].push,\n    toString          = Object.prototype.toString,\n    getPrototypeOf    = Object.getPrototypeOf,\n    ngMinErr          = minErr('ng'),\n\n    /** @name angular */\n    angular           = window.angular || (window.angular = {}),\n    angularModule,\n    uid               = 0;\n\n// Support: IE 9-11 only\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nmsie = window.document.documentMode;\n\n\n/**\n * @private\n * @param {*} obj\n * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,\n *                   String ...)\n */\nfunction isArrayLike(obj) {\n\n  // `null`, `undefined` and `window` are not array-like\n  if (obj == null || isWindow(obj)) return false;\n\n  // arrays, strings and jQuery/jqLite objects are array like\n  // * jqLite is either the jQuery or jqLite constructor function\n  // * we have to check the existence of jqLite first as this method is called\n  //   via the forEach method when constructing the jqLite object in the first place\n  if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;\n\n  // Support: iOS 8.2 (not reproducible in simulator)\n  // \"length\" in obj used to prevent JIT error (gh-11508)\n  var length = 'length' in Object(obj) && obj.length;\n\n  // NodeList objects (with `item` method) and\n  // other objects with suitable length characteristics are array-like\n  return isNumber(length) &&\n    (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item === 'function');\n\n}\n\n/**\n * @ngdoc function\n * @name angular.forEach\n * @module ng\n * @kind function\n *\n * @description\n * Invokes the `iterator` function once for each item in `obj` collection, which can be either an\n * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`\n * is the value of an object property or an array element, `key` is the object property key or\n * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.\n *\n * It is worth noting that `.forEach` does not iterate over inherited properties because it filters\n * using the `hasOwnProperty` method.\n *\n * Unlike ES262's\n * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),\n * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just\n * return the value provided.\n *\n   ```js\n     var values = {name: 'misko', gender: 'male'};\n     var log = [];\n     angular.forEach(values, function(value, key) {\n       this.push(key + ': ' + value);\n     }, log);\n     expect(log).toEqual(['name: misko', 'gender: male']);\n   ```\n *\n * @param {Object|Array} obj Object to iterate over.\n * @param {Function} iterator Iterator function.\n * @param {Object=} context Object to become context (`this`) for the iterator function.\n * @returns {Object|Array} Reference to `obj`.\n */\n\nfunction forEach(obj, iterator, context) {\n  var key, length;\n  if (obj) {\n    if (isFunction(obj)) {\n      for (key in obj) {\n        if (key !== 'prototype' && key !== 'length' && key !== 'name' && obj.hasOwnProperty(key)) {\n          iterator.call(context, obj[key], key, obj);\n        }\n      }\n    } else if (isArray(obj) || isArrayLike(obj)) {\n      var isPrimitive = typeof obj !== 'object';\n      for (key = 0, length = obj.length; key < length; key++) {\n        if (isPrimitive || key in obj) {\n          iterator.call(context, obj[key], key, obj);\n        }\n      }\n    } else if (obj.forEach && obj.forEach !== forEach) {\n        obj.forEach(iterator, context, obj);\n    } else if (isBlankObject(obj)) {\n      // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty\n      for (key in obj) {\n        iterator.call(context, obj[key], key, obj);\n      }\n    } else if (typeof obj.hasOwnProperty === 'function') {\n      // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed\n      for (key in obj) {\n        if (obj.hasOwnProperty(key)) {\n          iterator.call(context, obj[key], key, obj);\n        }\n      }\n    } else {\n      // Slow path for objects which do not have a method `hasOwnProperty`\n      for (key in obj) {\n        if (hasOwnProperty.call(obj, key)) {\n          iterator.call(context, obj[key], key, obj);\n        }\n      }\n    }\n  }\n  return obj;\n}\n\nfunction forEachSorted(obj, iterator, context) {\n  var keys = Object.keys(obj).sort();\n  for (var i = 0; i < keys.length; i++) {\n    iterator.call(context, obj[keys[i]], keys[i]);\n  }\n  return keys;\n}\n\n\n/**\n * when using forEach the params are value, key, but it is often useful to have key, value.\n * @param {function(string, *)} iteratorFn\n * @returns {function(*, string)}\n */\nfunction reverseParams(iteratorFn) {\n  return function(value, key) {iteratorFn(key, value);};\n}\n\n/**\n * A consistent way of creating unique IDs in angular.\n *\n * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before\n * we hit number precision issues in JavaScript.\n *\n * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M\n *\n * @returns {number} an unique alpha-numeric string\n */\nfunction nextUid() {\n  return ++uid;\n}\n\n\n/**\n * Set or clear the hashkey for an object.\n * @param obj object\n * @param h the hashkey (!truthy to delete the hashkey)\n */\nfunction setHashKey(obj, h) {\n  if (h) {\n    obj.$$hashKey = h;\n  } else {\n    delete obj.$$hashKey;\n  }\n}\n\n\nfunction baseExtend(dst, objs, deep) {\n  var h = dst.$$hashKey;\n\n  for (var i = 0, ii = objs.length; i < ii; ++i) {\n    var obj = objs[i];\n    if (!isObject(obj) && !isFunction(obj)) continue;\n    var keys = Object.keys(obj);\n    for (var j = 0, jj = keys.length; j < jj; j++) {\n      var key = keys[j];\n      var src = obj[key];\n\n      if (deep && isObject(src)) {\n        if (isDate(src)) {\n          dst[key] = new Date(src.valueOf());\n        } else if (isRegExp(src)) {\n          dst[key] = new RegExp(src);\n        } else if (src.nodeName) {\n          dst[key] = src.cloneNode(true);\n        } else if (isElement(src)) {\n          dst[key] = src.clone();\n        } else {\n          if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};\n          baseExtend(dst[key], [src], true);\n        }\n      } else {\n        dst[key] = src;\n      }\n    }\n  }\n\n  setHashKey(dst, h);\n  return dst;\n}\n\n/**\n * @ngdoc function\n * @name angular.extend\n * @module ng\n * @kind function\n *\n * @description\n * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)\n * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so\n * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.\n *\n * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use\n * {@link angular.merge} for this.\n *\n * @param {Object} dst Destination object.\n * @param {...Object} src Source object(s).\n * @returns {Object} Reference to `dst`.\n */\nfunction extend(dst) {\n  return baseExtend(dst, slice.call(arguments, 1), false);\n}\n\n\n/**\n* @ngdoc function\n* @name angular.merge\n* @module ng\n* @kind function\n*\n* @description\n* Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)\n* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so\n* by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.\n*\n* Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source\n* objects, performing a deep copy.\n*\n* @param {Object} dst Destination object.\n* @param {...Object} src Source object(s).\n* @returns {Object} Reference to `dst`.\n*/\nfunction merge(dst) {\n  return baseExtend(dst, slice.call(arguments, 1), true);\n}\n\n\n\nfunction toInt(str) {\n  return parseInt(str, 10);\n}\n\nvar isNumberNaN = Number.isNaN || function isNumberNaN(num) {\n  // eslint-disable-next-line no-self-compare\n  return num !== num;\n};\n\n\nfunction inherit(parent, extra) {\n  return extend(Object.create(parent), extra);\n}\n\n/**\n * @ngdoc function\n * @name angular.noop\n * @module ng\n * @kind function\n *\n * @description\n * A function that performs no operations. This function can be useful when writing code in the\n * functional style.\n   ```js\n     function foo(callback) {\n       var result = calculateResult();\n       (callback || angular.noop)(result);\n     }\n   ```\n */\nfunction noop() {}\nnoop.$inject = [];\n\n\n/**\n * @ngdoc function\n * @name angular.identity\n * @module ng\n * @kind function\n *\n * @description\n * A function that returns its first argument. This function is useful when writing code in the\n * functional style.\n *\n   ```js\n   function transformer(transformationFn, value) {\n     return (transformationFn || angular.identity)(value);\n   };\n\n   // E.g.\n   function getResult(fn, input) {\n     return (fn || angular.identity)(input);\n   };\n\n   getResult(function(n) { return n * 2; }, 21);   // returns 42\n   getResult(null, 21);                            // returns 21\n   getResult(undefined, 21);                       // returns 21\n   ```\n *\n * @param {*} value to be returned.\n * @returns {*} the value passed in.\n */\nfunction identity($) {return $;}\nidentity.$inject = [];\n\n\nfunction valueFn(value) {return function valueRef() {return value;};}\n\nfunction hasCustomToString(obj) {\n  return isFunction(obj.toString) && obj.toString !== toString;\n}\n\n\n/**\n * @ngdoc function\n * @name angular.isUndefined\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is undefined.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is undefined.\n */\nfunction isUndefined(value) {return typeof value === 'undefined';}\n\n\n/**\n * @ngdoc function\n * @name angular.isDefined\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is defined.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is defined.\n */\nfunction isDefined(value) {return typeof value !== 'undefined';}\n\n\n/**\n * @ngdoc function\n * @name angular.isObject\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not\n * considered to be objects. Note that JavaScript arrays are objects.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is an `Object` but not `null`.\n */\nfunction isObject(value) {\n  // http://jsperf.com/isobject4\n  return value !== null && typeof value === 'object';\n}\n\n\n/**\n * Determine if a value is an object with a null prototype\n *\n * @returns {boolean} True if `value` is an `Object` with a null prototype\n */\nfunction isBlankObject(value) {\n  return value !== null && typeof value === 'object' && !getPrototypeOf(value);\n}\n\n\n/**\n * @ngdoc function\n * @name angular.isString\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is a `String`.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `String`.\n */\nfunction isString(value) {return typeof value === 'string';}\n\n\n/**\n * @ngdoc function\n * @name angular.isNumber\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is a `Number`.\n *\n * This includes the \"special\" numbers `NaN`, `+Infinity` and `-Infinity`.\n *\n * If you wish to exclude these then you can use the native\n * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)\n * method.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Number`.\n */\nfunction isNumber(value) {return typeof value === 'number';}\n\n\n/**\n * @ngdoc function\n * @name angular.isDate\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a value is a date.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Date`.\n */\nfunction isDate(value) {\n  return toString.call(value) === '[object Date]';\n}\n\n\n/**\n * @ngdoc function\n * @name angular.isArray\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is an `Array`. Alias of Array.isArray.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is an `Array`.\n */\nvar isArray = Array.isArray;\n\n/**\n * @ngdoc function\n * @name angular.isFunction\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is a `Function`.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Function`.\n */\nfunction isFunction(value) {return typeof value === 'function';}\n\n\n/**\n * Determines if a value is a regular expression object.\n *\n * @private\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `RegExp`.\n */\nfunction isRegExp(value) {\n  return toString.call(value) === '[object RegExp]';\n}\n\n\n/**\n * Checks if `obj` is a window object.\n *\n * @private\n * @param {*} obj Object to check\n * @returns {boolean} True if `obj` is a window obj.\n */\nfunction isWindow(obj) {\n  return obj && obj.window === obj;\n}\n\n\nfunction isScope(obj) {\n  return obj && obj.$evalAsync && obj.$watch;\n}\n\n\nfunction isFile(obj) {\n  return toString.call(obj) === '[object File]';\n}\n\n\nfunction isFormData(obj) {\n  return toString.call(obj) === '[object FormData]';\n}\n\n\nfunction isBlob(obj) {\n  return toString.call(obj) === '[object Blob]';\n}\n\n\nfunction isBoolean(value) {\n  return typeof value === 'boolean';\n}\n\n\nfunction isPromiseLike(obj) {\n  return obj && isFunction(obj.then);\n}\n\n\nvar TYPED_ARRAY_REGEXP = /^\\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array]$/;\nfunction isTypedArray(value) {\n  return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));\n}\n\nfunction isArrayBuffer(obj) {\n  return toString.call(obj) === '[object ArrayBuffer]';\n}\n\n\nvar trim = function(value) {\n  return isString(value) ? value.trim() : value;\n};\n\n// Copied from:\n// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021\n// Prereq: s is a string.\nvar escapeForRegexp = function(s) {\n  return s\n    .replace(/([-()[\\]{}+?*.$^|,:#<!\\\\])/g, '\\\\$1')\n    // eslint-disable-next-line no-control-regex\n    .replace(/\\x08/g, '\\\\x08');\n};\n\n\n/**\n * @ngdoc function\n * @name angular.isElement\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is a DOM element (or wrapped jQuery element).\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).\n */\nfunction isElement(node) {\n  return !!(node &&\n    (node.nodeName  // We are a direct element.\n    || (node.prop && node.attr && node.find)));  // We have an on and find method part of jQuery API.\n}\n\n/**\n * @param str 'key1,key2,...'\n * @returns {object} in the form of {key1:true, key2:true, ...}\n */\nfunction makeMap(str) {\n  var obj = {}, items = str.split(','), i;\n  for (i = 0; i < items.length; i++) {\n    obj[items[i]] = true;\n  }\n  return obj;\n}\n\n\nfunction nodeName_(element) {\n  return lowercase(element.nodeName || (element[0] && element[0].nodeName));\n}\n\nfunction includes(array, obj) {\n  return Array.prototype.indexOf.call(array, obj) !== -1;\n}\n\nfunction arrayRemove(array, value) {\n  var index = array.indexOf(value);\n  if (index >= 0) {\n    array.splice(index, 1);\n  }\n  return index;\n}\n\n/**\n * @ngdoc function\n * @name angular.copy\n * @module ng\n * @kind function\n *\n * @description\n * Creates a deep copy of `source`, which should be an object or an array.\n *\n * * If no destination is supplied, a copy of the object or array is created.\n * * If a destination is provided, all of its elements (for arrays) or properties (for objects)\n *   are deleted and then all elements/properties from the source are copied to it.\n * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.\n * * If `source` is identical to `destination` an exception will be thrown.\n *\n * <br />\n * <div class=\"alert alert-warning\">\n *   Only enumerable properties are taken into account. Non-enumerable properties (both on `source`\n *   and on `destination`) will be ignored.\n * </div>\n *\n * @param {*} source The source that will be used to make a copy.\n *                   Can be any type, including primitives, `null`, and `undefined`.\n * @param {(Object|Array)=} destination Destination into which the source is copied. If\n *     provided, must be of the same type as `source`.\n * @returns {*} The copy or updated `destination`, if `destination` was specified.\n *\n * @example\n  <example module=\"copyExample\" name=\"angular-copy\">\n    <file name=\"index.html\">\n      <div ng-controller=\"ExampleController\">\n        <form novalidate class=\"simple-form\">\n          <label>Name: <input type=\"text\" ng-model=\"user.name\" /></label><br />\n          <label>Age:  <input type=\"number\" ng-model=\"user.age\" /></label><br />\n          Gender: <label><input type=\"radio\" ng-model=\"user.gender\" value=\"male\" />male</label>\n                  <label><input type=\"radio\" ng-model=\"user.gender\" value=\"female\" />female</label><br />\n          <button ng-click=\"reset()\">RESET</button>\n          <button ng-click=\"update(user)\">SAVE</button>\n        </form>\n        <pre>form = {{user | json}}</pre>\n        <pre>master = {{master | json}}</pre>\n      </div>\n    </file>\n    <file name=\"script.js\">\n      // Module: copyExample\n      angular.\n        module('copyExample', []).\n        controller('ExampleController', ['$scope', function($scope) {\n          $scope.master = {};\n\n          $scope.reset = function() {\n            // Example with 1 argument\n            $scope.user = angular.copy($scope.master);\n          };\n\n          $scope.update = function(user) {\n            // Example with 2 arguments\n            angular.copy(user, $scope.master);\n          };\n\n          $scope.reset();\n        }]);\n    </file>\n  </example>\n */\nfunction copy(source, destination, maxDepth) {\n  var stackSource = [];\n  var stackDest = [];\n  maxDepth = isValidObjectMaxDepth(maxDepth) ? maxDepth : NaN;\n\n  if (destination) {\n    if (isTypedArray(destination) || isArrayBuffer(destination)) {\n      throw ngMinErr('cpta', 'Can\\'t copy! TypedArray destination cannot be mutated.');\n    }\n    if (source === destination) {\n      throw ngMinErr('cpi', 'Can\\'t copy! Source and destination are identical.');\n    }\n\n    // Empty the destination object\n    if (isArray(destination)) {\n      destination.length = 0;\n    } else {\n      forEach(destination, function(value, key) {\n        if (key !== '$$hashKey') {\n          delete destination[key];\n        }\n      });\n    }\n\n    stackSource.push(source);\n    stackDest.push(destination);\n    return copyRecurse(source, destination, maxDepth);\n  }\n\n  return copyElement(source, maxDepth);\n\n  function copyRecurse(source, destination, maxDepth) {\n    maxDepth--;\n    if (maxDepth < 0) {\n      return '...';\n    }\n    var h = destination.$$hashKey;\n    var key;\n    if (isArray(source)) {\n      for (var i = 0, ii = source.length; i < ii; i++) {\n        destination.push(copyElement(source[i], maxDepth));\n      }\n    } else if (isBlankObject(source)) {\n      // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty\n      for (key in source) {\n        destination[key] = copyElement(source[key], maxDepth);\n      }\n    } else if (source && typeof source.hasOwnProperty === 'function') {\n      // Slow path, which must rely on hasOwnProperty\n      for (key in source) {\n        if (source.hasOwnProperty(key)) {\n          destination[key] = copyElement(source[key], maxDepth);\n        }\n      }\n    } else {\n      // Slowest path --- hasOwnProperty can't be called as a method\n      for (key in source) {\n        if (hasOwnProperty.call(source, key)) {\n          destination[key] = copyElement(source[key], maxDepth);\n        }\n      }\n    }\n    setHashKey(destination, h);\n    return destination;\n  }\n\n  function copyElement(source, maxDepth) {\n    // Simple values\n    if (!isObject(source)) {\n      return source;\n    }\n\n    // Already copied values\n    var index = stackSource.indexOf(source);\n    if (index !== -1) {\n      return stackDest[index];\n    }\n\n    if (isWindow(source) || isScope(source)) {\n      throw ngMinErr('cpws',\n        'Can\\'t copy! Making copies of Window or Scope instances is not supported.');\n    }\n\n    var needsRecurse = false;\n    var destination = copyType(source);\n\n    if (destination === undefined) {\n      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));\n      needsRecurse = true;\n    }\n\n    stackSource.push(source);\n    stackDest.push(destination);\n\n    return needsRecurse\n      ? copyRecurse(source, destination, maxDepth)\n      : destination;\n  }\n\n  function copyType(source) {\n    switch (toString.call(source)) {\n      case '[object Int8Array]':\n      case '[object Int16Array]':\n      case '[object Int32Array]':\n      case '[object Float32Array]':\n      case '[object Float64Array]':\n      case '[object Uint8Array]':\n      case '[object Uint8ClampedArray]':\n      case '[object Uint16Array]':\n      case '[object Uint32Array]':\n        return new source.constructor(copyElement(source.buffer), source.byteOffset, source.length);\n\n      case '[object ArrayBuffer]':\n        // Support: IE10\n        if (!source.slice) {\n          // If we're in this case we know the environment supports ArrayBuffer\n          /* eslint-disable no-undef */\n          var copied = new ArrayBuffer(source.byteLength);\n          new Uint8Array(copied).set(new Uint8Array(source));\n          /* eslint-enable */\n          return copied;\n        }\n        return source.slice(0);\n\n      case '[object Boolean]':\n      case '[object Number]':\n      case '[object String]':\n      case '[object Date]':\n        return new source.constructor(source.valueOf());\n\n      case '[object RegExp]':\n        var re = new RegExp(source.source, source.toString().match(/[^/]*$/)[0]);\n        re.lastIndex = source.lastIndex;\n        return re;\n\n      case '[object Blob]':\n        return new source.constructor([source], {type: source.type});\n    }\n\n    if (isFunction(source.cloneNode)) {\n      return source.cloneNode(true);\n    }\n  }\n}\n\n\n/**\n * @ngdoc function\n * @name angular.equals\n * @module ng\n * @kind function\n *\n * @description\n * Determines if two objects or two values are equivalent. Supports value types, regular\n * expressions, arrays and objects.\n *\n * Two objects or values are considered equivalent if at least one of the following is true:\n *\n * * Both objects or values pass `===` comparison.\n * * Both objects or values are of the same type and all of their properties are equal by\n *   comparing them with `angular.equals`.\n * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)\n * * Both values represent the same regular expression (In JavaScript,\n *   /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual\n *   representation matches).\n *\n * During a property comparison, properties of `function` type and properties with names\n * that begin with `$` are ignored.\n *\n * Scope and DOMWindow objects are being compared only by identify (`===`).\n *\n * @param {*} o1 Object or value to compare.\n * @param {*} o2 Object or value to compare.\n * @returns {boolean} True if arguments are equal.\n *\n * @example\n   <example module=\"equalsExample\" name=\"equalsExample\">\n     <file name=\"index.html\">\n      <div ng-controller=\"ExampleController\">\n        <form novalidate>\n          <h3>User 1</h3>\n          Name: <input type=\"text\" ng-model=\"user1.name\">\n          Age: <input type=\"number\" ng-model=\"user1.age\">\n\n          <h3>User 2</h3>\n          Name: <input type=\"text\" ng-model=\"user2.name\">\n          Age: <input type=\"number\" ng-model=\"user2.age\">\n\n          <div>\n            <br/>\n            <input type=\"button\" value=\"Compare\" ng-click=\"compare()\">\n          </div>\n          User 1: <pre>{{user1 | json}}</pre>\n          User 2: <pre>{{user2 | json}}</pre>\n          Equal: <pre>{{result}}</pre>\n        </form>\n      </div>\n    </file>\n    <file name=\"script.js\">\n        angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) {\n          $scope.user1 = {};\n          $scope.user2 = {};\n          $scope.compare = function() {\n            $scope.result = angular.equals($scope.user1, $scope.user2);\n          };\n        }]);\n    </file>\n  </example>\n */\nfunction equals(o1, o2) {\n  if (o1 === o2) return true;\n  if (o1 === null || o2 === null) return false;\n  // eslint-disable-next-line no-self-compare\n  if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN\n  var t1 = typeof o1, t2 = typeof o2, length, key, keySet;\n  if (t1 === t2 && t1 === 'object') {\n    if (isArray(o1)) {\n      if (!isArray(o2)) return false;\n      if ((length = o1.length) === o2.length) {\n        for (key = 0; key < length; key++) {\n          if (!equals(o1[key], o2[key])) return false;\n        }\n        return true;\n      }\n    } else if (isDate(o1)) {\n      if (!isDate(o2)) return false;\n      return equals(o1.getTime(), o2.getTime());\n    } else if (isRegExp(o1)) {\n      if (!isRegExp(o2)) return false;\n      return o1.toString() === o2.toString();\n    } else {\n      if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||\n        isArray(o2) || isDate(o2) || isRegExp(o2)) return false;\n      keySet = createMap();\n      for (key in o1) {\n        if (key.charAt(0) === '$' || isFunction(o1[key])) continue;\n        if (!equals(o1[key], o2[key])) return false;\n        keySet[key] = true;\n      }\n      for (key in o2) {\n        if (!(key in keySet) &&\n            key.charAt(0) !== '$' &&\n            isDefined(o2[key]) &&\n            !isFunction(o2[key])) return false;\n      }\n      return true;\n    }\n  }\n  return false;\n}\n\nvar csp = function() {\n  if (!isDefined(csp.rules)) {\n\n\n    var ngCspElement = (window.document.querySelector('[ng-csp]') ||\n                    window.document.querySelector('[data-ng-csp]'));\n\n    if (ngCspElement) {\n      var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||\n                    ngCspElement.getAttribute('data-ng-csp');\n      csp.rules = {\n        noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),\n        noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)\n      };\n    } else {\n      csp.rules = {\n        noUnsafeEval: noUnsafeEval(),\n        noInlineStyle: false\n      };\n    }\n  }\n\n  return csp.rules;\n\n  function noUnsafeEval() {\n    try {\n      // eslint-disable-next-line no-new, no-new-func\n      new Function('');\n      return false;\n    } catch (e) {\n      return true;\n    }\n  }\n};\n\n/**\n * @ngdoc directive\n * @module ng\n * @name ngJq\n *\n * @element ANY\n * @param {string=} ngJq the name of the library available under `window`\n * to be used for angular.element\n * @description\n * Use this directive to force the angular.element library.  This should be\n * used to force either jqLite by leaving ng-jq blank or setting the name of\n * the jquery variable under window (eg. jQuery).\n *\n * Since angular looks for this directive when it is loaded (doesn't wait for the\n * DOMContentLoaded event), it must be placed on an element that comes before the script\n * which loads angular. Also, only the first instance of `ng-jq` will be used and all\n * others ignored.\n *\n * @example\n * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.\n ```html\n <!doctype html>\n <html ng-app ng-jq>\n ...\n ...\n </html>\n ```\n * @example\n * This example shows how to use a jQuery based library of a different name.\n * The library name must be available at the top most 'window'.\n ```html\n <!doctype html>\n <html ng-app ng-jq=\"jQueryLib\">\n ...\n ...\n </html>\n ```\n */\nvar jq = function() {\n  if (isDefined(jq.name_)) return jq.name_;\n  var el;\n  var i, ii = ngAttrPrefixes.length, prefix, name;\n  for (i = 0; i < ii; ++i) {\n    prefix = ngAttrPrefixes[i];\n    el = window.document.querySelector('[' + prefix.replace(':', '\\\\:') + 'jq]');\n    if (el) {\n      name = el.getAttribute(prefix + 'jq');\n      break;\n    }\n  }\n\n  return (jq.name_ = name);\n};\n\nfunction concat(array1, array2, index) {\n  return array1.concat(slice.call(array2, index));\n}\n\nfunction sliceArgs(args, startIndex) {\n  return slice.call(args, startIndex || 0);\n}\n\n\n/**\n * @ngdoc function\n * @name angular.bind\n * @module ng\n * @kind function\n *\n * @description\n * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for\n * `fn`). You can supply optional `args` that are prebound to the function. This feature is also\n * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as\n * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).\n *\n * @param {Object} self Context which `fn` should be evaluated in.\n * @param {function()} fn Function to be bound.\n * @param {...*} args Optional arguments to be prebound to the `fn` function call.\n * @returns {function()} Function that wraps the `fn` with all the specified bindings.\n */\nfunction bind(self, fn) {\n  var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];\n  if (isFunction(fn) && !(fn instanceof RegExp)) {\n    return curryArgs.length\n      ? function() {\n          return arguments.length\n            ? fn.apply(self, concat(curryArgs, arguments, 0))\n            : fn.apply(self, curryArgs);\n        }\n      : function() {\n          return arguments.length\n            ? fn.apply(self, arguments)\n            : fn.call(self);\n        };\n  } else {\n    // In IE, native methods are not functions so they cannot be bound (note: they don't need to be).\n    return fn;\n  }\n}\n\n\nfunction toJsonReplacer(key, value) {\n  var val = value;\n\n  if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {\n    val = undefined;\n  } else if (isWindow(value)) {\n    val = '$WINDOW';\n  } else if (value &&  window.document === value) {\n    val = '$DOCUMENT';\n  } else if (isScope(value)) {\n    val = '$SCOPE';\n  }\n\n  return val;\n}\n\n\n/**\n * @ngdoc function\n * @name angular.toJson\n * @module ng\n * @kind function\n *\n * @description\n * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be\n * stripped since angular uses this notation internally.\n *\n * @param {Object|Array|Date|string|number|boolean} obj Input to be serialized into JSON.\n * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.\n *    If set to an integer, the JSON output will contain that many spaces per indentation.\n * @returns {string|undefined} JSON-ified string representing `obj`.\n * @knownIssue\n *\n * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date`\n * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the\n * `Date.prototype.toJSON` method as follows:\n *\n * ```\n * var _DatetoJSON = Date.prototype.toJSON;\n * Date.prototype.toJSON = function() {\n *   try {\n *     return _DatetoJSON.call(this);\n *   } catch(e) {\n *     if (e instanceof RangeError) {\n *       return null;\n *     }\n *     throw e;\n *   }\n * };\n * ```\n *\n * See https://github.com/angular/angular.js/pull/14221 for more information.\n */\nfunction toJson(obj, pretty) {\n  if (isUndefined(obj)) return undefined;\n  if (!isNumber(pretty)) {\n    pretty = pretty ? 2 : null;\n  }\n  return JSON.stringify(obj, toJsonReplacer, pretty);\n}\n\n\n/**\n * @ngdoc function\n * @name angular.fromJson\n * @module ng\n * @kind function\n *\n * @description\n * Deserializes a JSON string.\n *\n * @param {string} json JSON string to deserialize.\n * @returns {Object|Array|string|number} Deserialized JSON string.\n */\nfunction fromJson(json) {\n  return isString(json)\n      ? JSON.parse(json)\n      : json;\n}\n\n\nvar ALL_COLONS = /:/g;\nfunction timezoneToOffset(timezone, fallback) {\n  // Support: IE 9-11 only, Edge 13-14+\n  // IE/Edge do not \"understand\" colon (`:`) in timezone\n  timezone = timezone.replace(ALL_COLONS, '');\n  var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;\n  return isNumberNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;\n}\n\n\nfunction addDateMinutes(date, minutes) {\n  date = new Date(date.getTime());\n  date.setMinutes(date.getMinutes() + minutes);\n  return date;\n}\n\n\nfunction convertTimezoneToLocal(date, timezone, reverse) {\n  reverse = reverse ? -1 : 1;\n  var dateTimezoneOffset = date.getTimezoneOffset();\n  var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);\n  return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));\n}\n\n\n/**\n * @returns {string} Returns the string representation of the element.\n */\nfunction startingTag(element) {\n  element = jqLite(element).clone();\n  try {\n    // turns out IE does not let you set .html() on elements which\n    // are not allowed to have children. So we just ignore it.\n    element.empty();\n  } catch (e) { /* empty */ }\n  var elemHtml = jqLite('<div>').append(element).html();\n  try {\n    return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :\n        elemHtml.\n          match(/^(<[^>]+>)/)[1].\n          replace(/^<([\\w-]+)/, function(match, nodeName) {return '<' + lowercase(nodeName);});\n  } catch (e) {\n    return lowercase(elemHtml);\n  }\n\n}\n\n\n/////////////////////////////////////////////////\n\n/**\n * Tries to decode the URI component without throwing an exception.\n *\n * @private\n * @param str value potential URI component to check.\n * @returns {boolean} True if `value` can be decoded\n * with the decodeURIComponent function.\n */\nfunction tryDecodeURIComponent(value) {\n  try {\n    return decodeURIComponent(value);\n  } catch (e) {\n    // Ignore any invalid uri component.\n  }\n}\n\n\n/**\n * Parses an escaped url query string into key-value pairs.\n * @returns {Object.<string,boolean|Array>}\n */\nfunction parseKeyValue(/**string*/keyValue) {\n  var obj = {};\n  forEach((keyValue || '').split('&'), function(keyValue) {\n    var splitPoint, key, val;\n    if (keyValue) {\n      key = keyValue = keyValue.replace(/\\+/g,'%20');\n      splitPoint = keyValue.indexOf('=');\n      if (splitPoint !== -1) {\n        key = keyValue.substring(0, splitPoint);\n        val = keyValue.substring(splitPoint + 1);\n      }\n      key = tryDecodeURIComponent(key);\n      if (isDefined(key)) {\n        val = isDefined(val) ? tryDecodeURIComponent(val) : true;\n        if (!hasOwnProperty.call(obj, key)) {\n          obj[key] = val;\n        } else if (isArray(obj[key])) {\n          obj[key].push(val);\n        } else {\n          obj[key] = [obj[key],val];\n        }\n      }\n    }\n  });\n  return obj;\n}\n\nfunction toKeyValue(obj) {\n  var parts = [];\n  forEach(obj, function(value, key) {\n    if (isArray(value)) {\n      forEach(value, function(arrayValue) {\n        parts.push(encodeUriQuery(key, true) +\n                   (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));\n      });\n    } else {\n    parts.push(encodeUriQuery(key, true) +\n               (value === true ? '' : '=' + encodeUriQuery(value, true)));\n    }\n  });\n  return parts.length ? parts.join('&') : '';\n}\n\n\n/**\n * We need our custom method because encodeURIComponent is too aggressive and doesn't follow\n * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path\n * segments:\n *    segment       = *pchar\n *    pchar         = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n *    pct-encoded   = \"%\" HEXDIG HEXDIG\n *    unreserved    = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n *    sub-delims    = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n *                     / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n */\nfunction encodeUriSegment(val) {\n  return encodeUriQuery(val, true).\n             replace(/%26/gi, '&').\n             replace(/%3D/gi, '=').\n             replace(/%2B/gi, '+');\n}\n\n\n/**\n * This method is intended for encoding *key* or *value* parts of query component. We need a custom\n * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be\n * encoded per http://tools.ietf.org/html/rfc3986:\n *    query         = *( pchar / \"/\" / \"?\" )\n *    pchar         = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n *    unreserved    = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n *    pct-encoded   = \"%\" HEXDIG HEXDIG\n *    sub-delims    = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n *                     / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n */\nfunction encodeUriQuery(val, pctEncodeSpaces) {\n  return encodeURIComponent(val).\n             replace(/%40/gi, '@').\n             replace(/%3A/gi, ':').\n             replace(/%24/g, '$').\n             replace(/%2C/gi, ',').\n             replace(/%3B/gi, ';').\n             replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));\n}\n\nvar ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];\n\nfunction getNgAttribute(element, ngAttr) {\n  var attr, i, ii = ngAttrPrefixes.length;\n  for (i = 0; i < ii; ++i) {\n    attr = ngAttrPrefixes[i] + ngAttr;\n    if (isString(attr = element.getAttribute(attr))) {\n      return attr;\n    }\n  }\n  return null;\n}\n\nfunction allowAutoBootstrap(document) {\n  var script = document.currentScript;\n\n  if (!script) {\n    // IE does not have `document.currentScript`\n    return true;\n  }\n\n  // If the `currentScript` property has been clobbered just return false, since this indicates a probable attack\n  if (!(script instanceof window.HTMLScriptElement || script instanceof window.SVGScriptElement)) {\n    return false;\n  }\n\n  var attributes = script.attributes;\n  var srcs = [attributes.getNamedItem('src'), attributes.getNamedItem('href'), attributes.getNamedItem('xlink:href')];\n\n  return srcs.every(function(src) {\n    if (!src) {\n      return true;\n    }\n    if (!src.value) {\n      return false;\n    }\n\n    var link = document.createElement('a');\n    link.href = src.value;\n\n    if (document.location.origin === link.origin) {\n      // Same-origin resources are always allowed, even for non-whitelisted schemes.\n      return true;\n    }\n    // Disabled bootstrapping unless angular.js was loaded from a known scheme used on the web.\n    // This is to prevent angular.js bundled with browser extensions from being used to bypass the\n    // content security policy in web pages and other browser extensions.\n    switch (link.protocol) {\n      case 'http:':\n      case 'https:':\n      case 'ftp:':\n      case 'blob:':\n      case 'file:':\n      case 'data:':\n        return true;\n      default:\n        return false;\n    }\n  });\n}\n\n// Cached as it has to run during loading so that document.currentScript is available.\nvar isAutoBootstrapAllowed = allowAutoBootstrap(window.document);\n\n/**\n * @ngdoc directive\n * @name ngApp\n * @module ng\n *\n * @element ANY\n * @param {angular.Module} ngApp an optional application\n *   {@link angular.module module} name to load.\n * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be\n *   created in \"strict-di\" mode. This means that the application will fail to invoke functions which\n *   do not use explicit function annotation (and are thus unsuitable for minification), as described\n *   in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in\n *   tracking down the root of these bugs.\n *\n * @description\n *\n * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive\n * designates the **root element** of the application and is typically placed near the root element\n * of the page - e.g. on the `<body>` or `<html>` tags.\n *\n * There are a few things to keep in mind when using `ngApp`:\n * - only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`\n *   found in the document will be used to define the root element to auto-bootstrap as an\n *   application. To run multiple applications in an HTML document you must manually bootstrap them using\n *   {@link angular.bootstrap} instead.\n * - AngularJS applications cannot be nested within each other.\n * - Do not use a directive that uses {@link ng.$compile#transclusion transclusion} on the same element as `ngApp`.\n *   This includes directives such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and\n *   {@link ngRoute.ngView `ngView`}.\n *   Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},\n *   causing animations to stop working and making the injector inaccessible from outside the app.\n *\n * You can specify an **AngularJS module** to be used as the root module for the application.  This\n * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It\n * should contain the application code needed or have dependencies on other modules that will\n * contain the code. See {@link angular.module} for more information.\n *\n * In the example below if the `ngApp` directive were not placed on the `html` element then the\n * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`\n * would not be resolved to `3`.\n *\n * `ngApp` is the easiest, and most common way to bootstrap an application.\n *\n <example module=\"ngAppDemo\" name=\"ng-app\">\n   <file name=\"index.html\">\n   <div ng-controller=\"ngAppDemoController\">\n     I can add: {{a}} + {{b}} =  {{ a+b }}\n   </div>\n   </file>\n   <file name=\"script.js\">\n   angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {\n     $scope.a = 1;\n     $scope.b = 2;\n   });\n   </file>\n </example>\n *\n * Using `ngStrictDi`, you would see something like this:\n *\n <example ng-app-included=\"true\" name=\"strict-di\">\n   <file name=\"index.html\">\n   <div ng-app=\"ngAppStrictDemo\" ng-strict-di>\n       <div ng-controller=\"GoodController1\">\n           I can add: {{a}} + {{b}} =  {{ a+b }}\n\n           <p>This renders because the controller does not fail to\n              instantiate, by using explicit annotation style (see\n              script.js for details)\n           </p>\n       </div>\n\n       <div ng-controller=\"GoodController2\">\n           Name: <input ng-model=\"name\"><br />\n           Hello, {{name}}!\n\n           <p>This renders because the controller does not fail to\n              instantiate, by using explicit annotation style\n              (see script.js for details)\n           </p>\n       </div>\n\n       <div ng-controller=\"BadController\">\n           I can add: {{a}} + {{b}} =  {{ a+b }}\n\n           <p>The controller could not be instantiated, due to relying\n              on automatic function annotations (which are disabled in\n              strict mode). As such, the content of this section is not\n              interpolated, and there should be an error in your web console.\n           </p>\n       </div>\n   </div>\n   </file>\n   <file name=\"script.js\">\n   angular.module('ngAppStrictDemo', [])\n     // BadController will fail to instantiate, due to relying on automatic function annotation,\n     // rather than an explicit annotation\n     .controller('BadController', function($scope) {\n       $scope.a = 1;\n       $scope.b = 2;\n     })\n     // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,\n     // due to using explicit annotations using the array style and $inject property, respectively.\n     .controller('GoodController1', ['$scope', function($scope) {\n       $scope.a = 1;\n       $scope.b = 2;\n     }])\n     .controller('GoodController2', GoodController2);\n     function GoodController2($scope) {\n       $scope.name = 'World';\n     }\n     GoodController2.$inject = ['$scope'];\n   </file>\n   <file name=\"style.css\">\n   div[ng-controller] {\n       margin-bottom: 1em;\n       -webkit-border-radius: 4px;\n       border-radius: 4px;\n       border: 1px solid;\n       padding: .5em;\n   }\n   div[ng-controller^=Good] {\n       border-color: #d6e9c6;\n       background-color: #dff0d8;\n       color: #3c763d;\n   }\n   div[ng-controller^=Bad] {\n       border-color: #ebccd1;\n       background-color: #f2dede;\n       color: #a94442;\n       margin-bottom: 0;\n   }\n   </file>\n </example>\n */\nfunction angularInit(element, bootstrap) {\n  var appElement,\n      module,\n      config = {};\n\n  // The element `element` has priority over any other element.\n  forEach(ngAttrPrefixes, function(prefix) {\n    var name = prefix + 'app';\n\n    if (!appElement && element.hasAttribute && element.hasAttribute(name)) {\n      appElement = element;\n      module = element.getAttribute(name);\n    }\n  });\n  forEach(ngAttrPrefixes, function(prefix) {\n    var name = prefix + 'app';\n    var candidate;\n\n    if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\\\:') + ']'))) {\n      appElement = candidate;\n      module = candidate.getAttribute(name);\n    }\n  });\n  if (appElement) {\n    if (!isAutoBootstrapAllowed) {\n      window.console.error('Angular: disabling automatic bootstrap. <script> protocol indicates ' +\n          'an extension, document.location.href does not match.');\n      return;\n    }\n    config.strictDi = getNgAttribute(appElement, 'strict-di') !== null;\n    bootstrap(appElement, module ? [module] : [], config);\n  }\n}\n\n/**\n * @ngdoc function\n * @name angular.bootstrap\n * @module ng\n * @description\n * Use this function to manually start up angular application.\n *\n * For more information, see the {@link guide/bootstrap Bootstrap guide}.\n *\n * Angular will detect if it has been loaded into the browser more than once and only allow the\n * first loaded script to be bootstrapped and will report a warning to the browser console for\n * each of the subsequent scripts. This prevents strange results in applications, where otherwise\n * multiple instances of Angular try to work on the DOM.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Protractor based end-to-end tests cannot use this function to bootstrap manually.\n * They must use {@link ng.directive:ngApp ngApp}.\n * </div>\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},\n * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.\n * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},\n * causing animations to stop working and making the injector inaccessible from outside the app.\n * </div>\n *\n * ```html\n * <!doctype html>\n * <html>\n * <body>\n * <div ng-controller=\"WelcomeController\">\n *   {{greeting}}\n * </div>\n *\n * <script src=\"angular.js\"></script>\n * <script>\n *   var app = angular.module('demo', [])\n *   .controller('WelcomeController', function($scope) {\n *       $scope.greeting = 'Welcome!';\n *   });\n *   angular.bootstrap(document, ['demo']);\n * </script>\n * </body>\n * </html>\n * ```\n *\n * @param {DOMElement} element DOM element which is the root of angular application.\n * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.\n *     Each item in the array should be the name of a predefined module or a (DI annotated)\n *     function that will be invoked by the injector as a `config` block.\n *     See: {@link angular.module modules}\n * @param {Object=} config an object for defining configuration options for the application. The\n *     following keys are supported:\n *\n * * `strictDi` - disable automatic function annotation for the application. This is meant to\n *   assist in finding bugs which break minified code. Defaults to `false`.\n *\n * @returns {auto.$injector} Returns the newly created injector for this app.\n */\nfunction bootstrap(element, modules, config) {\n  if (!isObject(config)) config = {};\n  var defaultConfig = {\n    strictDi: false\n  };\n  config = extend(defaultConfig, config);\n  var doBootstrap = function() {\n    element = jqLite(element);\n\n    if (element.injector()) {\n      var tag = (element[0] === window.document) ? 'document' : startingTag(element);\n      // Encode angle brackets to prevent input from being sanitized to empty string #8683.\n      throw ngMinErr(\n          'btstrpd',\n          'App already bootstrapped with this element \\'{0}\\'',\n          tag.replace(/</,'&lt;').replace(/>/,'&gt;'));\n    }\n\n    modules = modules || [];\n    modules.unshift(['$provide', function($provide) {\n      $provide.value('$rootElement', element);\n    }]);\n\n    if (config.debugInfoEnabled) {\n      // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.\n      modules.push(['$compileProvider', function($compileProvider) {\n        $compileProvider.debugInfoEnabled(true);\n      }]);\n    }\n\n    modules.unshift('ng');\n    var injector = createInjector(modules, config.strictDi);\n    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',\n       function bootstrapApply(scope, element, compile, injector) {\n        scope.$apply(function() {\n          element.data('$injector', injector);\n          compile(element)(scope);\n        });\n      }]\n    );\n    return injector;\n  };\n\n  var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;\n  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;\n\n  if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {\n    config.debugInfoEnabled = true;\n    window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');\n  }\n\n  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {\n    return doBootstrap();\n  }\n\n  window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');\n  angular.resumeBootstrap = function(extraModules) {\n    forEach(extraModules, function(module) {\n      modules.push(module);\n    });\n    return doBootstrap();\n  };\n\n  if (isFunction(angular.resumeDeferredBootstrap)) {\n    angular.resumeDeferredBootstrap();\n  }\n}\n\n/**\n * @ngdoc function\n * @name angular.reloadWithDebugInfo\n * @module ng\n * @description\n * Use this function to reload the current application with debug information turned on.\n * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.\n *\n * See {@link ng.$compileProvider#debugInfoEnabled} for more.\n */\nfunction reloadWithDebugInfo() {\n  window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;\n  window.location.reload();\n}\n\n/**\n * @name angular.getTestability\n * @module ng\n * @description\n * Get the testability service for the instance of Angular on the given\n * element.\n * @param {DOMElement} element DOM element which is the root of angular application.\n */\nfunction getTestability(rootElement) {\n  var injector = angular.element(rootElement).injector();\n  if (!injector) {\n    throw ngMinErr('test',\n      'no injector found for element argument to getTestability');\n  }\n  return injector.get('$$testability');\n}\n\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nfunction snake_case(name, separator) {\n  separator = separator || '_';\n  return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n    return (pos ? separator : '') + letter.toLowerCase();\n  });\n}\n\nvar bindJQueryFired = false;\nfunction bindJQuery() {\n  var originalCleanData;\n\n  if (bindJQueryFired) {\n    return;\n  }\n\n  // bind to jQuery if present;\n  var jqName = jq();\n  jQuery = isUndefined(jqName) ? window.jQuery :   // use jQuery (if present)\n           !jqName             ? undefined     :   // use jqLite\n                                 window[jqName];   // use jQuery specified by `ngJq`\n\n  // Use jQuery if it exists with proper functionality, otherwise default to us.\n  // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.\n  // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older\n  // versions. It will not work for sure with jQuery <1.7, though.\n  if (jQuery && jQuery.fn.on) {\n    jqLite = jQuery;\n    extend(jQuery.fn, {\n      scope: JQLitePrototype.scope,\n      isolateScope: JQLitePrototype.isolateScope,\n      controller: /** @type {?} */ (JQLitePrototype).controller,\n      injector: JQLitePrototype.injector,\n      inheritedData: JQLitePrototype.inheritedData\n    });\n\n    // All nodes removed from the DOM via various jQuery APIs like .remove()\n    // are passed through jQuery.cleanData. Monkey-patch this method to fire\n    // the $destroy event on all removed nodes.\n    originalCleanData = jQuery.cleanData;\n    jQuery.cleanData = function(elems) {\n      var events;\n      for (var i = 0, elem; (elem = elems[i]) != null; i++) {\n        events = jQuery._data(elem, 'events');\n        if (events && events.$destroy) {\n          jQuery(elem).triggerHandler('$destroy');\n        }\n      }\n      originalCleanData(elems);\n    };\n  } else {\n    jqLite = JQLite;\n  }\n\n  angular.element = jqLite;\n\n  // Prevent double-proxying.\n  bindJQueryFired = true;\n}\n\n/**\n * throw error if the argument is falsy.\n */\nfunction assertArg(arg, name, reason) {\n  if (!arg) {\n    throw ngMinErr('areq', 'Argument \\'{0}\\' is {1}', (name || '?'), (reason || 'required'));\n  }\n  return arg;\n}\n\nfunction assertArgFn(arg, name, acceptArrayAnnotation) {\n  if (acceptArrayAnnotation && isArray(arg)) {\n      arg = arg[arg.length - 1];\n  }\n\n  assertArg(isFunction(arg), name, 'not a function, got ' +\n      (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));\n  return arg;\n}\n\n/**\n * throw error if the name given is hasOwnProperty\n * @param  {String} name    the name to test\n * @param  {String} context the context in which the name is used, such as module or directive\n */\nfunction assertNotHasOwnProperty(name, context) {\n  if (name === 'hasOwnProperty') {\n    throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);\n  }\n}\n\n/**\n * Return the value accessible from the object by path. Any undefined traversals are ignored\n * @param {Object} obj starting object\n * @param {String} path path to traverse\n * @param {boolean} [bindFnToScope=true]\n * @returns {Object} value as accessible by path\n */\n//TODO(misko): this function needs to be removed\nfunction getter(obj, path, bindFnToScope) {\n  if (!path) return obj;\n  var keys = path.split('.');\n  var key;\n  var lastInstance = obj;\n  var len = keys.length;\n\n  for (var i = 0; i < len; i++) {\n    key = keys[i];\n    if (obj) {\n      obj = (lastInstance = obj)[key];\n    }\n  }\n  if (!bindFnToScope && isFunction(obj)) {\n    return bind(lastInstance, obj);\n  }\n  return obj;\n}\n\n/**\n * Return the DOM siblings between the first and last node in the given array.\n * @param {Array} array like object\n * @returns {Array} the inputted object or a jqLite collection containing the nodes\n */\nfunction getBlockNodes(nodes) {\n  // TODO(perf): update `nodes` instead of creating a new object?\n  var node = nodes[0];\n  var endNode = nodes[nodes.length - 1];\n  var blockNodes;\n\n  for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {\n    if (blockNodes || nodes[i] !== node) {\n      if (!blockNodes) {\n        blockNodes = jqLite(slice.call(nodes, 0, i));\n      }\n      blockNodes.push(node);\n    }\n  }\n\n  return blockNodes || nodes;\n}\n\n\n/**\n * Creates a new object without a prototype. This object is useful for lookup without having to\n * guard against prototypically inherited properties via hasOwnProperty.\n *\n * Related micro-benchmarks:\n * - http://jsperf.com/object-create2\n * - http://jsperf.com/proto-map-lookup/2\n * - http://jsperf.com/for-in-vs-object-keys2\n *\n * @returns {Object}\n */\nfunction createMap() {\n  return Object.create(null);\n}\n\nfunction stringify(value) {\n  if (value == null) { // null || undefined\n    return '';\n  }\n  switch (typeof value) {\n    case 'string':\n      break;\n    case 'number':\n      value = '' + value;\n      break;\n    default:\n      if (hasCustomToString(value) && !isArray(value) && !isDate(value)) {\n        value = value.toString();\n      } else {\n        value = toJson(value);\n      }\n  }\n\n  return value;\n}\n\nvar NODE_TYPE_ELEMENT = 1;\nvar NODE_TYPE_ATTRIBUTE = 2;\nvar NODE_TYPE_TEXT = 3;\nvar NODE_TYPE_COMMENT = 8;\nvar NODE_TYPE_DOCUMENT = 9;\nvar NODE_TYPE_DOCUMENT_FRAGMENT = 11;\n\n/**\n * @ngdoc type\n * @name angular.Module\n * @module ng\n * @description\n *\n * Interface for configuring angular {@link angular.module modules}.\n */\n\nfunction setupModuleLoader(window) {\n\n  var $injectorMinErr = minErr('$injector');\n  var ngMinErr = minErr('ng');\n\n  function ensure(obj, name, factory) {\n    return obj[name] || (obj[name] = factory());\n  }\n\n  var angular = ensure(window, 'angular', Object);\n\n  // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap\n  angular.$$minErr = angular.$$minErr || minErr;\n\n  return ensure(angular, 'module', function() {\n    /** @type {Object.<string, angular.Module>} */\n    var modules = {};\n\n    /**\n     * @ngdoc function\n     * @name angular.module\n     * @module ng\n     * @description\n     *\n     * The `angular.module` is a global place for creating, registering and retrieving Angular\n     * modules.\n     * All modules (angular core or 3rd party) that should be available to an application must be\n     * registered using this mechanism.\n     *\n     * Passing one argument retrieves an existing {@link angular.Module},\n     * whereas passing more than one argument creates a new {@link angular.Module}\n     *\n     *\n     * # Module\n     *\n     * A module is a collection of services, directives, controllers, filters, and configuration information.\n     * `angular.module` is used to configure the {@link auto.$injector $injector}.\n     *\n     * ```js\n     * // Create a new module\n     * var myModule = angular.module('myModule', []);\n     *\n     * // register a new service\n     * myModule.value('appName', 'MyCoolApp');\n     *\n     * // configure existing services inside initialization blocks.\n     * myModule.config(['$locationProvider', function($locationProvider) {\n     *   // Configure existing providers\n     *   $locationProvider.hashPrefix('!');\n     * }]);\n     * ```\n     *\n     * Then you can create an injector and load your modules like this:\n     *\n     * ```js\n     * var injector = angular.injector(['ng', 'myModule'])\n     * ```\n     *\n     * However it's more likely that you'll just use\n     * {@link ng.directive:ngApp ngApp} or\n     * {@link angular.bootstrap} to simplify this process for you.\n     *\n     * @param {!string} name The name of the module to create or retrieve.\n     * @param {!Array.<string>=} requires If specified then new module is being created. If\n     *        unspecified then the module is being retrieved for further configuration.\n     * @param {Function=} configFn Optional configuration function for the module. Same as\n     *        {@link angular.Module#config Module#config()}.\n     * @returns {angular.Module} new module with the {@link angular.Module} api.\n     */\n    return function module(name, requires, configFn) {\n\n      var info = {};\n\n      var assertNotHasOwnProperty = function(name, context) {\n        if (name === 'hasOwnProperty') {\n          throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);\n        }\n      };\n\n      assertNotHasOwnProperty(name, 'module');\n      if (requires && modules.hasOwnProperty(name)) {\n        modules[name] = null;\n      }\n      return ensure(modules, name, function() {\n        if (!requires) {\n          throw $injectorMinErr('nomod', 'Module \\'{0}\\' is not available! You either misspelled ' +\n             'the module name or forgot to load it. If registering a module ensure that you ' +\n             'specify the dependencies as the second argument.', name);\n        }\n\n        /** @type {!Array.<Array.<*>>} */\n        var invokeQueue = [];\n\n        /** @type {!Array.<Function>} */\n        var configBlocks = [];\n\n        /** @type {!Array.<Function>} */\n        var runBlocks = [];\n\n        var config = invokeLater('$injector', 'invoke', 'push', configBlocks);\n\n        /** @type {angular.Module} */\n        var moduleInstance = {\n          // Private state\n          _invokeQueue: invokeQueue,\n          _configBlocks: configBlocks,\n          _runBlocks: runBlocks,\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#info\n           * @module ng\n           *\n           * @param {Object=} info Information about the module\n           * @returns {Object|Module} The current info object for this module if called as a getter,\n           *                          or `this` if called as a setter.\n           *\n           * @description\n           * Read and write custom information about this module.\n           * For example you could put the version of the module in here.\n           *\n           * ```js\n           * angular.module('myModule', []).info({ version: '1.0.0' });\n           * ```\n           *\n           * The version could then be read back out by accessing the module elsewhere:\n           *\n           * ```\n           * var version = angular.module('myModule').info().version;\n           * ```\n           *\n           * You can also retrieve this information during runtime via the\n           * {@link $injector#modules `$injector.modules`} property:\n           *\n           * ```js\n           * var version = $injector.modules['myModule'].info().version;\n           * ```\n           */\n          info: function(value) {\n            if (isDefined(value)) {\n              if (!isObject(value)) throw ngMinErr('aobj', 'Argument \\'{0}\\' must be an object', 'value');\n              info = value;\n              return this;\n            }\n            return info;\n          },\n\n          /**\n           * @ngdoc property\n           * @name angular.Module#requires\n           * @module ng\n           *\n           * @description\n           * Holds the list of modules which the injector will load before the current module is\n           * loaded.\n           */\n          requires: requires,\n\n          /**\n           * @ngdoc property\n           * @name angular.Module#name\n           * @module ng\n           *\n           * @description\n           * Name of the module.\n           */\n          name: name,\n\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#provider\n           * @module ng\n           * @param {string} name service name\n           * @param {Function} providerType Construction function for creating new instance of the\n           *                                service.\n           * @description\n           * See {@link auto.$provide#provider $provide.provider()}.\n           */\n          provider: invokeLaterAndSetModuleName('$provide', 'provider'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#factory\n           * @module ng\n           * @param {string} name service name\n           * @param {Function} providerFunction Function for creating new instance of the service.\n           * @description\n           * See {@link auto.$provide#factory $provide.factory()}.\n           */\n          factory: invokeLaterAndSetModuleName('$provide', 'factory'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#service\n           * @module ng\n           * @param {string} name service name\n           * @param {Function} constructor A constructor function that will be instantiated.\n           * @description\n           * See {@link auto.$provide#service $provide.service()}.\n           */\n          service: invokeLaterAndSetModuleName('$provide', 'service'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#value\n           * @module ng\n           * @param {string} name service name\n           * @param {*} object Service instance object.\n           * @description\n           * See {@link auto.$provide#value $provide.value()}.\n           */\n          value: invokeLater('$provide', 'value'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#constant\n           * @module ng\n           * @param {string} name constant name\n           * @param {*} object Constant value.\n           * @description\n           * Because the constants are fixed, they get applied before other provide methods.\n           * See {@link auto.$provide#constant $provide.constant()}.\n           */\n          constant: invokeLater('$provide', 'constant', 'unshift'),\n\n           /**\n           * @ngdoc method\n           * @name angular.Module#decorator\n           * @module ng\n           * @param {string} name The name of the service to decorate.\n           * @param {Function} decorFn This function will be invoked when the service needs to be\n           *                           instantiated and should return the decorated service instance.\n           * @description\n           * See {@link auto.$provide#decorator $provide.decorator()}.\n           */\n          decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#animation\n           * @module ng\n           * @param {string} name animation name\n           * @param {Function} animationFactory Factory function for creating new instance of an\n           *                                    animation.\n           * @description\n           *\n           * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.\n           *\n           *\n           * Defines an animation hook that can be later used with\n           * {@link $animate $animate} service and directives that use this service.\n           *\n           * ```js\n           * module.animation('.animation-name', function($inject1, $inject2) {\n           *   return {\n           *     eventName : function(element, done) {\n           *       //code to run the animation\n           *       //once complete, then run done()\n           *       return function cancellationFunction(element) {\n           *         //code to cancel the animation\n           *       }\n           *     }\n           *   }\n           * })\n           * ```\n           *\n           * See {@link ng.$animateProvider#register $animateProvider.register()} and\n           * {@link ngAnimate ngAnimate module} for more information.\n           */\n          animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#filter\n           * @module ng\n           * @param {string} name Filter name - this must be a valid angular expression identifier\n           * @param {Function} filterFactory Factory function for creating new instance of filter.\n           * @description\n           * See {@link ng.$filterProvider#register $filterProvider.register()}.\n           *\n           * <div class=\"alert alert-warning\">\n           * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.\n           * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace\n           * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores\n           * (`myapp_subsection_filterx`).\n           * </div>\n           */\n          filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#controller\n           * @module ng\n           * @param {string|Object} name Controller name, or an object map of controllers where the\n           *    keys are the names and the values are the constructors.\n           * @param {Function} constructor Controller constructor function.\n           * @description\n           * See {@link ng.$controllerProvider#register $controllerProvider.register()}.\n           */\n          controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#directive\n           * @module ng\n           * @param {string|Object} name Directive name, or an object map of directives where the\n           *    keys are the names and the values are the factories.\n           * @param {Function} directiveFactory Factory function for creating new instance of\n           * directives.\n           * @description\n           * See {@link ng.$compileProvider#directive $compileProvider.directive()}.\n           */\n          directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#component\n           * @module ng\n           * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp)\n           * @param {Object} options Component definition object (a simplified\n           *    {@link ng.$compile#directive-definition-object directive definition object})\n           *\n           * @description\n           * See {@link ng.$compileProvider#component $compileProvider.component()}.\n           */\n          component: invokeLaterAndSetModuleName('$compileProvider', 'component'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#config\n           * @module ng\n           * @param {Function} configFn Execute this function on module load. Useful for service\n           *    configuration.\n           * @description\n           * Use this method to register work which needs to be performed on module loading.\n           * For more about how to configure services, see\n           * {@link providers#provider-recipe Provider Recipe}.\n           */\n          config: config,\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#run\n           * @module ng\n           * @param {Function} initializationFn Execute this function after injector creation.\n           *    Useful for application initialization.\n           * @description\n           * Use this method to register work which should be performed when the injector is done\n           * loading all modules.\n           */\n          run: function(block) {\n            runBlocks.push(block);\n            return this;\n          }\n        };\n\n        if (configFn) {\n          config(configFn);\n        }\n\n        return moduleInstance;\n\n        /**\n         * @param {string} provider\n         * @param {string} method\n         * @param {String=} insertMethod\n         * @returns {angular.Module}\n         */\n        function invokeLater(provider, method, insertMethod, queue) {\n          if (!queue) queue = invokeQueue;\n          return function() {\n            queue[insertMethod || 'push']([provider, method, arguments]);\n            return moduleInstance;\n          };\n        }\n\n        /**\n         * @param {string} provider\n         * @param {string} method\n         * @returns {angular.Module}\n         */\n        function invokeLaterAndSetModuleName(provider, method, queue) {\n          if (!queue) queue = invokeQueue;\n          return function(recipeName, factoryFunction) {\n            if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;\n            queue.push([provider, method, arguments]);\n            return moduleInstance;\n          };\n        }\n      });\n    };\n  });\n\n}\n\n/* global shallowCopy: true */\n\n/**\n * Creates a shallow copy of an object, an array or a primitive.\n *\n * Assumes that there are no proto properties for objects.\n */\nfunction shallowCopy(src, dst) {\n  if (isArray(src)) {\n    dst = dst || [];\n\n    for (var i = 0, ii = src.length; i < ii; i++) {\n      dst[i] = src[i];\n    }\n  } else if (isObject(src)) {\n    dst = dst || {};\n\n    for (var key in src) {\n      if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {\n        dst[key] = src[key];\n      }\n    }\n  }\n\n  return dst || src;\n}\n\n/* global toDebugString: true */\n\nfunction serializeObject(obj, maxDepth) {\n  var seen = [];\n\n  // There is no direct way to stringify object until reaching a specific depth\n  // and a very deep object can cause a performance issue, so we copy the object\n  // based on this specific depth and then stringify it.\n  if (isValidObjectMaxDepth(maxDepth)) {\n    obj = copy(obj, null, maxDepth);\n  }\n  return JSON.stringify(obj, function(key, val) {\n    val = toJsonReplacer(key, val);\n    if (isObject(val)) {\n\n      if (seen.indexOf(val) >= 0) return '...';\n\n      seen.push(val);\n    }\n    return val;\n  });\n}\n\nfunction toDebugString(obj, maxDepth) {\n  if (typeof obj === 'function') {\n    return obj.toString().replace(/ \\{[\\s\\S]*$/, '');\n  } else if (isUndefined(obj)) {\n    return 'undefined';\n  } else if (typeof obj !== 'string') {\n    return serializeObject(obj, maxDepth);\n  }\n  return obj;\n}\n\n/* global angularModule: true,\n  version: true,\n\n  $CompileProvider,\n\n  htmlAnchorDirective,\n  inputDirective,\n  inputDirective,\n  formDirective,\n  scriptDirective,\n  selectDirective,\n  optionDirective,\n  ngBindDirective,\n  ngBindHtmlDirective,\n  ngBindTemplateDirective,\n  ngClassDirective,\n  ngClassEvenDirective,\n  ngClassOddDirective,\n  ngCloakDirective,\n  ngControllerDirective,\n  ngFormDirective,\n  ngHideDirective,\n  ngIfDirective,\n  ngIncludeDirective,\n  ngIncludeFillContentDirective,\n  ngInitDirective,\n  ngNonBindableDirective,\n  ngPluralizeDirective,\n  ngRepeatDirective,\n  ngShowDirective,\n  ngStyleDirective,\n  ngSwitchDirective,\n  ngSwitchWhenDirective,\n  ngSwitchDefaultDirective,\n  ngOptionsDirective,\n  ngTranscludeDirective,\n  ngModelDirective,\n  ngListDirective,\n  ngChangeDirective,\n  patternDirective,\n  patternDirective,\n  requiredDirective,\n  requiredDirective,\n  minlengthDirective,\n  minlengthDirective,\n  maxlengthDirective,\n  maxlengthDirective,\n  ngValueDirective,\n  ngModelOptionsDirective,\n  ngAttributeAliasDirectives,\n  ngEventDirectives,\n\n  $AnchorScrollProvider,\n  $AnimateProvider,\n  $CoreAnimateCssProvider,\n  $$CoreAnimateJsProvider,\n  $$CoreAnimateQueueProvider,\n  $$AnimateRunnerFactoryProvider,\n  $$AnimateAsyncRunFactoryProvider,\n  $BrowserProvider,\n  $CacheFactoryProvider,\n  $ControllerProvider,\n  $DateProvider,\n  $DocumentProvider,\n  $$IsDocumentHiddenProvider,\n  $ExceptionHandlerProvider,\n  $FilterProvider,\n  $$ForceReflowProvider,\n  $InterpolateProvider,\n  $IntervalProvider,\n  $HttpProvider,\n  $HttpParamSerializerProvider,\n  $HttpParamSerializerJQLikeProvider,\n  $HttpBackendProvider,\n  $xhrFactoryProvider,\n  $jsonpCallbacksProvider,\n  $LocationProvider,\n  $LogProvider,\n  $$MapProvider,\n  $ParseProvider,\n  $RootScopeProvider,\n  $QProvider,\n  $$QProvider,\n  $$SanitizeUriProvider,\n  $SceProvider,\n  $SceDelegateProvider,\n  $SnifferProvider,\n  $TemplateCacheProvider,\n  $TemplateRequestProvider,\n  $$TestabilityProvider,\n  $TimeoutProvider,\n  $$RAFProvider,\n  $WindowProvider,\n  $$jqLiteProvider,\n  $$CookieReaderProvider\n*/\n\n\n/**\n * @ngdoc object\n * @name angular.version\n * @module ng\n * @description\n * An object that contains information about the current AngularJS version.\n *\n * This object has the following properties:\n *\n * - `full` – `{string}` – Full version string, such as \"0.9.18\".\n * - `major` – `{number}` – Major version number, such as \"0\".\n * - `minor` – `{number}` – Minor version number, such as \"9\".\n * - `dot` – `{number}` – Dot version number, such as \"18\".\n * - `codeName` – `{string}` – Code name of the release, such as \"jiggling-armfat\".\n */\nvar version = {\n  // These placeholder strings will be replaced by grunt's `build` task.\n  // They need to be double- or single-quoted.\n  full: '1.6.3',\n  major: 1,\n  minor: 6,\n  dot: 3,\n  codeName: 'scriptalicious-bootstrapping'\n};\n\n\nfunction publishExternalAPI(angular) {\n  extend(angular, {\n    'errorHandlingConfig': errorHandlingConfig,\n    'bootstrap': bootstrap,\n    'copy': copy,\n    'extend': extend,\n    'merge': merge,\n    'equals': equals,\n    'element': jqLite,\n    'forEach': forEach,\n    'injector': createInjector,\n    'noop': noop,\n    'bind': bind,\n    'toJson': toJson,\n    'fromJson': fromJson,\n    'identity': identity,\n    'isUndefined': isUndefined,\n    'isDefined': isDefined,\n    'isString': isString,\n    'isFunction': isFunction,\n    'isObject': isObject,\n    'isNumber': isNumber,\n    'isElement': isElement,\n    'isArray': isArray,\n    'version': version,\n    'isDate': isDate,\n    'lowercase': lowercase,\n    'uppercase': uppercase,\n    'callbacks': {$$counter: 0},\n    'getTestability': getTestability,\n    'reloadWithDebugInfo': reloadWithDebugInfo,\n    '$$minErr': minErr,\n    '$$csp': csp,\n    '$$encodeUriSegment': encodeUriSegment,\n    '$$encodeUriQuery': encodeUriQuery,\n    '$$stringify': stringify\n  });\n\n  angularModule = setupModuleLoader(window);\n\n  angularModule('ng', ['ngLocale'], ['$provide',\n    function ngModule($provide) {\n      // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.\n      $provide.provider({\n        $$sanitizeUri: $$SanitizeUriProvider\n      });\n      $provide.provider('$compile', $CompileProvider).\n        directive({\n            a: htmlAnchorDirective,\n            input: inputDirective,\n            textarea: inputDirective,\n            form: formDirective,\n            script: scriptDirective,\n            select: selectDirective,\n            option: optionDirective,\n            ngBind: ngBindDirective,\n            ngBindHtml: ngBindHtmlDirective,\n            ngBindTemplate: ngBindTemplateDirective,\n            ngClass: ngClassDirective,\n            ngClassEven: ngClassEvenDirective,\n            ngClassOdd: ngClassOddDirective,\n            ngCloak: ngCloakDirective,\n            ngController: ngControllerDirective,\n            ngForm: ngFormDirective,\n            ngHide: ngHideDirective,\n            ngIf: ngIfDirective,\n            ngInclude: ngIncludeDirective,\n            ngInit: ngInitDirective,\n            ngNonBindable: ngNonBindableDirective,\n            ngPluralize: ngPluralizeDirective,\n            ngRepeat: ngRepeatDirective,\n            ngShow: ngShowDirective,\n            ngStyle: ngStyleDirective,\n            ngSwitch: ngSwitchDirective,\n            ngSwitchWhen: ngSwitchWhenDirective,\n            ngSwitchDefault: ngSwitchDefaultDirective,\n            ngOptions: ngOptionsDirective,\n            ngTransclude: ngTranscludeDirective,\n            ngModel: ngModelDirective,\n            ngList: ngListDirective,\n            ngChange: ngChangeDirective,\n            pattern: patternDirective,\n            ngPattern: patternDirective,\n            required: requiredDirective,\n            ngRequired: requiredDirective,\n            minlength: minlengthDirective,\n            ngMinlength: minlengthDirective,\n            maxlength: maxlengthDirective,\n            ngMaxlength: maxlengthDirective,\n            ngValue: ngValueDirective,\n            ngModelOptions: ngModelOptionsDirective\n        }).\n        directive({\n          ngInclude: ngIncludeFillContentDirective\n        }).\n        directive(ngAttributeAliasDirectives).\n        directive(ngEventDirectives);\n      $provide.provider({\n        $anchorScroll: $AnchorScrollProvider,\n        $animate: $AnimateProvider,\n        $animateCss: $CoreAnimateCssProvider,\n        $$animateJs: $$CoreAnimateJsProvider,\n        $$animateQueue: $$CoreAnimateQueueProvider,\n        $$AnimateRunner: $$AnimateRunnerFactoryProvider,\n        $$animateAsyncRun: $$AnimateAsyncRunFactoryProvider,\n        $browser: $BrowserProvider,\n        $cacheFactory: $CacheFactoryProvider,\n        $controller: $ControllerProvider,\n        $document: $DocumentProvider,\n        $$isDocumentHidden: $$IsDocumentHiddenProvider,\n        $exceptionHandler: $ExceptionHandlerProvider,\n        $filter: $FilterProvider,\n        $$forceReflow: $$ForceReflowProvider,\n        $interpolate: $InterpolateProvider,\n        $interval: $IntervalProvider,\n        $http: $HttpProvider,\n        $httpParamSerializer: $HttpParamSerializerProvider,\n        $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,\n        $httpBackend: $HttpBackendProvider,\n        $xhrFactory: $xhrFactoryProvider,\n        $jsonpCallbacks: $jsonpCallbacksProvider,\n        $location: $LocationProvider,\n        $log: $LogProvider,\n        $parse: $ParseProvider,\n        $rootScope: $RootScopeProvider,\n        $q: $QProvider,\n        $$q: $$QProvider,\n        $sce: $SceProvider,\n        $sceDelegate: $SceDelegateProvider,\n        $sniffer: $SnifferProvider,\n        $templateCache: $TemplateCacheProvider,\n        $templateRequest: $TemplateRequestProvider,\n        $$testability: $$TestabilityProvider,\n        $timeout: $TimeoutProvider,\n        $window: $WindowProvider,\n        $$rAF: $$RAFProvider,\n        $$jqLite: $$jqLiteProvider,\n        $$Map: $$MapProvider,\n        $$cookieReader: $$CookieReaderProvider\n      });\n    }\n  ])\n  .info({ angularVersion: '1.6.3' });\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *     Any commits to this file should be reviewed with security in mind.  *\n *   Changes to this file can potentially create security vulnerabilities. *\n *          An approval from 2 Core members with history of modifying      *\n *                         this file is required.                          *\n *                                                                         *\n *  Does the change somehow allow for arbitrary javascript to be executed? *\n *    Or allows for someone to change the prototype of built-in objects?   *\n *     Or gives undesired access to variables likes document or window?    *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/* global\n  JQLitePrototype: true,\n  BOOLEAN_ATTR: true,\n  ALIASED_ATTR: true\n*/\n\n//////////////////////////////////\n//JQLite\n//////////////////////////////////\n\n/**\n * @ngdoc function\n * @name angular.element\n * @module ng\n * @kind function\n *\n * @description\n * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.\n *\n * If jQuery is available, `angular.element` is an alias for the\n * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element`\n * delegates to Angular's built-in subset of jQuery, called \"jQuery lite\" or **jqLite**.\n *\n * jqLite is a tiny, API-compatible subset of jQuery that allows\n * Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most\n * commonly needed functionality with the goal of having a very small footprint.\n *\n * To use `jQuery`, simply ensure it is loaded before the `angular.js` file. You can also use the\n * {@link ngJq `ngJq`} directive to specify that jqlite should be used over jQuery, or to use a\n * specific version of jQuery if multiple versions exist on the page.\n *\n * <div class=\"alert alert-info\">**Note:** All element references in Angular are always wrapped with jQuery or\n * jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.</div>\n *\n * <div class=\"alert alert-warning\">**Note:** Keep in mind that this function will not find elements\n * by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)`\n * or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.</div>\n *\n * ## Angular's jqLite\n * jqLite provides only the following jQuery methods:\n *\n * - [`addClass()`](http://api.jquery.com/addClass/) - Does not support a function as first argument\n * - [`after()`](http://api.jquery.com/after/)\n * - [`append()`](http://api.jquery.com/append/)\n * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters\n * - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData\n * - [`children()`](http://api.jquery.com/children/) - Does not support selectors\n * - [`clone()`](http://api.jquery.com/clone/)\n * - [`contents()`](http://api.jquery.com/contents/)\n * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`.\n *   As a setter, does not convert numbers to strings or append 'px', and also does not have automatic property prefixing.\n * - [`data()`](http://api.jquery.com/data/)\n * - [`detach()`](http://api.jquery.com/detach/)\n * - [`empty()`](http://api.jquery.com/empty/)\n * - [`eq()`](http://api.jquery.com/eq/)\n * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name\n * - [`hasClass()`](http://api.jquery.com/hasClass/)\n * - [`html()`](http://api.jquery.com/html/)\n * - [`next()`](http://api.jquery.com/next/) - Does not support selectors\n * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData\n * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter\n * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors\n * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors\n * - [`prepend()`](http://api.jquery.com/prepend/)\n * - [`prop()`](http://api.jquery.com/prop/)\n * - [`ready()`](http://api.jquery.com/ready/) (_deprecated_, use `angular.element(callback)` instead of `angular.element(document).ready(callback)`)\n * - [`remove()`](http://api.jquery.com/remove/)\n * - [`removeAttr()`](http://api.jquery.com/removeAttr/) - Does not support multiple attributes\n * - [`removeClass()`](http://api.jquery.com/removeClass/) - Does not support a function as first argument\n * - [`removeData()`](http://api.jquery.com/removeData/)\n * - [`replaceWith()`](http://api.jquery.com/replaceWith/)\n * - [`text()`](http://api.jquery.com/text/)\n * - [`toggleClass()`](http://api.jquery.com/toggleClass/) - Does not support a function as first argument\n * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers\n * - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter\n * - [`val()`](http://api.jquery.com/val/)\n * - [`wrap()`](http://api.jquery.com/wrap/)\n *\n * ## jQuery/jqLite Extras\n * Angular also provides the following additional methods and events to both jQuery and jqLite:\n *\n * ### Events\n * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event\n *    on all DOM nodes being removed.  This can be used to clean up any 3rd party bindings to the DOM\n *    element before it is removed.\n *\n * ### Methods\n * - `controller(name)` - retrieves the controller of the current element or its parent. By default\n *   retrieves controller associated with the `ngController` directive. If `name` is provided as\n *   camelCase directive name, then the controller for this directive will be retrieved (e.g.\n *   `'ngModel'`).\n * - `injector()` - retrieves the injector of the current element or its parent.\n * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current\n *   element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to\n *   be enabled.\n * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the\n *   current element. This getter should be used only on elements that contain a directive which starts a new isolate\n *   scope. Calling `scope()` on this element always returns the original non-isolate scope.\n *   Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.\n * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top\n *   parent element is reached.\n *\n * @knownIssue You cannot spy on `angular.element` if you are using Jasmine version 1.x. See\n * https://github.com/angular/angular.js/issues/14251 for more information.\n *\n * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.\n * @returns {Object} jQuery object.\n */\n\nJQLite.expando = 'ng339';\n\nvar jqCache = JQLite.cache = {},\n    jqId = 1;\n\n/*\n * !!! This is an undocumented \"private\" function !!!\n */\nJQLite._data = function(node) {\n  //jQuery always returns an object on cache miss\n  return this.cache[node[this.expando]] || {};\n};\n\nfunction jqNextId() { return ++jqId; }\n\n\nvar DASH_LOWERCASE_REGEXP = /-([a-z])/g;\nvar MS_HACK_REGEXP = /^-ms-/;\nvar MOUSE_EVENT_MAP = { mouseleave: 'mouseout', mouseenter: 'mouseover' };\nvar jqLiteMinErr = minErr('jqLite');\n\n/**\n * Converts kebab-case to camelCase.\n * There is also a special case for the ms prefix starting with a lowercase letter.\n * @param name Name to normalize\n */\nfunction cssKebabToCamel(name) {\n    return kebabToCamel(name.replace(MS_HACK_REGEXP, 'ms-'));\n}\n\nfunction fnCamelCaseReplace(all, letter) {\n  return letter.toUpperCase();\n}\n\n/**\n * Converts kebab-case to camelCase.\n * @param name Name to normalize\n */\nfunction kebabToCamel(name) {\n  return name\n    .replace(DASH_LOWERCASE_REGEXP, fnCamelCaseReplace);\n}\n\nvar SINGLE_TAG_REGEXP = /^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/;\nvar HTML_REGEXP = /<|&#?\\w+;/;\nvar TAG_NAME_REGEXP = /<([\\w:-]+)/;\nvar XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi;\n\nvar wrapMap = {\n  'option': [1, '<select multiple=\"multiple\">', '</select>'],\n\n  'thead': [1, '<table>', '</table>'],\n  'col': [2, '<table><colgroup>', '</colgroup></table>'],\n  'tr': [2, '<table><tbody>', '</tbody></table>'],\n  'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],\n  '_default': [0, '', '']\n};\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction jqLiteIsTextNode(html) {\n  return !HTML_REGEXP.test(html);\n}\n\nfunction jqLiteAcceptsData(node) {\n  // The window object can accept data but has no nodeType\n  // Otherwise we are only interested in elements (1) and documents (9)\n  var nodeType = node.nodeType;\n  return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;\n}\n\nfunction jqLiteHasData(node) {\n  for (var key in jqCache[node.ng339]) {\n    return true;\n  }\n  return false;\n}\n\nfunction jqLiteCleanData(nodes) {\n  for (var i = 0, ii = nodes.length; i < ii; i++) {\n    jqLiteRemoveData(nodes[i]);\n  }\n}\n\nfunction jqLiteBuildFragment(html, context) {\n  var tmp, tag, wrap,\n      fragment = context.createDocumentFragment(),\n      nodes = [], i;\n\n  if (jqLiteIsTextNode(html)) {\n    // Convert non-html into a text node\n    nodes.push(context.createTextNode(html));\n  } else {\n    // Convert html into DOM nodes\n    tmp = fragment.appendChild(context.createElement('div'));\n    tag = (TAG_NAME_REGEXP.exec(html) || ['', ''])[1].toLowerCase();\n    wrap = wrapMap[tag] || wrapMap._default;\n    tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, '<$1></$2>') + wrap[2];\n\n    // Descend through wrappers to the right content\n    i = wrap[0];\n    while (i--) {\n      tmp = tmp.lastChild;\n    }\n\n    nodes = concat(nodes, tmp.childNodes);\n\n    tmp = fragment.firstChild;\n    tmp.textContent = '';\n  }\n\n  // Remove wrapper from fragment\n  fragment.textContent = '';\n  fragment.innerHTML = ''; // Clear inner HTML\n  forEach(nodes, function(node) {\n    fragment.appendChild(node);\n  });\n\n  return fragment;\n}\n\nfunction jqLiteParseHTML(html, context) {\n  context = context || window.document;\n  var parsed;\n\n  if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {\n    return [context.createElement(parsed[1])];\n  }\n\n  if ((parsed = jqLiteBuildFragment(html, context))) {\n    return parsed.childNodes;\n  }\n\n  return [];\n}\n\nfunction jqLiteWrapNode(node, wrapper) {\n  var parent = node.parentNode;\n\n  if (parent) {\n    parent.replaceChild(wrapper, node);\n  }\n\n  wrapper.appendChild(node);\n}\n\n\n// IE9-11 has no method \"contains\" in SVG element and in Node.prototype. Bug #10259.\nvar jqLiteContains = window.Node.prototype.contains || /** @this */ function(arg) {\n  // eslint-disable-next-line no-bitwise\n  return !!(this.compareDocumentPosition(arg) & 16);\n};\n\n/////////////////////////////////////////////\nfunction JQLite(element) {\n  if (element instanceof JQLite) {\n    return element;\n  }\n\n  var argIsString;\n\n  if (isString(element)) {\n    element = trim(element);\n    argIsString = true;\n  }\n  if (!(this instanceof JQLite)) {\n    if (argIsString && element.charAt(0) !== '<') {\n      throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');\n    }\n    return new JQLite(element);\n  }\n\n  if (argIsString) {\n    jqLiteAddNodes(this, jqLiteParseHTML(element));\n  } else if (isFunction(element)) {\n    jqLiteReady(element);\n  } else {\n    jqLiteAddNodes(this, element);\n  }\n}\n\nfunction jqLiteClone(element) {\n  return element.cloneNode(true);\n}\n\nfunction jqLiteDealoc(element, onlyDescendants) {\n  if (!onlyDescendants) jqLiteRemoveData(element);\n\n  if (element.querySelectorAll) {\n    var descendants = element.querySelectorAll('*');\n    for (var i = 0, l = descendants.length; i < l; i++) {\n      jqLiteRemoveData(descendants[i]);\n    }\n  }\n}\n\nfunction jqLiteOff(element, type, fn, unsupported) {\n  if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');\n\n  var expandoStore = jqLiteExpandoStore(element);\n  var events = expandoStore && expandoStore.events;\n  var handle = expandoStore && expandoStore.handle;\n\n  if (!handle) return; //no listeners registered\n\n  if (!type) {\n    for (type in events) {\n      if (type !== '$destroy') {\n        element.removeEventListener(type, handle);\n      }\n      delete events[type];\n    }\n  } else {\n\n    var removeHandler = function(type) {\n      var listenerFns = events[type];\n      if (isDefined(fn)) {\n        arrayRemove(listenerFns || [], fn);\n      }\n      if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) {\n        element.removeEventListener(type, handle);\n        delete events[type];\n      }\n    };\n\n    forEach(type.split(' '), function(type) {\n      removeHandler(type);\n      if (MOUSE_EVENT_MAP[type]) {\n        removeHandler(MOUSE_EVENT_MAP[type]);\n      }\n    });\n  }\n}\n\nfunction jqLiteRemoveData(element, name) {\n  var expandoId = element.ng339;\n  var expandoStore = expandoId && jqCache[expandoId];\n\n  if (expandoStore) {\n    if (name) {\n      delete expandoStore.data[name];\n      return;\n    }\n\n    if (expandoStore.handle) {\n      if (expandoStore.events.$destroy) {\n        expandoStore.handle({}, '$destroy');\n      }\n      jqLiteOff(element);\n    }\n    delete jqCache[expandoId];\n    element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it\n  }\n}\n\n\nfunction jqLiteExpandoStore(element, createIfNecessary) {\n  var expandoId = element.ng339,\n      expandoStore = expandoId && jqCache[expandoId];\n\n  if (createIfNecessary && !expandoStore) {\n    element.ng339 = expandoId = jqNextId();\n    expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined};\n  }\n\n  return expandoStore;\n}\n\n\nfunction jqLiteData(element, key, value) {\n  if (jqLiteAcceptsData(element)) {\n    var prop;\n\n    var isSimpleSetter = isDefined(value);\n    var isSimpleGetter = !isSimpleSetter && key && !isObject(key);\n    var massGetter = !key;\n    var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);\n    var data = expandoStore && expandoStore.data;\n\n    if (isSimpleSetter) { // data('key', value)\n      data[kebabToCamel(key)] = value;\n    } else {\n      if (massGetter) {  // data()\n        return data;\n      } else {\n        if (isSimpleGetter) { // data('key')\n          // don't force creation of expandoStore if it doesn't exist yet\n          return data && data[kebabToCamel(key)];\n        } else { // mass-setter: data({key1: val1, key2: val2})\n          for (prop in key) {\n            data[kebabToCamel(prop)] = key[prop];\n          }\n        }\n      }\n    }\n  }\n}\n\nfunction jqLiteHasClass(element, selector) {\n  if (!element.getAttribute) return false;\n  return ((' ' + (element.getAttribute('class') || '') + ' ').replace(/[\\n\\t]/g, ' ').\n      indexOf(' ' + selector + ' ') > -1);\n}\n\nfunction jqLiteRemoveClass(element, cssClasses) {\n  if (cssClasses && element.setAttribute) {\n    forEach(cssClasses.split(' '), function(cssClass) {\n      element.setAttribute('class', trim(\n          (' ' + (element.getAttribute('class') || '') + ' ')\n          .replace(/[\\n\\t]/g, ' ')\n          .replace(' ' + trim(cssClass) + ' ', ' '))\n      );\n    });\n  }\n}\n\nfunction jqLiteAddClass(element, cssClasses) {\n  if (cssClasses && element.setAttribute) {\n    var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')\n                            .replace(/[\\n\\t]/g, ' ');\n\n    forEach(cssClasses.split(' '), function(cssClass) {\n      cssClass = trim(cssClass);\n      if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {\n        existingClasses += cssClass + ' ';\n      }\n    });\n\n    element.setAttribute('class', trim(existingClasses));\n  }\n}\n\n\nfunction jqLiteAddNodes(root, elements) {\n  // THIS CODE IS VERY HOT. Don't make changes without benchmarking.\n\n  if (elements) {\n\n    // if a Node (the most common case)\n    if (elements.nodeType) {\n      root[root.length++] = elements;\n    } else {\n      var length = elements.length;\n\n      // if an Array or NodeList and not a Window\n      if (typeof length === 'number' && elements.window !== elements) {\n        if (length) {\n          for (var i = 0; i < length; i++) {\n            root[root.length++] = elements[i];\n          }\n        }\n      } else {\n        root[root.length++] = elements;\n      }\n    }\n  }\n}\n\n\nfunction jqLiteController(element, name) {\n  return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');\n}\n\nfunction jqLiteInheritedData(element, name, value) {\n  // if element is the document object work with the html element instead\n  // this makes $(document).scope() possible\n  if (element.nodeType === NODE_TYPE_DOCUMENT) {\n    element = element.documentElement;\n  }\n  var names = isArray(name) ? name : [name];\n\n  while (element) {\n    for (var i = 0, ii = names.length; i < ii; i++) {\n      if (isDefined(value = jqLite.data(element, names[i]))) return value;\n    }\n\n    // If dealing with a document fragment node with a host element, and no parent, use the host\n    // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM\n    // to lookup parent controllers.\n    element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);\n  }\n}\n\nfunction jqLiteEmpty(element) {\n  jqLiteDealoc(element, true);\n  while (element.firstChild) {\n    element.removeChild(element.firstChild);\n  }\n}\n\nfunction jqLiteRemove(element, keepData) {\n  if (!keepData) jqLiteDealoc(element);\n  var parent = element.parentNode;\n  if (parent) parent.removeChild(element);\n}\n\n\nfunction jqLiteDocumentLoaded(action, win) {\n  win = win || window;\n  if (win.document.readyState === 'complete') {\n    // Force the action to be run async for consistent behavior\n    // from the action's point of view\n    // i.e. it will definitely not be in a $apply\n    win.setTimeout(action);\n  } else {\n    // No need to unbind this handler as load is only ever called once\n    jqLite(win).on('load', action);\n  }\n}\n\nfunction jqLiteReady(fn) {\n  function trigger() {\n    window.document.removeEventListener('DOMContentLoaded', trigger);\n    window.removeEventListener('load', trigger);\n    fn();\n  }\n\n  // check if document is already loaded\n  if (window.document.readyState === 'complete') {\n    window.setTimeout(fn);\n  } else {\n    // We can not use jqLite since we are not done loading and jQuery could be loaded later.\n\n    // Works for modern browsers and IE9\n    window.document.addEventListener('DOMContentLoaded', trigger);\n\n    // Fallback to window.onload for others\n    window.addEventListener('load', trigger);\n  }\n}\n\n//////////////////////////////////////////\n// Functions which are declared directly.\n//////////////////////////////////////////\nvar JQLitePrototype = JQLite.prototype = {\n  ready: jqLiteReady,\n  toString: function() {\n    var value = [];\n    forEach(this, function(e) { value.push('' + e);});\n    return '[' + value.join(', ') + ']';\n  },\n\n  eq: function(index) {\n      return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);\n  },\n\n  length: 0,\n  push: push,\n  sort: [].sort,\n  splice: [].splice\n};\n\n//////////////////////////////////////////\n// Functions iterating getter/setters.\n// these functions return self on setter and\n// value on get.\n//////////////////////////////////////////\nvar BOOLEAN_ATTR = {};\nforEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {\n  BOOLEAN_ATTR[lowercase(value)] = value;\n});\nvar BOOLEAN_ELEMENTS = {};\nforEach('input,select,option,textarea,button,form,details'.split(','), function(value) {\n  BOOLEAN_ELEMENTS[value] = true;\n});\nvar ALIASED_ATTR = {\n  'ngMinlength': 'minlength',\n  'ngMaxlength': 'maxlength',\n  'ngMin': 'min',\n  'ngMax': 'max',\n  'ngPattern': 'pattern',\n  'ngStep': 'step'\n};\n\nfunction getBooleanAttrName(element, name) {\n  // check dom last since we will most likely fail on name\n  var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];\n\n  // booleanAttr is here twice to minimize DOM access\n  return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;\n}\n\nfunction getAliasedAttrName(name) {\n  return ALIASED_ATTR[name];\n}\n\nforEach({\n  data: jqLiteData,\n  removeData: jqLiteRemoveData,\n  hasData: jqLiteHasData,\n  cleanData: jqLiteCleanData\n}, function(fn, name) {\n  JQLite[name] = fn;\n});\n\nforEach({\n  data: jqLiteData,\n  inheritedData: jqLiteInheritedData,\n\n  scope: function(element) {\n    // Can't use jqLiteData here directly so we stay compatible with jQuery!\n    return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);\n  },\n\n  isolateScope: function(element) {\n    // Can't use jqLiteData here directly so we stay compatible with jQuery!\n    return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');\n  },\n\n  controller: jqLiteController,\n\n  injector: function(element) {\n    return jqLiteInheritedData(element, '$injector');\n  },\n\n  removeAttr: function(element, name) {\n    element.removeAttribute(name);\n  },\n\n  hasClass: jqLiteHasClass,\n\n  css: function(element, name, value) {\n    name = cssKebabToCamel(name);\n\n    if (isDefined(value)) {\n      element.style[name] = value;\n    } else {\n      return element.style[name];\n    }\n  },\n\n  attr: function(element, name, value) {\n    var ret;\n    var nodeType = element.nodeType;\n    if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT ||\n      !element.getAttribute) {\n      return;\n    }\n\n    var lowercasedName = lowercase(name);\n    var isBooleanAttr = BOOLEAN_ATTR[lowercasedName];\n\n    if (isDefined(value)) {\n      // setter\n\n      if (value === null || (value === false && isBooleanAttr)) {\n        element.removeAttribute(name);\n      } else {\n        element.setAttribute(name, isBooleanAttr ? lowercasedName : value);\n      }\n    } else {\n      // getter\n\n      ret = element.getAttribute(name);\n\n      if (isBooleanAttr && ret !== null) {\n        ret = lowercasedName;\n      }\n      // Normalize non-existing attributes to undefined (as jQuery).\n      return ret === null ? undefined : ret;\n    }\n  },\n\n  prop: function(element, name, value) {\n    if (isDefined(value)) {\n      element[name] = value;\n    } else {\n      return element[name];\n    }\n  },\n\n  text: (function() {\n    getText.$dv = '';\n    return getText;\n\n    function getText(element, value) {\n      if (isUndefined(value)) {\n        var nodeType = element.nodeType;\n        return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';\n      }\n      element.textContent = value;\n    }\n  })(),\n\n  val: function(element, value) {\n    if (isUndefined(value)) {\n      if (element.multiple && nodeName_(element) === 'select') {\n        var result = [];\n        forEach(element.options, function(option) {\n          if (option.selected) {\n            result.push(option.value || option.text);\n          }\n        });\n        return result;\n      }\n      return element.value;\n    }\n    element.value = value;\n  },\n\n  html: function(element, value) {\n    if (isUndefined(value)) {\n      return element.innerHTML;\n    }\n    jqLiteDealoc(element, true);\n    element.innerHTML = value;\n  },\n\n  empty: jqLiteEmpty\n}, function(fn, name) {\n  /**\n   * Properties: writes return selection, reads return first value\n   */\n  JQLite.prototype[name] = function(arg1, arg2) {\n    var i, key;\n    var nodeCount = this.length;\n\n    // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it\n    // in a way that survives minification.\n    // jqLiteEmpty takes no arguments but is a setter.\n    if (fn !== jqLiteEmpty &&\n        (isUndefined((fn.length === 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) {\n      if (isObject(arg1)) {\n\n        // we are a write, but the object properties are the key/values\n        for (i = 0; i < nodeCount; i++) {\n          if (fn === jqLiteData) {\n            // data() takes the whole object in jQuery\n            fn(this[i], arg1);\n          } else {\n            for (key in arg1) {\n              fn(this[i], key, arg1[key]);\n            }\n          }\n        }\n        // return self for chaining\n        return this;\n      } else {\n        // we are a read, so read the first child.\n        // TODO: do we still need this?\n        var value = fn.$dv;\n        // Only if we have $dv do we iterate over all, otherwise it is just the first element.\n        var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount;\n        for (var j = 0; j < jj; j++) {\n          var nodeValue = fn(this[j], arg1, arg2);\n          value = value ? value + nodeValue : nodeValue;\n        }\n        return value;\n      }\n    } else {\n      // we are a write, so apply to all children\n      for (i = 0; i < nodeCount; i++) {\n        fn(this[i], arg1, arg2);\n      }\n      // return self for chaining\n      return this;\n    }\n  };\n});\n\nfunction createEventHandler(element, events) {\n  var eventHandler = function(event, type) {\n    // jQuery specific api\n    event.isDefaultPrevented = function() {\n      return event.defaultPrevented;\n    };\n\n    var eventFns = events[type || event.type];\n    var eventFnsLength = eventFns ? eventFns.length : 0;\n\n    if (!eventFnsLength) return;\n\n    if (isUndefined(event.immediatePropagationStopped)) {\n      var originalStopImmediatePropagation = event.stopImmediatePropagation;\n      event.stopImmediatePropagation = function() {\n        event.immediatePropagationStopped = true;\n\n        if (event.stopPropagation) {\n          event.stopPropagation();\n        }\n\n        if (originalStopImmediatePropagation) {\n          originalStopImmediatePropagation.call(event);\n        }\n      };\n    }\n\n    event.isImmediatePropagationStopped = function() {\n      return event.immediatePropagationStopped === true;\n    };\n\n    // Some events have special handlers that wrap the real handler\n    var handlerWrapper = eventFns.specialHandlerWrapper || defaultHandlerWrapper;\n\n    // Copy event handlers in case event handlers array is modified during execution.\n    if ((eventFnsLength > 1)) {\n      eventFns = shallowCopy(eventFns);\n    }\n\n    for (var i = 0; i < eventFnsLength; i++) {\n      if (!event.isImmediatePropagationStopped()) {\n        handlerWrapper(element, event, eventFns[i]);\n      }\n    }\n  };\n\n  // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all\n  //       events on `element`\n  eventHandler.elem = element;\n  return eventHandler;\n}\n\nfunction defaultHandlerWrapper(element, event, handler) {\n  handler.call(element, event);\n}\n\nfunction specialMouseHandlerWrapper(target, event, handler) {\n  // Refer to jQuery's implementation of mouseenter & mouseleave\n  // Read about mouseenter and mouseleave:\n  // http://www.quirksmode.org/js/events_mouse.html#link8\n  var related = event.relatedTarget;\n  // For mousenter/leave call the handler if related is outside the target.\n  // NB: No relatedTarget if the mouse left/entered the browser window\n  if (!related || (related !== target && !jqLiteContains.call(target, related))) {\n    handler.call(target, event);\n  }\n}\n\n//////////////////////////////////////////\n// Functions iterating traversal.\n// These functions chain results into a single\n// selector.\n//////////////////////////////////////////\nforEach({\n  removeData: jqLiteRemoveData,\n\n  on: function jqLiteOn(element, type, fn, unsupported) {\n    if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');\n\n    // Do not add event handlers to non-elements because they will not be cleaned up.\n    if (!jqLiteAcceptsData(element)) {\n      return;\n    }\n\n    var expandoStore = jqLiteExpandoStore(element, true);\n    var events = expandoStore.events;\n    var handle = expandoStore.handle;\n\n    if (!handle) {\n      handle = expandoStore.handle = createEventHandler(element, events);\n    }\n\n    // http://jsperf.com/string-indexof-vs-split\n    var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type];\n    var i = types.length;\n\n    var addHandler = function(type, specialHandlerWrapper, noEventListener) {\n      var eventFns = events[type];\n\n      if (!eventFns) {\n        eventFns = events[type] = [];\n        eventFns.specialHandlerWrapper = specialHandlerWrapper;\n        if (type !== '$destroy' && !noEventListener) {\n          element.addEventListener(type, handle);\n        }\n      }\n\n      eventFns.push(fn);\n    };\n\n    while (i--) {\n      type = types[i];\n      if (MOUSE_EVENT_MAP[type]) {\n        addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);\n        addHandler(type, undefined, true);\n      } else {\n        addHandler(type);\n      }\n    }\n  },\n\n  off: jqLiteOff,\n\n  one: function(element, type, fn) {\n    element = jqLite(element);\n\n    //add the listener twice so that when it is called\n    //you can remove the original function and still be\n    //able to call element.off(ev, fn) normally\n    element.on(type, function onFn() {\n      element.off(type, fn);\n      element.off(type, onFn);\n    });\n    element.on(type, fn);\n  },\n\n  replaceWith: function(element, replaceNode) {\n    var index, parent = element.parentNode;\n    jqLiteDealoc(element);\n    forEach(new JQLite(replaceNode), function(node) {\n      if (index) {\n        parent.insertBefore(node, index.nextSibling);\n      } else {\n        parent.replaceChild(node, element);\n      }\n      index = node;\n    });\n  },\n\n  children: function(element) {\n    var children = [];\n    forEach(element.childNodes, function(element) {\n      if (element.nodeType === NODE_TYPE_ELEMENT) {\n        children.push(element);\n      }\n    });\n    return children;\n  },\n\n  contents: function(element) {\n    return element.contentDocument || element.childNodes || [];\n  },\n\n  append: function(element, node) {\n    var nodeType = element.nodeType;\n    if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return;\n\n    node = new JQLite(node);\n\n    for (var i = 0, ii = node.length; i < ii; i++) {\n      var child = node[i];\n      element.appendChild(child);\n    }\n  },\n\n  prepend: function(element, node) {\n    if (element.nodeType === NODE_TYPE_ELEMENT) {\n      var index = element.firstChild;\n      forEach(new JQLite(node), function(child) {\n        element.insertBefore(child, index);\n      });\n    }\n  },\n\n  wrap: function(element, wrapNode) {\n    jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);\n  },\n\n  remove: jqLiteRemove,\n\n  detach: function(element) {\n    jqLiteRemove(element, true);\n  },\n\n  after: function(element, newElement) {\n    var index = element, parent = element.parentNode;\n\n    if (parent) {\n      newElement = new JQLite(newElement);\n\n      for (var i = 0, ii = newElement.length; i < ii; i++) {\n        var node = newElement[i];\n        parent.insertBefore(node, index.nextSibling);\n        index = node;\n      }\n    }\n  },\n\n  addClass: jqLiteAddClass,\n  removeClass: jqLiteRemoveClass,\n\n  toggleClass: function(element, selector, condition) {\n    if (selector) {\n      forEach(selector.split(' '), function(className) {\n        var classCondition = condition;\n        if (isUndefined(classCondition)) {\n          classCondition = !jqLiteHasClass(element, className);\n        }\n        (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className);\n      });\n    }\n  },\n\n  parent: function(element) {\n    var parent = element.parentNode;\n    return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null;\n  },\n\n  next: function(element) {\n    return element.nextElementSibling;\n  },\n\n  find: function(element, selector) {\n    if (element.getElementsByTagName) {\n      return element.getElementsByTagName(selector);\n    } else {\n      return [];\n    }\n  },\n\n  clone: jqLiteClone,\n\n  triggerHandler: function(element, event, extraParameters) {\n\n    var dummyEvent, eventFnsCopy, handlerArgs;\n    var eventName = event.type || event;\n    var expandoStore = jqLiteExpandoStore(element);\n    var events = expandoStore && expandoStore.events;\n    var eventFns = events && events[eventName];\n\n    if (eventFns) {\n      // Create a dummy event to pass to the handlers\n      dummyEvent = {\n        preventDefault: function() { this.defaultPrevented = true; },\n        isDefaultPrevented: function() { return this.defaultPrevented === true; },\n        stopImmediatePropagation: function() { this.immediatePropagationStopped = true; },\n        isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; },\n        stopPropagation: noop,\n        type: eventName,\n        target: element\n      };\n\n      // If a custom event was provided then extend our dummy event with it\n      if (event.type) {\n        dummyEvent = extend(dummyEvent, event);\n      }\n\n      // Copy event handlers in case event handlers array is modified during execution.\n      eventFnsCopy = shallowCopy(eventFns);\n      handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];\n\n      forEach(eventFnsCopy, function(fn) {\n        if (!dummyEvent.isImmediatePropagationStopped()) {\n          fn.apply(element, handlerArgs);\n        }\n      });\n    }\n  }\n}, function(fn, name) {\n  /**\n   * chaining functions\n   */\n  JQLite.prototype[name] = function(arg1, arg2, arg3) {\n    var value;\n\n    for (var i = 0, ii = this.length; i < ii; i++) {\n      if (isUndefined(value)) {\n        value = fn(this[i], arg1, arg2, arg3);\n        if (isDefined(value)) {\n          // any function which returns a value needs to be wrapped\n          value = jqLite(value);\n        }\n      } else {\n        jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));\n      }\n    }\n    return isDefined(value) ? value : this;\n  };\n});\n\n// bind legacy bind/unbind to on/off\nJQLite.prototype.bind = JQLite.prototype.on;\nJQLite.prototype.unbind = JQLite.prototype.off;\n\n\n// Provider for private $$jqLite service\n/** @this */\nfunction $$jqLiteProvider() {\n  this.$get = function $$jqLite() {\n    return extend(JQLite, {\n      hasClass: function(node, classes) {\n        if (node.attr) node = node[0];\n        return jqLiteHasClass(node, classes);\n      },\n      addClass: function(node, classes) {\n        if (node.attr) node = node[0];\n        return jqLiteAddClass(node, classes);\n      },\n      removeClass: function(node, classes) {\n        if (node.attr) node = node[0];\n        return jqLiteRemoveClass(node, classes);\n      }\n    });\n  };\n}\n\n/**\n * Computes a hash of an 'obj'.\n * Hash of a:\n *  string is string\n *  number is number as string\n *  object is either result of calling $$hashKey function on the object or uniquely generated id,\n *         that is also assigned to the $$hashKey property of the object.\n *\n * @param obj\n * @returns {string} hash string such that the same input will have the same hash string.\n *         The resulting string key is in 'type:hashKey' format.\n */\nfunction hashKey(obj, nextUidFn) {\n  var key = obj && obj.$$hashKey;\n\n  if (key) {\n    if (typeof key === 'function') {\n      key = obj.$$hashKey();\n    }\n    return key;\n  }\n\n  var objType = typeof obj;\n  if (objType === 'function' || (objType === 'object' && obj !== null)) {\n    key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)();\n  } else {\n    key = objType + ':' + obj;\n  }\n\n  return key;\n}\n\n// A minimal ES2015 Map implementation.\n// Should be bug/feature equivalent to the native implementations of supported browsers\n// (for the features required in Angular).\n// See https://kangax.github.io/compat-table/es6/#test-Map\nvar nanKey = Object.create(null);\nfunction NgMapShim() {\n  this._keys = [];\n  this._values = [];\n  this._lastKey = NaN;\n  this._lastIndex = -1;\n}\nNgMapShim.prototype = {\n  _idx: function(key) {\n    if (key === this._lastKey) {\n      return this._lastIndex;\n    }\n    this._lastKey = key;\n    this._lastIndex = this._keys.indexOf(key);\n    return this._lastIndex;\n  },\n  _transformKey: function(key) {\n    return isNumberNaN(key) ? nanKey : key;\n  },\n  get: function(key) {\n    key = this._transformKey(key);\n    var idx = this._idx(key);\n    if (idx !== -1) {\n      return this._values[idx];\n    }\n  },\n  set: function(key, value) {\n    key = this._transformKey(key);\n    var idx = this._idx(key);\n    if (idx === -1) {\n      idx = this._lastIndex = this._keys.length;\n    }\n    this._keys[idx] = key;\n    this._values[idx] = value;\n\n    // Support: IE11\n    // Do not `return this` to simulate the partial IE11 implementation\n  },\n  delete: function(key) {\n    key = this._transformKey(key);\n    var idx = this._idx(key);\n    if (idx === -1) {\n      return false;\n    }\n    this._keys.splice(idx, 1);\n    this._values.splice(idx, 1);\n    this._lastKey = NaN;\n    this._lastIndex = -1;\n    return true;\n  }\n};\n\n// For now, always use `NgMapShim`, even if `window.Map` is available. Some native implementations\n// are still buggy (often in subtle ways) and can cause hard-to-debug failures. When native `Map`\n// implementations get more stable, we can reconsider switching to `window.Map` (when available).\nvar NgMap = NgMapShim;\n\nvar $$MapProvider = [/** @this */function() {\n  this.$get = [function() {\n    return NgMap;\n  }];\n}];\n\n/**\n * @ngdoc function\n * @module ng\n * @name angular.injector\n * @kind function\n *\n * @description\n * Creates an injector object that can be used for retrieving services as well as for\n * dependency injection (see {@link guide/di dependency injection}).\n *\n * @param {Array.<string|Function>} modules A list of module functions or their aliases. See\n *     {@link angular.module}. The `ng` module must be explicitly added.\n * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which\n *     disallows argument name annotation inference.\n * @returns {injector} Injector object. See {@link auto.$injector $injector}.\n *\n * @example\n * Typical usage\n * ```js\n *   // create an injector\n *   var $injector = angular.injector(['ng']);\n *\n *   // use the injector to kick off your application\n *   // use the type inference to auto inject arguments, or use implicit injection\n *   $injector.invoke(function($rootScope, $compile, $document) {\n *     $compile($document)($rootScope);\n *     $rootScope.$digest();\n *   });\n * ```\n *\n * Sometimes you want to get access to the injector of a currently running Angular app\n * from outside Angular. Perhaps, you want to inject and compile some markup after the\n * application has been bootstrapped. You can do this using the extra `injector()` added\n * to JQuery/jqLite elements. See {@link angular.element}.\n *\n * *This is fairly rare but could be the case if a third party library is injecting the\n * markup.*\n *\n * In the following example a new block of HTML containing a `ng-controller`\n * directive is added to the end of the document body by JQuery. We then compile and link\n * it into the current AngularJS scope.\n *\n * ```js\n * var $div = $('<div ng-controller=\"MyCtrl\">{{content.label}}</div>');\n * $(document.body).append($div);\n *\n * angular.element(document).injector().invoke(function($compile) {\n *   var scope = angular.element($div).scope();\n *   $compile($div)(scope);\n * });\n * ```\n */\n\n\n/**\n * @ngdoc module\n * @name auto\n * @installation\n * @description\n *\n * Implicit module which gets automatically added to each {@link auto.$injector $injector}.\n */\n\nvar ARROW_ARG = /^([^(]+?)=>/;\nvar FN_ARGS = /^[^(]*\\(\\s*([^)]*)\\)/m;\nvar FN_ARG_SPLIT = /,/;\nvar FN_ARG = /^\\s*(_?)(\\S+?)\\1\\s*$/;\nvar STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\nvar $injectorMinErr = minErr('$injector');\n\nfunction stringifyFn(fn) {\n  return Function.prototype.toString.call(fn);\n}\n\nfunction extractArgs(fn) {\n  var fnText = stringifyFn(fn).replace(STRIP_COMMENTS, ''),\n      args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);\n  return args;\n}\n\nfunction anonFn(fn) {\n  // For anonymous functions, showing at the very least the function signature can help in\n  // debugging.\n  var args = extractArgs(fn);\n  if (args) {\n    return 'function(' + (args[1] || '').replace(/[\\s\\r\\n]+/, ' ') + ')';\n  }\n  return 'fn';\n}\n\nfunction annotate(fn, strictDi, name) {\n  var $inject,\n      argDecl,\n      last;\n\n  if (typeof fn === 'function') {\n    if (!($inject = fn.$inject)) {\n      $inject = [];\n      if (fn.length) {\n        if (strictDi) {\n          if (!isString(name) || !name) {\n            name = fn.name || anonFn(fn);\n          }\n          throw $injectorMinErr('strictdi',\n            '{0} is not using explicit annotation and cannot be invoked in strict mode', name);\n        }\n        argDecl = extractArgs(fn);\n        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {\n          arg.replace(FN_ARG, function(all, underscore, name) {\n            $inject.push(name);\n          });\n        });\n      }\n      fn.$inject = $inject;\n    }\n  } else if (isArray(fn)) {\n    last = fn.length - 1;\n    assertArgFn(fn[last], 'fn');\n    $inject = fn.slice(0, last);\n  } else {\n    assertArgFn(fn, 'fn', true);\n  }\n  return $inject;\n}\n\n///////////////////////////////////////\n\n/**\n * @ngdoc service\n * @name $injector\n *\n * @description\n *\n * `$injector` is used to retrieve object instances as defined by\n * {@link auto.$provide provider}, instantiate types, invoke methods,\n * and load modules.\n *\n * The following always holds true:\n *\n * ```js\n *   var $injector = angular.injector();\n *   expect($injector.get('$injector')).toBe($injector);\n *   expect($injector.invoke(function($injector) {\n *     return $injector;\n *   })).toBe($injector);\n * ```\n *\n * # Injection Function Annotation\n *\n * JavaScript does not have annotations, and annotations are needed for dependency injection. The\n * following are all valid ways of annotating function with injection arguments and are equivalent.\n *\n * ```js\n *   // inferred (only works if code not minified/obfuscated)\n *   $injector.invoke(function(serviceA){});\n *\n *   // annotated\n *   function explicit(serviceA) {};\n *   explicit.$inject = ['serviceA'];\n *   $injector.invoke(explicit);\n *\n *   // inline\n *   $injector.invoke(['serviceA', function(serviceA){}]);\n * ```\n *\n * ## Inference\n *\n * In JavaScript calling `toString()` on a function returns the function definition. The definition\n * can then be parsed and the function arguments can be extracted. This method of discovering\n * annotations is disallowed when the injector is in strict mode.\n * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the\n * argument names.\n *\n * ## `$inject` Annotation\n * By adding an `$inject` property onto a function the injection parameters can be specified.\n *\n * ## Inline\n * As an array of injection names, where the last item in the array is the function to call.\n */\n\n/**\n * @ngdoc property\n * @name $injector#modules\n * @type {Object}\n * @description\n * A hash containing all the modules that have been loaded into the\n * $injector.\n *\n * You can use this property to find out information about a module via the\n * {@link angular.Module#info `myModule.info(...)`} method.\n *\n * For example:\n *\n * ```\n * var info = $injector.modules['ngAnimate'].info();\n * ```\n *\n * **Do not use this property to attempt to modify the modules after the application\n * has been bootstrapped.**\n */\n\n\n/**\n * @ngdoc method\n * @name $injector#get\n *\n * @description\n * Return an instance of the service.\n *\n * @param {string} name The name of the instance to retrieve.\n * @param {string=} caller An optional string to provide the origin of the function call for error messages.\n * @return {*} The instance.\n */\n\n/**\n * @ngdoc method\n * @name $injector#invoke\n *\n * @description\n * Invoke the method and supply the method arguments from the `$injector`.\n *\n * @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are\n *   injected according to the {@link guide/di $inject Annotation} rules.\n * @param {Object=} self The `this` for the invoked method.\n * @param {Object=} locals Optional object. If preset then any argument names are read from this\n *                         object first, before the `$injector` is consulted.\n * @returns {*} the value returned by the invoked `fn` function.\n */\n\n/**\n * @ngdoc method\n * @name $injector#has\n *\n * @description\n * Allows the user to query if the particular service exists.\n *\n * @param {string} name Name of the service to query.\n * @returns {boolean} `true` if injector has given service.\n */\n\n/**\n * @ngdoc method\n * @name $injector#instantiate\n * @description\n * Create a new instance of JS type. The method takes a constructor function, invokes the new\n * operator, and supplies all of the arguments to the constructor function as specified by the\n * constructor annotation.\n *\n * @param {Function} Type Annotated constructor function.\n * @param {Object=} locals Optional object. If preset then any argument names are read from this\n * object first, before the `$injector` is consulted.\n * @returns {Object} new instance of `Type`.\n */\n\n/**\n * @ngdoc method\n * @name $injector#annotate\n *\n * @description\n * Returns an array of service names which the function is requesting for injection. This API is\n * used by the injector to determine which services need to be injected into the function when the\n * function is invoked. There are three ways in which the function can be annotated with the needed\n * dependencies.\n *\n * # Argument names\n *\n * The simplest form is to extract the dependencies from the arguments of the function. This is done\n * by converting the function into a string using `toString()` method and extracting the argument\n * names.\n * ```js\n *   // Given\n *   function MyController($scope, $route) {\n *     // ...\n *   }\n *\n *   // Then\n *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);\n * ```\n *\n * You can disallow this method by using strict injection mode.\n *\n * This method does not work with code minification / obfuscation. For this reason the following\n * annotation strategies are supported.\n *\n * # The `$inject` property\n *\n * If a function has an `$inject` property and its value is an array of strings, then the strings\n * represent names of services to be injected into the function.\n * ```js\n *   // Given\n *   var MyController = function(obfuscatedScope, obfuscatedRoute) {\n *     // ...\n *   }\n *   // Define function dependencies\n *   MyController['$inject'] = ['$scope', '$route'];\n *\n *   // Then\n *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);\n * ```\n *\n * # The array notation\n *\n * It is often desirable to inline Injected functions and that's when setting the `$inject` property\n * is very inconvenient. In these situations using the array notation to specify the dependencies in\n * a way that survives minification is a better choice:\n *\n * ```js\n *   // We wish to write this (not minification / obfuscation safe)\n *   injector.invoke(function($compile, $rootScope) {\n *     // ...\n *   });\n *\n *   // We are forced to write break inlining\n *   var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) {\n *     // ...\n *   };\n *   tmpFn.$inject = ['$compile', '$rootScope'];\n *   injector.invoke(tmpFn);\n *\n *   // To better support inline function the inline annotation is supported\n *   injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {\n *     // ...\n *   }]);\n *\n *   // Therefore\n *   expect(injector.annotate(\n *      ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])\n *    ).toEqual(['$compile', '$rootScope']);\n * ```\n *\n * @param {Function|Array.<string|Function>} fn Function for which dependent service names need to\n * be retrieved as described above.\n *\n * @param {boolean=} [strictDi=false] Disallow argument name annotation inference.\n *\n * @returns {Array.<string>} The names of the services which the function requires.\n */\n\n\n\n/**\n * @ngdoc service\n * @name $provide\n *\n * @description\n *\n * The {@link auto.$provide $provide} service has a number of methods for registering components\n * with the {@link auto.$injector $injector}. Many of these functions are also exposed on\n * {@link angular.Module}.\n *\n * An Angular **service** is a singleton object created by a **service factory**.  These **service\n * factories** are functions which, in turn, are created by a **service provider**.\n * The **service providers** are constructor functions. When instantiated they must contain a\n * property called `$get`, which holds the **service factory** function.\n *\n * When you request a service, the {@link auto.$injector $injector} is responsible for finding the\n * correct **service provider**, instantiating it and then calling its `$get` **service factory**\n * function to get the instance of the **service**.\n *\n * Often services have no configuration options and there is no need to add methods to the service\n * provider.  The provider will be no more than a constructor function with a `$get` property. For\n * these cases the {@link auto.$provide $provide} service has additional helper methods to register\n * services without specifying a provider.\n *\n * * {@link auto.$provide#provider provider(name, provider)} - registers a **service provider** with the\n *     {@link auto.$injector $injector}\n * * {@link auto.$provide#constant constant(name, obj)} - registers a value/object that can be accessed by\n *     providers and services.\n * * {@link auto.$provide#value value(name, obj)} - registers a value/object that can only be accessed by\n *     services, not providers.\n * * {@link auto.$provide#factory factory(name, fn)} - registers a service **factory function**\n *     that will be wrapped in a **service provider** object, whose `$get` property will contain the\n *     given factory function.\n * * {@link auto.$provide#service service(name, Fn)} - registers a **constructor function**\n *     that will be wrapped in a **service provider** object, whose `$get` property will instantiate\n *      a new object using the given constructor function.\n * * {@link auto.$provide#decorator decorator(name, decorFn)} - registers a **decorator function** that\n *      will be able to modify or replace the implementation of another service.\n *\n * See the individual methods for more information and examples.\n */\n\n/**\n * @ngdoc method\n * @name $provide#provider\n * @description\n *\n * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions\n * are constructor functions, whose instances are responsible for \"providing\" a factory for a\n * service.\n *\n * Service provider names start with the name of the service they provide followed by `Provider`.\n * For example, the {@link ng.$log $log} service has a provider called\n * {@link ng.$logProvider $logProvider}.\n *\n * Service provider objects can have additional methods which allow configuration of the provider\n * and its service. Importantly, you can configure what kind of service is created by the `$get`\n * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a\n * method {@link ng.$logProvider#debugEnabled debugEnabled}\n * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the\n * console or not.\n *\n * @param {string} name The name of the instance. NOTE: the provider will be available under `name +\n                        'Provider'` key.\n * @param {(Object|function())} provider If the provider is:\n *\n *   - `Object`: then it should have a `$get` method. The `$get` method will be invoked using\n *     {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created.\n *   - `Constructor`: a new instance of the provider will be created using\n *     {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`.\n *\n * @returns {Object} registered provider instance\n\n * @example\n *\n * The following example shows how to create a simple event tracking service and register it using\n * {@link auto.$provide#provider $provide.provider()}.\n *\n * ```js\n *  // Define the eventTracker provider\n *  function EventTrackerProvider() {\n *    var trackingUrl = '/track';\n *\n *    // A provider method for configuring where the tracked events should been saved\n *    this.setTrackingUrl = function(url) {\n *      trackingUrl = url;\n *    };\n *\n *    // The service factory function\n *    this.$get = ['$http', function($http) {\n *      var trackedEvents = {};\n *      return {\n *        // Call this to track an event\n *        event: function(event) {\n *          var count = trackedEvents[event] || 0;\n *          count += 1;\n *          trackedEvents[event] = count;\n *          return count;\n *        },\n *        // Call this to save the tracked events to the trackingUrl\n *        save: function() {\n *          $http.post(trackingUrl, trackedEvents);\n *        }\n *      };\n *    }];\n *  }\n *\n *  describe('eventTracker', function() {\n *    var postSpy;\n *\n *    beforeEach(module(function($provide) {\n *      // Register the eventTracker provider\n *      $provide.provider('eventTracker', EventTrackerProvider);\n *    }));\n *\n *    beforeEach(module(function(eventTrackerProvider) {\n *      // Configure eventTracker provider\n *      eventTrackerProvider.setTrackingUrl('/custom-track');\n *    }));\n *\n *    it('tracks events', inject(function(eventTracker) {\n *      expect(eventTracker.event('login')).toEqual(1);\n *      expect(eventTracker.event('login')).toEqual(2);\n *    }));\n *\n *    it('saves to the tracking url', inject(function(eventTracker, $http) {\n *      postSpy = spyOn($http, 'post');\n *      eventTracker.event('login');\n *      eventTracker.save();\n *      expect(postSpy).toHaveBeenCalled();\n *      expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');\n *      expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');\n *      expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });\n *    }));\n *  });\n * ```\n */\n\n/**\n * @ngdoc method\n * @name $provide#factory\n * @description\n *\n * Register a **service factory**, which will be called to return the service instance.\n * This is short for registering a service where its provider consists of only a `$get` property,\n * which is the given service factory function.\n * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to\n * configure your service in a provider.\n *\n * @param {string} name The name of the instance.\n * @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation.\n *                      Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`.\n * @returns {Object} registered provider instance\n *\n * @example\n * Here is an example of registering a service\n * ```js\n *   $provide.factory('ping', ['$http', function($http) {\n *     return function ping() {\n *       return $http.send('/ping');\n *     };\n *   }]);\n * ```\n * You would then inject and use this service like this:\n * ```js\n *   someModule.controller('Ctrl', ['ping', function(ping) {\n *     ping();\n *   }]);\n * ```\n */\n\n\n/**\n * @ngdoc method\n * @name $provide#service\n * @description\n *\n * Register a **service constructor**, which will be invoked with `new` to create the service\n * instance.\n * This is short for registering a service where its provider's `$get` property is a factory\n * function that returns an instance instantiated by the injector from the service constructor\n * function.\n *\n * Internally it looks a bit like this:\n *\n * ```\n * {\n *   $get: function() {\n *     return $injector.instantiate(constructor);\n *   }\n * }\n * ```\n *\n *\n * You should use {@link auto.$provide#service $provide.service(class)} if you define your service\n * as a type/class.\n *\n * @param {string} name The name of the instance.\n * @param {Function|Array.<string|Function>} constructor An injectable class (constructor function)\n *     that will be instantiated.\n * @returns {Object} registered provider instance\n *\n * @example\n * Here is an example of registering a service using\n * {@link auto.$provide#service $provide.service(class)}.\n * ```js\n *   var Ping = function($http) {\n *     this.$http = $http;\n *   };\n *\n *   Ping.$inject = ['$http'];\n *\n *   Ping.prototype.send = function() {\n *     return this.$http.get('/ping');\n *   };\n *   $provide.service('ping', Ping);\n * ```\n * You would then inject and use this service like this:\n * ```js\n *   someModule.controller('Ctrl', ['ping', function(ping) {\n *     ping.send();\n *   }]);\n * ```\n */\n\n\n/**\n * @ngdoc method\n * @name $provide#value\n * @description\n *\n * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a\n * number, an array, an object or a function. This is short for registering a service where its\n * provider's `$get` property is a factory function that takes no arguments and returns the **value\n * service**. That also means it is not possible to inject other services into a value service.\n *\n * Value services are similar to constant services, except that they cannot be injected into a\n * module configuration function (see {@link angular.Module#config}) but they can be overridden by\n * an Angular {@link auto.$provide#decorator decorator}.\n *\n * @param {string} name The name of the instance.\n * @param {*} value The value.\n * @returns {Object} registered provider instance\n *\n * @example\n * Here are some examples of creating value services.\n * ```js\n *   $provide.value('ADMIN_USER', 'admin');\n *\n *   $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });\n *\n *   $provide.value('halfOf', function(value) {\n *     return value / 2;\n *   });\n * ```\n */\n\n\n/**\n * @ngdoc method\n * @name $provide#constant\n * @description\n *\n * Register a **constant service** with the {@link auto.$injector $injector}, such as a string,\n * a number, an array, an object or a function. Like the {@link auto.$provide#value value}, it is not\n * possible to inject other services into a constant.\n *\n * But unlike {@link auto.$provide#value value}, a constant can be\n * injected into a module configuration function (see {@link angular.Module#config}) and it cannot\n * be overridden by an Angular {@link auto.$provide#decorator decorator}.\n *\n * @param {string} name The name of the constant.\n * @param {*} value The constant value.\n * @returns {Object} registered instance\n *\n * @example\n * Here a some examples of creating constants:\n * ```js\n *   $provide.constant('SHARD_HEIGHT', 306);\n *\n *   $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);\n *\n *   $provide.constant('double', function(value) {\n *     return value * 2;\n *   });\n * ```\n */\n\n\n/**\n * @ngdoc method\n * @name $provide#decorator\n * @description\n *\n * Register a **decorator function** with the {@link auto.$injector $injector}. A decorator function\n * intercepts the creation of a service, allowing it to override or modify the behavior of the\n * service. The return value of the decorator function may be the original service, or a new service\n * that replaces (or wraps and delegates to) the original service.\n *\n * You can find out more about using decorators in the {@link guide/decorators} guide.\n *\n * @param {string} name The name of the service to decorate.\n * @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be\n *    provided and should return the decorated service instance. The function is called using\n *    the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.\n *    Local injection arguments:\n *\n *    * `$delegate` - The original service instance, which can be replaced, monkey patched, configured,\n *      decorated or delegated to.\n *\n * @example\n * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting\n * calls to {@link ng.$log#error $log.warn()}.\n * ```js\n *   $provide.decorator('$log', ['$delegate', function($delegate) {\n *     $delegate.warn = $delegate.error;\n *     return $delegate;\n *   }]);\n * ```\n */\n\n\nfunction createInjector(modulesToLoad, strictDi) {\n  strictDi = (strictDi === true);\n  var INSTANTIATING = {},\n      providerSuffix = 'Provider',\n      path = [],\n      loadedModules = new NgMap(),\n      providerCache = {\n        $provide: {\n            provider: supportObject(provider),\n            factory: supportObject(factory),\n            service: supportObject(service),\n            value: supportObject(value),\n            constant: supportObject(constant),\n            decorator: decorator\n          }\n      },\n      providerInjector = (providerCache.$injector =\n          createInternalInjector(providerCache, function(serviceName, caller) {\n            if (angular.isString(caller)) {\n              path.push(caller);\n            }\n            throw $injectorMinErr('unpr', 'Unknown provider: {0}', path.join(' <- '));\n          })),\n      instanceCache = {},\n      protoInstanceInjector =\n          createInternalInjector(instanceCache, function(serviceName, caller) {\n            var provider = providerInjector.get(serviceName + providerSuffix, caller);\n            return instanceInjector.invoke(\n                provider.$get, provider, undefined, serviceName);\n          }),\n      instanceInjector = protoInstanceInjector;\n\n  providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };\n  instanceInjector.modules = providerInjector.modules = createMap();\n  var runBlocks = loadModules(modulesToLoad);\n  instanceInjector = protoInstanceInjector.get('$injector');\n  instanceInjector.strictDi = strictDi;\n  forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });\n\n  return instanceInjector;\n\n  ////////////////////////////////////\n  // $provider\n  ////////////////////////////////////\n\n  function supportObject(delegate) {\n    return function(key, value) {\n      if (isObject(key)) {\n        forEach(key, reverseParams(delegate));\n      } else {\n        return delegate(key, value);\n      }\n    };\n  }\n\n  function provider(name, provider_) {\n    assertNotHasOwnProperty(name, 'service');\n    if (isFunction(provider_) || isArray(provider_)) {\n      provider_ = providerInjector.instantiate(provider_);\n    }\n    if (!provider_.$get) {\n      throw $injectorMinErr('pget', 'Provider \\'{0}\\' must define $get factory method.', name);\n    }\n    return (providerCache[name + providerSuffix] = provider_);\n  }\n\n  function enforceReturnValue(name, factory) {\n    return /** @this */ function enforcedReturnValue() {\n      var result = instanceInjector.invoke(factory, this);\n      if (isUndefined(result)) {\n        throw $injectorMinErr('undef', 'Provider \\'{0}\\' must return a value from $get factory method.', name);\n      }\n      return result;\n    };\n  }\n\n  function factory(name, factoryFn, enforce) {\n    return provider(name, {\n      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn\n    });\n  }\n\n  function service(name, constructor) {\n    return factory(name, ['$injector', function($injector) {\n      return $injector.instantiate(constructor);\n    }]);\n  }\n\n  function value(name, val) { return factory(name, valueFn(val), false); }\n\n  function constant(name, value) {\n    assertNotHasOwnProperty(name, 'constant');\n    providerCache[name] = value;\n    instanceCache[name] = value;\n  }\n\n  function decorator(serviceName, decorFn) {\n    var origProvider = providerInjector.get(serviceName + providerSuffix),\n        orig$get = origProvider.$get;\n\n    origProvider.$get = function() {\n      var origInstance = instanceInjector.invoke(orig$get, origProvider);\n      return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});\n    };\n  }\n\n  ////////////////////////////////////\n  // Module Loading\n  ////////////////////////////////////\n  function loadModules(modulesToLoad) {\n    assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array');\n    var runBlocks = [], moduleFn;\n    forEach(modulesToLoad, function(module) {\n      if (loadedModules.get(module)) return;\n      loadedModules.set(module, true);\n\n      function runInvokeQueue(queue) {\n        var i, ii;\n        for (i = 0, ii = queue.length; i < ii; i++) {\n          var invokeArgs = queue[i],\n              provider = providerInjector.get(invokeArgs[0]);\n\n          provider[invokeArgs[1]].apply(provider, invokeArgs[2]);\n        }\n      }\n\n      try {\n        if (isString(module)) {\n          moduleFn = angularModule(module);\n          instanceInjector.modules[module] = moduleFn;\n          runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);\n          runInvokeQueue(moduleFn._invokeQueue);\n          runInvokeQueue(moduleFn._configBlocks);\n        } else if (isFunction(module)) {\n            runBlocks.push(providerInjector.invoke(module));\n        } else if (isArray(module)) {\n            runBlocks.push(providerInjector.invoke(module));\n        } else {\n          assertArgFn(module, 'module');\n        }\n      } catch (e) {\n        if (isArray(module)) {\n          module = module[module.length - 1];\n        }\n        if (e.message && e.stack && e.stack.indexOf(e.message) === -1) {\n          // Safari & FF's stack traces don't contain error.message content\n          // unlike those of Chrome and IE\n          // So if stack doesn't contain message, we create a new string that contains both.\n          // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.\n          // eslint-disable-next-line no-ex-assign\n          e = e.message + '\\n' + e.stack;\n        }\n        throw $injectorMinErr('modulerr', 'Failed to instantiate module {0} due to:\\n{1}',\n                  module, e.stack || e.message || e);\n      }\n    });\n    return runBlocks;\n  }\n\n  ////////////////////////////////////\n  // internal Injector\n  ////////////////////////////////////\n\n  function createInternalInjector(cache, factory) {\n\n    function getService(serviceName, caller) {\n      if (cache.hasOwnProperty(serviceName)) {\n        if (cache[serviceName] === INSTANTIATING) {\n          throw $injectorMinErr('cdep', 'Circular dependency found: {0}',\n                    serviceName + ' <- ' + path.join(' <- '));\n        }\n        return cache[serviceName];\n      } else {\n        try {\n          path.unshift(serviceName);\n          cache[serviceName] = INSTANTIATING;\n          cache[serviceName] = factory(serviceName, caller);\n          return cache[serviceName];\n        } catch (err) {\n          if (cache[serviceName] === INSTANTIATING) {\n            delete cache[serviceName];\n          }\n          throw err;\n        } finally {\n          path.shift();\n        }\n      }\n    }\n\n\n    function injectionArgs(fn, locals, serviceName) {\n      var args = [],\n          $inject = createInjector.$$annotate(fn, strictDi, serviceName);\n\n      for (var i = 0, length = $inject.length; i < length; i++) {\n        var key = $inject[i];\n        if (typeof key !== 'string') {\n          throw $injectorMinErr('itkn',\n                  'Incorrect injection token! Expected service name as string, got {0}', key);\n        }\n        args.push(locals && locals.hasOwnProperty(key) ? locals[key] :\n                                                         getService(key, serviceName));\n      }\n      return args;\n    }\n\n    function isClass(func) {\n      // Support: IE 9-11 only\n      // IE 9-11 do not support classes and IE9 leaks with the code below.\n      if (msie || typeof func !== 'function') {\n        return false;\n      }\n      var result = func.$$ngIsClass;\n      if (!isBoolean(result)) {\n        // Support: Edge 12-13 only\n        // See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6156135/\n        result = func.$$ngIsClass = /^(?:class\\b|constructor\\()/.test(stringifyFn(func));\n      }\n      return result;\n    }\n\n    function invoke(fn, self, locals, serviceName) {\n      if (typeof locals === 'string') {\n        serviceName = locals;\n        locals = null;\n      }\n\n      var args = injectionArgs(fn, locals, serviceName);\n      if (isArray(fn)) {\n        fn = fn[fn.length - 1];\n      }\n\n      if (!isClass(fn)) {\n        // http://jsperf.com/angularjs-invoke-apply-vs-switch\n        // #5388\n        return fn.apply(self, args);\n      } else {\n        args.unshift(null);\n        return new (Function.prototype.bind.apply(fn, args))();\n      }\n    }\n\n\n    function instantiate(Type, locals, serviceName) {\n      // Check if Type is annotated and use just the given function at n-1 as parameter\n      // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);\n      var ctor = (isArray(Type) ? Type[Type.length - 1] : Type);\n      var args = injectionArgs(Type, locals, serviceName);\n      // Empty object at position 0 is ignored for invocation with `new`, but required.\n      args.unshift(null);\n      return new (Function.prototype.bind.apply(ctor, args))();\n    }\n\n\n    return {\n      invoke: invoke,\n      instantiate: instantiate,\n      get: getService,\n      annotate: createInjector.$$annotate,\n      has: function(name) {\n        return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);\n      }\n    };\n  }\n}\n\ncreateInjector.$$annotate = annotate;\n\n/**\n * @ngdoc provider\n * @name $anchorScrollProvider\n * @this\n *\n * @description\n * Use `$anchorScrollProvider` to disable automatic scrolling whenever\n * {@link ng.$location#hash $location.hash()} changes.\n */\nfunction $AnchorScrollProvider() {\n\n  var autoScrollingEnabled = true;\n\n  /**\n   * @ngdoc method\n   * @name $anchorScrollProvider#disableAutoScrolling\n   *\n   * @description\n   * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to\n   * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />\n   * Use this method to disable automatic scrolling.\n   *\n   * If automatic scrolling is disabled, one must explicitly call\n   * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the\n   * current hash.\n   */\n  this.disableAutoScrolling = function() {\n    autoScrollingEnabled = false;\n  };\n\n  /**\n   * @ngdoc service\n   * @name $anchorScroll\n   * @kind function\n   * @requires $window\n   * @requires $location\n   * @requires $rootScope\n   *\n   * @description\n   * When called, it scrolls to the element related to the specified `hash` or (if omitted) to the\n   * current value of {@link ng.$location#hash $location.hash()}, according to the rules specified\n   * in the\n   * [HTML5 spec](http://www.w3.org/html/wg/drafts/html/master/browsers.html#an-indicated-part-of-the-document).\n   *\n   * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to\n   * match any anchor whenever it changes. This can be disabled by calling\n   * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}.\n   *\n   * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a\n   * vertical scroll-offset (either fixed or dynamic).\n   *\n   * @param {string=} hash The hash specifying the element to scroll to. If omitted, the value of\n   *                       {@link ng.$location#hash $location.hash()} will be used.\n   *\n   * @property {(number|function|jqLite)} yOffset\n   * If set, specifies a vertical scroll-offset. This is often useful when there are fixed\n   * positioned elements at the top of the page, such as navbars, headers etc.\n   *\n   * `yOffset` can be specified in various ways:\n   * - **number**: A fixed number of pixels to be used as offset.<br /><br />\n   * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return\n   *   a number representing the offset (in pixels).<br /><br />\n   * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from\n   *   the top of the page to the element's bottom will be used as offset.<br />\n   *   **Note**: The element will be taken into account only as long as its `position` is set to\n   *   `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust\n   *   their height and/or positioning according to the viewport's size.\n   *\n   * <br />\n   * <div class=\"alert alert-warning\">\n   * In order for `yOffset` to work properly, scrolling should take place on the document's root and\n   * not some child element.\n   * </div>\n   *\n   * @example\n     <example module=\"anchorScrollExample\" name=\"anchor-scroll\">\n       <file name=\"index.html\">\n         <div id=\"scrollArea\" ng-controller=\"ScrollController\">\n           <a ng-click=\"gotoBottom()\">Go to bottom</a>\n           <a id=\"bottom\"></a> You're at the bottom!\n         </div>\n       </file>\n       <file name=\"script.js\">\n         angular.module('anchorScrollExample', [])\n           .controller('ScrollController', ['$scope', '$location', '$anchorScroll',\n             function($scope, $location, $anchorScroll) {\n               $scope.gotoBottom = function() {\n                 // set the location.hash to the id of\n                 // the element you wish to scroll to.\n                 $location.hash('bottom');\n\n                 // call $anchorScroll()\n                 $anchorScroll();\n               };\n             }]);\n       </file>\n       <file name=\"style.css\">\n         #scrollArea {\n           height: 280px;\n           overflow: auto;\n         }\n\n         #bottom {\n           display: block;\n           margin-top: 2000px;\n         }\n       </file>\n     </example>\n   *\n   * <hr />\n   * The example below illustrates the use of a vertical scroll-offset (specified as a fixed value).\n   * See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details.\n   *\n   * @example\n     <example module=\"anchorScrollOffsetExample\" name=\"anchor-scroll-offset\">\n       <file name=\"index.html\">\n         <div class=\"fixed-header\" ng-controller=\"headerCtrl\">\n           <a href=\"\" ng-click=\"gotoAnchor(x)\" ng-repeat=\"x in [1,2,3,4,5]\">\n             Go to anchor {{x}}\n           </a>\n         </div>\n         <div id=\"anchor{{x}}\" class=\"anchor\" ng-repeat=\"x in [1,2,3,4,5]\">\n           Anchor {{x}} of 5\n         </div>\n       </file>\n       <file name=\"script.js\">\n         angular.module('anchorScrollOffsetExample', [])\n           .run(['$anchorScroll', function($anchorScroll) {\n             $anchorScroll.yOffset = 50;   // always scroll by 50 extra pixels\n           }])\n           .controller('headerCtrl', ['$anchorScroll', '$location', '$scope',\n             function($anchorScroll, $location, $scope) {\n               $scope.gotoAnchor = function(x) {\n                 var newHash = 'anchor' + x;\n                 if ($location.hash() !== newHash) {\n                   // set the $location.hash to `newHash` and\n                   // $anchorScroll will automatically scroll to it\n                   $location.hash('anchor' + x);\n                 } else {\n                   // call $anchorScroll() explicitly,\n                   // since $location.hash hasn't changed\n                   $anchorScroll();\n                 }\n               };\n             }\n           ]);\n       </file>\n       <file name=\"style.css\">\n         body {\n           padding-top: 50px;\n         }\n\n         .anchor {\n           border: 2px dashed DarkOrchid;\n           padding: 10px 10px 200px 10px;\n         }\n\n         .fixed-header {\n           background-color: rgba(0, 0, 0, 0.2);\n           height: 50px;\n           position: fixed;\n           top: 0; left: 0; right: 0;\n         }\n\n         .fixed-header > a {\n           display: inline-block;\n           margin: 5px 15px;\n         }\n       </file>\n     </example>\n   */\n  this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {\n    var document = $window.document;\n\n    // Helper function to get first anchor from a NodeList\n    // (using `Array#some()` instead of `angular#forEach()` since it's more performant\n    //  and working in all supported browsers.)\n    function getFirstAnchor(list) {\n      var result = null;\n      Array.prototype.some.call(list, function(element) {\n        if (nodeName_(element) === 'a') {\n          result = element;\n          return true;\n        }\n      });\n      return result;\n    }\n\n    function getYOffset() {\n\n      var offset = scroll.yOffset;\n\n      if (isFunction(offset)) {\n        offset = offset();\n      } else if (isElement(offset)) {\n        var elem = offset[0];\n        var style = $window.getComputedStyle(elem);\n        if (style.position !== 'fixed') {\n          offset = 0;\n        } else {\n          offset = elem.getBoundingClientRect().bottom;\n        }\n      } else if (!isNumber(offset)) {\n        offset = 0;\n      }\n\n      return offset;\n    }\n\n    function scrollTo(elem) {\n      if (elem) {\n        elem.scrollIntoView();\n\n        var offset = getYOffset();\n\n        if (offset) {\n          // `offset` is the number of pixels we should scroll UP in order to align `elem` properly.\n          // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the\n          // top of the viewport.\n          //\n          // IF the number of pixels from the top of `elem` to the end of the page's content is less\n          // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some\n          // way down the page.\n          //\n          // This is often the case for elements near the bottom of the page.\n          //\n          // In such cases we do not need to scroll the whole `offset` up, just the difference between\n          // the top of the element and the offset, which is enough to align the top of `elem` at the\n          // desired position.\n          var elemTop = elem.getBoundingClientRect().top;\n          $window.scrollBy(0, elemTop - offset);\n        }\n      } else {\n        $window.scrollTo(0, 0);\n      }\n    }\n\n    function scroll(hash) {\n      // Allow numeric hashes\n      hash = isString(hash) ? hash : isNumber(hash) ? hash.toString() : $location.hash();\n      var elm;\n\n      // empty hash, scroll to the top of the page\n      if (!hash) scrollTo(null);\n\n      // element with given id\n      else if ((elm = document.getElementById(hash))) scrollTo(elm);\n\n      // first anchor with given name :-D\n      else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);\n\n      // no element and hash === 'top', scroll to the top of the page\n      else if (hash === 'top') scrollTo(null);\n    }\n\n    // does not scroll when user clicks on anchor link that is currently on\n    // (no url change, no $location.hash() change), browser native does scroll\n    if (autoScrollingEnabled) {\n      $rootScope.$watch(function autoScrollWatch() {return $location.hash();},\n        function autoScrollWatchAction(newVal, oldVal) {\n          // skip the initial scroll if $location.hash is empty\n          if (newVal === oldVal && newVal === '') return;\n\n          jqLiteDocumentLoaded(function() {\n            $rootScope.$evalAsync(scroll);\n          });\n        });\n    }\n\n    return scroll;\n  }];\n}\n\nvar $animateMinErr = minErr('$animate');\nvar ELEMENT_NODE = 1;\nvar NG_ANIMATE_CLASSNAME = 'ng-animate';\n\nfunction mergeClasses(a,b) {\n  if (!a && !b) return '';\n  if (!a) return b;\n  if (!b) return a;\n  if (isArray(a)) a = a.join(' ');\n  if (isArray(b)) b = b.join(' ');\n  return a + ' ' + b;\n}\n\nfunction extractElementNode(element) {\n  for (var i = 0; i < element.length; i++) {\n    var elm = element[i];\n    if (elm.nodeType === ELEMENT_NODE) {\n      return elm;\n    }\n  }\n}\n\nfunction splitClasses(classes) {\n  if (isString(classes)) {\n    classes = classes.split(' ');\n  }\n\n  // Use createMap() to prevent class assumptions involving property names in\n  // Object.prototype\n  var obj = createMap();\n  forEach(classes, function(klass) {\n    // sometimes the split leaves empty string values\n    // incase extra spaces were applied to the options\n    if (klass.length) {\n      obj[klass] = true;\n    }\n  });\n  return obj;\n}\n\n// if any other type of options value besides an Object value is\n// passed into the $animate.method() animation then this helper code\n// will be run which will ignore it. While this patch is not the\n// greatest solution to this, a lot of existing plugins depend on\n// $animate to either call the callback (< 1.2) or return a promise\n// that can be changed. This helper function ensures that the options\n// are wiped clean incase a callback function is provided.\nfunction prepareAnimateOptions(options) {\n  return isObject(options)\n      ? options\n      : {};\n}\n\nvar $$CoreAnimateJsProvider = /** @this */ function() {\n  this.$get = noop;\n};\n\n// this is prefixed with Core since it conflicts with\n// the animateQueueProvider defined in ngAnimate/animateQueue.js\nvar $$CoreAnimateQueueProvider = /** @this */ function() {\n  var postDigestQueue = new NgMap();\n  var postDigestElements = [];\n\n  this.$get = ['$$AnimateRunner', '$rootScope',\n       function($$AnimateRunner,   $rootScope) {\n    return {\n      enabled: noop,\n      on: noop,\n      off: noop,\n      pin: noop,\n\n      push: function(element, event, options, domOperation) {\n        if (domOperation) {\n          domOperation();\n        }\n\n        options = options || {};\n        if (options.from) {\n          element.css(options.from);\n        }\n        if (options.to) {\n          element.css(options.to);\n        }\n\n        if (options.addClass || options.removeClass) {\n          addRemoveClassesPostDigest(element, options.addClass, options.removeClass);\n        }\n\n        var runner = new $$AnimateRunner();\n\n        // since there are no animations to run the runner needs to be\n        // notified that the animation call is complete.\n        runner.complete();\n        return runner;\n      }\n    };\n\n\n    function updateData(data, classes, value) {\n      var changed = false;\n      if (classes) {\n        classes = isString(classes) ? classes.split(' ') :\n                  isArray(classes) ? classes : [];\n        forEach(classes, function(className) {\n          if (className) {\n            changed = true;\n            data[className] = value;\n          }\n        });\n      }\n      return changed;\n    }\n\n    function handleCSSClassChanges() {\n      forEach(postDigestElements, function(element) {\n        var data = postDigestQueue.get(element);\n        if (data) {\n          var existing = splitClasses(element.attr('class'));\n          var toAdd = '';\n          var toRemove = '';\n          forEach(data, function(status, className) {\n            var hasClass = !!existing[className];\n            if (status !== hasClass) {\n              if (status) {\n                toAdd += (toAdd.length ? ' ' : '') + className;\n              } else {\n                toRemove += (toRemove.length ? ' ' : '') + className;\n              }\n            }\n          });\n\n          forEach(element, function(elm) {\n            if (toAdd) {\n              jqLiteAddClass(elm, toAdd);\n            }\n            if (toRemove) {\n              jqLiteRemoveClass(elm, toRemove);\n            }\n          });\n          postDigestQueue.delete(element);\n        }\n      });\n      postDigestElements.length = 0;\n    }\n\n\n    function addRemoveClassesPostDigest(element, add, remove) {\n      var data = postDigestQueue.get(element) || {};\n\n      var classesAdded = updateData(data, add, true);\n      var classesRemoved = updateData(data, remove, false);\n\n      if (classesAdded || classesRemoved) {\n\n        postDigestQueue.set(element, data);\n        postDigestElements.push(element);\n\n        if (postDigestElements.length === 1) {\n          $rootScope.$$postDigest(handleCSSClassChanges);\n        }\n      }\n    }\n  }];\n};\n\n/**\n * @ngdoc provider\n * @name $animateProvider\n *\n * @description\n * Default implementation of $animate that doesn't perform any animations, instead just\n * synchronously performs DOM updates and resolves the returned runner promise.\n *\n * In order to enable animations the `ngAnimate` module has to be loaded.\n *\n * To see the functional implementation check out `src/ngAnimate/animate.js`.\n */\nvar $AnimateProvider = ['$provide', /** @this */ function($provide) {\n  var provider = this;\n  var classNameFilter = null;\n\n  this.$$registeredAnimations = Object.create(null);\n\n   /**\n   * @ngdoc method\n   * @name $animateProvider#register\n   *\n   * @description\n   * Registers a new injectable animation factory function. The factory function produces the\n   * animation object which contains callback functions for each event that is expected to be\n   * animated.\n   *\n   *   * `eventFn`: `function(element, ... , doneFunction, options)`\n   *   The element to animate, the `doneFunction` and the options fed into the animation. Depending\n   *   on the type of animation additional arguments will be injected into the animation function. The\n   *   list below explains the function signatures for the different animation methods:\n   *\n   *   - setClass: function(element, addedClasses, removedClasses, doneFunction, options)\n   *   - addClass: function(element, addedClasses, doneFunction, options)\n   *   - removeClass: function(element, removedClasses, doneFunction, options)\n   *   - enter, leave, move: function(element, doneFunction, options)\n   *   - animate: function(element, fromStyles, toStyles, doneFunction, options)\n   *\n   *   Make sure to trigger the `doneFunction` once the animation is fully complete.\n   *\n   * ```js\n   *   return {\n   *     //enter, leave, move signature\n   *     eventFn : function(element, done, options) {\n   *       //code to run the animation\n   *       //once complete, then run done()\n   *       return function endFunction(wasCancelled) {\n   *         //code to cancel the animation\n   *       }\n   *     }\n   *   }\n   * ```\n   *\n   * @param {string} name The name of the animation (this is what the class-based CSS value will be compared to).\n   * @param {Function} factory The factory function that will be executed to return the animation\n   *                           object.\n   */\n  this.register = function(name, factory) {\n    if (name && name.charAt(0) !== '.') {\n      throw $animateMinErr('notcsel', 'Expecting class selector starting with \\'.\\' got \\'{0}\\'.', name);\n    }\n\n    var key = name + '-animation';\n    provider.$$registeredAnimations[name.substr(1)] = key;\n    $provide.factory(key, factory);\n  };\n\n  /**\n   * @ngdoc method\n   * @name $animateProvider#classNameFilter\n   *\n   * @description\n   * Sets and/or returns the CSS class regular expression that is checked when performing\n   * an animation. Upon bootstrap the classNameFilter value is not set at all and will\n   * therefore enable $animate to attempt to perform an animation on any element that is triggered.\n   * When setting the `classNameFilter` value, animations will only be performed on elements\n   * that successfully match the filter expression. This in turn can boost performance\n   * for low-powered devices as well as applications containing a lot of structural operations.\n   * @param {RegExp=} expression The className expression which will be checked against all animations\n   * @return {RegExp} The current CSS className expression value. If null then there is no expression value\n   */\n  this.classNameFilter = function(expression) {\n    if (arguments.length === 1) {\n      classNameFilter = (expression instanceof RegExp) ? expression : null;\n      if (classNameFilter) {\n        var reservedRegex = new RegExp('[(\\\\s|\\\\/)]' + NG_ANIMATE_CLASSNAME + '[(\\\\s|\\\\/)]');\n        if (reservedRegex.test(classNameFilter.toString())) {\n          classNameFilter = null;\n          throw $animateMinErr('nongcls', '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the \"{0}\" CSS class.', NG_ANIMATE_CLASSNAME);\n        }\n      }\n    }\n    return classNameFilter;\n  };\n\n  this.$get = ['$$animateQueue', function($$animateQueue) {\n    function domInsert(element, parentElement, afterElement) {\n      // if for some reason the previous element was removed\n      // from the dom sometime before this code runs then let's\n      // just stick to using the parent element as the anchor\n      if (afterElement) {\n        var afterNode = extractElementNode(afterElement);\n        if (afterNode && !afterNode.parentNode && !afterNode.previousElementSibling) {\n          afterElement = null;\n        }\n      }\n      if (afterElement) {\n        afterElement.after(element);\n      } else {\n        parentElement.prepend(element);\n      }\n    }\n\n    /**\n     * @ngdoc service\n     * @name $animate\n     * @description The $animate service exposes a series of DOM utility methods that provide support\n     * for animation hooks. The default behavior is the application of DOM operations, however,\n     * when an animation is detected (and animations are enabled), $animate will do the heavy lifting\n     * to ensure that animation runs with the triggered DOM operation.\n     *\n     * By default $animate doesn't trigger any animations. This is because the `ngAnimate` module isn't\n     * included and only when it is active then the animation hooks that `$animate` triggers will be\n     * functional. Once active then all structural `ng-` directives will trigger animations as they perform\n     * their DOM-related operations (enter, leave and move). Other directives such as `ngClass`,\n     * `ngShow`, `ngHide` and `ngMessages` also provide support for animations.\n     *\n     * It is recommended that the`$animate` service is always used when executing DOM-related procedures within directives.\n     *\n     * To learn more about enabling animation support, click here to visit the\n     * {@link ngAnimate ngAnimate module page}.\n     */\n    return {\n      // we don't call it directly since non-existant arguments may\n      // be interpreted as null within the sub enabled function\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#on\n       * @kind function\n       * @description Sets up an event listener to fire whenever the animation event (enter, leave, move, etc...)\n       *    has fired on the given element or among any of its children. Once the listener is fired, the provided callback\n       *    is fired with the following params:\n       *\n       * ```js\n       * $animate.on('enter', container,\n       *    function callback(element, phase) {\n       *      // cool we detected an enter animation within the container\n       *    }\n       * );\n       * ```\n       *\n       * @param {string} event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...)\n       * @param {DOMElement} container the container element that will capture each of the animation events that are fired on itself\n       *     as well as among its children\n       * @param {Function} callback the callback function that will be fired when the listener is triggered\n       *\n       * The arguments present in the callback function are:\n       * * `element` - The captured DOM element that the animation was fired on.\n       * * `phase` - The phase of the animation. The two possible phases are **start** (when the animation starts) and **close** (when it ends).\n       */\n      on: $$animateQueue.on,\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#off\n       * @kind function\n       * @description Deregisters an event listener based on the event which has been associated with the provided element. This method\n       * can be used in three different ways depending on the arguments:\n       *\n       * ```js\n       * // remove all the animation event listeners listening for `enter`\n       * $animate.off('enter');\n       *\n       * // remove listeners for all animation events from the container element\n       * $animate.off(container);\n       *\n       * // remove all the animation event listeners listening for `enter` on the given element and its children\n       * $animate.off('enter', container);\n       *\n       * // remove the event listener function provided by `callback` that is set\n       * // to listen for `enter` on the given `container` as well as its children\n       * $animate.off('enter', container, callback);\n       * ```\n       *\n       * @param {string|DOMElement} event|container the animation event (e.g. enter, leave, move,\n       * addClass, removeClass, etc...), or the container element. If it is the element, all other\n       * arguments are ignored.\n       * @param {DOMElement=} container the container element the event listener was placed on\n       * @param {Function=} callback the callback function that was registered as the listener\n       */\n      off: $$animateQueue.off,\n\n      /**\n       * @ngdoc method\n       * @name $animate#pin\n       * @kind function\n       * @description Associates the provided element with a host parent element to allow the element to be animated even if it exists\n       *    outside of the DOM structure of the Angular application. By doing so, any animation triggered via `$animate` can be issued on the\n       *    element despite being outside the realm of the application or within another application. Say for example if the application\n       *    was bootstrapped on an element that is somewhere inside of the `<body>` tag, but we wanted to allow for an element to be situated\n       *    as a direct child of `document.body`, then this can be achieved by pinning the element via `$animate.pin(element)`. Keep in mind\n       *    that calling `$animate.pin(element, parentElement)` will not actually insert into the DOM anywhere; it will just create the association.\n       *\n       *    Note that this feature is only active when the `ngAnimate` module is used.\n       *\n       * @param {DOMElement} element the external element that will be pinned\n       * @param {DOMElement} parentElement the host parent element that will be associated with the external element\n       */\n      pin: $$animateQueue.pin,\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#enabled\n       * @kind function\n       * @description Used to get and set whether animations are enabled or not on the entire application or on an element and its children. This\n       * function can be called in four ways:\n       *\n       * ```js\n       * // returns true or false\n       * $animate.enabled();\n       *\n       * // changes the enabled state for all animations\n       * $animate.enabled(false);\n       * $animate.enabled(true);\n       *\n       * // returns true or false if animations are enabled for an element\n       * $animate.enabled(element);\n       *\n       * // changes the enabled state for an element and its children\n       * $animate.enabled(element, true);\n       * $animate.enabled(element, false);\n       * ```\n       *\n       * @param {DOMElement=} element the element that will be considered for checking/setting the enabled state\n       * @param {boolean=} enabled whether or not the animations will be enabled for the element\n       *\n       * @return {boolean} whether or not animations are enabled\n       */\n      enabled: $$animateQueue.enabled,\n\n      /**\n       * @ngdoc method\n       * @name $animate#cancel\n       * @kind function\n       * @description Cancels the provided animation.\n       *\n       * @param {Promise} animationPromise The animation promise that is returned when an animation is started.\n       */\n      cancel: function(runner) {\n        if (runner.end) {\n          runner.end();\n        }\n      },\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#enter\n       * @kind function\n       * @description Inserts the element into the DOM either after the `after` element (if provided) or\n       *   as the first child within the `parent` element and then triggers an animation.\n       *   A promise is returned that will be resolved during the next digest once the animation\n       *   has completed.\n       *\n       * @param {DOMElement} element the element which will be inserted into the DOM\n       * @param {DOMElement} parent the parent element which will append the element as\n       *   a child (so long as the after element is not present)\n       * @param {DOMElement=} after the sibling element after which the element will be appended\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      enter: function(element, parent, after, options) {\n        parent = parent && jqLite(parent);\n        after = after && jqLite(after);\n        parent = parent || after.parent();\n        domInsert(element, parent, after);\n        return $$animateQueue.push(element, 'enter', prepareAnimateOptions(options));\n      },\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#move\n       * @kind function\n       * @description Inserts (moves) the element into its new position in the DOM either after\n       *   the `after` element (if provided) or as the first child within the `parent` element\n       *   and then triggers an animation. A promise is returned that will be resolved\n       *   during the next digest once the animation has completed.\n       *\n       * @param {DOMElement} element the element which will be moved into the new DOM position\n       * @param {DOMElement} parent the parent element which will append the element as\n       *   a child (so long as the after element is not present)\n       * @param {DOMElement=} after the sibling element after which the element will be appended\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      move: function(element, parent, after, options) {\n        parent = parent && jqLite(parent);\n        after = after && jqLite(after);\n        parent = parent || after.parent();\n        domInsert(element, parent, after);\n        return $$animateQueue.push(element, 'move', prepareAnimateOptions(options));\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#leave\n       * @kind function\n       * @description Triggers an animation and then removes the element from the DOM.\n       * When the function is called a promise is returned that will be resolved during the next\n       * digest once the animation has completed.\n       *\n       * @param {DOMElement} element the element which will be removed from the DOM\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      leave: function(element, options) {\n        return $$animateQueue.push(element, 'leave', prepareAnimateOptions(options), function() {\n          element.remove();\n        });\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#addClass\n       * @kind function\n       *\n       * @description Triggers an addClass animation surrounding the addition of the provided CSS class(es). Upon\n       *   execution, the addClass operation will only be handled after the next digest and it will not trigger an\n       *   animation if element already contains the CSS class or if the class is removed at a later step.\n       *   Note that class-based animations are treated differently compared to structural animations\n       *   (like enter, move and leave) since the CSS classes may be added/removed at different points\n       *   depending if CSS or JavaScript animations are used.\n       *\n       * @param {DOMElement} element the element which the CSS classes will be applied to\n       * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces)\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      addClass: function(element, className, options) {\n        options = prepareAnimateOptions(options);\n        options.addClass = mergeClasses(options.addclass, className);\n        return $$animateQueue.push(element, 'addClass', options);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#removeClass\n       * @kind function\n       *\n       * @description Triggers a removeClass animation surrounding the removal of the provided CSS class(es). Upon\n       *   execution, the removeClass operation will only be handled after the next digest and it will not trigger an\n       *   animation if element does not contain the CSS class or if the class is added at a later step.\n       *   Note that class-based animations are treated differently compared to structural animations\n       *   (like enter, move and leave) since the CSS classes may be added/removed at different points\n       *   depending if CSS or JavaScript animations are used.\n       *\n       * @param {DOMElement} element the element which the CSS classes will be applied to\n       * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces)\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      removeClass: function(element, className, options) {\n        options = prepareAnimateOptions(options);\n        options.removeClass = mergeClasses(options.removeClass, className);\n        return $$animateQueue.push(element, 'removeClass', options);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#setClass\n       * @kind function\n       *\n       * @description Performs both the addition and removal of a CSS classes on an element and (during the process)\n       *    triggers an animation surrounding the class addition/removal. Much like `$animate.addClass` and\n       *    `$animate.removeClass`, `setClass` will only evaluate the classes being added/removed once a digest has\n       *    passed. Note that class-based animations are treated differently compared to structural animations\n       *    (like enter, move and leave) since the CSS classes may be added/removed at different points\n       *    depending if CSS or JavaScript animations are used.\n       *\n       * @param {DOMElement} element the element which the CSS classes will be applied to\n       * @param {string} add the CSS class(es) that will be added (multiple classes are separated via spaces)\n       * @param {string} remove the CSS class(es) that will be removed (multiple classes are separated via spaces)\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      setClass: function(element, add, remove, options) {\n        options = prepareAnimateOptions(options);\n        options.addClass = mergeClasses(options.addClass, add);\n        options.removeClass = mergeClasses(options.removeClass, remove);\n        return $$animateQueue.push(element, 'setClass', options);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#animate\n       * @kind function\n       *\n       * @description Performs an inline animation on the element which applies the provided to and from CSS styles to the element.\n       * If any detected CSS transition, keyframe or JavaScript matches the provided className value, then the animation will take\n       * on the provided styles. For example, if a transition animation is set for the given className, then the provided `from` and\n       * `to` styles will be applied alongside the given transition. If the CSS style provided in `from` does not have a corresponding\n       * style in `to`, the style in `from` is applied immediately, and no animation is run.\n       * If a JavaScript animation is detected then the provided styles will be given in as function parameters into the `animate`\n       * method (or as part of the `options` parameter):\n       *\n       * ```js\n       * ngModule.animation('.my-inline-animation', function() {\n       *   return {\n       *     animate : function(element, from, to, done, options) {\n       *       //animation\n       *       done();\n       *     }\n       *   }\n       * });\n       * ```\n       *\n       * @param {DOMElement} element the element which the CSS styles will be applied to\n       * @param {object} from the from (starting) CSS styles that will be applied to the element and across the animation.\n       * @param {object} to the to (destination) CSS styles that will be applied to the element and across the animation.\n       * @param {string=} className an optional CSS class that will be applied to the element for the duration of the animation. If\n       *    this value is left as empty then a CSS class of `ng-inline-animate` will be applied to the element.\n       *    (Note that if no animation is detected then this value will not be applied to the element.)\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      animate: function(element, from, to, className, options) {\n        options = prepareAnimateOptions(options);\n        options.from = options.from ? extend(options.from, from) : from;\n        options.to   = options.to   ? extend(options.to, to)     : to;\n\n        className = className || 'ng-inline-animate';\n        options.tempClasses = mergeClasses(options.tempClasses, className);\n        return $$animateQueue.push(element, 'animate', options);\n      }\n    };\n  }];\n}];\n\nvar $$AnimateAsyncRunFactoryProvider = /** @this */ function() {\n  this.$get = ['$$rAF', function($$rAF) {\n    var waitQueue = [];\n\n    function waitForTick(fn) {\n      waitQueue.push(fn);\n      if (waitQueue.length > 1) return;\n      $$rAF(function() {\n        for (var i = 0; i < waitQueue.length; i++) {\n          waitQueue[i]();\n        }\n        waitQueue = [];\n      });\n    }\n\n    return function() {\n      var passed = false;\n      waitForTick(function() {\n        passed = true;\n      });\n      return function(callback) {\n        if (passed) {\n          callback();\n        } else {\n          waitForTick(callback);\n        }\n      };\n    };\n  }];\n};\n\nvar $$AnimateRunnerFactoryProvider = /** @this */ function() {\n  this.$get = ['$q', '$sniffer', '$$animateAsyncRun', '$$isDocumentHidden', '$timeout',\n       function($q,   $sniffer,   $$animateAsyncRun,   $$isDocumentHidden,   $timeout) {\n\n    var INITIAL_STATE = 0;\n    var DONE_PENDING_STATE = 1;\n    var DONE_COMPLETE_STATE = 2;\n\n    AnimateRunner.chain = function(chain, callback) {\n      var index = 0;\n\n      next();\n      function next() {\n        if (index === chain.length) {\n          callback(true);\n          return;\n        }\n\n        chain[index](function(response) {\n          if (response === false) {\n            callback(false);\n            return;\n          }\n          index++;\n          next();\n        });\n      }\n    };\n\n    AnimateRunner.all = function(runners, callback) {\n      var count = 0;\n      var status = true;\n      forEach(runners, function(runner) {\n        runner.done(onProgress);\n      });\n\n      function onProgress(response) {\n        status = status && response;\n        if (++count === runners.length) {\n          callback(status);\n        }\n      }\n    };\n\n    function AnimateRunner(host) {\n      this.setHost(host);\n\n      var rafTick = $$animateAsyncRun();\n      var timeoutTick = function(fn) {\n        $timeout(fn, 0, false);\n      };\n\n      this._doneCallbacks = [];\n      this._tick = function(fn) {\n        if ($$isDocumentHidden()) {\n          timeoutTick(fn);\n        } else {\n          rafTick(fn);\n        }\n      };\n      this._state = 0;\n    }\n\n    AnimateRunner.prototype = {\n      setHost: function(host) {\n        this.host = host || {};\n      },\n\n      done: function(fn) {\n        if (this._state === DONE_COMPLETE_STATE) {\n          fn();\n        } else {\n          this._doneCallbacks.push(fn);\n        }\n      },\n\n      progress: noop,\n\n      getPromise: function() {\n        if (!this.promise) {\n          var self = this;\n          this.promise = $q(function(resolve, reject) {\n            self.done(function(status) {\n              if (status === false) {\n                reject();\n              } else {\n                resolve();\n              }\n            });\n          });\n        }\n        return this.promise;\n      },\n\n      then: function(resolveHandler, rejectHandler) {\n        return this.getPromise().then(resolveHandler, rejectHandler);\n      },\n\n      'catch': function(handler) {\n        return this.getPromise()['catch'](handler);\n      },\n\n      'finally': function(handler) {\n        return this.getPromise()['finally'](handler);\n      },\n\n      pause: function() {\n        if (this.host.pause) {\n          this.host.pause();\n        }\n      },\n\n      resume: function() {\n        if (this.host.resume) {\n          this.host.resume();\n        }\n      },\n\n      end: function() {\n        if (this.host.end) {\n          this.host.end();\n        }\n        this._resolve(true);\n      },\n\n      cancel: function() {\n        if (this.host.cancel) {\n          this.host.cancel();\n        }\n        this._resolve(false);\n      },\n\n      complete: function(response) {\n        var self = this;\n        if (self._state === INITIAL_STATE) {\n          self._state = DONE_PENDING_STATE;\n          self._tick(function() {\n            self._resolve(response);\n          });\n        }\n      },\n\n      _resolve: function(response) {\n        if (this._state !== DONE_COMPLETE_STATE) {\n          forEach(this._doneCallbacks, function(fn) {\n            fn(response);\n          });\n          this._doneCallbacks.length = 0;\n          this._state = DONE_COMPLETE_STATE;\n        }\n      }\n    };\n\n    return AnimateRunner;\n  }];\n};\n\n/* exported $CoreAnimateCssProvider */\n\n/**\n * @ngdoc service\n * @name $animateCss\n * @kind object\n * @this\n *\n * @description\n * This is the core version of `$animateCss`. By default, only when the `ngAnimate` is included,\n * then the `$animateCss` service will actually perform animations.\n *\n * Click here {@link ngAnimate.$animateCss to read the documentation for $animateCss}.\n */\nvar $CoreAnimateCssProvider = function() {\n  this.$get = ['$$rAF', '$q', '$$AnimateRunner', function($$rAF, $q, $$AnimateRunner) {\n\n    return function(element, initialOptions) {\n      // all of the animation functions should create\n      // a copy of the options data, however, if a\n      // parent service has already created a copy then\n      // we should stick to using that\n      var options = initialOptions || {};\n      if (!options.$$prepared) {\n        options = copy(options);\n      }\n\n      // there is no point in applying the styles since\n      // there is no animation that goes on at all in\n      // this version of $animateCss.\n      if (options.cleanupStyles) {\n        options.from = options.to = null;\n      }\n\n      if (options.from) {\n        element.css(options.from);\n        options.from = null;\n      }\n\n      var closed, runner = new $$AnimateRunner();\n      return {\n        start: run,\n        end: run\n      };\n\n      function run() {\n        $$rAF(function() {\n          applyAnimationContents();\n          if (!closed) {\n            runner.complete();\n          }\n          closed = true;\n        });\n        return runner;\n      }\n\n      function applyAnimationContents() {\n        if (options.addClass) {\n          element.addClass(options.addClass);\n          options.addClass = null;\n        }\n        if (options.removeClass) {\n          element.removeClass(options.removeClass);\n          options.removeClass = null;\n        }\n        if (options.to) {\n          element.css(options.to);\n          options.to = null;\n        }\n      }\n    };\n  }];\n};\n\n/* global stripHash: true */\n\n/**\n * ! This is a private undocumented service !\n *\n * @name $browser\n * @requires $log\n * @description\n * This object has two goals:\n *\n * - hide all the global state in the browser caused by the window object\n * - abstract away all the browser specific features and inconsistencies\n *\n * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser`\n * service, which can be used for convenient testing of the application without the interaction with\n * the real browser apis.\n */\n/**\n * @param {object} window The global window object.\n * @param {object} document jQuery wrapped document.\n * @param {object} $log window.console or an object with the same interface.\n * @param {object} $sniffer $sniffer service\n */\nfunction Browser(window, document, $log, $sniffer) {\n  var self = this,\n      location = window.location,\n      history = window.history,\n      setTimeout = window.setTimeout,\n      clearTimeout = window.clearTimeout,\n      pendingDeferIds = {};\n\n  self.isMock = false;\n\n  var outstandingRequestCount = 0;\n  var outstandingRequestCallbacks = [];\n\n  // TODO(vojta): remove this temporary api\n  self.$$completeOutstandingRequest = completeOutstandingRequest;\n  self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; };\n\n  /**\n   * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks`\n   * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed.\n   */\n  function completeOutstandingRequest(fn) {\n    try {\n      fn.apply(null, sliceArgs(arguments, 1));\n    } finally {\n      outstandingRequestCount--;\n      if (outstandingRequestCount === 0) {\n        while (outstandingRequestCallbacks.length) {\n          try {\n            outstandingRequestCallbacks.pop()();\n          } catch (e) {\n            $log.error(e);\n          }\n        }\n      }\n    }\n  }\n\n  function getHash(url) {\n    var index = url.indexOf('#');\n    return index === -1 ? '' : url.substr(index);\n  }\n\n  /**\n   * @private\n   * Note: this method is used only by scenario runner\n   * TODO(vojta): prefix this method with $$ ?\n   * @param {function()} callback Function that will be called when no outstanding request\n   */\n  self.notifyWhenNoOutstandingRequests = function(callback) {\n    if (outstandingRequestCount === 0) {\n      callback();\n    } else {\n      outstandingRequestCallbacks.push(callback);\n    }\n  };\n\n  //////////////////////////////////////////////////////////////\n  // URL API\n  //////////////////////////////////////////////////////////////\n\n  var cachedState, lastHistoryState,\n      lastBrowserUrl = location.href,\n      baseElement = document.find('base'),\n      pendingLocation = null,\n      getCurrentState = !$sniffer.history ? noop : function getCurrentState() {\n        try {\n          return history.state;\n        } catch (e) {\n          // MSIE can reportedly throw when there is no state (UNCONFIRMED).\n        }\n      };\n\n  cacheState();\n\n  /**\n   * @name $browser#url\n   *\n   * @description\n   * GETTER:\n   * Without any argument, this method just returns current value of location.href.\n   *\n   * SETTER:\n   * With at least one argument, this method sets url to new value.\n   * If html5 history api supported, pushState/replaceState is used, otherwise\n   * location.href/location.replace is used.\n   * Returns its own instance to allow chaining\n   *\n   * NOTE: this api is intended for use only by the $location service. Please use the\n   * {@link ng.$location $location service} to change url.\n   *\n   * @param {string} url New url (when used as setter)\n   * @param {boolean=} replace Should new url replace current history record?\n   * @param {object=} state object to use with pushState/replaceState\n   */\n  self.url = function(url, replace, state) {\n    // In modern browsers `history.state` is `null` by default; treating it separately\n    // from `undefined` would cause `$browser.url('/foo')` to change `history.state`\n    // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.\n    if (isUndefined(state)) {\n      state = null;\n    }\n\n    // Android Browser BFCache causes location, history reference to become stale.\n    if (location !== window.location) location = window.location;\n    if (history !== window.history) history = window.history;\n\n    // setter\n    if (url) {\n      var sameState = lastHistoryState === state;\n\n      // Don't change anything if previous and current URLs and states match. This also prevents\n      // IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.\n      // See https://github.com/angular/angular.js/commit/ffb2701\n      if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {\n        return self;\n      }\n      var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);\n      lastBrowserUrl = url;\n      lastHistoryState = state;\n      // Don't use history API if only the hash changed\n      // due to a bug in IE10/IE11 which leads\n      // to not firing a `hashchange` nor `popstate` event\n      // in some cases (see #9143).\n      if ($sniffer.history && (!sameBase || !sameState)) {\n        history[replace ? 'replaceState' : 'pushState'](state, '', url);\n        cacheState();\n      } else {\n        if (!sameBase) {\n          pendingLocation = url;\n        }\n        if (replace) {\n          location.replace(url);\n        } else if (!sameBase) {\n          location.href = url;\n        } else {\n          location.hash = getHash(url);\n        }\n        if (location.href !== url) {\n          pendingLocation = url;\n        }\n      }\n      if (pendingLocation) {\n        pendingLocation = url;\n      }\n      return self;\n    // getter\n    } else {\n      // - pendingLocation is needed as browsers don't allow to read out\n      //   the new location.href if a reload happened or if there is a bug like in iOS 9 (see\n      //   https://openradar.appspot.com/22186109).\n      // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172\n      return pendingLocation || location.href.replace(/%27/g,'\\'');\n    }\n  };\n\n  /**\n   * @name $browser#state\n   *\n   * @description\n   * This method is a getter.\n   *\n   * Return history.state or null if history.state is undefined.\n   *\n   * @returns {object} state\n   */\n  self.state = function() {\n    return cachedState;\n  };\n\n  var urlChangeListeners = [],\n      urlChangeInit = false;\n\n  function cacheStateAndFireUrlChange() {\n    pendingLocation = null;\n    fireStateOrUrlChange();\n  }\n\n  // This variable should be used *only* inside the cacheState function.\n  var lastCachedState = null;\n  function cacheState() {\n    // This should be the only place in $browser where `history.state` is read.\n    cachedState = getCurrentState();\n    cachedState = isUndefined(cachedState) ? null : cachedState;\n\n    // Prevent callbacks fo fire twice if both hashchange & popstate were fired.\n    if (equals(cachedState, lastCachedState)) {\n      cachedState = lastCachedState;\n    }\n\n    lastCachedState = cachedState;\n    lastHistoryState = cachedState;\n  }\n\n  function fireStateOrUrlChange() {\n    var prevLastHistoryState = lastHistoryState;\n    cacheState();\n\n    if (lastBrowserUrl === self.url() && prevLastHistoryState === cachedState) {\n      return;\n    }\n\n    lastBrowserUrl = self.url();\n    lastHistoryState = cachedState;\n    forEach(urlChangeListeners, function(listener) {\n      listener(self.url(), cachedState);\n    });\n  }\n\n  /**\n   * @name $browser#onUrlChange\n   *\n   * @description\n   * Register callback function that will be called, when url changes.\n   *\n   * It's only called when the url is changed from outside of angular:\n   * - user types different url into address bar\n   * - user clicks on history (forward/back) button\n   * - user clicks on a link\n   *\n   * It's not called when url is changed by $browser.url() method\n   *\n   * The listener gets called with new url as parameter.\n   *\n   * NOTE: this api is intended for use only by the $location service. Please use the\n   * {@link ng.$location $location service} to monitor url changes in angular apps.\n   *\n   * @param {function(string)} listener Listener function to be called when url changes.\n   * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous.\n   */\n  self.onUrlChange = function(callback) {\n    // TODO(vojta): refactor to use node's syntax for events\n    if (!urlChangeInit) {\n      // We listen on both (hashchange/popstate) when available, as some browsers don't\n      // fire popstate when user changes the address bar and don't fire hashchange when url\n      // changed by push/replaceState\n\n      // html5 history api - popstate event\n      if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);\n      // hashchange event\n      jqLite(window).on('hashchange', cacheStateAndFireUrlChange);\n\n      urlChangeInit = true;\n    }\n\n    urlChangeListeners.push(callback);\n    return callback;\n  };\n\n  /**\n   * @private\n   * Remove popstate and hashchange handler from window.\n   *\n   * NOTE: this api is intended for use only by $rootScope.\n   */\n  self.$$applicationDestroyed = function() {\n    jqLite(window).off('hashchange popstate', cacheStateAndFireUrlChange);\n  };\n\n  /**\n   * Checks whether the url has changed outside of Angular.\n   * Needs to be exported to be able to check for changes that have been done in sync,\n   * as hashchange/popstate events fire in async.\n   */\n  self.$$checkUrlChange = fireStateOrUrlChange;\n\n  //////////////////////////////////////////////////////////////\n  // Misc API\n  //////////////////////////////////////////////////////////////\n\n  /**\n   * @name $browser#baseHref\n   *\n   * @description\n   * Returns current <base href>\n   * (always relative - without domain)\n   *\n   * @returns {string} The current base href\n   */\n  self.baseHref = function() {\n    var href = baseElement.attr('href');\n    return href ? href.replace(/^(https?:)?\\/\\/[^/]*/, '') : '';\n  };\n\n  /**\n   * @name $browser#defer\n   * @param {function()} fn A function, who's execution should be deferred.\n   * @param {number=} [delay=0] of milliseconds to defer the function execution.\n   * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`.\n   *\n   * @description\n   * Executes a fn asynchronously via `setTimeout(fn, delay)`.\n   *\n   * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using\n   * `setTimeout` in tests, the fns are queued in an array, which can be programmatically flushed\n   * via `$browser.defer.flush()`.\n   *\n   */\n  self.defer = function(fn, delay) {\n    var timeoutId;\n    outstandingRequestCount++;\n    timeoutId = setTimeout(function() {\n      delete pendingDeferIds[timeoutId];\n      completeOutstandingRequest(fn);\n    }, delay || 0);\n    pendingDeferIds[timeoutId] = true;\n    return timeoutId;\n  };\n\n\n  /**\n   * @name $browser#defer.cancel\n   *\n   * @description\n   * Cancels a deferred task identified with `deferId`.\n   *\n   * @param {*} deferId Token returned by the `$browser.defer` function.\n   * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully\n   *                    canceled.\n   */\n  self.defer.cancel = function(deferId) {\n    if (pendingDeferIds[deferId]) {\n      delete pendingDeferIds[deferId];\n      clearTimeout(deferId);\n      completeOutstandingRequest(noop);\n      return true;\n    }\n    return false;\n  };\n\n}\n\n/** @this */\nfunction $BrowserProvider() {\n  this.$get = ['$window', '$log', '$sniffer', '$document',\n      function($window, $log, $sniffer, $document) {\n        return new Browser($window, $document, $log, $sniffer);\n      }];\n}\n\n/**\n * @ngdoc service\n * @name $cacheFactory\n * @this\n *\n * @description\n * Factory that constructs {@link $cacheFactory.Cache Cache} objects and gives access to\n * them.\n *\n * ```js\n *\n *  var cache = $cacheFactory('cacheId');\n *  expect($cacheFactory.get('cacheId')).toBe(cache);\n *  expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();\n *\n *  cache.put(\"key\", \"value\");\n *  cache.put(\"another key\", \"another value\");\n *\n *  // We've specified no options on creation\n *  expect(cache.info()).toEqual({id: 'cacheId', size: 2});\n *\n * ```\n *\n *\n * @param {string} cacheId Name or id of the newly created cache.\n * @param {object=} options Options object that specifies the cache behavior. Properties:\n *\n *   - `{number=}` `capacity` — turns the cache into LRU cache.\n *\n * @returns {object} Newly created cache object with the following set of methods:\n *\n * - `{object}` `info()` — Returns id, size, and options of cache.\n * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns\n *   it.\n * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.\n * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.\n * - `{void}` `removeAll()` — Removes all cached values.\n * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.\n *\n * @example\n   <example module=\"cacheExampleApp\" name=\"cache-factory\">\n     <file name=\"index.html\">\n       <div ng-controller=\"CacheController\">\n         <input ng-model=\"newCacheKey\" placeholder=\"Key\">\n         <input ng-model=\"newCacheValue\" placeholder=\"Value\">\n         <button ng-click=\"put(newCacheKey, newCacheValue)\">Cache</button>\n\n         <p ng-if=\"keys.length\">Cached Values</p>\n         <div ng-repeat=\"key in keys\">\n           <span ng-bind=\"key\"></span>\n           <span>: </span>\n           <b ng-bind=\"cache.get(key)\"></b>\n         </div>\n\n         <p>Cache Info</p>\n         <div ng-repeat=\"(key, value) in cache.info()\">\n           <span ng-bind=\"key\"></span>\n           <span>: </span>\n           <b ng-bind=\"value\"></b>\n         </div>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('cacheExampleApp', []).\n         controller('CacheController', ['$scope', '$cacheFactory', function($scope, $cacheFactory) {\n           $scope.keys = [];\n           $scope.cache = $cacheFactory('cacheId');\n           $scope.put = function(key, value) {\n             if (angular.isUndefined($scope.cache.get(key))) {\n               $scope.keys.push(key);\n             }\n             $scope.cache.put(key, angular.isUndefined(value) ? null : value);\n           };\n         }]);\n     </file>\n     <file name=\"style.css\">\n       p {\n         margin: 10px 0 3px;\n       }\n     </file>\n   </example>\n */\nfunction $CacheFactoryProvider() {\n\n  this.$get = function() {\n    var caches = {};\n\n    function cacheFactory(cacheId, options) {\n      if (cacheId in caches) {\n        throw minErr('$cacheFactory')('iid', 'CacheId \\'{0}\\' is already taken!', cacheId);\n      }\n\n      var size = 0,\n          stats = extend({}, options, {id: cacheId}),\n          data = createMap(),\n          capacity = (options && options.capacity) || Number.MAX_VALUE,\n          lruHash = createMap(),\n          freshEnd = null,\n          staleEnd = null;\n\n      /**\n       * @ngdoc type\n       * @name $cacheFactory.Cache\n       *\n       * @description\n       * A cache object used to store and retrieve data, primarily used by\n       * {@link $http $http} and the {@link ng.directive:script script} directive to cache\n       * templates and other data.\n       *\n       * ```js\n       *  angular.module('superCache')\n       *    .factory('superCache', ['$cacheFactory', function($cacheFactory) {\n       *      return $cacheFactory('super-cache');\n       *    }]);\n       * ```\n       *\n       * Example test:\n       *\n       * ```js\n       *  it('should behave like a cache', inject(function(superCache) {\n       *    superCache.put('key', 'value');\n       *    superCache.put('another key', 'another value');\n       *\n       *    expect(superCache.info()).toEqual({\n       *      id: 'super-cache',\n       *      size: 2\n       *    });\n       *\n       *    superCache.remove('another key');\n       *    expect(superCache.get('another key')).toBeUndefined();\n       *\n       *    superCache.removeAll();\n       *    expect(superCache.info()).toEqual({\n       *      id: 'super-cache',\n       *      size: 0\n       *    });\n       *  }));\n       * ```\n       */\n      return (caches[cacheId] = {\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#put\n         * @kind function\n         *\n         * @description\n         * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be\n         * retrieved later, and incrementing the size of the cache if the key was not already\n         * present in the cache. If behaving like an LRU cache, it will also remove stale\n         * entries from the set.\n         *\n         * It will not insert undefined values into the cache.\n         *\n         * @param {string} key the key under which the cached data is stored.\n         * @param {*} value the value to store alongside the key. If it is undefined, the key\n         *    will not be stored.\n         * @returns {*} the value stored.\n         */\n        put: function(key, value) {\n          if (isUndefined(value)) return;\n          if (capacity < Number.MAX_VALUE) {\n            var lruEntry = lruHash[key] || (lruHash[key] = {key: key});\n\n            refresh(lruEntry);\n          }\n\n          if (!(key in data)) size++;\n          data[key] = value;\n\n          if (size > capacity) {\n            this.remove(staleEnd.key);\n          }\n\n          return value;\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#get\n         * @kind function\n         *\n         * @description\n         * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object.\n         *\n         * @param {string} key the key of the data to be retrieved\n         * @returns {*} the value stored.\n         */\n        get: function(key) {\n          if (capacity < Number.MAX_VALUE) {\n            var lruEntry = lruHash[key];\n\n            if (!lruEntry) return;\n\n            refresh(lruEntry);\n          }\n\n          return data[key];\n        },\n\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#remove\n         * @kind function\n         *\n         * @description\n         * Removes an entry from the {@link $cacheFactory.Cache Cache} object.\n         *\n         * @param {string} key the key of the entry to be removed\n         */\n        remove: function(key) {\n          if (capacity < Number.MAX_VALUE) {\n            var lruEntry = lruHash[key];\n\n            if (!lruEntry) return;\n\n            if (lruEntry === freshEnd) freshEnd = lruEntry.p;\n            if (lruEntry === staleEnd) staleEnd = lruEntry.n;\n            link(lruEntry.n,lruEntry.p);\n\n            delete lruHash[key];\n          }\n\n          if (!(key in data)) return;\n\n          delete data[key];\n          size--;\n        },\n\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#removeAll\n         * @kind function\n         *\n         * @description\n         * Clears the cache object of any entries.\n         */\n        removeAll: function() {\n          data = createMap();\n          size = 0;\n          lruHash = createMap();\n          freshEnd = staleEnd = null;\n        },\n\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#destroy\n         * @kind function\n         *\n         * @description\n         * Destroys the {@link $cacheFactory.Cache Cache} object entirely,\n         * removing it from the {@link $cacheFactory $cacheFactory} set.\n         */\n        destroy: function() {\n          data = null;\n          stats = null;\n          lruHash = null;\n          delete caches[cacheId];\n        },\n\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#info\n         * @kind function\n         *\n         * @description\n         * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}.\n         *\n         * @returns {object} an object with the following properties:\n         *   <ul>\n         *     <li>**id**: the id of the cache instance</li>\n         *     <li>**size**: the number of entries kept in the cache instance</li>\n         *     <li>**...**: any additional properties from the options object when creating the\n         *       cache.</li>\n         *   </ul>\n         */\n        info: function() {\n          return extend({}, stats, {size: size});\n        }\n      });\n\n\n      /**\n       * makes the `entry` the freshEnd of the LRU linked list\n       */\n      function refresh(entry) {\n        if (entry !== freshEnd) {\n          if (!staleEnd) {\n            staleEnd = entry;\n          } else if (staleEnd === entry) {\n            staleEnd = entry.n;\n          }\n\n          link(entry.n, entry.p);\n          link(entry, freshEnd);\n          freshEnd = entry;\n          freshEnd.n = null;\n        }\n      }\n\n\n      /**\n       * bidirectionally links two entries of the LRU linked list\n       */\n      function link(nextEntry, prevEntry) {\n        if (nextEntry !== prevEntry) {\n          if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify\n          if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify\n        }\n      }\n    }\n\n\n  /**\n   * @ngdoc method\n   * @name $cacheFactory#info\n   *\n   * @description\n   * Get information about all the caches that have been created\n   *\n   * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`\n   */\n    cacheFactory.info = function() {\n      var info = {};\n      forEach(caches, function(cache, cacheId) {\n        info[cacheId] = cache.info();\n      });\n      return info;\n    };\n\n\n  /**\n   * @ngdoc method\n   * @name $cacheFactory#get\n   *\n   * @description\n   * Get access to a cache object by the `cacheId` used when it was created.\n   *\n   * @param {string} cacheId Name or id of a cache to access.\n   * @returns {object} Cache object identified by the cacheId or undefined if no such cache.\n   */\n    cacheFactory.get = function(cacheId) {\n      return caches[cacheId];\n    };\n\n\n    return cacheFactory;\n  };\n}\n\n/**\n * @ngdoc service\n * @name $templateCache\n * @this\n *\n * @description\n * The first time a template is used, it is loaded in the template cache for quick retrieval. You\n * can load templates directly into the cache in a `script` tag, or by consuming the\n * `$templateCache` service directly.\n *\n * Adding via the `script` tag:\n *\n * ```html\n *   <script type=\"text/ng-template\" id=\"templateId.html\">\n *     <p>This is the content of the template</p>\n *   </script>\n * ```\n *\n * **Note:** the `script` tag containing the template does not need to be included in the `head` of\n * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,\n * element with ng-app attribute), otherwise the template will be ignored.\n *\n * Adding via the `$templateCache` service:\n *\n * ```js\n * var myApp = angular.module('myApp', []);\n * myApp.run(function($templateCache) {\n *   $templateCache.put('templateId.html', 'This is the content of the template');\n * });\n * ```\n *\n * To retrieve the template later, simply use it in your component:\n * ```js\n * myApp.component('myComponent', {\n *    templateUrl: 'templateId.html'\n * });\n * ```\n *\n * or get it via the `$templateCache` service:\n * ```js\n * $templateCache.get('templateId.html')\n * ```\n *\n * See {@link ng.$cacheFactory $cacheFactory}.\n *\n */\nfunction $TemplateCacheProvider() {\n  this.$get = ['$cacheFactory', function($cacheFactory) {\n    return $cacheFactory('templates');\n  }];\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *     Any commits to this file should be reviewed with security in mind.  *\n *   Changes to this file can potentially create security vulnerabilities. *\n *          An approval from 2 Core members with history of modifying      *\n *                         this file is required.                          *\n *                                                                         *\n *  Does the change somehow allow for arbitrary javascript to be executed? *\n *    Or allows for someone to change the prototype of built-in objects?   *\n *     Or gives undesired access to variables like document or window?    *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE!\n *\n * DOM-related variables:\n *\n * - \"node\" - DOM Node\n * - \"element\" - DOM Element or Node\n * - \"$node\" or \"$element\" - jqLite-wrapped node or element\n *\n *\n * Compiler related stuff:\n *\n * - \"linkFn\" - linking fn of a single directive\n * - \"nodeLinkFn\" - function that aggregates all linking fns for a particular node\n * - \"childLinkFn\" -  function that aggregates all linking fns for child nodes of a particular node\n * - \"compositeLinkFn\" - function that aggregates all linking fns for a compilation root (nodeList)\n */\n\n\n/**\n * @ngdoc service\n * @name $compile\n * @kind function\n *\n * @description\n * Compiles an HTML string or DOM into a template and produces a template function, which\n * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together.\n *\n * The compilation is a process of walking the DOM tree and matching DOM elements to\n * {@link ng.$compileProvider#directive directives}.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** This document is an in-depth reference of all directive options.\n * For a gentle introduction to directives with examples of common use cases,\n * see the {@link guide/directive directive guide}.\n * </div>\n *\n * ## Comprehensive Directive API\n *\n * There are many different options for a directive.\n *\n * The difference resides in the return value of the factory function.\n * You can either return a {@link $compile#directive-definition-object Directive Definition Object (see below)}\n * that defines the directive properties, or just the `postLink` function (all other properties will have\n * the default values).\n *\n * <div class=\"alert alert-success\">\n * **Best Practice:** It's recommended to use the \"directive definition object\" form.\n * </div>\n *\n * Here's an example directive declared with a Directive Definition Object:\n *\n * ```js\n *   var myModule = angular.module(...);\n *\n *   myModule.directive('directiveName', function factory(injectables) {\n *     var directiveDefinitionObject = {\n *       {@link $compile#-priority- priority}: 0,\n *       {@link $compile#-template- template}: '<div></div>', // or // function(tElement, tAttrs) { ... },\n *       // or\n *       // {@link $compile#-templateurl- templateUrl}: 'directive.html', // or // function(tElement, tAttrs) { ... },\n *       {@link $compile#-transclude- transclude}: false,\n *       {@link $compile#-restrict- restrict}: 'A',\n *       {@link $compile#-templatenamespace- templateNamespace}: 'html',\n *       {@link $compile#-scope- scope}: false,\n *       {@link $compile#-controller- controller}: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },\n *       {@link $compile#-controlleras- controllerAs}: 'stringIdentifier',\n *       {@link $compile#-bindtocontroller- bindToController}: false,\n *       {@link $compile#-require- require}: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],\n *       {@link $compile#-multielement- multiElement}: false,\n *       {@link $compile#-compile- compile}: function compile(tElement, tAttrs, transclude) {\n *         return {\n *            {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },\n *            {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }\n *         }\n *         // or\n *         // return function postLink( ... ) { ... }\n *       },\n *       // or\n *       // {@link $compile#-link- link}: {\n *       //  {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },\n *       //  {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }\n *       // }\n *       // or\n *       // {@link $compile#-link- link}: function postLink( ... ) { ... }\n *     };\n *     return directiveDefinitionObject;\n *   });\n * ```\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Any unspecified options will use the default value. You can see the default values below.\n * </div>\n *\n * Therefore the above can be simplified as:\n *\n * ```js\n *   var myModule = angular.module(...);\n *\n *   myModule.directive('directiveName', function factory(injectables) {\n *     var directiveDefinitionObject = {\n *       link: function postLink(scope, iElement, iAttrs) { ... }\n *     };\n *     return directiveDefinitionObject;\n *     // or\n *     // return function postLink(scope, iElement, iAttrs) { ... }\n *   });\n * ```\n *\n * ### Life-cycle hooks\n * Directive controllers can provide the following methods that are called by Angular at points in the life-cycle of the\n * directive:\n * * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and\n *   had their bindings initialized (and before the pre &amp; post linking functions for the directives on\n *   this element). This is a good place to put initialization code for your controller.\n * * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The\n *   `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an\n *   object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a\n *   component such as cloning the bound value to prevent accidental mutation of the outer value. Note that this will\n *   also be called when your bindings are initialized.\n * * `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on\n *   changes. Any actions that you wish to take in response to the changes that you detect must be\n *   invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook\n *   could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not\n *   be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;\n *   if detecting changes, you must store the previous value(s) for comparison to the current values.\n * * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing\n *   external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in\n *   the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent\n *   components will have their `$onDestroy()` hook called before child components.\n * * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link\n *   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.\n *   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since\n *   they are waiting for their template to load asynchronously and their own compilation and linking has been\n *   suspended until that occurs.\n *\n * #### Comparison with Angular 2 life-cycle hooks\n * Angular 2 also uses life-cycle hooks for its components. While the Angular 1 life-cycle hooks are similar there are\n * some differences that you should be aware of, especially when it comes to moving your code from Angular 1 to Angular 2:\n *\n * * Angular 1 hooks are prefixed with `$`, such as `$onInit`. Angular 2 hooks are prefixed with `ng`, such as `ngOnInit`.\n * * Angular 1 hooks can be defined on the controller prototype or added to the controller inside its constructor.\n *   In Angular 2 you can only define hooks on the prototype of the Component class.\n * * Due to the differences in change-detection, you may get many more calls to `$doCheck` in Angular 1 than you would to\n *   `ngDoCheck` in Angular 2\n * * Changes to the model inside `$doCheck` will trigger new turns of the digest loop, which will cause the changes to be\n *   propagated throughout the application.\n *   Angular 2 does not allow the `ngDoCheck` hook to trigger a change outside of the component. It will either throw an\n *   error or do nothing depending upon the state of `enableProdMode()`.\n *\n * #### Life-cycle hook examples\n *\n * This example shows how you can check for mutations to a Date object even though the identity of the object\n * has not changed.\n *\n * <example name=\"doCheckDateExample\" module=\"do-check-module\">\n *   <file name=\"app.js\">\n *     angular.module('do-check-module', [])\n *       .component('app', {\n *         template:\n *           'Month: <input ng-model=\"$ctrl.month\" ng-change=\"$ctrl.updateDate()\">' +\n *           'Date: {{ $ctrl.date }}' +\n *           '<test date=\"$ctrl.date\"></test>',\n *         controller: function() {\n *           this.date = new Date();\n *           this.month = this.date.getMonth();\n *           this.updateDate = function() {\n *             this.date.setMonth(this.month);\n *           };\n *         }\n *       })\n *       .component('test', {\n *         bindings: { date: '<' },\n *         template:\n *           '<pre>{{ $ctrl.log | json }}</pre>',\n *         controller: function() {\n *           var previousValue;\n *           this.log = [];\n *           this.$doCheck = function() {\n *             var currentValue = this.date && this.date.valueOf();\n *             if (previousValue !== currentValue) {\n *               this.log.push('doCheck: date mutated: ' + this.date);\n *               previousValue = currentValue;\n *             }\n *           };\n *         }\n *       });\n *   </file>\n *   <file name=\"index.html\">\n *     <app></app>\n *   </file>\n * </example>\n *\n * This example show how you might use `$doCheck` to trigger changes in your component's inputs even if the\n * actual identity of the component doesn't change. (Be aware that cloning and deep equality checks on large\n * arrays or objects can have a negative impact on your application performance)\n *\n * <example name=\"doCheckArrayExample\" module=\"do-check-module\">\n *   <file name=\"index.html\">\n *     <div ng-init=\"items = []\">\n *       <button ng-click=\"items.push(items.length)\">Add Item</button>\n *       <button ng-click=\"items = []\">Reset Items</button>\n *       <pre>{{ items }}</pre>\n *       <test items=\"items\"></test>\n *     </div>\n *   </file>\n *   <file name=\"app.js\">\n *      angular.module('do-check-module', [])\n *        .component('test', {\n *          bindings: { items: '<' },\n *          template:\n *            '<pre>{{ $ctrl.log | json }}</pre>',\n *          controller: function() {\n *            this.log = [];\n *\n *            this.$doCheck = function() {\n *              if (this.items_ref !== this.items) {\n *                this.log.push('doCheck: items changed');\n *                this.items_ref = this.items;\n *              }\n *              if (!angular.equals(this.items_clone, this.items)) {\n *                this.log.push('doCheck: items mutated');\n *                this.items_clone = angular.copy(this.items);\n *              }\n *            };\n *          }\n *        });\n *   </file>\n * </example>\n *\n *\n * ### Directive Definition Object\n *\n * The directive definition object provides instructions to the {@link ng.$compile\n * compiler}. The attributes are:\n *\n * #### `multiElement`\n * When this property is set to true (default is `false`), the HTML compiler will collect DOM nodes between\n * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them\n * together as the directive elements. It is recommended that this feature be used on directives\n * which are not strictly behavioral (such as {@link ngClick}), and which\n * do not manipulate or replace child nodes (such as {@link ngInclude}).\n *\n * #### `priority`\n * When there are multiple directives defined on a single DOM element, sometimes it\n * is necessary to specify the order in which the directives are applied. The `priority` is used\n * to sort the directives before their `compile` functions get called. Priority is defined as a\n * number. Directives with greater numerical `priority` are compiled first. Pre-link functions\n * are also run in priority order, but post-link functions are run in reverse order. The order\n * of directives with the same priority is undefined. The default priority is `0`.\n *\n * #### `terminal`\n * If set to true then the current `priority` will be the last set of directives\n * which will execute (any directives at the current priority will still execute\n * as the order of execution on same `priority` is undefined). Note that expressions\n * and other directives used in the directive's template will also be excluded from execution.\n *\n * #### `scope`\n * The scope property can be `false`, `true`, or an object:\n *\n * * **`false` (default):** No scope will be created for the directive. The directive will use its\n * parent's scope.\n *\n * * **`true`:** A new child scope that prototypically inherits from its parent will be created for\n * the directive's element. If multiple directives on the same element request a new scope,\n * only one new scope is created.\n *\n * * **`{...}` (an object hash):** A new \"isolate\" scope is created for the directive's template.\n * The 'isolate' scope differs from normal scope in that it does not prototypically\n * inherit from its parent scope. This is useful when creating reusable components, which should not\n * accidentally read or modify data in the parent scope. Note that an isolate scope\n * directive without a `template` or `templateUrl` will not apply the isolate scope\n * to its children elements.\n *\n * The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the\n * directive's element. These local properties are useful for aliasing values for templates. The keys in\n * the object hash map to the name of the property on the isolate scope; the values define how the property\n * is bound to the parent scope, via matching attributes on the directive's element:\n *\n * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is\n *   always a string since DOM attributes are strings. If no `attr` name is specified then the\n *   attribute name is assumed to be the same as the local name. Given `<my-component\n *   my-attr=\"hello {{name}}\">` and the isolate scope definition `scope: { localName:'@myAttr' }`,\n *   the directive's scope property `localName` will reflect the interpolated value of `hello\n *   {{name}}`. As the `name` attribute changes so will the `localName` property on the directive's\n *   scope. The `name` is read from the parent scope (not the directive's scope).\n *\n * * `=` or `=attr` - set up a bidirectional binding between a local scope property and an expression\n *   passed via the attribute `attr`. The expression is evaluated in the context of the parent scope.\n *   If no `attr` name is specified then the attribute name is assumed to be the same as the local\n *   name. Given `<my-component my-attr=\"parentModel\">` and the isolate scope definition `scope: {\n *   localModel: '=myAttr' }`, the property `localModel` on the directive's scope will reflect the\n *   value of `parentModel` on the parent scope. Changes to `parentModel` will be reflected in\n *   `localModel` and vice versa. Optional attributes should be marked as such with a question mark:\n *   `=?` or `=?attr`. If the binding expression is non-assignable, or if the attribute isn't\n *   optional and doesn't exist, an exception ({@link error/$compile/nonassign `$compile:nonassign`})\n *   will be thrown upon discovering changes to the local value, since it will be impossible to sync\n *   them back to the parent scope. By default, the {@link ng.$rootScope.Scope#$watch `$watch`}\n *   method is used for tracking changes, and the equality check is based on object identity.\n *   However, if an object literal or an array literal is passed as the binding expression, the\n *   equality check is done by value (using the {@link angular.equals} function). It's also possible\n *   to watch the evaluated value shallowly with {@link ng.$rootScope.Scope#$watchCollection\n *   `$watchCollection`}: use `=*` or `=*attr` (`=*?` or `=*?attr` if the attribute is optional).\n *\n  * * `<` or `<attr` - set up a one-way (one-directional) binding between a local scope property and an\n *   expression passed via the attribute `attr`. The expression is evaluated in the context of the\n *   parent scope. If no `attr` name is specified then the attribute name is assumed to be the same as the\n *   local name. You can also make the binding optional by adding `?`: `<?` or `<?attr`.\n *\n *   For example, given `<my-component my-attr=\"parentModel\">` and directive definition of\n *   `scope: { localModel:'<myAttr' }`, then the isolated scope property `localModel` will reflect the\n *   value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected\n *   in `localModel`, but changes in `localModel` will not reflect in `parentModel`. There are however\n *   two caveats:\n *     1. one-way binding does not copy the value from the parent to the isolate scope, it simply\n *     sets the same value. That means if your bound value is an object, changes to its properties\n *     in the isolated scope will be reflected in the parent scope (because both reference the same object).\n *     2. one-way binding watches changes to the **identity** of the parent value. That means the\n *     {@link ng.$rootScope.Scope#$watch `$watch`} on the parent value only fires if the reference\n *     to the value has changed. In most cases, this should not be of concern, but can be important\n *     to know if you one-way bind to an object, and then replace that object in the isolated scope.\n *     If you now change a property of the object in your parent scope, the change will not be\n *     propagated to the isolated scope, because the identity of the object on the parent scope\n *     has not changed. Instead you must assign a new object.\n *\n *   One-way binding is useful if you do not plan to propagate changes to your isolated scope bindings\n *   back to the parent. However, it does not make this completely impossible.\n *\n * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. If\n *   no `attr` name is specified then the attribute name is assumed to be the same as the local name.\n *   Given `<my-component my-attr=\"count = count + value\">` and the isolate scope definition `scope: {\n *   localFn:'&myAttr' }`, the isolate scope property `localFn` will point to a function wrapper for\n *   the `count = count + value` expression. Often it's desirable to pass data from the isolated scope\n *   via an expression to the parent scope. This can be done by passing a map of local variable names\n *   and values into the expression wrapper fn. For example, if the expression is `increment(amount)`\n *   then we can specify the amount value by calling the `localFn` as `localFn({amount: 22})`.\n *\n * In general it's possible to apply more than one directive to one element, but there might be limitations\n * depending on the type of scope required by the directives. The following points will help explain these limitations.\n * For simplicity only two directives are taken into account, but it is also applicable for several directives:\n *\n * * **no scope** + **no scope** => Two directives which don't require their own scope will use their parent's scope\n * * **child scope** + **no scope** =>  Both directives will share one single child scope\n * * **child scope** + **child scope** =>  Both directives will share one single child scope\n * * **isolated scope** + **no scope** =>  The isolated directive will use it's own created isolated scope. The other directive will use\n * its parent's scope\n * * **isolated scope** + **child scope** =>  **Won't work!** Only one scope can be related to one element. Therefore these directives cannot\n * be applied to the same element.\n * * **isolated scope** + **isolated scope**  =>  **Won't work!** Only one scope can be related to one element. Therefore these directives\n * cannot be applied to the same element.\n *\n *\n * #### `bindToController`\n * This property is used to bind scope properties directly to the controller. It can be either\n * `true` or an object hash with the same format as the `scope` property.\n *\n * When an isolate scope is used for a directive (see above), `bindToController: true` will\n * allow a component to have its properties bound to the controller, rather than to scope.\n *\n * After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller\n * properties. You can access these bindings once they have been initialized by providing a controller method called\n * `$onInit`, which is called after all the controllers on an element have been constructed and had their bindings\n * initialized.\n *\n * <div class=\"alert alert-warning\">\n * **Deprecation warning:** although bindings for non-ES6 class controllers are currently\n * bound to `this` before the controller constructor is called, this use is now deprecated. Please place initialization\n * code that relies upon bindings inside a `$onInit` method on the controller, instead.\n * </div>\n *\n * It is also possible to set `bindToController` to an object hash with the same format as the `scope` property.\n * This will set up the scope bindings to the controller directly. Note that `scope` can still be used\n * to define which kind of scope is created. By default, no scope is created. Use `scope: {}` to create an isolate\n * scope (useful for component directives).\n *\n * If both `bindToController` and `scope` are defined and have object hashes, `bindToController` overrides `scope`.\n *\n *\n * #### `controller`\n * Controller constructor function. The controller is instantiated before the\n * pre-linking phase and can be accessed by other directives (see\n * `require` attribute). This allows the directives to communicate with each other and augment\n * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:\n *\n * * `$scope` - Current scope associated with the element\n * * `$element` - Current element\n * * `$attrs` - Current attributes object for the element\n * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:\n *   `function([scope], cloneLinkingFn, futureParentElement, slotName)`:\n *    * `scope`: (optional) override the scope.\n *    * `cloneLinkingFn`: (optional) argument to create clones of the original transcluded content.\n *    * `futureParentElement` (optional):\n *        * defines the parent to which the `cloneLinkingFn` will add the cloned elements.\n *        * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.\n *        * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)\n *          and when the `cloneLinkingFn` is passed,\n *          as those elements need to created and cloned in a special way when they are defined outside their\n *          usual containers (e.g. like `<svg>`).\n *        * See also the `directive.templateNamespace` property.\n *    * `slotName`: (optional) the name of the slot to transclude. If falsy (e.g. `null`, `undefined` or `''`)\n *      then the default transclusion is provided.\n *    The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns\n *    `true` if the specified slot contains content (i.e. one or more DOM nodes).\n *\n * #### `require`\n * Require another directive and inject its controller as the fourth argument to the linking function. The\n * `require` property can be a string, an array or an object:\n * * a **string** containing the name of the directive to pass to the linking function\n * * an **array** containing the names of directives to pass to the linking function. The argument passed to the\n * linking function will be an array of controllers in the same order as the names in the `require` property\n * * an **object** whose property values are the names of the directives to pass to the linking function. The argument\n * passed to the linking function will also be an object with matching keys, whose values will hold the corresponding\n * controllers.\n *\n * If the `require` property is an object and `bindToController` is truthy, then the required controllers are\n * bound to the controller using the keys of the `require` property. This binding occurs after all the controllers\n * have been constructed but before `$onInit` is called.\n * If the name of the required controller is the same as the local name (the key), the name can be\n * omitted. For example, `{parentDir: '^^'}` is equivalent to `{parentDir: '^^parentDir'}`.\n * See the {@link $compileProvider#component} helper for an example of how this can be used.\n * If no such required directive(s) can be found, or if the directive does not have a controller, then an error is\n * raised (unless no link function is specified and the required controllers are not being bound to the directive\n * controller, in which case error checking is skipped). The name can be prefixed with:\n *\n * * (no prefix) - Locate the required controller on the current element. Throw an error if not found.\n * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.\n * * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found.\n * * `^^` - Locate the required controller by searching the element's parents. Throw an error if not found.\n * * `?^` - Attempt to locate the required controller by searching the element and its parents or pass\n *   `null` to the `link` fn if not found.\n * * `?^^` - Attempt to locate the required controller by searching the element's parents, or pass\n *   `null` to the `link` fn if not found.\n *\n *\n * #### `controllerAs`\n * Identifier name for a reference to the controller in the directive's scope.\n * This allows the controller to be referenced from the directive template. This is especially\n * useful when a directive is used as component, i.e. with an `isolate` scope. It's also possible\n * to use it in a directive without an `isolate` / `new` scope, but you need to be aware that the\n * `controllerAs` reference might overwrite a property that already exists on the parent scope.\n *\n *\n * #### `restrict`\n * String of subset of `EACM` which restricts the directive to a specific directive\n * declaration style. If omitted, the defaults (elements and attributes) are used.\n *\n * * `E` - Element name (default): `<my-directive></my-directive>`\n * * `A` - Attribute (default): `<div my-directive=\"exp\"></div>`\n * * `C` - Class: `<div class=\"my-directive: exp;\"></div>`\n * * `M` - Comment: `<!-- directive: my-directive exp -->`\n *\n *\n * #### `templateNamespace`\n * String representing the document type used by the markup in the template.\n * AngularJS needs this information as those elements need to be created and cloned\n * in a special way when they are defined outside their usual containers like `<svg>` and `<math>`.\n *\n * * `html` - All root nodes in the template are HTML. Root nodes may also be\n *   top-level elements such as `<svg>` or `<math>`.\n * * `svg` - The root nodes in the template are SVG elements (excluding `<math>`).\n * * `math` - The root nodes in the template are MathML elements (excluding `<svg>`).\n *\n * If no `templateNamespace` is specified, then the namespace is considered to be `html`.\n *\n * #### `template`\n * HTML markup that may:\n * * Replace the contents of the directive's element (default).\n * * Replace the directive's element itself (if `replace` is true - DEPRECATED).\n * * Wrap the contents of the directive's element (if `transclude` is true).\n *\n * Value may be:\n *\n * * A string. For example `<div red-on-hover>{{delete_str}}</div>`.\n * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile`\n *   function api below) and returns a string value.\n *\n *\n * #### `templateUrl`\n * This is similar to `template` but the template is loaded from the specified URL, asynchronously.\n *\n * Because template loading is asynchronous the compiler will suspend compilation of directives on that element\n * for later when the template has been resolved.  In the meantime it will continue to compile and link\n * sibling and parent elements as though this element had not contained any directives.\n *\n * The compiler does not suspend the entire compilation to wait for templates to be loaded because this\n * would result in the whole app \"stalling\" until all templates are loaded asynchronously - even in the\n * case when only one deeply nested directive has `templateUrl`.\n *\n * Template loading is asynchronous even if the template has been preloaded into the {@link $templateCache}\n *\n * You can specify `templateUrl` as a string representing the URL or as a function which takes two\n * arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns\n * a string value representing the url.  In either case, the template URL is passed through {@link\n * $sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}.\n *\n *\n * #### `replace` ([*DEPRECATED*!], will be removed in next major release - i.e. v2.0)\n * specify what the template should replace. Defaults to `false`.\n *\n * * `true` - the template will replace the directive's element.\n * * `false` - the template will replace the contents of the directive's element.\n *\n * The replacement process migrates all of the attributes / classes from the old element to the new\n * one. See the {@link guide/directive#template-expanding-directive\n * Directives Guide} for an example.\n *\n * There are very few scenarios where element replacement is required for the application function,\n * the main one being reusable custom components that are used within SVG contexts\n * (because SVG doesn't work with custom elements in the DOM tree).\n *\n * #### `transclude`\n * Extract the contents of the element where the directive appears and make it available to the directive.\n * The contents are compiled and provided to the directive as a **transclusion function**. See the\n * {@link $compile#transclusion Transclusion} section below.\n *\n *\n * #### `compile`\n *\n * ```js\n *   function compile(tElement, tAttrs, transclude) { ... }\n * ```\n *\n * The compile function deals with transforming the template DOM. Since most directives do not do\n * template transformation, it is not used often. The compile function takes the following arguments:\n *\n *   * `tElement` - template element - The element where the directive has been declared. It is\n *     safe to do template transformation on the element and child elements only.\n *\n *   * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared\n *     between all directive compile functions.\n *\n *   * `transclude` -  [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`\n *\n * <div class=\"alert alert-warning\">\n * **Note:** The template instance and the link instance may be different objects if the template has\n * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that\n * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration\n * should be done in a linking function rather than in a compile function.\n * </div>\n\n * <div class=\"alert alert-warning\">\n * **Note:** The compile function cannot handle directives that recursively use themselves in their\n * own templates or compile functions. Compiling these directives results in an infinite loop and\n * stack overflow errors.\n *\n * This can be avoided by manually using $compile in the postLink function to imperatively compile\n * a directive's template instead of relying on automatic template compilation via `template` or\n * `templateUrl` declaration or manual compilation inside the compile function.\n * </div>\n *\n * <div class=\"alert alert-danger\">\n * **Note:** The `transclude` function that is passed to the compile function is deprecated, as it\n *   e.g. does not know about the right outer scope. Please use the transclude function that is passed\n *   to the link function instead.\n * </div>\n\n * A compile function can have a return value which can be either a function or an object.\n *\n * * returning a (post-link) function - is equivalent to registering the linking function via the\n *   `link` property of the config object when the compile function is empty.\n *\n * * returning an object with function(s) registered via `pre` and `post` properties - allows you to\n *   control when a linking function should be called during the linking phase. See info about\n *   pre-linking and post-linking functions below.\n *\n *\n * #### `link`\n * This property is used only if the `compile` property is not defined.\n *\n * ```js\n *   function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }\n * ```\n *\n * The link function is responsible for registering DOM listeners as well as updating the DOM. It is\n * executed after the template has been cloned. This is where most of the directive logic will be\n * put.\n *\n *   * `scope` - {@link ng.$rootScope.Scope Scope} - The scope to be used by the\n *     directive for registering {@link ng.$rootScope.Scope#$watch watches}.\n *\n *   * `iElement` - instance element - The element where the directive is to be used. It is safe to\n *     manipulate the children of the element only in `postLink` function since the children have\n *     already been linked.\n *\n *   * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared\n *     between all directive linking functions.\n *\n *   * `controller` - the directive's required controller instance(s) - Instances are shared\n *     among all directives, which allows the directives to use the controllers as a communication\n *     channel. The exact value depends on the directive's `require` property:\n *       * no controller(s) required: the directive's own controller, or `undefined` if it doesn't have one\n *       * `string`: the controller instance\n *       * `array`: array of controller instances\n *\n *     If a required controller cannot be found, and it is optional, the instance is `null`,\n *     otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.\n *\n *     Note that you can also require the directive's own controller - it will be made available like\n *     any other controller.\n *\n *   * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.\n *     This is the same as the `$transclude` parameter of directive controllers,\n *     see {@link ng.$compile#-controller- the controller section for details}.\n *     `function([scope], cloneLinkingFn, futureParentElement)`.\n *\n * #### Pre-linking function\n *\n * Executed before the child elements are linked. Not safe to do DOM transformation since the\n * compiler linking function will fail to locate the correct elements for linking.\n *\n * #### Post-linking function\n *\n * Executed after the child elements are linked.\n *\n * Note that child elements that contain `templateUrl` directives will not have been compiled\n * and linked since they are waiting for their template to load asynchronously and their own\n * compilation and linking has been suspended until that occurs.\n *\n * It is safe to do DOM transformation in the post-linking function on elements that are not waiting\n * for their async templates to be resolved.\n *\n *\n * ### Transclusion\n *\n * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and\n * copying them to another part of the DOM, while maintaining their connection to the original AngularJS\n * scope from where they were taken.\n *\n * Transclusion is used (often with {@link ngTransclude}) to insert the\n * original contents of a directive's element into a specified place in the template of the directive.\n * The benefit of transclusion, over simply moving the DOM elements manually, is that the transcluded\n * content has access to the properties on the scope from which it was taken, even if the directive\n * has isolated scope.\n * See the {@link guide/directive#creating-a-directive-that-wraps-other-elements Directives Guide}.\n *\n * This makes it possible for the widget to have private state for its template, while the transcluded\n * content has access to its originating scope.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** When testing an element transclude directive you must not place the directive at the root of the\n * DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives\n * Testing Transclusion Directives}.\n * </div>\n *\n * There are three kinds of transclusion depending upon whether you want to transclude just the contents of the\n * directive's element, the entire element or multiple parts of the element contents:\n *\n * * `true` - transclude the content (i.e. the child nodes) of the directive's element.\n * * `'element'` - transclude the whole of the directive's element including any directives on this\n *   element that defined at a lower priority than this directive. When used, the `template`\n *   property is ignored.\n * * **`{...}` (an object hash):** - map elements of the content onto transclusion \"slots\" in the template.\n *\n * **Mult-slot transclusion** is declared by providing an object for the `transclude` property.\n *\n * This object is a map where the keys are the name of the slot to fill and the value is an element selector\n * used to match the HTML to the slot. The element selector should be in normalized form (e.g. `myElement`)\n * and will match the standard element variants (e.g. `my-element`, `my:element`, `data-my-element`, etc).\n *\n * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}\n *\n * If the element selector is prefixed with a `?` then that slot is optional.\n *\n * For example, the transclude object `{ slotA: '?myCustomElement' }` maps `<my-custom-element>` elements to\n * the `slotA` slot, which can be accessed via the `$transclude` function or via the {@link ngTransclude} directive.\n *\n * Slots that are not marked as optional (`?`) will trigger a compile time error if there are no matching elements\n * in the transclude content. If you wish to know if an optional slot was filled with content, then you can call\n * `$transclude.isSlotFilled(slotName)` on the transclude function passed to the directive's link function and\n * injectable into the directive's controller.\n *\n *\n * #### Transclusion Functions\n *\n * When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion\n * function** to the directive's `link` function and `controller`. This transclusion function is a special\n * **linking function** that will return the compiled contents linked to a new transclusion scope.\n *\n * <div class=\"alert alert-info\">\n * If you are just using {@link ngTransclude} then you don't need to worry about this function, since\n * ngTransclude will deal with it for us.\n * </div>\n *\n * If you want to manually control the insertion and removal of the transcluded content in your directive\n * then you must use this transclude function. When you call a transclude function it returns a a jqLite/JQuery\n * object that contains the compiled DOM, which is linked to the correct transclusion scope.\n *\n * When you call a transclusion function you can pass in a **clone attach function**. This function accepts\n * two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded\n * content and the `scope` is the newly created transclusion scope, which the clone will be linked to.\n *\n * <div class=\"alert alert-info\">\n * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a transclude function\n * since you then get a fresh clone of the original DOM and also have access to the new transclusion scope.\n * </div>\n *\n * It is normal practice to attach your transcluded content (`clone`) to the DOM inside your **clone\n * attach function**:\n *\n * ```js\n * var transcludedContent, transclusionScope;\n *\n * $transclude(function(clone, scope) {\n *   element.append(clone);\n *   transcludedContent = clone;\n *   transclusionScope = scope;\n * });\n * ```\n *\n * Later, if you want to remove the transcluded content from your DOM then you should also destroy the\n * associated transclusion scope:\n *\n * ```js\n * transcludedContent.remove();\n * transclusionScope.$destroy();\n * ```\n *\n * <div class=\"alert alert-info\">\n * **Best Practice**: if you intend to add and remove transcluded content manually in your directive\n * (by calling the transclude function to get the DOM and calling `element.remove()` to remove it),\n * then you are also responsible for calling `$destroy` on the transclusion scope.\n * </div>\n *\n * The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat}\n * automatically destroy their transcluded clones as necessary so you do not need to worry about this if\n * you are simply using {@link ngTransclude} to inject the transclusion into your directive.\n *\n *\n * #### Transclusion Scopes\n *\n * When you call a transclude function it returns a DOM fragment that is pre-bound to a **transclusion\n * scope**. This scope is special, in that it is a child of the directive's scope (and so gets destroyed\n * when the directive's scope gets destroyed) but it inherits the properties of the scope from which it\n * was taken.\n *\n * For example consider a directive that uses transclusion and isolated scope. The DOM hierarchy might look\n * like this:\n *\n * ```html\n * <div ng-app>\n *   <div isolate>\n *     <div transclusion>\n *     </div>\n *   </div>\n * </div>\n * ```\n *\n * The `$parent` scope hierarchy will look like this:\n *\n   ```\n   - $rootScope\n     - isolate\n       - transclusion\n   ```\n *\n * but the scopes will inherit prototypically from different scopes to their `$parent`.\n *\n   ```\n   - $rootScope\n     - transclusion\n   - isolate\n   ```\n *\n *\n * ### Attributes\n *\n * The {@link ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the\n * `link()` or `compile()` functions. It has a variety of uses.\n *\n * * *Accessing normalized attribute names:* Directives like 'ngBind' can be expressed in many ways:\n *   'ng:bind', `data-ng-bind`, or 'x-ng-bind'. The attributes object allows for normalized access\n *   to the attributes.\n *\n * * *Directive inter-communication:* All directives share the same instance of the attributes\n *   object which allows the directives to use the attributes object as inter directive\n *   communication.\n *\n * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object\n *   allowing other directives to read the interpolated value.\n *\n * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes\n *   that contain interpolation (e.g. `src=\"{{bar}}\"`). Not only is this very efficient but it's also\n *   the only way to easily get the actual value because during the linking phase the interpolation\n *   hasn't been evaluated yet and so the value is at this time set to `undefined`.\n *\n * ```js\n * function linkingFn(scope, elm, attrs, ctrl) {\n *   // get the attribute value\n *   console.log(attrs.ngModel);\n *\n *   // change the attribute\n *   attrs.$set('ngModel', 'new value');\n *\n *   // observe changes to interpolated attribute\n *   attrs.$observe('ngModel', function(value) {\n *     console.log('ngModel has changed value to ' + value);\n *   });\n * }\n * ```\n *\n * ## Example\n *\n * <div class=\"alert alert-warning\">\n * **Note**: Typically directives are registered with `module.directive`. The example below is\n * to illustrate how `$compile` works.\n * </div>\n *\n <example module=\"compileExample\" name=\"compile\">\n   <file name=\"index.html\">\n    <script>\n      angular.module('compileExample', [], function($compileProvider) {\n        // configure new 'compile' directive by passing a directive\n        // factory function. The factory function injects the '$compile'\n        $compileProvider.directive('compile', function($compile) {\n          // directive factory creates a link function\n          return function(scope, element, attrs) {\n            scope.$watch(\n              function(scope) {\n                 // watch the 'compile' expression for changes\n                return scope.$eval(attrs.compile);\n              },\n              function(value) {\n                // when the 'compile' expression changes\n                // assign it into the current DOM\n                element.html(value);\n\n                // compile the new DOM and link it to the current\n                // scope.\n                // NOTE: we only compile .childNodes so that\n                // we don't get into infinite loop compiling ourselves\n                $compile(element.contents())(scope);\n              }\n            );\n          };\n        });\n      })\n      .controller('GreeterController', ['$scope', function($scope) {\n        $scope.name = 'Angular';\n        $scope.html = 'Hello {{name}}';\n      }]);\n    </script>\n    <div ng-controller=\"GreeterController\">\n      <input ng-model=\"name\"> <br/>\n      <textarea ng-model=\"html\"></textarea> <br/>\n      <div compile=\"html\"></div>\n    </div>\n   </file>\n   <file name=\"protractor.js\" type=\"protractor\">\n     it('should auto compile', function() {\n       var textarea = $('textarea');\n       var output = $('div[compile]');\n       // The initial state reads 'Hello Angular'.\n       expect(output.getText()).toBe('Hello Angular');\n       textarea.clear();\n       textarea.sendKeys('{{name}}!');\n       expect(output.getText()).toBe('Angular!');\n     });\n   </file>\n </example>\n\n *\n *\n * @param {string|DOMElement} element Element or HTML string to compile into a template function.\n * @param {function(angular.Scope, cloneAttachFn=)} transclude function available to directives - DEPRECATED.\n *\n * <div class=\"alert alert-danger\">\n * **Note:** Passing a `transclude` function to the $compile function is deprecated, as it\n *   e.g. will not use the right outer scope. Please pass the transclude function as a\n *   `parentBoundTranscludeFn` to the link function instead.\n * </div>\n *\n * @param {number} maxPriority only apply directives lower than given priority (Only effects the\n *                 root element(s), not their children)\n * @returns {function(scope, cloneAttachFn=, options=)} a link function which is used to bind template\n * (a DOM element/tree) to a scope. Where:\n *\n *  * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to.\n *  * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the\n *  `template` and call the `cloneAttachFn` function allowing the caller to attach the\n *  cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is\n *  called as: <br/> `cloneAttachFn(clonedElement, scope)` where:\n *\n *      * `clonedElement` - is a clone of the original `element` passed into the compiler.\n *      * `scope` - is the current scope with which the linking function is working with.\n *\n *  * `options` - An optional object hash with linking options. If `options` is provided, then the following\n *  keys may be used to control linking behavior:\n *\n *      * `parentBoundTranscludeFn` - the transclude function made available to\n *        directives; if given, it will be passed through to the link functions of\n *        directives found in `element` during compilation.\n *      * `transcludeControllers` - an object hash with keys that map controller names\n *        to a hash with the key `instance`, which maps to the controller instance;\n *        if given, it will make the controllers available to directives on the compileNode:\n *        ```\n *        {\n *          parent: {\n *            instance: parentControllerInstance\n *          }\n *        }\n *        ```\n *      * `futureParentElement` - defines the parent to which the `cloneAttachFn` will add\n *        the cloned elements; only needed for transcludes that are allowed to contain non html\n *        elements (e.g. SVG elements). See also the directive.controller property.\n *\n * Calling the linking function returns the element of the template. It is either the original\n * element passed in, or the clone of the element if the `cloneAttachFn` is provided.\n *\n * After linking the view is not updated until after a call to $digest which typically is done by\n * Angular automatically.\n *\n * If you need access to the bound view, there are two ways to do it:\n *\n * - If you are not asking the linking function to clone the template, create the DOM element(s)\n *   before you send them to the compiler and keep this reference around.\n *   ```js\n *     var element = $compile('<p>{{total}}</p>')(scope);\n *   ```\n *\n * - if on the other hand, you need the element to be cloned, the view reference from the original\n *   example would not point to the clone, but rather to the original template that was cloned. In\n *   this case, you can access the clone via the cloneAttachFn:\n *   ```js\n *     var templateElement = angular.element('<p>{{total}}</p>'),\n *         scope = ....;\n *\n *     var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {\n *       //attach the clone to DOM document at the right place\n *     });\n *\n *     //now we have reference to the cloned DOM via `clonedElement`\n *   ```\n *\n *\n * For information on how the compiler works, see the\n * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide.\n *\n * @knownIssue\n *\n * ### Double Compilation\n *\n   Double compilation occurs when an already compiled part of the DOM gets\n   compiled again. This is an undesired effect and can lead to misbehaving directives, performance issues,\n   and memory leaks. Refer to the Compiler Guide {@link guide/compiler#double-compilation-and-how-to-avoid-it\n   section on double compilation} for an in-depth explanation and ways to avoid it.\n *\n */\n\nvar $compileMinErr = minErr('$compile');\n\nfunction UNINITIALIZED_VALUE() {}\nvar _UNINITIALIZED_VALUE = new UNINITIALIZED_VALUE();\n\n/**\n * @ngdoc provider\n * @name $compileProvider\n *\n * @description\n */\n$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];\n/** @this */\nfunction $CompileProvider($provide, $$sanitizeUriProvider) {\n  var hasDirectives = {},\n      Suffix = 'Directive',\n      COMMENT_DIRECTIVE_REGEXP = /^\\s*directive:\\s*([\\w-]+)\\s+(.*)$/,\n      CLASS_DIRECTIVE_REGEXP = /(([\\w-]+)(?::([^;]+))?;?)/,\n      ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),\n      REQUIRE_PREFIX_REGEXP = /^(?:(\\^\\^?)?(\\?)?(\\^\\^?)?)?/;\n\n  // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes\n  // The assumption is that future DOM event attribute names will begin with\n  // 'on' and be composed of only English letters.\n  var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;\n  var bindingCache = createMap();\n\n  function parseIsolateBindings(scope, directiveName, isController) {\n    var LOCAL_REGEXP = /^\\s*([@&<]|=(\\*?))(\\??)\\s*([\\w$]*)\\s*$/;\n\n    var bindings = createMap();\n\n    forEach(scope, function(definition, scopeName) {\n      if (definition in bindingCache) {\n        bindings[scopeName] = bindingCache[definition];\n        return;\n      }\n      var match = definition.match(LOCAL_REGEXP);\n\n      if (!match) {\n        throw $compileMinErr('iscp',\n            'Invalid {3} for directive \\'{0}\\'.' +\n            ' Definition: {... {1}: \\'{2}\\' ...}',\n            directiveName, scopeName, definition,\n            (isController ? 'controller bindings definition' :\n            'isolate scope definition'));\n      }\n\n      bindings[scopeName] = {\n        mode: match[1][0],\n        collection: match[2] === '*',\n        optional: match[3] === '?',\n        attrName: match[4] || scopeName\n      };\n      if (match[4]) {\n        bindingCache[definition] = bindings[scopeName];\n      }\n    });\n\n    return bindings;\n  }\n\n  function parseDirectiveBindings(directive, directiveName) {\n    var bindings = {\n      isolateScope: null,\n      bindToController: null\n    };\n    if (isObject(directive.scope)) {\n      if (directive.bindToController === true) {\n        bindings.bindToController = parseIsolateBindings(directive.scope,\n                                                         directiveName, true);\n        bindings.isolateScope = {};\n      } else {\n        bindings.isolateScope = parseIsolateBindings(directive.scope,\n                                                     directiveName, false);\n      }\n    }\n    if (isObject(directive.bindToController)) {\n      bindings.bindToController =\n          parseIsolateBindings(directive.bindToController, directiveName, true);\n    }\n    if (bindings.bindToController && !directive.controller) {\n      // There is no controller\n      throw $compileMinErr('noctrl',\n            'Cannot bind to controller without directive \\'{0}\\'s controller.',\n            directiveName);\n    }\n    return bindings;\n  }\n\n  function assertValidDirectiveName(name) {\n    var letter = name.charAt(0);\n    if (!letter || letter !== lowercase(letter)) {\n      throw $compileMinErr('baddir', 'Directive/Component name \\'{0}\\' is invalid. The first character must be a lowercase letter', name);\n    }\n    if (name !== name.trim()) {\n      throw $compileMinErr('baddir',\n            'Directive/Component name \\'{0}\\' is invalid. The name should not contain leading or trailing whitespaces',\n            name);\n    }\n  }\n\n  function getDirectiveRequire(directive) {\n    var require = directive.require || (directive.controller && directive.name);\n\n    if (!isArray(require) && isObject(require)) {\n      forEach(require, function(value, key) {\n        var match = value.match(REQUIRE_PREFIX_REGEXP);\n        var name = value.substring(match[0].length);\n        if (!name) require[key] = match[0] + key;\n      });\n    }\n\n    return require;\n  }\n\n  function getDirectiveRestrict(restrict, name) {\n    if (restrict && !(isString(restrict) && /[EACM]/.test(restrict))) {\n      throw $compileMinErr('badrestrict',\n          'Restrict property \\'{0}\\' of directive \\'{1}\\' is invalid',\n          restrict,\n          name);\n    }\n\n    return restrict || 'EA';\n  }\n\n  /**\n   * @ngdoc method\n   * @name $compileProvider#directive\n   * @kind function\n   *\n   * @description\n   * Register a new directive with the compiler.\n   *\n   * @param {string|Object} name Name of the directive in camel-case (i.e. <code>ngBind</code> which\n   *    will match as <code>ng-bind</code>), or an object map of directives where the keys are the\n   *    names and the values are the factories.\n   * @param {Function|Array} directiveFactory An injectable directive factory function. See the\n   *    {@link guide/directive directive guide} and the {@link $compile compile API} for more info.\n   * @returns {ng.$compileProvider} Self for chaining.\n   */\n  this.directive = function registerDirective(name, directiveFactory) {\n    assertArg(name, 'name');\n    assertNotHasOwnProperty(name, 'directive');\n    if (isString(name)) {\n      assertValidDirectiveName(name);\n      assertArg(directiveFactory, 'directiveFactory');\n      if (!hasDirectives.hasOwnProperty(name)) {\n        hasDirectives[name] = [];\n        $provide.factory(name + Suffix, ['$injector', '$exceptionHandler',\n          function($injector, $exceptionHandler) {\n            var directives = [];\n            forEach(hasDirectives[name], function(directiveFactory, index) {\n              try {\n                var directive = $injector.invoke(directiveFactory);\n                if (isFunction(directive)) {\n                  directive = { compile: valueFn(directive) };\n                } else if (!directive.compile && directive.link) {\n                  directive.compile = valueFn(directive.link);\n                }\n                directive.priority = directive.priority || 0;\n                directive.index = index;\n                directive.name = directive.name || name;\n                directive.require = getDirectiveRequire(directive);\n                directive.restrict = getDirectiveRestrict(directive.restrict, name);\n                directive.$$moduleName = directiveFactory.$$moduleName;\n                directives.push(directive);\n              } catch (e) {\n                $exceptionHandler(e);\n              }\n            });\n            return directives;\n          }]);\n      }\n      hasDirectives[name].push(directiveFactory);\n    } else {\n      forEach(name, reverseParams(registerDirective));\n    }\n    return this;\n  };\n\n  /**\n   * @ngdoc method\n   * @name $compileProvider#component\n   * @module ng\n   * @param {string} name Name of the component in camelCase (i.e. `myComp` which will match `<my-comp>`)\n   * @param {Object} options Component definition object (a simplified\n   *    {@link ng.$compile#directive-definition-object directive definition object}),\n   *    with the following properties (all optional):\n   *\n   *    - `controller` – `{(string|function()=}` – controller constructor function that should be\n   *      associated with newly created scope or the name of a {@link ng.$compile#-controller-\n   *      registered controller} if passed as a string. An empty `noop` function by default.\n   *    - `controllerAs` – `{string=}` – identifier name for to reference the controller in the component's scope.\n   *      If present, the controller will be published to scope under the `controllerAs` name.\n   *      If not present, this will default to be `$ctrl`.\n   *    - `template` – `{string=|function()=}` – html template as a string or a function that\n   *      returns an html template as a string which should be used as the contents of this component.\n   *      Empty string by default.\n   *\n   *      If `template` is a function, then it is {@link auto.$injector#invoke injected} with\n   *      the following locals:\n   *\n   *      - `$element` - Current element\n   *      - `$attrs` - Current attributes object for the element\n   *\n   *    - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html\n   *      template that should be used  as the contents of this component.\n   *\n   *      If `templateUrl` is a function, then it is {@link auto.$injector#invoke injected} with\n   *      the following locals:\n   *\n   *      - `$element` - Current element\n   *      - `$attrs` - Current attributes object for the element\n   *\n   *    - `bindings` – `{object=}` – defines bindings between DOM attributes and component properties.\n   *      Component properties are always bound to the component controller and not to the scope.\n   *      See {@link ng.$compile#-bindtocontroller- `bindToController`}.\n   *    - `transclude` – `{boolean=}` – whether {@link $compile#transclusion content transclusion} is enabled.\n   *      Disabled by default.\n   *    - `require` - `{Object<string, string>=}` - requires the controllers of other directives and binds them to\n   *      this component's controller. The object keys specify the property names under which the required\n   *      controllers (object values) will be bound. See {@link ng.$compile#-require- `require`}.\n   *    - `$...` – additional properties to attach to the directive factory function and the controller\n   *      constructor function. (This is used by the component router to annotate)\n   *\n   * @returns {ng.$compileProvider} the compile provider itself, for chaining of function calls.\n   * @description\n   * Register a **component definition** with the compiler. This is a shorthand for registering a special\n   * type of directive, which represents a self-contained UI component in your application. Such components\n   * are always isolated (i.e. `scope: {}`) and are always restricted to elements (i.e. `restrict: 'E'`).\n   *\n   * Component definitions are very simple and do not require as much configuration as defining general\n   * directives. Component definitions usually consist only of a template and a controller backing it.\n   *\n   * In order to make the definition easier, components enforce best practices like use of `controllerAs`,\n   * `bindToController`. They always have **isolate scope** and are restricted to elements.\n   *\n   * Here are a few examples of how you would usually define components:\n   *\n   * ```js\n   *   var myMod = angular.module(...);\n   *   myMod.component('myComp', {\n   *     template: '<div>My name is {{$ctrl.name}}</div>',\n   *     controller: function() {\n   *       this.name = 'shahar';\n   *     }\n   *   });\n   *\n   *   myMod.component('myComp', {\n   *     template: '<div>My name is {{$ctrl.name}}</div>',\n   *     bindings: {name: '@'}\n   *   });\n   *\n   *   myMod.component('myComp', {\n   *     templateUrl: 'views/my-comp.html',\n   *     controller: 'MyCtrl',\n   *     controllerAs: 'ctrl',\n   *     bindings: {name: '@'}\n   *   });\n   *\n   * ```\n   * For more examples, and an in-depth guide, see the {@link guide/component component guide}.\n   *\n   * <br />\n   * See also {@link ng.$compileProvider#directive $compileProvider.directive()}.\n   */\n  this.component = function registerComponent(name, options) {\n    var controller = options.controller || function() {};\n\n    function factory($injector) {\n      function makeInjectable(fn) {\n        if (isFunction(fn) || isArray(fn)) {\n          return /** @this */ function(tElement, tAttrs) {\n            return $injector.invoke(fn, this, {$element: tElement, $attrs: tAttrs});\n          };\n        } else {\n          return fn;\n        }\n      }\n\n      var template = (!options.template && !options.templateUrl ? '' : options.template);\n      var ddo = {\n        controller: controller,\n        controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',\n        template: makeInjectable(template),\n        templateUrl: makeInjectable(options.templateUrl),\n        transclude: options.transclude,\n        scope: {},\n        bindToController: options.bindings || {},\n        restrict: 'E',\n        require: options.require\n      };\n\n      // Copy annotations (starting with $) over to the DDO\n      forEach(options, function(val, key) {\n        if (key.charAt(0) === '$') ddo[key] = val;\n      });\n\n      return ddo;\n    }\n\n    // TODO(pete) remove the following `forEach` before we release 1.6.0\n    // The component-router@0.2.0 looks for the annotations on the controller constructor\n    // Nothing in Angular looks for annotations on the factory function but we can't remove\n    // it from 1.5.x yet.\n\n    // Copy any annotation properties (starting with $) over to the factory and controller constructor functions\n    // These could be used by libraries such as the new component router\n    forEach(options, function(val, key) {\n      if (key.charAt(0) === '$') {\n        factory[key] = val;\n        // Don't try to copy over annotations to named controller\n        if (isFunction(controller)) controller[key] = val;\n      }\n    });\n\n    factory.$inject = ['$injector'];\n\n    return this.directive(name, factory);\n  };\n\n\n  /**\n   * @ngdoc method\n   * @name $compileProvider#aHrefSanitizationWhitelist\n   * @kind function\n   *\n   * @description\n   * Retrieves or overrides the default regular expression that is used for whitelisting of safe\n   * urls during a[href] sanitization.\n   *\n   * The sanitization is a security measure aimed at preventing XSS attacks via html links.\n   *\n   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into\n   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`\n   * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n   *\n   * @param {RegExp=} regexp New regexp to whitelist urls with.\n   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for\n   *    chaining otherwise.\n   */\n  this.aHrefSanitizationWhitelist = function(regexp) {\n    if (isDefined(regexp)) {\n      $$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);\n      return this;\n    } else {\n      return $$sanitizeUriProvider.aHrefSanitizationWhitelist();\n    }\n  };\n\n\n  /**\n   * @ngdoc method\n   * @name $compileProvider#imgSrcSanitizationWhitelist\n   * @kind function\n   *\n   * @description\n   * Retrieves or overrides the default regular expression that is used for whitelisting of safe\n   * urls during img[src] sanitization.\n   *\n   * The sanitization is a security measure aimed at prevent XSS attacks via html links.\n   *\n   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into\n   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`\n   * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n   *\n   * @param {RegExp=} regexp New regexp to whitelist urls with.\n   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for\n   *    chaining otherwise.\n   */\n  this.imgSrcSanitizationWhitelist = function(regexp) {\n    if (isDefined(regexp)) {\n      $$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);\n      return this;\n    } else {\n      return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();\n    }\n  };\n\n  /**\n   * @ngdoc method\n   * @name  $compileProvider#debugInfoEnabled\n   *\n   * @param {boolean=} enabled update the debugInfoEnabled state if provided, otherwise just return the\n   * current debugInfoEnabled state\n   * @returns {*} current value if used as getter or itself (chaining) if used as setter\n   *\n   * @kind function\n   *\n   * @description\n   * Call this method to enable/disable various debug runtime information in the compiler such as adding\n   * binding information and a reference to the current scope on to DOM elements.\n   * If enabled, the compiler will add the following to DOM elements that have been bound to the scope\n   * * `ng-binding` CSS class\n   * * `$binding` data property containing an array of the binding expressions\n   *\n   * You may want to disable this in production for a significant performance boost. See\n   * {@link guide/production#disabling-debug-data Disabling Debug Data} for more.\n   *\n   * The default value is true.\n   */\n  var debugInfoEnabled = true;\n  this.debugInfoEnabled = function(enabled) {\n    if (isDefined(enabled)) {\n      debugInfoEnabled = enabled;\n      return this;\n    }\n    return debugInfoEnabled;\n  };\n\n  /**\n   * @ngdoc method\n   * @name  $compileProvider#preAssignBindingsEnabled\n   *\n   * @param {boolean=} enabled update the preAssignBindingsEnabled state if provided, otherwise just return the\n   * current preAssignBindingsEnabled state\n   * @returns {*} current value if used as getter or itself (chaining) if used as setter\n   *\n   * @kind function\n   *\n   * @description\n   * Call this method to enable/disable whether directive controllers are assigned bindings before\n   * calling the controller's constructor.\n   * If enabled (true), the compiler assigns the value of each of the bindings to the\n   * properties of the controller object before the constructor of this object is called.\n   *\n   * If disabled (false), the compiler calls the constructor first before assigning bindings.\n   *\n   * The default value is true in Angular 1.5.x but will switch to false in Angular 1.6.x.\n   */\n  var preAssignBindingsEnabled = false;\n  this.preAssignBindingsEnabled = function(enabled) {\n    if (isDefined(enabled)) {\n      preAssignBindingsEnabled = enabled;\n      return this;\n    }\n    return preAssignBindingsEnabled;\n  };\n\n\n  var TTL = 10;\n  /**\n   * @ngdoc method\n   * @name $compileProvider#onChangesTtl\n   * @description\n   *\n   * Sets the number of times `$onChanges` hooks can trigger new changes before giving up and\n   * assuming that the model is unstable.\n   *\n   * The current default is 10 iterations.\n   *\n   * In complex applications it's possible that dependencies between `$onChanges` hooks and bindings will result\n   * in several iterations of calls to these hooks. However if an application needs more than the default 10\n   * iterations to stabilize then you should investigate what is causing the model to continuously change during\n   * the `$onChanges` hook execution.\n   *\n   * Increasing the TTL could have performance implications, so you should not change it without proper justification.\n   *\n   * @param {number} limit The number of `$onChanges` hook iterations.\n   * @returns {number|object} the current limit (or `this` if called as a setter for chaining)\n   */\n  this.onChangesTtl = function(value) {\n    if (arguments.length) {\n      TTL = value;\n      return this;\n    }\n    return TTL;\n  };\n\n  var commentDirectivesEnabledConfig = true;\n  /**\n   * @ngdoc method\n   * @name $compileProvider#commentDirectivesEnabled\n   * @description\n   *\n   * It indicates to the compiler\n   * whether or not directives on comments should be compiled.\n   * Defaults to `true`.\n   *\n   * Calling this function with false disables the compilation of directives\n   * on comments for the whole application.\n   * This results in a compilation performance gain,\n   * as the compiler doesn't have to check comments when looking for directives.\n   * This should however only be used if you are sure that no comment directives are used in\n   * the application (including any 3rd party directives).\n   *\n   * @param {boolean} enabled `false` if the compiler may ignore directives on comments\n   * @returns {boolean|object} the current value (or `this` if called as a setter for chaining)\n   */\n  this.commentDirectivesEnabled = function(value) {\n    if (arguments.length) {\n      commentDirectivesEnabledConfig = value;\n      return this;\n    }\n    return commentDirectivesEnabledConfig;\n  };\n\n\n  var cssClassDirectivesEnabledConfig = true;\n  /**\n   * @ngdoc method\n   * @name $compileProvider#cssClassDirectivesEnabled\n   * @description\n   *\n   * It indicates to the compiler\n   * whether or not directives on element classes should be compiled.\n   * Defaults to `true`.\n   *\n   * Calling this function with false disables the compilation of directives\n   * on element classes for the whole application.\n   * This results in a compilation performance gain,\n   * as the compiler doesn't have to check element classes when looking for directives.\n   * This should however only be used if you are sure that no class directives are used in\n   * the application (including any 3rd party directives).\n   *\n   * @param {boolean} enabled `false` if the compiler may ignore directives on element classes\n   * @returns {boolean|object} the current value (or `this` if called as a setter for chaining)\n   */\n  this.cssClassDirectivesEnabled = function(value) {\n    if (arguments.length) {\n      cssClassDirectivesEnabledConfig = value;\n      return this;\n    }\n    return cssClassDirectivesEnabledConfig;\n  };\n\n  this.$get = [\n            '$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',\n            '$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri',\n    function($injector,   $interpolate,   $exceptionHandler,   $templateRequest,   $parse,\n             $controller,   $rootScope,   $sce,   $animate,   $$sanitizeUri) {\n\n    var SIMPLE_ATTR_NAME = /^\\w/;\n    var specialAttrHolder = window.document.createElement('div');\n\n\n    var commentDirectivesEnabled = commentDirectivesEnabledConfig;\n    var cssClassDirectivesEnabled = cssClassDirectivesEnabledConfig;\n\n\n    var onChangesTtl = TTL;\n    // The onChanges hooks should all be run together in a single digest\n    // When changes occur, the call to trigger their hooks will be added to this queue\n    var onChangesQueue;\n\n    // This function is called in a $$postDigest to trigger all the onChanges hooks in a single digest\n    function flushOnChangesQueue() {\n      try {\n        if (!(--onChangesTtl)) {\n          // We have hit the TTL limit so reset everything\n          onChangesQueue = undefined;\n          throw $compileMinErr('infchng', '{0} $onChanges() iterations reached. Aborting!\\n', TTL);\n        }\n        // We must run this hook in an apply since the $$postDigest runs outside apply\n        $rootScope.$apply(function() {\n          var errors = [];\n          for (var i = 0, ii = onChangesQueue.length; i < ii; ++i) {\n            try {\n              onChangesQueue[i]();\n            } catch (e) {\n              errors.push(e);\n            }\n          }\n          // Reset the queue to trigger a new schedule next time there is a change\n          onChangesQueue = undefined;\n          if (errors.length) {\n            throw errors;\n          }\n        });\n      } finally {\n        onChangesTtl++;\n      }\n    }\n\n\n    function Attributes(element, attributesToCopy) {\n      if (attributesToCopy) {\n        var keys = Object.keys(attributesToCopy);\n        var i, l, key;\n\n        for (i = 0, l = keys.length; i < l; i++) {\n          key = keys[i];\n          this[key] = attributesToCopy[key];\n        }\n      } else {\n        this.$attr = {};\n      }\n\n      this.$$element = element;\n    }\n\n    Attributes.prototype = {\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$normalize\n       * @kind function\n       *\n       * @description\n       * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or\n       * `data-`) to its normalized, camelCase form.\n       *\n       * Also there is special case for Moz prefix starting with upper case letter.\n       *\n       * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}\n       *\n       * @param {string} name Name to normalize\n       */\n      $normalize: directiveNormalize,\n\n\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$addClass\n       * @kind function\n       *\n       * @description\n       * Adds the CSS class value specified by the classVal parameter to the element. If animations\n       * are enabled then an animation will be triggered for the class addition.\n       *\n       * @param {string} classVal The className value that will be added to the element\n       */\n      $addClass: function(classVal) {\n        if (classVal && classVal.length > 0) {\n          $animate.addClass(this.$$element, classVal);\n        }\n      },\n\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$removeClass\n       * @kind function\n       *\n       * @description\n       * Removes the CSS class value specified by the classVal parameter from the element. If\n       * animations are enabled then an animation will be triggered for the class removal.\n       *\n       * @param {string} classVal The className value that will be removed from the element\n       */\n      $removeClass: function(classVal) {\n        if (classVal && classVal.length > 0) {\n          $animate.removeClass(this.$$element, classVal);\n        }\n      },\n\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$updateClass\n       * @kind function\n       *\n       * @description\n       * Adds and removes the appropriate CSS class values to the element based on the difference\n       * between the new and old CSS class values (specified as newClasses and oldClasses).\n       *\n       * @param {string} newClasses The current CSS className value\n       * @param {string} oldClasses The former CSS className value\n       */\n      $updateClass: function(newClasses, oldClasses) {\n        var toAdd = tokenDifference(newClasses, oldClasses);\n        if (toAdd && toAdd.length) {\n          $animate.addClass(this.$$element, toAdd);\n        }\n\n        var toRemove = tokenDifference(oldClasses, newClasses);\n        if (toRemove && toRemove.length) {\n          $animate.removeClass(this.$$element, toRemove);\n        }\n      },\n\n      /**\n       * Set a normalized attribute on the element in a way such that all directives\n       * can share the attribute. This function properly handles boolean attributes.\n       * @param {string} key Normalized key. (ie ngAttribute)\n       * @param {string|boolean} value The value to set. If `null` attribute will be deleted.\n       * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.\n       *     Defaults to true.\n       * @param {string=} attrName Optional none normalized name. Defaults to key.\n       */\n      $set: function(key, value, writeAttr, attrName) {\n        // TODO: decide whether or not to throw an error if \"class\"\n        //is set through this function since it may cause $updateClass to\n        //become unstable.\n\n        var node = this.$$element[0],\n            booleanKey = getBooleanAttrName(node, key),\n            aliasedKey = getAliasedAttrName(key),\n            observer = key,\n            nodeName;\n\n        if (booleanKey) {\n          this.$$element.prop(key, value);\n          attrName = booleanKey;\n        } else if (aliasedKey) {\n          this[aliasedKey] = value;\n          observer = aliasedKey;\n        }\n\n        this[key] = value;\n\n        // translate normalized key to actual key\n        if (attrName) {\n          this.$attr[key] = attrName;\n        } else {\n          attrName = this.$attr[key];\n          if (!attrName) {\n            this.$attr[key] = attrName = snake_case(key, '-');\n          }\n        }\n\n        nodeName = nodeName_(this.$$element);\n\n        if ((nodeName === 'a' && (key === 'href' || key === 'xlinkHref')) ||\n            (nodeName === 'img' && key === 'src')) {\n          // sanitize a[href] and img[src] values\n          this[key] = value = $$sanitizeUri(value, key === 'src');\n        } else if (nodeName === 'img' && key === 'srcset' && isDefined(value)) {\n          // sanitize img[srcset] values\n          var result = '';\n\n          // first check if there are spaces because it's not the same pattern\n          var trimmedSrcset = trim(value);\n          //                (   999x   ,|   999w   ,|   ,|,   )\n          var srcPattern = /(\\s+\\d+x\\s*,|\\s+\\d+w\\s*,|\\s+,|,\\s+)/;\n          var pattern = /\\s/.test(trimmedSrcset) ? srcPattern : /(,)/;\n\n          // split srcset into tuple of uri and descriptor except for the last item\n          var rawUris = trimmedSrcset.split(pattern);\n\n          // for each tuples\n          var nbrUrisWith2parts = Math.floor(rawUris.length / 2);\n          for (var i = 0; i < nbrUrisWith2parts; i++) {\n            var innerIdx = i * 2;\n            // sanitize the uri\n            result += $$sanitizeUri(trim(rawUris[innerIdx]), true);\n            // add the descriptor\n            result += (' ' + trim(rawUris[innerIdx + 1]));\n          }\n\n          // split the last item into uri and descriptor\n          var lastTuple = trim(rawUris[i * 2]).split(/\\s/);\n\n          // sanitize the last uri\n          result += $$sanitizeUri(trim(lastTuple[0]), true);\n\n          // and add the last descriptor if any\n          if (lastTuple.length === 2) {\n            result += (' ' + trim(lastTuple[1]));\n          }\n          this[key] = value = result;\n        }\n\n        if (writeAttr !== false) {\n          if (value === null || isUndefined(value)) {\n            this.$$element.removeAttr(attrName);\n          } else {\n            if (SIMPLE_ATTR_NAME.test(attrName)) {\n              this.$$element.attr(attrName, value);\n            } else {\n              setSpecialAttr(this.$$element[0], attrName, value);\n            }\n          }\n        }\n\n        // fire observers\n        var $$observers = this.$$observers;\n        if ($$observers) {\n          forEach($$observers[observer], function(fn) {\n            try {\n              fn(value);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          });\n        }\n      },\n\n\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$observe\n       * @kind function\n       *\n       * @description\n       * Observes an interpolated attribute.\n       *\n       * The observer function will be invoked once during the next `$digest` following\n       * compilation. The observer is then invoked whenever the interpolated value\n       * changes.\n       *\n       * @param {string} key Normalized key. (ie ngAttribute) .\n       * @param {function(interpolatedValue)} fn Function that will be called whenever\n                the interpolated value of the attribute changes.\n       *        See the {@link guide/interpolation#how-text-and-attribute-bindings-work Interpolation\n       *        guide} for more info.\n       * @returns {function()} Returns a deregistration function for this observer.\n       */\n      $observe: function(key, fn) {\n        var attrs = this,\n            $$observers = (attrs.$$observers || (attrs.$$observers = createMap())),\n            listeners = ($$observers[key] || ($$observers[key] = []));\n\n        listeners.push(fn);\n        $rootScope.$evalAsync(function() {\n          if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) {\n            // no one registered attribute interpolation function, so lets call it manually\n            fn(attrs[key]);\n          }\n        });\n\n        return function() {\n          arrayRemove(listeners, fn);\n        };\n      }\n    };\n\n    function setSpecialAttr(element, attrName, value) {\n      // Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute`\n      // so we have to jump through some hoops to get such an attribute\n      // https://github.com/angular/angular.js/pull/13318\n      specialAttrHolder.innerHTML = '<span ' + attrName + '>';\n      var attributes = specialAttrHolder.firstChild.attributes;\n      var attribute = attributes[0];\n      // We have to remove the attribute from its container element before we can add it to the destination element\n      attributes.removeNamedItem(attribute.name);\n      attribute.value = value;\n      element.attributes.setNamedItem(attribute);\n    }\n\n    function safeAddClass($element, className) {\n      try {\n        $element.addClass(className);\n      } catch (e) {\n        // ignore, since it means that we are trying to set class on\n        // SVG element, where class name is read-only.\n      }\n    }\n\n\n    var startSymbol = $interpolate.startSymbol(),\n        endSymbol = $interpolate.endSymbol(),\n        denormalizeTemplate = (startSymbol === '{{' && endSymbol  === '}}')\n            ? identity\n            : function denormalizeTemplate(template) {\n              return template.replace(/\\{\\{/g, startSymbol).replace(/}}/g, endSymbol);\n        },\n        NG_ATTR_BINDING = /^ngAttr[A-Z]/;\n    var MULTI_ELEMENT_DIR_RE = /^(.+)Start$/;\n\n    compile.$$addBindingInfo = debugInfoEnabled ? function $$addBindingInfo($element, binding) {\n      var bindings = $element.data('$binding') || [];\n\n      if (isArray(binding)) {\n        bindings = bindings.concat(binding);\n      } else {\n        bindings.push(binding);\n      }\n\n      $element.data('$binding', bindings);\n    } : noop;\n\n    compile.$$addBindingClass = debugInfoEnabled ? function $$addBindingClass($element) {\n      safeAddClass($element, 'ng-binding');\n    } : noop;\n\n    compile.$$addScopeInfo = debugInfoEnabled ? function $$addScopeInfo($element, scope, isolated, noTemplate) {\n      var dataName = isolated ? (noTemplate ? '$isolateScopeNoTemplate' : '$isolateScope') : '$scope';\n      $element.data(dataName, scope);\n    } : noop;\n\n    compile.$$addScopeClass = debugInfoEnabled ? function $$addScopeClass($element, isolated) {\n      safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope');\n    } : noop;\n\n    compile.$$createComment = function(directiveName, comment) {\n      var content = '';\n      if (debugInfoEnabled) {\n        content = ' ' + (directiveName || '') + ': ';\n        if (comment) content += comment + ' ';\n      }\n      return window.document.createComment(content);\n    };\n\n    return compile;\n\n    //================================\n\n    function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective,\n                        previousCompileContext) {\n      if (!($compileNodes instanceof jqLite)) {\n        // jquery always rewraps, whereas we need to preserve the original selector so that we can\n        // modify it.\n        $compileNodes = jqLite($compileNodes);\n      }\n      var compositeLinkFn =\n              compileNodes($compileNodes, transcludeFn, $compileNodes,\n                           maxPriority, ignoreDirective, previousCompileContext);\n      compile.$$addScopeClass($compileNodes);\n      var namespace = null;\n      return function publicLinkFn(scope, cloneConnectFn, options) {\n        if (!$compileNodes) {\n          throw $compileMinErr('multilink', 'This element has already been linked.');\n        }\n        assertArg(scope, 'scope');\n\n        if (previousCompileContext && previousCompileContext.needsNewScope) {\n          // A parent directive did a replace and a directive on this element asked\n          // for transclusion, which caused us to lose a layer of element on which\n          // we could hold the new transclusion scope, so we will create it manually\n          // here.\n          scope = scope.$parent.$new();\n        }\n\n        options = options || {};\n        var parentBoundTranscludeFn = options.parentBoundTranscludeFn,\n          transcludeControllers = options.transcludeControllers,\n          futureParentElement = options.futureParentElement;\n\n        // When `parentBoundTranscludeFn` is passed, it is a\n        // `controllersBoundTransclude` function (it was previously passed\n        // as `transclude` to directive.link) so we must unwrap it to get\n        // its `boundTranscludeFn`\n        if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) {\n          parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude;\n        }\n\n        if (!namespace) {\n          namespace = detectNamespaceForChildElements(futureParentElement);\n        }\n        var $linkNode;\n        if (namespace !== 'html') {\n          // When using a directive with replace:true and templateUrl the $compileNodes\n          // (or a child element inside of them)\n          // might change, so we need to recreate the namespace adapted compileNodes\n          // for call to the link function.\n          // Note: This will already clone the nodes...\n          $linkNode = jqLite(\n            wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())\n          );\n        } else if (cloneConnectFn) {\n          // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart\n          // and sometimes changes the structure of the DOM.\n          $linkNode = JQLitePrototype.clone.call($compileNodes);\n        } else {\n          $linkNode = $compileNodes;\n        }\n\n        if (transcludeControllers) {\n          for (var controllerName in transcludeControllers) {\n            $linkNode.data('$' + controllerName + 'Controller', transcludeControllers[controllerName].instance);\n          }\n        }\n\n        compile.$$addScopeInfo($linkNode, scope);\n\n        if (cloneConnectFn) cloneConnectFn($linkNode, scope);\n        if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);\n\n        if (!cloneConnectFn) {\n          $compileNodes = compositeLinkFn = null;\n        }\n        return $linkNode;\n      };\n    }\n\n    function detectNamespaceForChildElements(parentElement) {\n      // TODO: Make this detect MathML as well...\n      var node = parentElement && parentElement[0];\n      if (!node) {\n        return 'html';\n      } else {\n        return nodeName_(node) !== 'foreignobject' && toString.call(node).match(/SVG/) ? 'svg' : 'html';\n      }\n    }\n\n    /**\n     * Compile function matches each node in nodeList against the directives. Once all directives\n     * for a particular node are collected their compile functions are executed. The compile\n     * functions return values - the linking functions - are combined into a composite linking\n     * function, which is the a linking function for the node.\n     *\n     * @param {NodeList} nodeList an array of nodes or NodeList to compile\n     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the\n     *        scope argument is auto-generated to the new child of the transcluded parent scope.\n     * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then\n     *        the rootElement must be set the jqLite collection of the compile root. This is\n     *        needed so that the jqLite collection items can be replaced with widgets.\n     * @param {number=} maxPriority Max directive priority.\n     * @returns {Function} A composite linking function of all of the matched directives or null.\n     */\n    function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,\n                            previousCompileContext) {\n      var linkFns = [],\n          // `nodeList` can be either an element's `.childNodes` (live NodeList)\n          // or a jqLite/jQuery collection or an array\n          notLiveList = isArray(nodeList) || (nodeList instanceof jqLite),\n          attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound;\n\n\n      for (var i = 0; i < nodeList.length; i++) {\n        attrs = new Attributes();\n\n        // Support: IE 11 only\n        // Workaround for #11781 and #14924\n        if (msie === 11) {\n          mergeConsecutiveTextNodes(nodeList, i, notLiveList);\n        }\n\n        // We must always refer to `nodeList[i]` hereafter,\n        // since the nodes can be replaced underneath us.\n        directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,\n                                        ignoreDirective);\n\n        nodeLinkFn = (directives.length)\n            ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement,\n                                      null, [], [], previousCompileContext)\n            : null;\n\n        if (nodeLinkFn && nodeLinkFn.scope) {\n          compile.$$addScopeClass(attrs.$$element);\n        }\n\n        childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||\n                      !(childNodes = nodeList[i].childNodes) ||\n                      !childNodes.length)\n            ? null\n            : compileNodes(childNodes,\n                 nodeLinkFn ? (\n                  (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement)\n                     && nodeLinkFn.transclude) : transcludeFn);\n\n        if (nodeLinkFn || childLinkFn) {\n          linkFns.push(i, nodeLinkFn, childLinkFn);\n          linkFnFound = true;\n          nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;\n        }\n\n        //use the previous context only for the first element in the virtual group\n        previousCompileContext = null;\n      }\n\n      // return a linking function if we have found anything, null otherwise\n      return linkFnFound ? compositeLinkFn : null;\n\n      function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {\n        var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;\n        var stableNodeList;\n\n\n        if (nodeLinkFnFound) {\n          // copy nodeList so that if a nodeLinkFn removes or adds an element at this DOM level our\n          // offsets don't get screwed up\n          var nodeListLength = nodeList.length;\n          stableNodeList = new Array(nodeListLength);\n\n          // create a sparse array by only copying the elements which have a linkFn\n          for (i = 0; i < linkFns.length; i += 3) {\n            idx = linkFns[i];\n            stableNodeList[idx] = nodeList[idx];\n          }\n        } else {\n          stableNodeList = nodeList;\n        }\n\n        for (i = 0, ii = linkFns.length; i < ii;) {\n          node = stableNodeList[linkFns[i++]];\n          nodeLinkFn = linkFns[i++];\n          childLinkFn = linkFns[i++];\n\n          if (nodeLinkFn) {\n            if (nodeLinkFn.scope) {\n              childScope = scope.$new();\n              compile.$$addScopeInfo(jqLite(node), childScope);\n            } else {\n              childScope = scope;\n            }\n\n            if (nodeLinkFn.transcludeOnThisElement) {\n              childBoundTranscludeFn = createBoundTranscludeFn(\n                  scope, nodeLinkFn.transclude, parentBoundTranscludeFn);\n\n            } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {\n              childBoundTranscludeFn = parentBoundTranscludeFn;\n\n            } else if (!parentBoundTranscludeFn && transcludeFn) {\n              childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);\n\n            } else {\n              childBoundTranscludeFn = null;\n            }\n\n            nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);\n\n          } else if (childLinkFn) {\n            childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);\n          }\n        }\n      }\n    }\n\n    function mergeConsecutiveTextNodes(nodeList, idx, notLiveList) {\n      var node = nodeList[idx];\n      var parent = node.parentNode;\n      var sibling;\n\n      if (node.nodeType !== NODE_TYPE_TEXT) {\n        return;\n      }\n\n      while (true) {\n        sibling = parent ? node.nextSibling : nodeList[idx + 1];\n        if (!sibling || sibling.nodeType !== NODE_TYPE_TEXT) {\n          break;\n        }\n\n        node.nodeValue = node.nodeValue + sibling.nodeValue;\n\n        if (sibling.parentNode) {\n          sibling.parentNode.removeChild(sibling);\n        }\n        if (notLiveList && sibling === nodeList[idx + 1]) {\n          nodeList.splice(idx + 1, 1);\n        }\n      }\n    }\n\n    function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {\n      function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {\n\n        if (!transcludedScope) {\n          transcludedScope = scope.$new(false, containingScope);\n          transcludedScope.$$transcluded = true;\n        }\n\n        return transcludeFn(transcludedScope, cloneFn, {\n          parentBoundTranscludeFn: previousBoundTranscludeFn,\n          transcludeControllers: controllers,\n          futureParentElement: futureParentElement\n        });\n      }\n\n      // We need  to attach the transclusion slots onto the `boundTranscludeFn`\n      // so that they are available inside the `controllersBoundTransclude` function\n      var boundSlots = boundTranscludeFn.$$slots = createMap();\n      for (var slotName in transcludeFn.$$slots) {\n        if (transcludeFn.$$slots[slotName]) {\n          boundSlots[slotName] = createBoundTranscludeFn(scope, transcludeFn.$$slots[slotName], previousBoundTranscludeFn);\n        } else {\n          boundSlots[slotName] = null;\n        }\n      }\n\n      return boundTranscludeFn;\n    }\n\n    /**\n     * Looks for directives on the given node and adds them to the directive collection which is\n     * sorted.\n     *\n     * @param node Node to search.\n     * @param directives An array to which the directives are added to. This array is sorted before\n     *        the function returns.\n     * @param attrs The shared attrs object which is used to populate the normalized attributes.\n     * @param {number=} maxPriority Max directive priority.\n     */\n    function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {\n      var nodeType = node.nodeType,\n          attrsMap = attrs.$attr,\n          match,\n          nodeName,\n          className;\n\n      switch (nodeType) {\n        case NODE_TYPE_ELEMENT: /* Element */\n\n          nodeName = nodeName_(node);\n\n          // use the node name: <directive>\n          addDirective(directives,\n              directiveNormalize(nodeName), 'E', maxPriority, ignoreDirective);\n\n          // iterate over the attributes\n          for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,\n                   j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {\n            var attrStartName = false;\n            var attrEndName = false;\n\n            attr = nAttrs[j];\n            name = attr.name;\n            value = attr.value;\n\n            // support ngAttr attribute binding\n            ngAttrName = directiveNormalize(name);\n            isNgAttr = NG_ATTR_BINDING.test(ngAttrName);\n            if (isNgAttr) {\n              name = name.replace(PREFIX_REGEXP, '')\n                .substr(8).replace(/_(.)/g, function(match, letter) {\n                  return letter.toUpperCase();\n                });\n            }\n\n            var multiElementMatch = ngAttrName.match(MULTI_ELEMENT_DIR_RE);\n            if (multiElementMatch && directiveIsMultiElement(multiElementMatch[1])) {\n              attrStartName = name;\n              attrEndName = name.substr(0, name.length - 5) + 'end';\n              name = name.substr(0, name.length - 6);\n            }\n\n            nName = directiveNormalize(name.toLowerCase());\n            attrsMap[nName] = name;\n            if (isNgAttr || !attrs.hasOwnProperty(nName)) {\n                attrs[nName] = value;\n                if (getBooleanAttrName(node, nName)) {\n                  attrs[nName] = true; // presence means true\n                }\n            }\n            addAttrInterpolateDirective(node, directives, value, nName, isNgAttr);\n            addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,\n                          attrEndName);\n          }\n\n          if (nodeName === 'input' && node.getAttribute('type') === 'hidden') {\n            // Hidden input elements can have strange behaviour when navigating back to the page\n            // This tells the browser not to try to cache and reinstate previous values\n            node.setAttribute('autocomplete', 'off');\n          }\n\n          // use class as directive\n          if (!cssClassDirectivesEnabled) break;\n          className = node.className;\n          if (isObject(className)) {\n              // Maybe SVGAnimatedString\n              className = className.animVal;\n          }\n          if (isString(className) && className !== '') {\n            while ((match = CLASS_DIRECTIVE_REGEXP.exec(className))) {\n              nName = directiveNormalize(match[2]);\n              if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) {\n                attrs[nName] = trim(match[3]);\n              }\n              className = className.substr(match.index + match[0].length);\n            }\n          }\n          break;\n        case NODE_TYPE_TEXT: /* Text Node */\n          addTextInterpolateDirective(directives, node.nodeValue);\n          break;\n        case NODE_TYPE_COMMENT: /* Comment */\n          if (!commentDirectivesEnabled) break;\n          collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective);\n          break;\n      }\n\n      directives.sort(byPriority);\n      return directives;\n    }\n\n    function collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective) {\n      // function created because of performance, try/catch disables\n      // the optimization of the whole function #14848\n      try {\n        var match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);\n        if (match) {\n          var nName = directiveNormalize(match[1]);\n          if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) {\n            attrs[nName] = trim(match[2]);\n          }\n        }\n      } catch (e) {\n        // turns out that under some circumstances IE9 throws errors when one attempts to read\n        // comment's node value.\n        // Just ignore it and continue. (Can't seem to reproduce in test case.)\n      }\n    }\n\n    /**\n     * Given a node with a directive-start it collects all of the siblings until it finds\n     * directive-end.\n     * @param node\n     * @param attrStart\n     * @param attrEnd\n     * @returns {*}\n     */\n    function groupScan(node, attrStart, attrEnd) {\n      var nodes = [];\n      var depth = 0;\n      if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {\n        do {\n          if (!node) {\n            throw $compileMinErr('uterdir',\n                      'Unterminated attribute, found \\'{0}\\' but no matching \\'{1}\\' found.',\n                      attrStart, attrEnd);\n          }\n          if (node.nodeType === NODE_TYPE_ELEMENT) {\n            if (node.hasAttribute(attrStart)) depth++;\n            if (node.hasAttribute(attrEnd)) depth--;\n          }\n          nodes.push(node);\n          node = node.nextSibling;\n        } while (depth > 0);\n      } else {\n        nodes.push(node);\n      }\n\n      return jqLite(nodes);\n    }\n\n    /**\n     * Wrapper for linking function which converts normal linking function into a grouped\n     * linking function.\n     * @param linkFn\n     * @param attrStart\n     * @param attrEnd\n     * @returns {Function}\n     */\n    function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {\n      return function groupedElementsLink(scope, element, attrs, controllers, transcludeFn) {\n        element = groupScan(element[0], attrStart, attrEnd);\n        return linkFn(scope, element, attrs, controllers, transcludeFn);\n      };\n    }\n\n    /**\n     * A function generator that is used to support both eager and lazy compilation\n     * linking function.\n     * @param eager\n     * @param $compileNodes\n     * @param transcludeFn\n     * @param maxPriority\n     * @param ignoreDirective\n     * @param previousCompileContext\n     * @returns {Function}\n     */\n    function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {\n      var compiled;\n\n      if (eager) {\n        return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);\n      }\n      return /** @this */ function lazyCompilation() {\n        if (!compiled) {\n          compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);\n\n          // Null out all of these references in order to make them eligible for garbage collection\n          // since this is a potentially long lived closure\n          $compileNodes = transcludeFn = previousCompileContext = null;\n        }\n        return compiled.apply(this, arguments);\n      };\n    }\n\n    /**\n     * Once the directives have been collected, their compile functions are executed. This method\n     * is responsible for inlining directive templates as well as terminating the application\n     * of the directives if the terminal directive has been reached.\n     *\n     * @param {Array} directives Array of collected directives to execute their compile function.\n     *        this needs to be pre-sorted by priority order.\n     * @param {Node} compileNode The raw DOM node to apply the compile functions to\n     * @param {Object} templateAttrs The shared attribute function\n     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the\n     *                                                  scope argument is auto-generated to the new\n     *                                                  child of the transcluded parent scope.\n     * @param {JQLite} jqCollection If we are working on the root of the compile tree then this\n     *                              argument has the root jqLite array so that we can replace nodes\n     *                              on it.\n     * @param {Object=} originalReplaceDirective An optional directive that will be ignored when\n     *                                           compiling the transclusion.\n     * @param {Array.<Function>} preLinkFns\n     * @param {Array.<Function>} postLinkFns\n     * @param {Object} previousCompileContext Context used for previous compilation of the current\n     *                                        node\n     * @returns {Function} linkFn\n     */\n    function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,\n                                   jqCollection, originalReplaceDirective, preLinkFns, postLinkFns,\n                                   previousCompileContext) {\n      previousCompileContext = previousCompileContext || {};\n\n      var terminalPriority = -Number.MAX_VALUE,\n          newScopeDirective = previousCompileContext.newScopeDirective,\n          controllerDirectives = previousCompileContext.controllerDirectives,\n          newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,\n          templateDirective = previousCompileContext.templateDirective,\n          nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,\n          hasTranscludeDirective = false,\n          hasTemplate = false,\n          hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,\n          $compileNode = templateAttrs.$$element = jqLite(compileNode),\n          directive,\n          directiveName,\n          $template,\n          replaceDirective = originalReplaceDirective,\n          childTranscludeFn = transcludeFn,\n          linkFn,\n          didScanForMultipleTransclusion = false,\n          mightHaveMultipleTransclusionError = false,\n          directiveValue;\n\n      // executes all directives on the current element\n      for (var i = 0, ii = directives.length; i < ii; i++) {\n        directive = directives[i];\n        var attrStart = directive.$$start;\n        var attrEnd = directive.$$end;\n\n        // collect multiblock sections\n        if (attrStart) {\n          $compileNode = groupScan(compileNode, attrStart, attrEnd);\n        }\n        $template = undefined;\n\n        if (terminalPriority > directive.priority) {\n          break; // prevent further processing of directives\n        }\n\n        directiveValue = directive.scope;\n\n        if (directiveValue) {\n\n          // skip the check for directives with async templates, we'll check the derived sync\n          // directive when the template arrives\n          if (!directive.templateUrl) {\n            if (isObject(directiveValue)) {\n              // This directive is trying to add an isolated scope.\n              // Check that there is no scope of any kind already\n              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective,\n                                directive, $compileNode);\n              newIsolateScopeDirective = directive;\n            } else {\n              // This directive is trying to add a child scope.\n              // Check that there is no isolated scope already\n              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive,\n                                $compileNode);\n            }\n          }\n\n          newScopeDirective = newScopeDirective || directive;\n        }\n\n        directiveName = directive.name;\n\n        // If we encounter a condition that can result in transclusion on the directive,\n        // then scan ahead in the remaining directives for others that may cause a multiple\n        // transclusion error to be thrown during the compilation process.  If a matching directive\n        // is found, then we know that when we encounter a transcluded directive, we need to eagerly\n        // compile the `transclude` function rather than doing it lazily in order to throw\n        // exceptions at the correct time\n        if (!didScanForMultipleTransclusion && ((directive.replace && (directive.templateUrl || directive.template))\n            || (directive.transclude && !directive.$$tlb))) {\n                var candidateDirective;\n\n                for (var scanningIndex = i + 1; (candidateDirective = directives[scanningIndex++]);) {\n                    if ((candidateDirective.transclude && !candidateDirective.$$tlb)\n                        || (candidateDirective.replace && (candidateDirective.templateUrl || candidateDirective.template))) {\n                        mightHaveMultipleTransclusionError = true;\n                        break;\n                    }\n                }\n\n                didScanForMultipleTransclusion = true;\n        }\n\n        if (!directive.templateUrl && directive.controller) {\n          controllerDirectives = controllerDirectives || createMap();\n          assertNoDuplicate('\\'' + directiveName + '\\' controller',\n              controllerDirectives[directiveName], directive, $compileNode);\n          controllerDirectives[directiveName] = directive;\n        }\n\n        directiveValue = directive.transclude;\n\n        if (directiveValue) {\n          hasTranscludeDirective = true;\n\n          // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.\n          // This option should only be used by directives that know how to safely handle element transclusion,\n          // where the transcluded nodes are added or replaced after linking.\n          if (!directive.$$tlb) {\n            assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);\n            nonTlbTranscludeDirective = directive;\n          }\n\n          if (directiveValue === 'element') {\n            hasElementTranscludeDirective = true;\n            terminalPriority = directive.priority;\n            $template = $compileNode;\n            $compileNode = templateAttrs.$$element =\n                jqLite(compile.$$createComment(directiveName, templateAttrs[directiveName]));\n            compileNode = $compileNode[0];\n            replaceWith(jqCollection, sliceArgs($template), compileNode);\n\n            // Support: Chrome < 50\n            // https://github.com/angular/angular.js/issues/14041\n\n            // In the versions of V8 prior to Chrome 50, the document fragment that is created\n            // in the `replaceWith` function is improperly garbage collected despite still\n            // being referenced by the `parentNode` property of all of the child nodes.  By adding\n            // a reference to the fragment via a different property, we can avoid that incorrect\n            // behavior.\n            // TODO: remove this line after Chrome 50 has been released\n            $template[0].$$parentNode = $template[0].parentNode;\n\n            childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority,\n                                        replaceDirective && replaceDirective.name, {\n                                          // Don't pass in:\n                                          // - controllerDirectives - otherwise we'll create duplicates controllers\n                                          // - newIsolateScopeDirective or templateDirective - combining templates with\n                                          //   element transclusion doesn't make sense.\n                                          //\n                                          // We need only nonTlbTranscludeDirective so that we prevent putting transclusion\n                                          // on the same element more than once.\n                                          nonTlbTranscludeDirective: nonTlbTranscludeDirective\n                                        });\n          } else {\n\n            var slots = createMap();\n\n            if (!isObject(directiveValue)) {\n              $template = jqLite(jqLiteClone(compileNode)).contents();\n            } else {\n\n              // We have transclusion slots,\n              // collect them up, compile them and store their transclusion functions\n              $template = [];\n\n              var slotMap = createMap();\n              var filledSlots = createMap();\n\n              // Parse the element selectors\n              forEach(directiveValue, function(elementSelector, slotName) {\n                // If an element selector starts with a ? then it is optional\n                var optional = (elementSelector.charAt(0) === '?');\n                elementSelector = optional ? elementSelector.substring(1) : elementSelector;\n\n                slotMap[elementSelector] = slotName;\n\n                // We explicitly assign `null` since this implies that a slot was defined but not filled.\n                // Later when calling boundTransclusion functions with a slot name we only error if the\n                // slot is `undefined`\n                slots[slotName] = null;\n\n                // filledSlots contains `true` for all slots that are either optional or have been\n                // filled. This is used to check that we have not missed any required slots\n                filledSlots[slotName] = optional;\n              });\n\n              // Add the matching elements into their slot\n              forEach($compileNode.contents(), function(node) {\n                var slotName = slotMap[directiveNormalize(nodeName_(node))];\n                if (slotName) {\n                  filledSlots[slotName] = true;\n                  slots[slotName] = slots[slotName] || [];\n                  slots[slotName].push(node);\n                } else {\n                  $template.push(node);\n                }\n              });\n\n              // Check for required slots that were not filled\n              forEach(filledSlots, function(filled, slotName) {\n                if (!filled) {\n                  throw $compileMinErr('reqslot', 'Required transclusion slot `{0}` was not filled.', slotName);\n                }\n              });\n\n              for (var slotName in slots) {\n                if (slots[slotName]) {\n                  // Only define a transclusion function if the slot was filled\n                  slots[slotName] = compilationGenerator(mightHaveMultipleTransclusionError, slots[slotName], transcludeFn);\n                }\n              }\n            }\n\n            $compileNode.empty(); // clear contents\n            childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, undefined,\n                undefined, { needsNewScope: directive.$$isolateScope || directive.$$newScope});\n            childTranscludeFn.$$slots = slots;\n          }\n        }\n\n        if (directive.template) {\n          hasTemplate = true;\n          assertNoDuplicate('template', templateDirective, directive, $compileNode);\n          templateDirective = directive;\n\n          directiveValue = (isFunction(directive.template))\n              ? directive.template($compileNode, templateAttrs)\n              : directive.template;\n\n          directiveValue = denormalizeTemplate(directiveValue);\n\n          if (directive.replace) {\n            replaceDirective = directive;\n            if (jqLiteIsTextNode(directiveValue)) {\n              $template = [];\n            } else {\n              $template = removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue)));\n            }\n            compileNode = $template[0];\n\n            if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {\n              throw $compileMinErr('tplrt',\n                  'Template for directive \\'{0}\\' must have exactly one root element. {1}',\n                  directiveName, '');\n            }\n\n            replaceWith(jqCollection, $compileNode, compileNode);\n\n            var newTemplateAttrs = {$attr: {}};\n\n            // combine directives from the original node and from the template:\n            // - take the array of directives for this element\n            // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)\n            // - collect directives from the template and sort them by priority\n            // - combine directives as: processed + template + unprocessed\n            var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs);\n            var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));\n\n            if (newIsolateScopeDirective || newScopeDirective) {\n              // The original directive caused the current element to be replaced but this element\n              // also needs to have a new scope, so we need to tell the template directives\n              // that they would need to get their scope from further up, if they require transclusion\n              markDirectiveScope(templateDirectives, newIsolateScopeDirective, newScopeDirective);\n            }\n            directives = directives.concat(templateDirectives).concat(unprocessedDirectives);\n            mergeTemplateAttributes(templateAttrs, newTemplateAttrs);\n\n            ii = directives.length;\n          } else {\n            $compileNode.html(directiveValue);\n          }\n        }\n\n        if (directive.templateUrl) {\n          hasTemplate = true;\n          assertNoDuplicate('template', templateDirective, directive, $compileNode);\n          templateDirective = directive;\n\n          if (directive.replace) {\n            replaceDirective = directive;\n          }\n\n          // eslint-disable-next-line no-func-assign\n          nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,\n              templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {\n                controllerDirectives: controllerDirectives,\n                newScopeDirective: (newScopeDirective !== directive) && newScopeDirective,\n                newIsolateScopeDirective: newIsolateScopeDirective,\n                templateDirective: templateDirective,\n                nonTlbTranscludeDirective: nonTlbTranscludeDirective\n              });\n          ii = directives.length;\n        } else if (directive.compile) {\n          try {\n            linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);\n            var context = directive.$$originalDirective || directive;\n            if (isFunction(linkFn)) {\n              addLinkFns(null, bind(context, linkFn), attrStart, attrEnd);\n            } else if (linkFn) {\n              addLinkFns(bind(context, linkFn.pre), bind(context, linkFn.post), attrStart, attrEnd);\n            }\n          } catch (e) {\n            $exceptionHandler(e, startingTag($compileNode));\n          }\n        }\n\n        if (directive.terminal) {\n          nodeLinkFn.terminal = true;\n          terminalPriority = Math.max(terminalPriority, directive.priority);\n        }\n\n      }\n\n      nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;\n      nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;\n      nodeLinkFn.templateOnThisElement = hasTemplate;\n      nodeLinkFn.transclude = childTranscludeFn;\n\n      previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;\n\n      // might be normal or delayed nodeLinkFn depending on if templateUrl is present\n      return nodeLinkFn;\n\n      ////////////////////\n\n      function addLinkFns(pre, post, attrStart, attrEnd) {\n        if (pre) {\n          if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);\n          pre.require = directive.require;\n          pre.directiveName = directiveName;\n          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {\n            pre = cloneAndAnnotateFn(pre, {isolateScope: true});\n          }\n          preLinkFns.push(pre);\n        }\n        if (post) {\n          if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);\n          post.require = directive.require;\n          post.directiveName = directiveName;\n          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {\n            post = cloneAndAnnotateFn(post, {isolateScope: true});\n          }\n          postLinkFns.push(post);\n        }\n      }\n\n      function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {\n        var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,\n            attrs, scopeBindingInfo;\n\n        if (compileNode === linkNode) {\n          attrs = templateAttrs;\n          $element = templateAttrs.$$element;\n        } else {\n          $element = jqLite(linkNode);\n          attrs = new Attributes($element, templateAttrs);\n        }\n\n        controllerScope = scope;\n        if (newIsolateScopeDirective) {\n          isolateScope = scope.$new(true);\n        } else if (newScopeDirective) {\n          controllerScope = scope.$parent;\n        }\n\n        if (boundTranscludeFn) {\n          // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`\n          // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`\n          transcludeFn = controllersBoundTransclude;\n          transcludeFn.$$boundTransclude = boundTranscludeFn;\n          // expose the slots on the `$transclude` function\n          transcludeFn.isSlotFilled = function(slotName) {\n            return !!boundTranscludeFn.$$slots[slotName];\n          };\n        }\n\n        if (controllerDirectives) {\n          elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective);\n        }\n\n        if (newIsolateScopeDirective) {\n          // Initialize isolate scope bindings for new isolate scope directive.\n          compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||\n              templateDirective === newIsolateScopeDirective.$$originalDirective)));\n          compile.$$addScopeClass($element, true);\n          isolateScope.$$isolateBindings =\n              newIsolateScopeDirective.$$isolateBindings;\n          scopeBindingInfo = initializeDirectiveBindings(scope, attrs, isolateScope,\n                                        isolateScope.$$isolateBindings,\n                                        newIsolateScopeDirective);\n          if (scopeBindingInfo.removeWatches) {\n            isolateScope.$on('$destroy', scopeBindingInfo.removeWatches);\n          }\n        }\n\n        // Initialize bindToController bindings\n        for (var name in elementControllers) {\n          var controllerDirective = controllerDirectives[name];\n          var controller = elementControllers[name];\n          var bindings = controllerDirective.$$bindings.bindToController;\n\n          if (preAssignBindingsEnabled) {\n            if (bindings) {\n              controller.bindingInfo =\n                initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);\n            } else {\n              controller.bindingInfo = {};\n            }\n\n            var controllerResult = controller();\n            if (controllerResult !== controller.instance) {\n              // If the controller constructor has a return value, overwrite the instance\n              // from setupControllers\n              controller.instance = controllerResult;\n              $element.data('$' + controllerDirective.name + 'Controller', controllerResult);\n              if (controller.bindingInfo.removeWatches) {\n                controller.bindingInfo.removeWatches();\n              }\n              controller.bindingInfo =\n                initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);\n            }\n          } else {\n            controller.instance = controller();\n            $element.data('$' + controllerDirective.name + 'Controller', controller.instance);\n            controller.bindingInfo =\n              initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);\n          }\n        }\n\n        // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy\n        forEach(controllerDirectives, function(controllerDirective, name) {\n          var require = controllerDirective.require;\n          if (controllerDirective.bindToController && !isArray(require) && isObject(require)) {\n            extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers));\n          }\n        });\n\n        // Handle the init and destroy lifecycle hooks on all controllers that have them\n        forEach(elementControllers, function(controller) {\n          var controllerInstance = controller.instance;\n          if (isFunction(controllerInstance.$onChanges)) {\n            try {\n              controllerInstance.$onChanges(controller.bindingInfo.initialChanges);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          }\n          if (isFunction(controllerInstance.$onInit)) {\n            try {\n              controllerInstance.$onInit();\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          }\n          if (isFunction(controllerInstance.$doCheck)) {\n            controllerScope.$watch(function() { controllerInstance.$doCheck(); });\n            controllerInstance.$doCheck();\n          }\n          if (isFunction(controllerInstance.$onDestroy)) {\n            controllerScope.$on('$destroy', function callOnDestroyHook() {\n              controllerInstance.$onDestroy();\n            });\n          }\n        });\n\n        // PRELINKING\n        for (i = 0, ii = preLinkFns.length; i < ii; i++) {\n          linkFn = preLinkFns[i];\n          invokeLinkFn(linkFn,\n              linkFn.isolateScope ? isolateScope : scope,\n              $element,\n              attrs,\n              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),\n              transcludeFn\n          );\n        }\n\n        // RECURSION\n        // We only pass the isolate scope, if the isolate directive has a template,\n        // otherwise the child elements do not belong to the isolate directive.\n        var scopeToChild = scope;\n        if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {\n          scopeToChild = isolateScope;\n        }\n        if (childLinkFn) {\n          childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);\n        }\n\n        // POSTLINKING\n        for (i = postLinkFns.length - 1; i >= 0; i--) {\n          linkFn = postLinkFns[i];\n          invokeLinkFn(linkFn,\n              linkFn.isolateScope ? isolateScope : scope,\n              $element,\n              attrs,\n              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),\n              transcludeFn\n          );\n        }\n\n        // Trigger $postLink lifecycle hooks\n        forEach(elementControllers, function(controller) {\n          var controllerInstance = controller.instance;\n          if (isFunction(controllerInstance.$postLink)) {\n            controllerInstance.$postLink();\n          }\n        });\n\n        // This is the function that is injected as `$transclude`.\n        // Note: all arguments are optional!\n        function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {\n          var transcludeControllers;\n          // No scope passed in:\n          if (!isScope(scope)) {\n            slotName = futureParentElement;\n            futureParentElement = cloneAttachFn;\n            cloneAttachFn = scope;\n            scope = undefined;\n          }\n\n          if (hasElementTranscludeDirective) {\n            transcludeControllers = elementControllers;\n          }\n          if (!futureParentElement) {\n            futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;\n          }\n          if (slotName) {\n            // slotTranscludeFn can be one of three things:\n            //  * a transclude function - a filled slot\n            //  * `null` - an optional slot that was not filled\n            //  * `undefined` - a slot that was not declared (i.e. invalid)\n            var slotTranscludeFn = boundTranscludeFn.$$slots[slotName];\n            if (slotTranscludeFn) {\n              return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);\n            } else if (isUndefined(slotTranscludeFn)) {\n              throw $compileMinErr('noslot',\n               'No parent directive that requires a transclusion with slot name \"{0}\". ' +\n               'Element: {1}',\n               slotName, startingTag($element));\n            }\n          } else {\n            return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);\n          }\n        }\n      }\n    }\n\n    function getControllers(directiveName, require, $element, elementControllers) {\n      var value;\n\n      if (isString(require)) {\n        var match = require.match(REQUIRE_PREFIX_REGEXP);\n        var name = require.substring(match[0].length);\n        var inheritType = match[1] || match[3];\n        var optional = match[2] === '?';\n\n        //If only parents then start at the parent element\n        if (inheritType === '^^') {\n          $element = $element.parent();\n        //Otherwise attempt getting the controller from elementControllers in case\n        //the element is transcluded (and has no data) and to avoid .data if possible\n        } else {\n          value = elementControllers && elementControllers[name];\n          value = value && value.instance;\n        }\n\n        if (!value) {\n          var dataName = '$' + name + 'Controller';\n          value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);\n        }\n\n        if (!value && !optional) {\n          throw $compileMinErr('ctreq',\n              'Controller \\'{0}\\', required by directive \\'{1}\\', can\\'t be found!',\n              name, directiveName);\n        }\n      } else if (isArray(require)) {\n        value = [];\n        for (var i = 0, ii = require.length; i < ii; i++) {\n          value[i] = getControllers(directiveName, require[i], $element, elementControllers);\n        }\n      } else if (isObject(require)) {\n        value = {};\n        forEach(require, function(controller, property) {\n          value[property] = getControllers(directiveName, controller, $element, elementControllers);\n        });\n      }\n\n      return value || null;\n    }\n\n    function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective) {\n      var elementControllers = createMap();\n      for (var controllerKey in controllerDirectives) {\n        var directive = controllerDirectives[controllerKey];\n        var locals = {\n          $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,\n          $element: $element,\n          $attrs: attrs,\n          $transclude: transcludeFn\n        };\n\n        var controller = directive.controller;\n        if (controller === '@') {\n          controller = attrs[directive.name];\n        }\n\n        var controllerInstance = $controller(controller, locals, true, directive.controllerAs);\n\n        // For directives with element transclusion the element is a comment.\n        // In this case .data will not attach any data.\n        // Instead, we save the controllers for the element in a local hash and attach to .data\n        // later, once we have the actual element.\n        elementControllers[directive.name] = controllerInstance;\n        $element.data('$' + directive.name + 'Controller', controllerInstance.instance);\n      }\n      return elementControllers;\n    }\n\n    // Depending upon the context in which a directive finds itself it might need to have a new isolated\n    // or child scope created. For instance:\n    // * if the directive has been pulled into a template because another directive with a higher priority\n    // asked for element transclusion\n    // * if the directive itself asks for transclusion but it is at the root of a template and the original\n    // element was replaced. See https://github.com/angular/angular.js/issues/12936\n    function markDirectiveScope(directives, isolateScope, newScope) {\n      for (var j = 0, jj = directives.length; j < jj; j++) {\n        directives[j] = inherit(directives[j], {$$isolateScope: isolateScope, $$newScope: newScope});\n      }\n    }\n\n    /**\n     * looks up the directive and decorates it with exception handling and proper parameters. We\n     * call this the boundDirective.\n     *\n     * @param {string} name name of the directive to look up.\n     * @param {string} location The directive must be found in specific format.\n     *   String containing any of theses characters:\n     *\n     *   * `E`: element name\n     *   * `A': attribute\n     *   * `C`: class\n     *   * `M`: comment\n     * @returns {boolean} true if directive was added.\n     */\n    function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName,\n                          endAttrName) {\n      if (name === ignoreDirective) return null;\n      var match = null;\n      if (hasDirectives.hasOwnProperty(name)) {\n        for (var directive, directives = $injector.get(name + Suffix),\n            i = 0, ii = directives.length; i < ii; i++) {\n          directive = directives[i];\n          if ((isUndefined(maxPriority) || maxPriority > directive.priority) &&\n               directive.restrict.indexOf(location) !== -1) {\n            if (startAttrName) {\n              directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});\n            }\n            if (!directive.$$bindings) {\n              var bindings = directive.$$bindings =\n                  parseDirectiveBindings(directive, directive.name);\n              if (isObject(bindings.isolateScope)) {\n                directive.$$isolateBindings = bindings.isolateScope;\n              }\n            }\n            tDirectives.push(directive);\n            match = directive;\n          }\n        }\n      }\n      return match;\n    }\n\n\n    /**\n     * looks up the directive and returns true if it is a multi-element directive,\n     * and therefore requires DOM nodes between -start and -end markers to be grouped\n     * together.\n     *\n     * @param {string} name name of the directive to look up.\n     * @returns true if directive was registered as multi-element.\n     */\n    function directiveIsMultiElement(name) {\n      if (hasDirectives.hasOwnProperty(name)) {\n        for (var directive, directives = $injector.get(name + Suffix),\n            i = 0, ii = directives.length; i < ii; i++) {\n          directive = directives[i];\n          if (directive.multiElement) {\n            return true;\n          }\n        }\n      }\n      return false;\n    }\n\n    /**\n     * When the element is replaced with HTML template then the new attributes\n     * on the template need to be merged with the existing attributes in the DOM.\n     * The desired effect is to have both of the attributes present.\n     *\n     * @param {object} dst destination attributes (original DOM)\n     * @param {object} src source attributes (from the directive template)\n     */\n    function mergeTemplateAttributes(dst, src) {\n      var srcAttr = src.$attr,\n          dstAttr = dst.$attr;\n\n      // reapply the old attributes to the new element\n      forEach(dst, function(value, key) {\n        if (key.charAt(0) !== '$') {\n          if (src[key] && src[key] !== value) {\n            if (value.length) {\n              value += (key === 'style' ? ';' : ' ') + src[key];\n            } else {\n              value = src[key];\n            }\n          }\n          dst.$set(key, value, true, srcAttr[key]);\n        }\n      });\n\n      // copy the new attributes on the old attrs object\n      forEach(src, function(value, key) {\n        // Check if we already set this attribute in the loop above.\n        // `dst` will never contain hasOwnProperty as DOM parser won't let it.\n        // You will get an \"InvalidCharacterError: DOM Exception 5\" error if you\n        // have an attribute like \"has-own-property\" or \"data-has-own-property\", etc.\n        if (!dst.hasOwnProperty(key) && key.charAt(0) !== '$') {\n          dst[key] = value;\n\n          if (key !== 'class' && key !== 'style') {\n            dstAttr[key] = srcAttr[key];\n          }\n        }\n      });\n    }\n\n\n    function compileTemplateUrl(directives, $compileNode, tAttrs,\n        $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {\n      var linkQueue = [],\n          afterTemplateNodeLinkFn,\n          afterTemplateChildLinkFn,\n          beforeTemplateCompileNode = $compileNode[0],\n          origAsyncDirective = directives.shift(),\n          derivedSyncDirective = inherit(origAsyncDirective, {\n            templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective\n          }),\n          templateUrl = (isFunction(origAsyncDirective.templateUrl))\n              ? origAsyncDirective.templateUrl($compileNode, tAttrs)\n              : origAsyncDirective.templateUrl,\n          templateNamespace = origAsyncDirective.templateNamespace;\n\n      $compileNode.empty();\n\n      $templateRequest(templateUrl)\n        .then(function(content) {\n          var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;\n\n          content = denormalizeTemplate(content);\n\n          if (origAsyncDirective.replace) {\n            if (jqLiteIsTextNode(content)) {\n              $template = [];\n            } else {\n              $template = removeComments(wrapTemplate(templateNamespace, trim(content)));\n            }\n            compileNode = $template[0];\n\n            if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {\n              throw $compileMinErr('tplrt',\n                  'Template for directive \\'{0}\\' must have exactly one root element. {1}',\n                  origAsyncDirective.name, templateUrl);\n            }\n\n            tempTemplateAttrs = {$attr: {}};\n            replaceWith($rootElement, $compileNode, compileNode);\n            var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs);\n\n            if (isObject(origAsyncDirective.scope)) {\n              // the original directive that caused the template to be loaded async required\n              // an isolate scope\n              markDirectiveScope(templateDirectives, true);\n            }\n            directives = templateDirectives.concat(directives);\n            mergeTemplateAttributes(tAttrs, tempTemplateAttrs);\n          } else {\n            compileNode = beforeTemplateCompileNode;\n            $compileNode.html(content);\n          }\n\n          directives.unshift(derivedSyncDirective);\n\n          afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs,\n              childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns,\n              previousCompileContext);\n          forEach($rootElement, function(node, i) {\n            if (node === compileNode) {\n              $rootElement[i] = $compileNode[0];\n            }\n          });\n          afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);\n\n          while (linkQueue.length) {\n            var scope = linkQueue.shift(),\n                beforeTemplateLinkNode = linkQueue.shift(),\n                linkRootElement = linkQueue.shift(),\n                boundTranscludeFn = linkQueue.shift(),\n                linkNode = $compileNode[0];\n\n            if (scope.$$destroyed) continue;\n\n            if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {\n              var oldClasses = beforeTemplateLinkNode.className;\n\n              if (!(previousCompileContext.hasElementTranscludeDirective &&\n                  origAsyncDirective.replace)) {\n                // it was cloned therefore we have to clone as well.\n                linkNode = jqLiteClone(compileNode);\n              }\n              replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);\n\n              // Copy in CSS classes from original node\n              safeAddClass(jqLite(linkNode), oldClasses);\n            }\n            if (afterTemplateNodeLinkFn.transcludeOnThisElement) {\n              childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);\n            } else {\n              childBoundTranscludeFn = boundTranscludeFn;\n            }\n            afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,\n              childBoundTranscludeFn);\n          }\n          linkQueue = null;\n        }).catch(function(error) {\n          if (error instanceof Error) {\n            $exceptionHandler(error);\n          }\n        });\n\n      return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {\n        var childBoundTranscludeFn = boundTranscludeFn;\n        if (scope.$$destroyed) return;\n        if (linkQueue) {\n          linkQueue.push(scope,\n                         node,\n                         rootElement,\n                         childBoundTranscludeFn);\n        } else {\n          if (afterTemplateNodeLinkFn.transcludeOnThisElement) {\n            childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);\n          }\n          afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn);\n        }\n      };\n    }\n\n\n    /**\n     * Sorting function for bound directives.\n     */\n    function byPriority(a, b) {\n      var diff = b.priority - a.priority;\n      if (diff !== 0) return diff;\n      if (a.name !== b.name) return (a.name < b.name) ? -1 : 1;\n      return a.index - b.index;\n    }\n\n    function assertNoDuplicate(what, previousDirective, directive, element) {\n\n      function wrapModuleNameIfDefined(moduleName) {\n        return moduleName ?\n          (' (module: ' + moduleName + ')') :\n          '';\n      }\n\n      if (previousDirective) {\n        throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}',\n            previousDirective.name, wrapModuleNameIfDefined(previousDirective.$$moduleName),\n            directive.name, wrapModuleNameIfDefined(directive.$$moduleName), what, startingTag(element));\n      }\n    }\n\n\n    function addTextInterpolateDirective(directives, text) {\n      var interpolateFn = $interpolate(text, true);\n      if (interpolateFn) {\n        directives.push({\n          priority: 0,\n          compile: function textInterpolateCompileFn(templateNode) {\n            var templateNodeParent = templateNode.parent(),\n                hasCompileParent = !!templateNodeParent.length;\n\n            // When transcluding a template that has bindings in the root\n            // we don't have a parent and thus need to add the class during linking fn.\n            if (hasCompileParent) compile.$$addBindingClass(templateNodeParent);\n\n            return function textInterpolateLinkFn(scope, node) {\n              var parent = node.parent();\n              if (!hasCompileParent) compile.$$addBindingClass(parent);\n              compile.$$addBindingInfo(parent, interpolateFn.expressions);\n              scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {\n                node[0].nodeValue = value;\n              });\n            };\n          }\n        });\n      }\n    }\n\n\n    function wrapTemplate(type, template) {\n      type = lowercase(type || 'html');\n      switch (type) {\n      case 'svg':\n      case 'math':\n        var wrapper = window.document.createElement('div');\n        wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';\n        return wrapper.childNodes[0].childNodes;\n      default:\n        return template;\n      }\n    }\n\n\n    function getTrustedContext(node, attrNormalizedName) {\n      if (attrNormalizedName === 'srcdoc') {\n        return $sce.HTML;\n      }\n      var tag = nodeName_(node);\n      // All tags with src attributes require a RESOURCE_URL value, except for\n      // img and various html5 media tags.\n      if (attrNormalizedName === 'src' || attrNormalizedName === 'ngSrc') {\n        if (['img', 'video', 'audio', 'source', 'track'].indexOf(tag) === -1) {\n          return $sce.RESOURCE_URL;\n        }\n      // maction[xlink:href] can source SVG.  It's not limited to <maction>.\n      } else if (attrNormalizedName === 'xlinkHref' ||\n          (tag === 'form' && attrNormalizedName === 'action') ||\n          // links can be stylesheets or imports, which can run script in the current origin\n          (tag === 'link' && attrNormalizedName === 'href')\n      ) {\n        return $sce.RESOURCE_URL;\n      }\n    }\n\n\n    function addAttrInterpolateDirective(node, directives, value, name, isNgAttr) {\n      var trustedContext = getTrustedContext(node, name);\n      var mustHaveExpression = !isNgAttr;\n      var allOrNothing = ALL_OR_NOTHING_ATTRS[name] || isNgAttr;\n\n      var interpolateFn = $interpolate(value, mustHaveExpression, trustedContext, allOrNothing);\n\n      // no interpolation found -> ignore\n      if (!interpolateFn) return;\n\n      if (name === 'multiple' && nodeName_(node) === 'select') {\n        throw $compileMinErr('selmulti',\n            'Binding to the \\'multiple\\' attribute is not supported. Element: {0}',\n            startingTag(node));\n      }\n\n      if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {\n        throw $compileMinErr('nodomevents',\n            'Interpolations for HTML DOM event attributes are disallowed.  Please use the ' +\n                'ng- versions (such as ng-click instead of onclick) instead.');\n      }\n\n      directives.push({\n        priority: 100,\n        compile: function() {\n            return {\n              pre: function attrInterpolatePreLinkFn(scope, element, attr) {\n                var $$observers = (attr.$$observers || (attr.$$observers = createMap()));\n\n                // If the attribute has changed since last $interpolate()ed\n                var newValue = attr[name];\n                if (newValue !== value) {\n                  // we need to interpolate again since the attribute value has been updated\n                  // (e.g. by another directive's compile function)\n                  // ensure unset/empty values make interpolateFn falsy\n                  interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing);\n                  value = newValue;\n                }\n\n                // if attribute was updated so that there is no interpolation going on we don't want to\n                // register any observers\n                if (!interpolateFn) return;\n\n                // initialize attr object so that it's ready in case we need the value for isolate\n                // scope initialization, otherwise the value would not be available from isolate\n                // directive's linking fn during linking phase\n                attr[name] = interpolateFn(scope);\n\n                ($$observers[name] || ($$observers[name] = [])).$$inter = true;\n                (attr.$$observers && attr.$$observers[name].$$scope || scope).\n                  $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {\n                    //special case for class attribute addition + removal\n                    //so that class changes can tap into the animation\n                    //hooks provided by the $animate service. Be sure to\n                    //skip animations when the first digest occurs (when\n                    //both the new and the old values are the same) since\n                    //the CSS classes are the non-interpolated values\n                    if (name === 'class' && newValue !== oldValue) {\n                      attr.$updateClass(newValue, oldValue);\n                    } else {\n                      attr.$set(name, newValue);\n                    }\n                  });\n              }\n            };\n          }\n      });\n    }\n\n\n    /**\n     * This is a special jqLite.replaceWith, which can replace items which\n     * have no parents, provided that the containing jqLite collection is provided.\n     *\n     * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes\n     *                               in the root of the tree.\n     * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep\n     *                                  the shell, but replace its DOM node reference.\n     * @param {Node} newNode The new DOM node.\n     */\n    function replaceWith($rootElement, elementsToRemove, newNode) {\n      var firstElementToRemove = elementsToRemove[0],\n          removeCount = elementsToRemove.length,\n          parent = firstElementToRemove.parentNode,\n          i, ii;\n\n      if ($rootElement) {\n        for (i = 0, ii = $rootElement.length; i < ii; i++) {\n          if ($rootElement[i] === firstElementToRemove) {\n            $rootElement[i++] = newNode;\n            for (var j = i, j2 = j + removeCount - 1,\n                     jj = $rootElement.length;\n                 j < jj; j++, j2++) {\n              if (j2 < jj) {\n                $rootElement[j] = $rootElement[j2];\n              } else {\n                delete $rootElement[j];\n              }\n            }\n            $rootElement.length -= removeCount - 1;\n\n            // If the replaced element is also the jQuery .context then replace it\n            // .context is a deprecated jQuery api, so we should set it only when jQuery set it\n            // http://api.jquery.com/context/\n            if ($rootElement.context === firstElementToRemove) {\n              $rootElement.context = newNode;\n            }\n            break;\n          }\n        }\n      }\n\n      if (parent) {\n        parent.replaceChild(newNode, firstElementToRemove);\n      }\n\n      // Append all the `elementsToRemove` to a fragment. This will...\n      // - remove them from the DOM\n      // - allow them to still be traversed with .nextSibling\n      // - allow a single fragment.qSA to fetch all elements being removed\n      var fragment = window.document.createDocumentFragment();\n      for (i = 0; i < removeCount; i++) {\n        fragment.appendChild(elementsToRemove[i]);\n      }\n\n      if (jqLite.hasData(firstElementToRemove)) {\n        // Copy over user data (that includes Angular's $scope etc.). Don't copy private\n        // data here because there's no public interface in jQuery to do that and copying over\n        // event listeners (which is the main use of private data) wouldn't work anyway.\n        jqLite.data(newNode, jqLite.data(firstElementToRemove));\n\n        // Remove $destroy event listeners from `firstElementToRemove`\n        jqLite(firstElementToRemove).off('$destroy');\n      }\n\n      // Cleanup any data/listeners on the elements and children.\n      // This includes invoking the $destroy event on any elements with listeners.\n      jqLite.cleanData(fragment.querySelectorAll('*'));\n\n      // Update the jqLite collection to only contain the `newNode`\n      for (i = 1; i < removeCount; i++) {\n        delete elementsToRemove[i];\n      }\n      elementsToRemove[0] = newNode;\n      elementsToRemove.length = 1;\n    }\n\n\n    function cloneAndAnnotateFn(fn, annotation) {\n      return extend(function() { return fn.apply(null, arguments); }, fn, annotation);\n    }\n\n\n    function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {\n      try {\n        linkFn(scope, $element, attrs, controllers, transcludeFn);\n      } catch (e) {\n        $exceptionHandler(e, startingTag($element));\n      }\n    }\n\n\n    // Set up $watches for isolate scope and controller bindings.\n    function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {\n      var removeWatchCollection = [];\n      var initialChanges = {};\n      var changes;\n      forEach(bindings, function initializeBinding(definition, scopeName) {\n        var attrName = definition.attrName,\n        optional = definition.optional,\n        mode = definition.mode, // @, =, <, or &\n        lastValue,\n        parentGet, parentSet, compare, removeWatch;\n\n        switch (mode) {\n\n          case '@':\n            if (!optional && !hasOwnProperty.call(attrs, attrName)) {\n              destination[scopeName] = attrs[attrName] = undefined;\n            }\n            removeWatch = attrs.$observe(attrName, function(value) {\n              if (isString(value) || isBoolean(value)) {\n                var oldValue = destination[scopeName];\n                recordChanges(scopeName, value, oldValue);\n                destination[scopeName] = value;\n              }\n            });\n            attrs.$$observers[attrName].$$scope = scope;\n            lastValue = attrs[attrName];\n            if (isString(lastValue)) {\n              // If the attribute has been provided then we trigger an interpolation to ensure\n              // the value is there for use in the link fn\n              destination[scopeName] = $interpolate(lastValue)(scope);\n            } else if (isBoolean(lastValue)) {\n              // If the attributes is one of the BOOLEAN_ATTR then Angular will have converted\n              // the value to boolean rather than a string, so we special case this situation\n              destination[scopeName] = lastValue;\n            }\n            initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);\n            removeWatchCollection.push(removeWatch);\n            break;\n\n          case '=':\n            if (!hasOwnProperty.call(attrs, attrName)) {\n              if (optional) break;\n              attrs[attrName] = undefined;\n            }\n            if (optional && !attrs[attrName]) break;\n\n            parentGet = $parse(attrs[attrName]);\n            if (parentGet.literal) {\n              compare = equals;\n            } else {\n              // eslint-disable-next-line no-self-compare\n              compare = function simpleCompare(a, b) { return a === b || (a !== a && b !== b); };\n            }\n            parentSet = parentGet.assign || function() {\n              // reset the change, or we will throw this exception on every $digest\n              lastValue = destination[scopeName] = parentGet(scope);\n              throw $compileMinErr('nonassign',\n                  'Expression \\'{0}\\' in attribute \\'{1}\\' used with directive \\'{2}\\' is non-assignable!',\n                  attrs[attrName], attrName, directive.name);\n            };\n            lastValue = destination[scopeName] = parentGet(scope);\n            var parentValueWatch = function parentValueWatch(parentValue) {\n              if (!compare(parentValue, destination[scopeName])) {\n                // we are out of sync and need to copy\n                if (!compare(parentValue, lastValue)) {\n                  // parent changed and it has precedence\n                  destination[scopeName] = parentValue;\n                } else {\n                  // if the parent can be assigned then do so\n                  parentSet(scope, parentValue = destination[scopeName]);\n                }\n              }\n              lastValue = parentValue;\n              return lastValue;\n            };\n            parentValueWatch.$stateful = true;\n            if (definition.collection) {\n              removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);\n            } else {\n              removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);\n            }\n            removeWatchCollection.push(removeWatch);\n            break;\n\n          case '<':\n            if (!hasOwnProperty.call(attrs, attrName)) {\n              if (optional) break;\n              attrs[attrName] = undefined;\n            }\n            if (optional && !attrs[attrName]) break;\n\n            parentGet = $parse(attrs[attrName]);\n            var deepWatch = parentGet.literal;\n\n            var initialValue = destination[scopeName] = parentGet(scope);\n            initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);\n\n            removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newValue, oldValue) {\n              if (oldValue === newValue) {\n                if (oldValue === initialValue || (deepWatch && equals(oldValue, initialValue))) {\n                  return;\n                }\n                oldValue = initialValue;\n              }\n              recordChanges(scopeName, newValue, oldValue);\n              destination[scopeName] = newValue;\n            }, deepWatch);\n\n            removeWatchCollection.push(removeWatch);\n            break;\n\n          case '&':\n            // Don't assign Object.prototype method to scope\n            parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;\n\n            // Don't assign noop to destination if expression is not valid\n            if (parentGet === noop && optional) break;\n\n            destination[scopeName] = function(locals) {\n              return parentGet(scope, locals);\n            };\n            break;\n        }\n      });\n\n      function recordChanges(key, currentValue, previousValue) {\n        if (isFunction(destination.$onChanges) && currentValue !== previousValue &&\n            // eslint-disable-next-line no-self-compare\n            (currentValue === currentValue || previousValue === previousValue)) {\n          // If we have not already scheduled the top level onChangesQueue handler then do so now\n          if (!onChangesQueue) {\n            scope.$$postDigest(flushOnChangesQueue);\n            onChangesQueue = [];\n          }\n          // If we have not already queued a trigger of onChanges for this controller then do so now\n          if (!changes) {\n            changes = {};\n            onChangesQueue.push(triggerOnChangesHook);\n          }\n          // If the has been a change on this property already then we need to reuse the previous value\n          if (changes[key]) {\n            previousValue = changes[key].previousValue;\n          }\n          // Store this change\n          changes[key] = new SimpleChange(previousValue, currentValue);\n        }\n      }\n\n      function triggerOnChangesHook() {\n        destination.$onChanges(changes);\n        // Now clear the changes so that we schedule onChanges when more changes arrive\n        changes = undefined;\n      }\n\n      return {\n        initialChanges: initialChanges,\n        removeWatches: removeWatchCollection.length && function removeWatches() {\n          for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) {\n            removeWatchCollection[i]();\n          }\n        }\n      };\n    }\n  }];\n}\n\nfunction SimpleChange(previous, current) {\n  this.previousValue = previous;\n  this.currentValue = current;\n}\nSimpleChange.prototype.isFirstChange = function() { return this.previousValue === _UNINITIALIZED_VALUE; };\n\n\nvar PREFIX_REGEXP = /^((?:x|data)[:\\-_])/i;\nvar SPECIAL_CHARS_REGEXP = /[:\\-_]+(.)/g;\n\n/**\n * Converts all accepted directives format into proper directive name.\n * @param name Name to normalize\n */\nfunction directiveNormalize(name) {\n  return name\n    .replace(PREFIX_REGEXP, '')\n    .replace(SPECIAL_CHARS_REGEXP, fnCamelCaseReplace);\n}\n\n/**\n * @ngdoc type\n * @name $compile.directive.Attributes\n *\n * @description\n * A shared object between directive compile / linking functions which contains normalized DOM\n * element attributes. The values reflect current binding state `{{ }}`. The normalization is\n * needed since all of these are treated as equivalent in Angular:\n *\n * ```\n *    <span ng:bind=\"a\" ng-bind=\"a\" data-ng-bind=\"a\" x-ng-bind=\"a\">\n * ```\n */\n\n/**\n * @ngdoc property\n * @name $compile.directive.Attributes#$attr\n *\n * @description\n * A map of DOM element attribute names to the normalized name. This is\n * needed to do reverse lookup from normalized name back to actual name.\n */\n\n\n/**\n * @ngdoc method\n * @name $compile.directive.Attributes#$set\n * @kind function\n *\n * @description\n * Set DOM element attribute value.\n *\n *\n * @param {string} name Normalized element attribute name of the property to modify. The name is\n *          reverse-translated using the {@link ng.$compile.directive.Attributes#$attr $attr}\n *          property to the original name.\n * @param {string} value Value to set the attribute to. The value can be an interpolated string.\n */\n\n\n\n/**\n * Closure compiler type information\n */\n\nfunction nodesetLinkingFn(\n  /* angular.Scope */ scope,\n  /* NodeList */ nodeList,\n  /* Element */ rootElement,\n  /* function(Function) */ boundTranscludeFn\n) {}\n\nfunction directiveLinkingFn(\n  /* nodesetLinkingFn */ nodesetLinkingFn,\n  /* angular.Scope */ scope,\n  /* Node */ node,\n  /* Element */ rootElement,\n  /* function(Function) */ boundTranscludeFn\n) {}\n\nfunction tokenDifference(str1, str2) {\n  var values = '',\n      tokens1 = str1.split(/\\s+/),\n      tokens2 = str2.split(/\\s+/);\n\n  outer:\n  for (var i = 0; i < tokens1.length; i++) {\n    var token = tokens1[i];\n    for (var j = 0; j < tokens2.length; j++) {\n      if (token === tokens2[j]) continue outer;\n    }\n    values += (values.length > 0 ? ' ' : '') + token;\n  }\n  return values;\n}\n\nfunction removeComments(jqNodes) {\n  jqNodes = jqLite(jqNodes);\n  var i = jqNodes.length;\n\n  if (i <= 1) {\n    return jqNodes;\n  }\n\n  while (i--) {\n    var node = jqNodes[i];\n    if (node.nodeType === NODE_TYPE_COMMENT ||\n       (node.nodeType === NODE_TYPE_TEXT && node.nodeValue.trim() === '')) {\n         splice.call(jqNodes, i, 1);\n    }\n  }\n  return jqNodes;\n}\n\nvar $controllerMinErr = minErr('$controller');\n\n\nvar CNTRL_REG = /^(\\S+)(\\s+as\\s+([\\w$]+))?$/;\nfunction identifierForController(controller, ident) {\n  if (ident && isString(ident)) return ident;\n  if (isString(controller)) {\n    var match = CNTRL_REG.exec(controller);\n    if (match) return match[3];\n  }\n}\n\n\n/**\n * @ngdoc provider\n * @name $controllerProvider\n * @this\n *\n * @description\n * The {@link ng.$controller $controller service} is used by Angular to create new\n * controllers.\n *\n * This provider allows controller registration via the\n * {@link ng.$controllerProvider#register register} method.\n */\nfunction $ControllerProvider() {\n  var controllers = {},\n      globals = false;\n\n  /**\n   * @ngdoc method\n   * @name $controllerProvider#has\n   * @param {string} name Controller name to check.\n   */\n  this.has = function(name) {\n    return controllers.hasOwnProperty(name);\n  };\n\n  /**\n   * @ngdoc method\n   * @name $controllerProvider#register\n   * @param {string|Object} name Controller name, or an object map of controllers where the keys are\n   *    the names and the values are the constructors.\n   * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI\n   *    annotations in the array notation).\n   */\n  this.register = function(name, constructor) {\n    assertNotHasOwnProperty(name, 'controller');\n    if (isObject(name)) {\n      extend(controllers, name);\n    } else {\n      controllers[name] = constructor;\n    }\n  };\n\n  /**\n   * @ngdoc method\n   * @name $controllerProvider#allowGlobals\n   * @description If called, allows `$controller` to find controller constructors on `window`\n   *\n   * @deprecated\n   * sinceVersion=\"v1.3.0\"\n   * removeVersion=\"v1.7.0\"\n   * This method of finding controllers has been deprecated.\n   */\n  this.allowGlobals = function() {\n    globals = true;\n  };\n\n\n  this.$get = ['$injector', '$window', function($injector, $window) {\n\n    /**\n     * @ngdoc service\n     * @name $controller\n     * @requires $injector\n     *\n     * @param {Function|string} constructor If called with a function then it's considered to be the\n     *    controller constructor function. Otherwise it's considered to be a string which is used\n     *    to retrieve the controller constructor using the following steps:\n     *\n     *    * check if a controller with given name is registered via `$controllerProvider`\n     *    * check if evaluating the string on the current scope returns a constructor\n     *    * if $controllerProvider#allowGlobals, check `window[constructor]` on the global\n     *      `window` object (deprecated, not recommended)\n     *\n     *    The string can use the `controller as property` syntax, where the controller instance is published\n     *    as the specified property on the `scope`; the `scope` must be injected into `locals` param for this\n     *    to work correctly.\n     *\n     * @param {Object} locals Injection locals for Controller.\n     * @return {Object} Instance of given controller.\n     *\n     * @description\n     * `$controller` service is responsible for instantiating controllers.\n     *\n     * It's just a simple call to {@link auto.$injector $injector}, but extracted into\n     * a service, so that one can override this service with [BC version](https://gist.github.com/1649788).\n     */\n    return function $controller(expression, locals, later, ident) {\n      // PRIVATE API:\n      //   param `later` --- indicates that the controller's constructor is invoked at a later time.\n      //                     If true, $controller will allocate the object with the correct\n      //                     prototype chain, but will not invoke the controller until a returned\n      //                     callback is invoked.\n      //   param `ident` --- An optional label which overrides the label parsed from the controller\n      //                     expression, if any.\n      var instance, match, constructor, identifier;\n      later = later === true;\n      if (ident && isString(ident)) {\n        identifier = ident;\n      }\n\n      if (isString(expression)) {\n        match = expression.match(CNTRL_REG);\n        if (!match) {\n          throw $controllerMinErr('ctrlfmt',\n            'Badly formed controller string \\'{0}\\'. ' +\n            'Must match `__name__ as __id__` or `__name__`.', expression);\n        }\n        constructor = match[1];\n        identifier = identifier || match[3];\n        expression = controllers.hasOwnProperty(constructor)\n            ? controllers[constructor]\n            : getter(locals.$scope, constructor, true) ||\n                (globals ? getter($window, constructor, true) : undefined);\n\n        if (!expression) {\n          throw $controllerMinErr('ctrlreg',\n            'The controller with the name \\'{0}\\' is not registered.', constructor);\n        }\n\n        assertArgFn(expression, constructor, true);\n      }\n\n      if (later) {\n        // Instantiate controller later:\n        // This machinery is used to create an instance of the object before calling the\n        // controller's constructor itself.\n        //\n        // This allows properties to be added to the controller before the constructor is\n        // invoked. Primarily, this is used for isolate scope bindings in $compile.\n        //\n        // This feature is not intended for use by applications, and is thus not documented\n        // publicly.\n        // Object creation: http://jsperf.com/create-constructor/2\n        var controllerPrototype = (isArray(expression) ?\n          expression[expression.length - 1] : expression).prototype;\n        instance = Object.create(controllerPrototype || null);\n\n        if (identifier) {\n          addIdentifier(locals, identifier, instance, constructor || expression.name);\n        }\n\n        return extend(function $controllerInit() {\n          var result = $injector.invoke(expression, instance, locals, constructor);\n          if (result !== instance && (isObject(result) || isFunction(result))) {\n            instance = result;\n            if (identifier) {\n              // If result changed, re-assign controllerAs value to scope.\n              addIdentifier(locals, identifier, instance, constructor || expression.name);\n            }\n          }\n          return instance;\n        }, {\n          instance: instance,\n          identifier: identifier\n        });\n      }\n\n      instance = $injector.instantiate(expression, locals, constructor);\n\n      if (identifier) {\n        addIdentifier(locals, identifier, instance, constructor || expression.name);\n      }\n\n      return instance;\n    };\n\n    function addIdentifier(locals, identifier, instance, name) {\n      if (!(locals && isObject(locals.$scope))) {\n        throw minErr('$controller')('noscp',\n          'Cannot export controller \\'{0}\\' as \\'{1}\\'! No $scope object provided via `locals`.',\n          name, identifier);\n      }\n\n      locals.$scope[identifier] = instance;\n    }\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $document\n * @requires $window\n * @this\n *\n * @description\n * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object.\n *\n * @example\n   <example module=\"documentExample\" name=\"document\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <p>$document title: <b ng-bind=\"title\"></b></p>\n         <p>window.document title: <b ng-bind=\"windowTitle\"></b></p>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('documentExample', [])\n         .controller('ExampleController', ['$scope', '$document', function($scope, $document) {\n           $scope.title = $document[0].title;\n           $scope.windowTitle = angular.element(window.document)[0].title;\n         }]);\n     </file>\n   </example>\n */\nfunction $DocumentProvider() {\n  this.$get = ['$window', function(window) {\n    return jqLite(window.document);\n  }];\n}\n\n\n/**\n * @private\n * @this\n * Listens for document visibility change and makes the current status accessible.\n */\nfunction $$IsDocumentHiddenProvider() {\n  this.$get = ['$document', '$rootScope', function($document, $rootScope) {\n    var doc = $document[0];\n    var hidden = doc && doc.hidden;\n\n    $document.on('visibilitychange', changeListener);\n\n    $rootScope.$on('$destroy', function() {\n      $document.off('visibilitychange', changeListener);\n    });\n\n    function changeListener() {\n      hidden = doc.hidden;\n    }\n\n    return function() {\n      return hidden;\n    };\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $exceptionHandler\n * @requires ng.$log\n * @this\n *\n * @description\n * Any uncaught exception in angular expressions is delegated to this service.\n * The default implementation simply delegates to `$log.error` which logs it into\n * the browser console.\n *\n * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by\n * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing.\n *\n * ## Example:\n *\n * The example below will overwrite the default `$exceptionHandler` in order to (a) log uncaught\n * errors to the backend for later inspection by the developers and (b) to use `$log.warn()` instead\n * of `$log.error()`.\n *\n * ```js\n *   angular.\n *     module('exceptionOverwrite', []).\n *     factory('$exceptionHandler', ['$log', 'logErrorsToBackend', function($log, logErrorsToBackend) {\n *       return function myExceptionHandler(exception, cause) {\n *         logErrorsToBackend(exception, cause);\n *         $log.warn(exception, cause);\n *       };\n *     }]);\n * ```\n *\n * <hr />\n * Note, that code executed in event-listeners (even those registered using jqLite's `on`/`bind`\n * methods) does not delegate exceptions to the {@link ng.$exceptionHandler $exceptionHandler}\n * (unless executed during a digest).\n *\n * If you wish, you can manually delegate exceptions, e.g.\n * `try { ... } catch(e) { $exceptionHandler(e); }`\n *\n * @param {Error} exception Exception associated with the error.\n * @param {string=} cause Optional information about the context in which\n *       the error was thrown.\n *\n */\nfunction $ExceptionHandlerProvider() {\n  this.$get = ['$log', function($log) {\n    return function(exception, cause) {\n      $log.error.apply($log, arguments);\n    };\n  }];\n}\n\nvar $$ForceReflowProvider = /** @this */ function() {\n  this.$get = ['$document', function($document) {\n    return function(domNode) {\n      //the line below will force the browser to perform a repaint so\n      //that all the animated elements within the animation frame will\n      //be properly updated and drawn on screen. This is required to\n      //ensure that the preparation animation is properly flushed so that\n      //the active state picks up from there. DO NOT REMOVE THIS LINE.\n      //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH\n      //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND\n      //WILL TAKE YEARS AWAY FROM YOUR LIFE.\n      if (domNode) {\n        if (!domNode.nodeType && domNode instanceof jqLite) {\n          domNode = domNode[0];\n        }\n      } else {\n        domNode = $document[0].body;\n      }\n      return domNode.offsetWidth + 1;\n    };\n  }];\n};\n\nvar APPLICATION_JSON = 'application/json';\nvar CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};\nvar JSON_START = /^\\[|^\\{(?!\\{)/;\nvar JSON_ENDS = {\n  '[': /]$/,\n  '{': /}$/\n};\nvar JSON_PROTECTION_PREFIX = /^\\)]\\}',?\\n/;\nvar $httpMinErr = minErr('$http');\n\nfunction serializeValue(v) {\n  if (isObject(v)) {\n    return isDate(v) ? v.toISOString() : toJson(v);\n  }\n  return v;\n}\n\n\n/** @this */\nfunction $HttpParamSerializerProvider() {\n  /**\n   * @ngdoc service\n   * @name $httpParamSerializer\n   * @description\n   *\n   * Default {@link $http `$http`} params serializer that converts objects to strings\n   * according to the following rules:\n   *\n   * * `{'foo': 'bar'}` results in `foo=bar`\n   * * `{'foo': Date.now()}` results in `foo=2015-04-01T09%3A50%3A49.262Z` (`toISOString()` and encoded representation of a Date object)\n   * * `{'foo': ['bar', 'baz']}` results in `foo=bar&foo=baz` (repeated key for each array element)\n   * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D` (stringified and encoded representation of an object)\n   *\n   * Note that serializer will sort the request parameters alphabetically.\n   * */\n\n  this.$get = function() {\n    return function ngParamSerializer(params) {\n      if (!params) return '';\n      var parts = [];\n      forEachSorted(params, function(value, key) {\n        if (value === null || isUndefined(value)) return;\n        if (isArray(value)) {\n          forEach(value, function(v) {\n            parts.push(encodeUriQuery(key)  + '=' + encodeUriQuery(serializeValue(v)));\n          });\n        } else {\n          parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value)));\n        }\n      });\n\n      return parts.join('&');\n    };\n  };\n}\n\n/** @this */\nfunction $HttpParamSerializerJQLikeProvider() {\n  /**\n   * @ngdoc service\n   * @name $httpParamSerializerJQLike\n   *\n   * @description\n   *\n   * Alternative {@link $http `$http`} params serializer that follows\n   * jQuery's [`param()`](http://api.jquery.com/jquery.param/) method logic.\n   * The serializer will also sort the params alphabetically.\n   *\n   * To use it for serializing `$http` request parameters, set it as the `paramSerializer` property:\n   *\n   * ```js\n   * $http({\n   *   url: myUrl,\n   *   method: 'GET',\n   *   params: myParams,\n   *   paramSerializer: '$httpParamSerializerJQLike'\n   * });\n   * ```\n   *\n   * It is also possible to set it as the default `paramSerializer` in the\n   * {@link $httpProvider#defaults `$httpProvider`}.\n   *\n   * Additionally, you can inject the serializer and use it explicitly, for example to serialize\n   * form data for submission:\n   *\n   * ```js\n   * .controller(function($http, $httpParamSerializerJQLike) {\n   *   //...\n   *\n   *   $http({\n   *     url: myUrl,\n   *     method: 'POST',\n   *     data: $httpParamSerializerJQLike(myData),\n   *     headers: {\n   *       'Content-Type': 'application/x-www-form-urlencoded'\n   *     }\n   *   });\n   *\n   * });\n   * ```\n   *\n   * */\n  this.$get = function() {\n    return function jQueryLikeParamSerializer(params) {\n      if (!params) return '';\n      var parts = [];\n      serialize(params, '', true);\n      return parts.join('&');\n\n      function serialize(toSerialize, prefix, topLevel) {\n        if (toSerialize === null || isUndefined(toSerialize)) return;\n        if (isArray(toSerialize)) {\n          forEach(toSerialize, function(value, index) {\n            serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');\n          });\n        } else if (isObject(toSerialize) && !isDate(toSerialize)) {\n          forEachSorted(toSerialize, function(value, key) {\n            serialize(value, prefix +\n                (topLevel ? '' : '[') +\n                key +\n                (topLevel ? '' : ']'));\n          });\n        } else {\n          parts.push(encodeUriQuery(prefix) + '=' + encodeUriQuery(serializeValue(toSerialize)));\n        }\n      }\n    };\n  };\n}\n\nfunction defaultHttpResponseTransform(data, headers) {\n  if (isString(data)) {\n    // Strip json vulnerability protection prefix and trim whitespace\n    var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();\n\n    if (tempData) {\n      var contentType = headers('Content-Type');\n      if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {\n        data = fromJson(tempData);\n      }\n    }\n  }\n\n  return data;\n}\n\nfunction isJsonLike(str) {\n    var jsonStart = str.match(JSON_START);\n    return jsonStart && JSON_ENDS[jsonStart[0]].test(str);\n}\n\n/**\n * Parse headers into key value object\n *\n * @param {string} headers Raw headers as a string\n * @returns {Object} Parsed headers as key value object\n */\nfunction parseHeaders(headers) {\n  var parsed = createMap(), i;\n\n  function fillInParsed(key, val) {\n    if (key) {\n      parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n    }\n  }\n\n  if (isString(headers)) {\n    forEach(headers.split('\\n'), function(line) {\n      i = line.indexOf(':');\n      fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1)));\n    });\n  } else if (isObject(headers)) {\n    forEach(headers, function(headerVal, headerKey) {\n      fillInParsed(lowercase(headerKey), trim(headerVal));\n    });\n  }\n\n  return parsed;\n}\n\n\n/**\n * Returns a function that provides access to parsed headers.\n *\n * Headers are lazy parsed when first requested.\n * @see parseHeaders\n *\n * @param {(string|Object)} headers Headers to provide access to.\n * @returns {function(string=)} Returns a getter function which if called with:\n *\n *   - if called with an argument returns a single header value or null\n *   - if called with no arguments returns an object containing all headers.\n */\nfunction headersGetter(headers) {\n  var headersObj;\n\n  return function(name) {\n    if (!headersObj) headersObj =  parseHeaders(headers);\n\n    if (name) {\n      var value = headersObj[lowercase(name)];\n      if (value === undefined) {\n        value = null;\n      }\n      return value;\n    }\n\n    return headersObj;\n  };\n}\n\n\n/**\n * Chain all given functions\n *\n * This function is used for both request and response transforming\n *\n * @param {*} data Data to transform.\n * @param {function(string=)} headers HTTP headers getter fn.\n * @param {number} status HTTP status code of the response.\n * @param {(Function|Array.<Function>)} fns Function or an array of functions.\n * @returns {*} Transformed data.\n */\nfunction transformData(data, headers, status, fns) {\n  if (isFunction(fns)) {\n    return fns(data, headers, status);\n  }\n\n  forEach(fns, function(fn) {\n    data = fn(data, headers, status);\n  });\n\n  return data;\n}\n\n\nfunction isSuccess(status) {\n  return 200 <= status && status < 300;\n}\n\n\n/**\n * @ngdoc provider\n * @name $httpProvider\n * @this\n *\n * @description\n * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.\n * */\nfunction $HttpProvider() {\n  /**\n   * @ngdoc property\n   * @name $httpProvider#defaults\n   * @description\n   *\n   * Object containing default values for all {@link ng.$http $http} requests.\n   *\n   * - **`defaults.cache`** - {boolean|Object} - A boolean value or object created with\n   * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of HTTP responses\n   * by default. See {@link $http#caching $http Caching} for more information.\n   *\n   * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.\n   * Defaults value is `'XSRF-TOKEN'`.\n   *\n   * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the\n   * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.\n   *\n   * - **`defaults.headers`** - {Object} - Default headers for all $http requests.\n   * Refer to {@link ng.$http#setting-http-headers $http} for documentation on\n   * setting default headers.\n   *     - **`defaults.headers.common`**\n   *     - **`defaults.headers.post`**\n   *     - **`defaults.headers.put`**\n   *     - **`defaults.headers.patch`**\n   *\n   *\n   * - **`defaults.paramSerializer`** - `{string|function(Object<string,string>):string}` - A function\n   *  used to the prepare string representation of request parameters (specified as an object).\n   *  If specified as string, it is interpreted as a function registered with the {@link auto.$injector $injector}.\n   *  Defaults to {@link ng.$httpParamSerializer $httpParamSerializer}.\n   *\n   * - **`defaults.jsonpCallbackParam`** - `{string}` - the name of the query parameter that passes the name of the\n   * callback in a JSONP request. The value of this parameter will be replaced with the expression generated by the\n   * {@link $jsonpCallbacks} service. Defaults to `'callback'`.\n   *\n   **/\n  var defaults = this.defaults = {\n    // transform incoming response data\n    transformResponse: [defaultHttpResponseTransform],\n\n    // transform outgoing request data\n    transformRequest: [function(d) {\n      return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;\n    }],\n\n    // default headers\n    headers: {\n      common: {\n        'Accept': 'application/json, text/plain, */*'\n      },\n      post:   shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n      put:    shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n      patch:  shallowCopy(CONTENT_TYPE_APPLICATION_JSON)\n    },\n\n    xsrfCookieName: 'XSRF-TOKEN',\n    xsrfHeaderName: 'X-XSRF-TOKEN',\n\n    paramSerializer: '$httpParamSerializer',\n\n    jsonpCallbackParam: 'callback'\n  };\n\n  var useApplyAsync = false;\n  /**\n   * @ngdoc method\n   * @name $httpProvider#useApplyAsync\n   * @description\n   *\n   * Configure $http service to combine processing of multiple http responses received at around\n   * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in\n   * significant performance improvement for bigger applications that make many HTTP requests\n   * concurrently (common during application bootstrap).\n   *\n   * Defaults to false. If no value is specified, returns the current configured value.\n   *\n   * @param {boolean=} value If true, when requests are loaded, they will schedule a deferred\n   *    \"apply\" on the next tick, giving time for subsequent requests in a roughly ~10ms window\n   *    to load and share the same digest cycle.\n   *\n   * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.\n   *    otherwise, returns the current configured value.\n   **/\n  this.useApplyAsync = function(value) {\n    if (isDefined(value)) {\n      useApplyAsync = !!value;\n      return this;\n    }\n    return useApplyAsync;\n  };\n\n  /**\n   * @ngdoc property\n   * @name $httpProvider#interceptors\n   * @description\n   *\n   * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}\n   * pre-processing of request or postprocessing of responses.\n   *\n   * These service factories are ordered by request, i.e. they are applied in the same order as the\n   * array, on request, but reverse order, on response.\n   *\n   * {@link ng.$http#interceptors Interceptors detailed info}\n   **/\n  var interceptorFactories = this.interceptors = [];\n\n  this.$get = ['$browser', '$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector', '$sce',\n      function($browser, $httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector, $sce) {\n\n    var defaultCache = $cacheFactory('$http');\n\n    /**\n     * Make sure that default param serializer is exposed as a function\n     */\n    defaults.paramSerializer = isString(defaults.paramSerializer) ?\n      $injector.get(defaults.paramSerializer) : defaults.paramSerializer;\n\n    /**\n     * Interceptors stored in reverse order. Inner interceptors before outer interceptors.\n     * The reversal is needed so that we can build up the interception chain around the\n     * server request.\n     */\n    var reversedInterceptors = [];\n\n    forEach(interceptorFactories, function(interceptorFactory) {\n      reversedInterceptors.unshift(isString(interceptorFactory)\n          ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));\n    });\n\n    /**\n     * @ngdoc service\n     * @kind function\n     * @name $http\n     * @requires ng.$httpBackend\n     * @requires $cacheFactory\n     * @requires $rootScope\n     * @requires $q\n     * @requires $injector\n     *\n     * @description\n     * The `$http` service is a core Angular service that facilitates communication with the remote\n     * HTTP servers via the browser's [XMLHttpRequest](https://developer.mozilla.org/en/xmlhttprequest)\n     * object or via [JSONP](http://en.wikipedia.org/wiki/JSONP).\n     *\n     * For unit testing applications that use `$http` service, see\n     * {@link ngMock.$httpBackend $httpBackend mock}.\n     *\n     * For a higher level of abstraction, please check out the {@link ngResource.$resource\n     * $resource} service.\n     *\n     * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by\n     * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage\n     * it is important to familiarize yourself with these APIs and the guarantees they provide.\n     *\n     *\n     * ## General usage\n     * The `$http` service is a function which takes a single argument — a {@link $http#usage configuration object} —\n     * that is used to generate an HTTP request and returns  a {@link ng.$q promise}.\n     *\n     * ```js\n     *   // Simple GET request example:\n     *   $http({\n     *     method: 'GET',\n     *     url: '/someUrl'\n     *   }).then(function successCallback(response) {\n     *       // this callback will be called asynchronously\n     *       // when the response is available\n     *     }, function errorCallback(response) {\n     *       // called asynchronously if an error occurs\n     *       // or server returns response with an error status.\n     *     });\n     * ```\n     *\n     * The response object has these properties:\n     *\n     *   - **data** – `{string|Object}` – The response body transformed with the transform\n     *     functions.\n     *   - **status** – `{number}` – HTTP status code of the response.\n     *   - **headers** – `{function([headerName])}` – Header getter function.\n     *   - **config** – `{Object}` – The configuration object that was used to generate the request.\n     *   - **statusText** – `{string}` – HTTP status text of the response.\n     *\n     * A response status code between 200 and 299 is considered a success status and will result in\n     * the success callback being called. Any response status code outside of that range is\n     * considered an error status and will result in the error callback being called.\n     * Also, status codes less than -1 are normalized to zero. -1 usually means the request was\n     * aborted, e.g. using a `config.timeout`.\n     * Note that if the response is a redirect, XMLHttpRequest will transparently follow it, meaning\n     * that the outcome (success or error) will be determined by the final response status code.\n     *\n     *\n     * ## Shortcut methods\n     *\n     * Shortcut methods are also available. All shortcut methods require passing in the URL, and\n     * request data must be passed in for POST/PUT requests. An optional config can be passed as the\n     * last argument.\n     *\n     * ```js\n     *   $http.get('/someUrl', config).then(successCallback, errorCallback);\n     *   $http.post('/someUrl', data, config).then(successCallback, errorCallback);\n     * ```\n     *\n     * Complete list of shortcut methods:\n     *\n     * - {@link ng.$http#get $http.get}\n     * - {@link ng.$http#head $http.head}\n     * - {@link ng.$http#post $http.post}\n     * - {@link ng.$http#put $http.put}\n     * - {@link ng.$http#delete $http.delete}\n     * - {@link ng.$http#jsonp $http.jsonp}\n     * - {@link ng.$http#patch $http.patch}\n     *\n     *\n     * ## Writing Unit Tests that use $http\n     * When unit testing (using {@link ngMock ngMock}), it is necessary to call\n     * {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending\n     * request using trained responses.\n     *\n     * ```\n     * $httpBackend.expectGET(...);\n     * $http.get(...);\n     * $httpBackend.flush();\n     * ```\n     *\n     * ## Setting HTTP Headers\n     *\n     * The $http service will automatically add certain HTTP headers to all requests. These defaults\n     * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration\n     * object, which currently contains this default configuration:\n     *\n     * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):\n     *   - <code>Accept: application/json, text/plain, \\*&#65279;/&#65279;\\*</code>\n     * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)\n     *   - `Content-Type: application/json`\n     * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)\n     *   - `Content-Type: application/json`\n     *\n     * To add or overwrite these defaults, simply add or remove a property from these configuration\n     * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object\n     * with the lowercased HTTP method name as the key, e.g.\n     * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }`.\n     *\n     * The defaults can also be set at runtime via the `$http.defaults` object in the same\n     * fashion. For example:\n     *\n     * ```\n     * module.run(function($http) {\n     *   $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';\n     * });\n     * ```\n     *\n     * In addition, you can supply a `headers` property in the config object passed when\n     * calling `$http(config)`, which overrides the defaults without changing them globally.\n     *\n     * To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis,\n     * Use the `headers` property, setting the desired header to `undefined`. For example:\n     *\n     * ```js\n     * var req = {\n     *  method: 'POST',\n     *  url: 'http://example.com',\n     *  headers: {\n     *    'Content-Type': undefined\n     *  },\n     *  data: { test: 'test' }\n     * }\n     *\n     * $http(req).then(function(){...}, function(){...});\n     * ```\n     *\n     * ## Transforming Requests and Responses\n     *\n     * Both requests and responses can be transformed using transformation functions: `transformRequest`\n     * and `transformResponse`. These properties can be a single function that returns\n     * the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions,\n     * which allows you to `push` or `unshift` a new transformation function into the transformation chain.\n     *\n     * <div class=\"alert alert-warning\">\n     * **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline.\n     * That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference).\n     * For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest\n     * function will be reflected on the scope and in any templates where the object is data-bound.\n     * To prevent this, transform functions should have no side-effects.\n     * If you need to modify properties, it is recommended to make a copy of the data, or create new object to return.\n     * </div>\n     *\n     * ### Default Transformations\n     *\n     * The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and\n     * `defaults.transformResponse` properties. If a request does not provide its own transformations\n     * then these will be applied.\n     *\n     * You can augment or replace the default transformations by modifying these properties by adding to or\n     * replacing the array.\n     *\n     * Angular provides the following default transformations:\n     *\n     * Request transformations (`$httpProvider.defaults.transformRequest` and `$http.defaults.transformRequest`):\n     *\n     * - If the `data` property of the request configuration object contains an object, serialize it\n     *   into JSON format.\n     *\n     * Response transformations (`$httpProvider.defaults.transformResponse` and `$http.defaults.transformResponse`):\n     *\n     *  - If XSRF prefix is detected, strip it (see Security Considerations section below).\n     *  - If JSON response is detected, deserialize it using a JSON parser.\n     *\n     *\n     * ### Overriding the Default Transformations Per Request\n     *\n     * If you wish to override the request/response transformations only for a single request then provide\n     * `transformRequest` and/or `transformResponse` properties on the configuration object passed\n     * into `$http`.\n     *\n     * Note that if you provide these properties on the config object the default transformations will be\n     * overwritten. If you wish to augment the default transformations then you must include them in your\n     * local transformation array.\n     *\n     * The following code demonstrates adding a new response transformation to be run after the default response\n     * transformations have been run.\n     *\n     * ```js\n     * function appendTransform(defaults, transform) {\n     *\n     *   // We can't guarantee that the default transformation is an array\n     *   defaults = angular.isArray(defaults) ? defaults : [defaults];\n     *\n     *   // Append the new transformation to the defaults\n     *   return defaults.concat(transform);\n     * }\n     *\n     * $http({\n     *   url: '...',\n     *   method: 'GET',\n     *   transformResponse: appendTransform($http.defaults.transformResponse, function(value) {\n     *     return doTransform(value);\n     *   })\n     * });\n     * ```\n     *\n     *\n     * ## Caching\n     *\n     * {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must\n     * set the config.cache value or the default cache value to TRUE or to a cache object (created\n     * with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes\n     * precedence over the default cache value.\n     *\n     * In order to:\n     *   * cache all responses - set the default cache value to TRUE or to a cache object\n     *   * cache a specific response - set config.cache value to TRUE or to a cache object\n     *\n     * If caching is enabled, but neither the default cache nor config.cache are set to a cache object,\n     * then the default `$cacheFactory(\"$http\")` object is used.\n     *\n     * The default cache value can be set by updating the\n     * {@link ng.$http#defaults `$http.defaults.cache`} property or the\n     * {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property.\n     *\n     * When caching is enabled, {@link ng.$http `$http`} stores the response from the server using\n     * the relevant cache object. The next time the same request is made, the response is returned\n     * from the cache without sending a request to the server.\n     *\n     * Take note that:\n     *\n     *   * Only GET and JSONP requests are cached.\n     *   * The cache key is the request URL including search parameters; headers are not considered.\n     *   * Cached responses are returned asynchronously, in the same way as responses from the server.\n     *   * If multiple identical requests are made using the same cache, which is not yet populated,\n     *     one request will be made to the server and remaining requests will return the same response.\n     *   * A cache-control header on the response does not affect if or how responses are cached.\n     *\n     *\n     * ## Interceptors\n     *\n     * Before you start creating interceptors, be sure to understand the\n     * {@link ng.$q $q and deferred/promise APIs}.\n     *\n     * For purposes of global error handling, authentication, or any kind of synchronous or\n     * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be\n     * able to intercept requests before they are handed to the server and\n     * responses before they are handed over to the application code that\n     * initiated these requests. The interceptors leverage the {@link ng.$q\n     * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.\n     *\n     * The interceptors are service factories that are registered with the `$httpProvider` by\n     * adding them to the `$httpProvider.interceptors` array. The factory is called and\n     * injected with dependencies (if specified) and returns the interceptor.\n     *\n     * There are two kinds of interceptors (and two kinds of rejection interceptors):\n     *\n     *   * `request`: interceptors get called with a http {@link $http#usage config} object. The function is free to\n     *     modify the `config` object or create a new one. The function needs to return the `config`\n     *     object directly, or a promise containing the `config` or a new `config` object.\n     *   * `requestError`: interceptor gets called when a previous interceptor threw an error or\n     *     resolved with a rejection.\n     *   * `response`: interceptors get called with http `response` object. The function is free to\n     *     modify the `response` object or create a new one. The function needs to return the `response`\n     *     object directly, or as a promise containing the `response` or a new `response` object.\n     *   * `responseError`: interceptor gets called when a previous interceptor threw an error or\n     *     resolved with a rejection.\n     *\n     *\n     * ```js\n     *   // register the interceptor as a service\n     *   $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {\n     *     return {\n     *       // optional method\n     *       'request': function(config) {\n     *         // do something on success\n     *         return config;\n     *       },\n     *\n     *       // optional method\n     *      'requestError': function(rejection) {\n     *         // do something on error\n     *         if (canRecover(rejection)) {\n     *           return responseOrNewPromise\n     *         }\n     *         return $q.reject(rejection);\n     *       },\n     *\n     *\n     *\n     *       // optional method\n     *       'response': function(response) {\n     *         // do something on success\n     *         return response;\n     *       },\n     *\n     *       // optional method\n     *      'responseError': function(rejection) {\n     *         // do something on error\n     *         if (canRecover(rejection)) {\n     *           return responseOrNewPromise\n     *         }\n     *         return $q.reject(rejection);\n     *       }\n     *     };\n     *   });\n     *\n     *   $httpProvider.interceptors.push('myHttpInterceptor');\n     *\n     *\n     *   // alternatively, register the interceptor via an anonymous factory\n     *   $httpProvider.interceptors.push(function($q, dependency1, dependency2) {\n     *     return {\n     *      'request': function(config) {\n     *          // same as above\n     *       },\n     *\n     *       'response': function(response) {\n     *          // same as above\n     *       }\n     *     };\n     *   });\n     * ```\n     *\n     * ## Security Considerations\n     *\n     * When designing web applications, consider security threats from:\n     *\n     * - [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)\n     * - [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery)\n     *\n     * Both server and the client must cooperate in order to eliminate these threats. Angular comes\n     * pre-configured with strategies that address these issues, but for this to work backend server\n     * cooperation is required.\n     *\n     * ### JSON Vulnerability Protection\n     *\n     * A [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)\n     * allows third party website to turn your JSON resource URL into\n     * [JSONP](http://en.wikipedia.org/wiki/JSONP) request under some conditions. To\n     * counter this your server can prefix all JSON requests with following string `\")]}',\\n\"`.\n     * Angular will automatically strip the prefix before processing it as JSON.\n     *\n     * For example if your server needs to return:\n     * ```js\n     * ['one','two']\n     * ```\n     *\n     * which is vulnerable to attack, your server can return:\n     * ```js\n     * )]}',\n     * ['one','two']\n     * ```\n     *\n     * Angular will strip the prefix, before processing the JSON.\n     *\n     *\n     * ### Cross Site Request Forgery (XSRF) Protection\n     *\n     * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by\n     * which the attacker can trick an authenticated user into unknowingly executing actions on your\n     * website. Angular provides a mechanism to counter XSRF. When performing XHR requests, the\n     * $http service reads a token from a cookie (by default, `XSRF-TOKEN`) and sets it as an HTTP\n     * header (`X-XSRF-TOKEN`). Since only JavaScript that runs on your domain could read the\n     * cookie, your server can be assured that the XHR came from JavaScript running on your domain.\n     * The header will not be set for cross-domain requests.\n     *\n     * To take advantage of this, your server needs to set a token in a JavaScript readable session\n     * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the\n     * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure\n     * that only JavaScript running on your domain could have sent the request. The token must be\n     * unique for each user and must be verifiable by the server (to prevent the JavaScript from\n     * making up its own tokens). We recommend that the token is a digest of your site's\n     * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography&#41;)\n     * for added security.\n     *\n     * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName\n     * properties of either $httpProvider.defaults at config-time, $http.defaults at run-time,\n     * or the per-request config object.\n     *\n     * In order to prevent collisions in environments where multiple Angular apps share the\n     * same domain or subdomain, we recommend that each application uses unique cookie name.\n     *\n     * @param {object} config Object describing the request to be made and how it should be\n     *    processed. The object has following properties:\n     *\n     *    - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)\n     *    - **url** – `{string|TrustedObject}` – Absolute or relative URL of the resource that is being requested;\n     *      or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     *    - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be serialized\n     *      with the `paramSerializer` and appended as GET parameters.\n     *    - **data** – `{string|Object}` – Data to be sent as the request message data.\n     *    - **headers** – `{Object}` – Map of strings or functions which return strings representing\n     *      HTTP headers to send to the server. If the return value of a function is null, the\n     *      header will not be sent. Functions accept a config object as an argument.\n     *    - **eventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest object.\n     *      To bind events to the XMLHttpRequest upload object, use `uploadEventHandlers`.\n     *      The handler will be called in the context of a `$apply` block.\n     *    - **uploadEventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest upload\n     *      object. To bind events to the XMLHttpRequest object, use `eventHandlers`.\n     *      The handler will be called in the context of a `$apply` block.\n     *    - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.\n     *    - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.\n     *    - **transformRequest** –\n     *      `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –\n     *      transform function or an array of such functions. The transform function takes the http\n     *      request body and headers and returns its transformed (typically serialized) version.\n     *      See {@link ng.$http#overriding-the-default-transformations-per-request\n     *      Overriding the Default Transformations}\n     *    - **transformResponse** –\n     *      `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –\n     *      transform function or an array of such functions. The transform function takes the http\n     *      response body, headers and status and returns its transformed (typically deserialized) version.\n     *      See {@link ng.$http#overriding-the-default-transformations-per-request\n     *      Overriding the Default Transformations}\n     *    - **paramSerializer** - `{string|function(Object<string,string>):string}` - A function used to\n     *      prepare the string representation of request parameters (specified as an object).\n     *      If specified as string, it is interpreted as function registered with the\n     *      {@link $injector $injector}, which means you can create your own serializer\n     *      by registering it as a {@link auto.$provide#service service}.\n     *      The default serializer is the {@link $httpParamSerializer $httpParamSerializer};\n     *      alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike}\n     *    - **cache** – `{boolean|Object}` – A boolean value or object created with\n     *      {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.\n     *      See {@link $http#caching $http Caching} for more information.\n     *    - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}\n     *      that should abort the request when resolved.\n     *    - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the\n     *      XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials)\n     *      for more information.\n     *    - **responseType** - `{string}` - see\n     *      [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype).\n     *\n     * @returns {HttpPromise} Returns a {@link ng.$q `Promise}` that will be resolved to a response object\n     *                        when the request succeeds or fails.\n     *\n     *\n     * @property {Array.<Object>} pendingRequests Array of config objects for currently pending\n     *   requests. This is primarily meant to be used for debugging purposes.\n     *\n     *\n     * @example\n<example module=\"httpExample\" name=\"http-service\">\n<file name=\"index.html\">\n  <div ng-controller=\"FetchController\">\n    <select ng-model=\"method\" aria-label=\"Request method\">\n      <option>GET</option>\n      <option>JSONP</option>\n    </select>\n    <input type=\"text\" ng-model=\"url\" size=\"80\" aria-label=\"URL\" />\n    <button id=\"fetchbtn\" ng-click=\"fetch()\">fetch</button><br>\n    <button id=\"samplegetbtn\" ng-click=\"updateModel('GET', 'http-hello.html')\">Sample GET</button>\n    <button id=\"samplejsonpbtn\"\n      ng-click=\"updateModel('JSONP',\n                    'https://angularjs.org/greet.php?name=Super%20Hero')\">\n      Sample JSONP\n    </button>\n    <button id=\"invalidjsonpbtn\"\n      ng-click=\"updateModel('JSONP', 'https://angularjs.org/doesntexist')\">\n        Invalid JSONP\n      </button>\n    <pre>http status code: {{status}}</pre>\n    <pre>http response data: {{data}}</pre>\n  </div>\n</file>\n<file name=\"script.js\">\n  angular.module('httpExample', [])\n    .config(['$sceDelegateProvider', function($sceDelegateProvider) {\n      // We must whitelist the JSONP endpoint that we are using to show that we trust it\n      $sceDelegateProvider.resourceUrlWhitelist([\n        'self',\n        'https://angularjs.org/**'\n      ]);\n    }])\n    .controller('FetchController', ['$scope', '$http', '$templateCache',\n      function($scope, $http, $templateCache) {\n        $scope.method = 'GET';\n        $scope.url = 'http-hello.html';\n\n        $scope.fetch = function() {\n          $scope.code = null;\n          $scope.response = null;\n\n          $http({method: $scope.method, url: $scope.url, cache: $templateCache}).\n            then(function(response) {\n              $scope.status = response.status;\n              $scope.data = response.data;\n            }, function(response) {\n              $scope.data = response.data || 'Request failed';\n              $scope.status = response.status;\n          });\n        };\n\n        $scope.updateModel = function(method, url) {\n          $scope.method = method;\n          $scope.url = url;\n        };\n      }]);\n</file>\n<file name=\"http-hello.html\">\n  Hello, $http!\n</file>\n<file name=\"protractor.js\" type=\"protractor\">\n  var status = element(by.binding('status'));\n  var data = element(by.binding('data'));\n  var fetchBtn = element(by.id('fetchbtn'));\n  var sampleGetBtn = element(by.id('samplegetbtn'));\n  var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));\n\n  it('should make an xhr GET request', function() {\n    sampleGetBtn.click();\n    fetchBtn.click();\n    expect(status.getText()).toMatch('200');\n    expect(data.getText()).toMatch(/Hello, \\$http!/);\n  });\n\n// Commented out due to flakes. See https://github.com/angular/angular.js/issues/9185\n// it('should make a JSONP request to angularjs.org', function() {\n//   var sampleJsonpBtn = element(by.id('samplejsonpbtn'));\n//   sampleJsonpBtn.click();\n//   fetchBtn.click();\n//   expect(status.getText()).toMatch('200');\n//   expect(data.getText()).toMatch(/Super Hero!/);\n// });\n\n  it('should make JSONP request to invalid URL and invoke the error handler',\n      function() {\n    invalidJsonpBtn.click();\n    fetchBtn.click();\n    expect(status.getText()).toMatch('0');\n    expect(data.getText()).toMatch('Request failed');\n  });\n</file>\n</example>\n     */\n    function $http(requestConfig) {\n\n      if (!isObject(requestConfig)) {\n        throw minErr('$http')('badreq', 'Http request configuration must be an object.  Received: {0}', requestConfig);\n      }\n\n      if (!isString($sce.valueOf(requestConfig.url))) {\n        throw minErr('$http')('badreq', 'Http request configuration url must be a string or a $sce trusted object.  Received: {0}', requestConfig.url);\n      }\n\n      var config = extend({\n        method: 'get',\n        transformRequest: defaults.transformRequest,\n        transformResponse: defaults.transformResponse,\n        paramSerializer: defaults.paramSerializer,\n        jsonpCallbackParam: defaults.jsonpCallbackParam\n      }, requestConfig);\n\n      config.headers = mergeHeaders(requestConfig);\n      config.method = uppercase(config.method);\n      config.paramSerializer = isString(config.paramSerializer) ?\n          $injector.get(config.paramSerializer) : config.paramSerializer;\n\n      $browser.$$incOutstandingRequestCount();\n\n      var requestInterceptors = [];\n      var responseInterceptors = [];\n      var promise = $q.resolve(config);\n\n      // apply interceptors\n      forEach(reversedInterceptors, function(interceptor) {\n        if (interceptor.request || interceptor.requestError) {\n          requestInterceptors.unshift(interceptor.request, interceptor.requestError);\n        }\n        if (interceptor.response || interceptor.responseError) {\n          responseInterceptors.push(interceptor.response, interceptor.responseError);\n        }\n      });\n\n      promise = chainInterceptors(promise, requestInterceptors);\n      promise = promise.then(serverRequest);\n      promise = chainInterceptors(promise, responseInterceptors);\n      promise = promise.finally(completeOutstandingRequest);\n\n      return promise;\n\n\n      function chainInterceptors(promise, interceptors) {\n        for (var i = 0, ii = interceptors.length; i < ii;) {\n          var thenFn = interceptors[i++];\n          var rejectFn = interceptors[i++];\n\n          promise = promise.then(thenFn, rejectFn);\n        }\n\n        interceptors.length = 0;\n\n        return promise;\n      }\n\n      function completeOutstandingRequest() {\n        $browser.$$completeOutstandingRequest(noop);\n      }\n\n      function executeHeaderFns(headers, config) {\n        var headerContent, processedHeaders = {};\n\n        forEach(headers, function(headerFn, header) {\n          if (isFunction(headerFn)) {\n            headerContent = headerFn(config);\n            if (headerContent != null) {\n              processedHeaders[header] = headerContent;\n            }\n          } else {\n            processedHeaders[header] = headerFn;\n          }\n        });\n\n        return processedHeaders;\n      }\n\n      function mergeHeaders(config) {\n        var defHeaders = defaults.headers,\n            reqHeaders = extend({}, config.headers),\n            defHeaderName, lowercaseDefHeaderName, reqHeaderName;\n\n        defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);\n\n        // using for-in instead of forEach to avoid unnecessary iteration after header has been found\n        defaultHeadersIteration:\n        for (defHeaderName in defHeaders) {\n          lowercaseDefHeaderName = lowercase(defHeaderName);\n\n          for (reqHeaderName in reqHeaders) {\n            if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {\n              continue defaultHeadersIteration;\n            }\n          }\n\n          reqHeaders[defHeaderName] = defHeaders[defHeaderName];\n        }\n\n        // execute if header value is a function for merged headers\n        return executeHeaderFns(reqHeaders, shallowCopy(config));\n      }\n\n      function serverRequest(config) {\n        var headers = config.headers;\n        var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest);\n\n        // strip content-type if data is undefined\n        if (isUndefined(reqData)) {\n          forEach(headers, function(value, header) {\n            if (lowercase(header) === 'content-type') {\n              delete headers[header];\n            }\n          });\n        }\n\n        if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {\n          config.withCredentials = defaults.withCredentials;\n        }\n\n        // send request\n        return sendReq(config, reqData).then(transformResponse, transformResponse);\n      }\n\n      function transformResponse(response) {\n        // make a copy since the response must be cacheable\n        var resp = extend({}, response);\n        resp.data = transformData(response.data, response.headers, response.status,\n                                  config.transformResponse);\n        return (isSuccess(response.status))\n          ? resp\n          : $q.reject(resp);\n      }\n    }\n\n    $http.pendingRequests = [];\n\n    /**\n     * @ngdoc method\n     * @name $http#get\n     *\n     * @description\n     * Shortcut method to perform `GET` request.\n     *\n     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;\n     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n    /**\n     * @ngdoc method\n     * @name $http#delete\n     *\n     * @description\n     * Shortcut method to perform `DELETE` request.\n     *\n     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;\n     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n    /**\n     * @ngdoc method\n     * @name $http#head\n     *\n     * @description\n     * Shortcut method to perform `HEAD` request.\n     *\n     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;\n     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n    /**\n     * @ngdoc method\n     * @name $http#jsonp\n     *\n     * @description\n     * Shortcut method to perform `JSONP` request.\n     *\n     * Note that, since JSONP requests are sensitive because the response is given full access to the browser,\n     * the url must be declared, via {@link $sce} as a trusted resource URL.\n     * You can trust a URL by adding it to the whitelist via\n     * {@link $sceDelegateProvider#resourceUrlWhitelist  `$sceDelegateProvider.resourceUrlWhitelist`} or\n     * by explicitly trusting the URL via {@link $sce#trustAsResourceUrl `$sce.trustAsResourceUrl(url)`}.\n     *\n     * JSONP requests must specify a callback to be used in the response from the server. This callback\n     * is passed as a query parameter in the request. You must specify the name of this parameter by\n     * setting the `jsonpCallbackParam` property on the request config object.\n     *\n     * ```\n     * $http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})\n     * ```\n     *\n     * You can also specify a default callback parameter name in `$http.defaults.jsonpCallbackParam`.\n     * Initially this is set to `'callback'`.\n     *\n     * <div class=\"alert alert-danger\">\n     * You can no longer use the `JSON_CALLBACK` string as a placeholder for specifying where the callback\n     * parameter value should go.\n     * </div>\n     *\n     * If you would like to customise where and how the callbacks are stored then try overriding\n     * or decorating the {@link $jsonpCallbacks} service.\n     *\n     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;\n     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n    createShortMethods('get', 'delete', 'head', 'jsonp');\n\n    /**\n     * @ngdoc method\n     * @name $http#post\n     *\n     * @description\n     * Shortcut method to perform `POST` request.\n     *\n     * @param {string} url Relative or absolute URL specifying the destination of the request\n     * @param {*} data Request content\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n    /**\n     * @ngdoc method\n     * @name $http#put\n     *\n     * @description\n     * Shortcut method to perform `PUT` request.\n     *\n     * @param {string} url Relative or absolute URL specifying the destination of the request\n     * @param {*} data Request content\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n     /**\n      * @ngdoc method\n      * @name $http#patch\n      *\n      * @description\n      * Shortcut method to perform `PATCH` request.\n      *\n      * @param {string} url Relative or absolute URL specifying the destination of the request\n      * @param {*} data Request content\n      * @param {Object=} config Optional configuration object\n      * @returns {HttpPromise} Future object\n      */\n    createShortMethodsWithData('post', 'put', 'patch');\n\n        /**\n         * @ngdoc property\n         * @name $http#defaults\n         *\n         * @description\n         * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of\n         * default headers, withCredentials as well as request and response transformations.\n         *\n         * See \"Setting HTTP Headers\" and \"Transforming Requests and Responses\" sections above.\n         */\n    $http.defaults = defaults;\n\n\n    return $http;\n\n\n    function createShortMethods(names) {\n      forEach(arguments, function(name) {\n        $http[name] = function(url, config) {\n          return $http(extend({}, config || {}, {\n            method: name,\n            url: url\n          }));\n        };\n      });\n    }\n\n\n    function createShortMethodsWithData(name) {\n      forEach(arguments, function(name) {\n        $http[name] = function(url, data, config) {\n          return $http(extend({}, config || {}, {\n            method: name,\n            url: url,\n            data: data\n          }));\n        };\n      });\n    }\n\n\n    /**\n     * Makes the request.\n     *\n     * !!! ACCESSES CLOSURE VARS:\n     * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests\n     */\n    function sendReq(config, reqData) {\n      var deferred = $q.defer(),\n          promise = deferred.promise,\n          cache,\n          cachedResp,\n          reqHeaders = config.headers,\n          isJsonp = lowercase(config.method) === 'jsonp',\n          url = config.url;\n\n      if (isJsonp) {\n        // JSONP is a pretty sensitive operation where we're allowing a script to have full access to\n        // our DOM and JS space.  So we require that the URL satisfies SCE.RESOURCE_URL.\n        url = $sce.getTrustedResourceUrl(url);\n      } else if (!isString(url)) {\n        // If it is not a string then the URL must be a $sce trusted object\n        url = $sce.valueOf(url);\n      }\n\n      url = buildUrl(url, config.paramSerializer(config.params));\n\n      if (isJsonp) {\n        // Check the url and add the JSONP callback placeholder\n        url = sanitizeJsonpCallbackParam(url, config.jsonpCallbackParam);\n      }\n\n      $http.pendingRequests.push(config);\n      promise.then(removePendingReq, removePendingReq);\n\n      if ((config.cache || defaults.cache) && config.cache !== false &&\n          (config.method === 'GET' || config.method === 'JSONP')) {\n        cache = isObject(config.cache) ? config.cache\n            : isObject(/** @type {?} */ (defaults).cache)\n              ? /** @type {?} */ (defaults).cache\n              : defaultCache;\n      }\n\n      if (cache) {\n        cachedResp = cache.get(url);\n        if (isDefined(cachedResp)) {\n          if (isPromiseLike(cachedResp)) {\n            // cached request has already been sent, but there is no response yet\n            cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult);\n          } else {\n            // serving from cache\n            if (isArray(cachedResp)) {\n              resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]);\n            } else {\n              resolvePromise(cachedResp, 200, {}, 'OK');\n            }\n          }\n        } else {\n          // put the promise for the non-transformed response into cache as a placeholder\n          cache.put(url, promise);\n        }\n      }\n\n\n      // if we won't have the response in cache, set the xsrf headers and\n      // send the request to the backend\n      if (isUndefined(cachedResp)) {\n        var xsrfValue = urlIsSameOrigin(config.url)\n            ? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName]\n            : undefined;\n        if (xsrfValue) {\n          reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;\n        }\n\n        $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,\n            config.withCredentials, config.responseType,\n            createApplyHandlers(config.eventHandlers),\n            createApplyHandlers(config.uploadEventHandlers));\n      }\n\n      return promise;\n\n      function createApplyHandlers(eventHandlers) {\n        if (eventHandlers) {\n          var applyHandlers = {};\n          forEach(eventHandlers, function(eventHandler, key) {\n            applyHandlers[key] = function(event) {\n              if (useApplyAsync) {\n                $rootScope.$applyAsync(callEventHandler);\n              } else if ($rootScope.$$phase) {\n                callEventHandler();\n              } else {\n                $rootScope.$apply(callEventHandler);\n              }\n\n              function callEventHandler() {\n                eventHandler(event);\n              }\n            };\n          });\n          return applyHandlers;\n        }\n      }\n\n\n      /**\n       * Callback registered to $httpBackend():\n       *  - caches the response if desired\n       *  - resolves the raw $http promise\n       *  - calls $apply\n       */\n      function done(status, response, headersString, statusText) {\n        if (cache) {\n          if (isSuccess(status)) {\n            cache.put(url, [status, response, parseHeaders(headersString), statusText]);\n          } else {\n            // remove promise from the cache\n            cache.remove(url);\n          }\n        }\n\n        function resolveHttpPromise() {\n          resolvePromise(response, status, headersString, statusText);\n        }\n\n        if (useApplyAsync) {\n          $rootScope.$applyAsync(resolveHttpPromise);\n        } else {\n          resolveHttpPromise();\n          if (!$rootScope.$$phase) $rootScope.$apply();\n        }\n      }\n\n\n      /**\n       * Resolves the raw $http promise.\n       */\n      function resolvePromise(response, status, headers, statusText) {\n        //status: HTTP response status code, 0, -1 (aborted by timeout / promise)\n        status = status >= -1 ? status : 0;\n\n        (isSuccess(status) ? deferred.resolve : deferred.reject)({\n          data: response,\n          status: status,\n          headers: headersGetter(headers),\n          config: config,\n          statusText: statusText\n        });\n      }\n\n      function resolvePromiseWithResult(result) {\n        resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText);\n      }\n\n      function removePendingReq() {\n        var idx = $http.pendingRequests.indexOf(config);\n        if (idx !== -1) $http.pendingRequests.splice(idx, 1);\n      }\n    }\n\n\n    function buildUrl(url, serializedParams) {\n      if (serializedParams.length > 0) {\n        url += ((url.indexOf('?') === -1) ? '?' : '&') + serializedParams;\n      }\n      return url;\n    }\n\n    function sanitizeJsonpCallbackParam(url, key) {\n      if (/[&?][^=]+=JSON_CALLBACK/.test(url)) {\n        // Throw if the url already contains a reference to JSON_CALLBACK\n        throw $httpMinErr('badjsonp', 'Illegal use of JSON_CALLBACK in url, \"{0}\"', url);\n      }\n\n      var callbackParamRegex = new RegExp('[&?]' + key + '=');\n      if (callbackParamRegex.test(url)) {\n        // Throw if the callback param was already provided\n        throw $httpMinErr('badjsonp', 'Illegal use of callback param, \"{0}\", in url, \"{1}\"', key, url);\n      }\n\n      // Add in the JSON_CALLBACK callback param value\n      url += ((url.indexOf('?') === -1) ? '?' : '&') + key + '=JSON_CALLBACK';\n\n      return url;\n    }\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $xhrFactory\n * @this\n *\n * @description\n * Factory function used to create XMLHttpRequest objects.\n *\n * Replace or decorate this service to create your own custom XMLHttpRequest objects.\n *\n * ```\n * angular.module('myApp', [])\n * .factory('$xhrFactory', function() {\n *   return function createXhr(method, url) {\n *     return new window.XMLHttpRequest({mozSystem: true});\n *   };\n * });\n * ```\n *\n * @param {string} method HTTP method of the request (GET, POST, PUT, ..)\n * @param {string} url URL of the request.\n */\nfunction $xhrFactoryProvider() {\n  this.$get = function() {\n    return function createXhr() {\n      return new window.XMLHttpRequest();\n    };\n  };\n}\n\n/**\n * @ngdoc service\n * @name $httpBackend\n * @requires $jsonpCallbacks\n * @requires $document\n * @requires $xhrFactory\n * @this\n *\n * @description\n * HTTP backend used by the {@link ng.$http service} that delegates to\n * XMLHttpRequest object or JSONP and deals with browser incompatibilities.\n *\n * You should never need to use this service directly, instead use the higher-level abstractions:\n * {@link ng.$http $http} or {@link ngResource.$resource $resource}.\n *\n * During testing this implementation is swapped with {@link ngMock.$httpBackend mock\n * $httpBackend} which can be trained with responses.\n */\nfunction $HttpBackendProvider() {\n  this.$get = ['$browser', '$jsonpCallbacks', '$document', '$xhrFactory', function($browser, $jsonpCallbacks, $document, $xhrFactory) {\n    return createHttpBackend($browser, $xhrFactory, $browser.defer, $jsonpCallbacks, $document[0]);\n  }];\n}\n\nfunction createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {\n  // TODO(vojta): fix the signature\n  return function(method, url, post, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers) {\n    url = url || $browser.url();\n\n    if (lowercase(method) === 'jsonp') {\n      var callbackPath = callbacks.createCallback(url);\n      var jsonpDone = jsonpReq(url, callbackPath, function(status, text) {\n        // jsonpReq only ever sets status to 200 (OK), 404 (ERROR) or -1 (WAITING)\n        var response = (status === 200) && callbacks.getResponse(callbackPath);\n        completeRequest(callback, status, response, '', text);\n        callbacks.removeCallback(callbackPath);\n      });\n    } else {\n\n      var xhr = createXhr(method, url);\n\n      xhr.open(method, url, true);\n      forEach(headers, function(value, key) {\n        if (isDefined(value)) {\n            xhr.setRequestHeader(key, value);\n        }\n      });\n\n      xhr.onload = function requestLoaded() {\n        var statusText = xhr.statusText || '';\n\n        // responseText is the old-school way of retrieving response (supported by IE9)\n        // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n        var response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n        // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n        var status = xhr.status === 1223 ? 204 : xhr.status;\n\n        // fix status code when it is 0 (0 status is undocumented).\n        // Occurs when accessing file resources or on Android 4.1 stock browser\n        // while retrieving files from application cache.\n        if (status === 0) {\n          status = response ? 200 : urlResolve(url).protocol === 'file' ? 404 : 0;\n        }\n\n        completeRequest(callback,\n            status,\n            response,\n            xhr.getAllResponseHeaders(),\n            statusText);\n      };\n\n      var requestError = function() {\n        // The response is always empty\n        // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error\n        completeRequest(callback, -1, null, null, '');\n      };\n\n      xhr.onerror = requestError;\n      xhr.onabort = requestError;\n      xhr.ontimeout = requestError;\n\n      forEach(eventHandlers, function(value, key) {\n          xhr.addEventListener(key, value);\n      });\n\n      forEach(uploadEventHandlers, function(value, key) {\n        xhr.upload.addEventListener(key, value);\n      });\n\n      if (withCredentials) {\n        xhr.withCredentials = true;\n      }\n\n      if (responseType) {\n        try {\n          xhr.responseType = responseType;\n        } catch (e) {\n          // WebKit added support for the json responseType value on 09/03/2013\n          // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are\n          // known to throw when setting the value \"json\" as the response type. Other older\n          // browsers implementing the responseType\n          //\n          // The json response type can be ignored if not supported, because JSON payloads are\n          // parsed on the client-side regardless.\n          if (responseType !== 'json') {\n            throw e;\n          }\n        }\n      }\n\n      xhr.send(isUndefined(post) ? null : post);\n    }\n\n    if (timeout > 0) {\n      var timeoutId = $browserDefer(timeoutRequest, timeout);\n    } else if (isPromiseLike(timeout)) {\n      timeout.then(timeoutRequest);\n    }\n\n\n    function timeoutRequest() {\n      if (jsonpDone) {\n        jsonpDone();\n      }\n      if (xhr) {\n        xhr.abort();\n      }\n    }\n\n    function completeRequest(callback, status, response, headersString, statusText) {\n      // cancel timeout and subsequent timeout promise resolution\n      if (isDefined(timeoutId)) {\n        $browserDefer.cancel(timeoutId);\n      }\n      jsonpDone = xhr = null;\n\n      callback(status, response, headersString, statusText);\n    }\n  };\n\n  function jsonpReq(url, callbackPath, done) {\n    url = url.replace('JSON_CALLBACK', callbackPath);\n    // we can't use jQuery/jqLite here because jQuery does crazy stuff with script elements, e.g.:\n    // - fetches local scripts via XHR and evals them\n    // - adds and immediately removes script elements from the document\n    var script = rawDocument.createElement('script'), callback = null;\n    script.type = 'text/javascript';\n    script.src = url;\n    script.async = true;\n\n    callback = function(event) {\n      script.removeEventListener('load', callback);\n      script.removeEventListener('error', callback);\n      rawDocument.body.removeChild(script);\n      script = null;\n      var status = -1;\n      var text = 'unknown';\n\n      if (event) {\n        if (event.type === 'load' && !callbacks.wasCalled(callbackPath)) {\n          event = { type: 'error' };\n        }\n        text = event.type;\n        status = event.type === 'error' ? 404 : 200;\n      }\n\n      if (done) {\n        done(status, text);\n      }\n    };\n\n    script.addEventListener('load', callback);\n    script.addEventListener('error', callback);\n    rawDocument.body.appendChild(script);\n    return callback;\n  }\n}\n\nvar $interpolateMinErr = angular.$interpolateMinErr = minErr('$interpolate');\n$interpolateMinErr.throwNoconcat = function(text) {\n  throw $interpolateMinErr('noconcat',\n      'Error while interpolating: {0}\\nStrict Contextual Escaping disallows ' +\n      'interpolations that concatenate multiple expressions when a trusted value is ' +\n      'required.  See http://docs.angularjs.org/api/ng.$sce', text);\n};\n\n$interpolateMinErr.interr = function(text, err) {\n  return $interpolateMinErr('interr', 'Can\\'t interpolate: {0}\\n{1}', text, err.toString());\n};\n\n/**\n * @ngdoc provider\n * @name $interpolateProvider\n * @this\n *\n * @description\n *\n * Used for configuring the interpolation markup. Defaults to `{{` and `}}`.\n *\n * <div class=\"alert alert-danger\">\n * This feature is sometimes used to mix different markup languages, e.g. to wrap an Angular\n * template within a Python Jinja template (or any other template language). Mixing templating\n * languages is **very dangerous**. The embedding template language will not safely escape Angular\n * expressions, so any user-controlled values in the template will cause Cross Site Scripting (XSS)\n * security bugs!\n * </div>\n *\n * @example\n<example name=\"custom-interpolation-markup\" module=\"customInterpolationApp\">\n<file name=\"index.html\">\n<script>\n  var customInterpolationApp = angular.module('customInterpolationApp', []);\n\n  customInterpolationApp.config(function($interpolateProvider) {\n    $interpolateProvider.startSymbol('//');\n    $interpolateProvider.endSymbol('//');\n  });\n\n\n  customInterpolationApp.controller('DemoController', function() {\n      this.label = \"This binding is brought you by // interpolation symbols.\";\n  });\n</script>\n<div ng-controller=\"DemoController as demo\">\n    //demo.label//\n</div>\n</file>\n<file name=\"protractor.js\" type=\"protractor\">\n  it('should interpolate binding with custom symbols', function() {\n    expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');\n  });\n</file>\n</example>\n */\nfunction $InterpolateProvider() {\n  var startSymbol = '{{';\n  var endSymbol = '}}';\n\n  /**\n   * @ngdoc method\n   * @name $interpolateProvider#startSymbol\n   * @description\n   * Symbol to denote start of expression in the interpolated string. Defaults to `{{`.\n   *\n   * @param {string=} value new value to set the starting symbol to.\n   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.\n   */\n  this.startSymbol = function(value) {\n    if (value) {\n      startSymbol = value;\n      return this;\n    } else {\n      return startSymbol;\n    }\n  };\n\n  /**\n   * @ngdoc method\n   * @name $interpolateProvider#endSymbol\n   * @description\n   * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.\n   *\n   * @param {string=} value new value to set the ending symbol to.\n   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.\n   */\n  this.endSymbol = function(value) {\n    if (value) {\n      endSymbol = value;\n      return this;\n    } else {\n      return endSymbol;\n    }\n  };\n\n\n  this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) {\n    var startSymbolLength = startSymbol.length,\n        endSymbolLength = endSymbol.length,\n        escapedStartRegexp = new RegExp(startSymbol.replace(/./g, escape), 'g'),\n        escapedEndRegexp = new RegExp(endSymbol.replace(/./g, escape), 'g');\n\n    function escape(ch) {\n      return '\\\\\\\\\\\\' + ch;\n    }\n\n    function unescapeText(text) {\n      return text.replace(escapedStartRegexp, startSymbol).\n        replace(escapedEndRegexp, endSymbol);\n    }\n\n    // TODO: this is the same as the constantWatchDelegate in parse.js\n    function constantWatchDelegate(scope, listener, objectEquality, constantInterp) {\n      var unwatch = scope.$watch(function constantInterpolateWatch(scope) {\n        unwatch();\n        return constantInterp(scope);\n      }, listener, objectEquality);\n      return unwatch;\n    }\n\n    /**\n     * @ngdoc service\n     * @name $interpolate\n     * @kind function\n     *\n     * @requires $parse\n     * @requires $sce\n     *\n     * @description\n     *\n     * Compiles a string with markup into an interpolation function. This service is used by the\n     * HTML {@link ng.$compile $compile} service for data binding. See\n     * {@link ng.$interpolateProvider $interpolateProvider} for configuring the\n     * interpolation markup.\n     *\n     *\n     * ```js\n     *   var $interpolate = ...; // injected\n     *   var exp = $interpolate('Hello {{name | uppercase}}!');\n     *   expect(exp({name:'Angular'})).toEqual('Hello ANGULAR!');\n     * ```\n     *\n     * `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is\n     * `true`, the interpolation function will return `undefined` unless all embedded expressions\n     * evaluate to a value other than `undefined`.\n     *\n     * ```js\n     *   var $interpolate = ...; // injected\n     *   var context = {greeting: 'Hello', name: undefined };\n     *\n     *   // default \"forgiving\" mode\n     *   var exp = $interpolate('{{greeting}} {{name}}!');\n     *   expect(exp(context)).toEqual('Hello !');\n     *\n     *   // \"allOrNothing\" mode\n     *   exp = $interpolate('{{greeting}} {{name}}!', false, null, true);\n     *   expect(exp(context)).toBeUndefined();\n     *   context.name = 'Angular';\n     *   expect(exp(context)).toEqual('Hello Angular!');\n     * ```\n     *\n     * `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior.\n     *\n     * #### Escaped Interpolation\n     * $interpolate provides a mechanism for escaping interpolation markers. Start and end markers\n     * can be escaped by preceding each of their characters with a REVERSE SOLIDUS U+005C (backslash).\n     * It will be rendered as a regular start/end marker, and will not be interpreted as an expression\n     * or binding.\n     *\n     * This enables web-servers to prevent script injection attacks and defacing attacks, to some\n     * degree, while also enabling code examples to work without relying on the\n     * {@link ng.directive:ngNonBindable ngNonBindable} directive.\n     *\n     * **For security purposes, it is strongly encouraged that web servers escape user-supplied data,\n     * replacing angle brackets (&lt;, &gt;) with &amp;lt; and &amp;gt; respectively, and replacing all\n     * interpolation start/end markers with their escaped counterparts.**\n     *\n     * Escaped interpolation markers are only replaced with the actual interpolation markers in rendered\n     * output when the $interpolate service processes the text. So, for HTML elements interpolated\n     * by {@link ng.$compile $compile}, or otherwise interpolated with the `mustHaveExpression` parameter\n     * set to `true`, the interpolated text must contain an unescaped interpolation expression. As such,\n     * this is typically useful only when user-data is used in rendering a template from the server, or\n     * when otherwise untrusted data is used by a directive.\n     *\n     * <example name=\"interpolation\">\n     *  <file name=\"index.html\">\n     *    <div ng-init=\"username='A user'\">\n     *      <p ng-init=\"apptitle='Escaping demo'\">{{apptitle}}: \\{\\{ username = \"defaced value\"; \\}\\}\n     *        </p>\n     *      <p><strong>{{username}}</strong> attempts to inject code which will deface the\n     *        application, but fails to accomplish their task, because the server has correctly\n     *        escaped the interpolation start/end markers with REVERSE SOLIDUS U+005C (backslash)\n     *        characters.</p>\n     *      <p>Instead, the result of the attempted script injection is visible, and can be removed\n     *        from the database by an administrator.</p>\n     *    </div>\n     *  </file>\n     * </example>\n     *\n     * @knownIssue\n     * It is currently not possible for an interpolated expression to contain the interpolation end\n     * symbol. For example, `{{ '}}' }}` will be incorrectly interpreted as `{{ ' }}` + `' }}`, i.e.\n     * an interpolated expression consisting of a single-quote (`'`) and the `' }}` string.\n     *\n     * @knownIssue\n     * All directives and components must use the standard `{{` `}}` interpolation symbols\n     * in their templates. If you change the application interpolation symbols the {@link $compile}\n     * service will attempt to denormalize the standard symbols to the custom symbols.\n     * The denormalization process is not clever enough to know not to replace instances of the standard\n     * symbols where they would not normally be treated as interpolation symbols. For example in the following\n     * code snippet the closing braces of the literal object will get incorrectly denormalized:\n     *\n     * ```\n     * <div data-context='{\"context\":{\"id\":3,\"type\":\"page\"}}\">\n     * ```\n     *\n     * The workaround is to ensure that such instances are separated by whitespace:\n     * ```\n     * <div data-context='{\"context\":{\"id\":3,\"type\":\"page\"} }\">\n     * ```\n     *\n     * See https://github.com/angular/angular.js/pull/14610#issuecomment-219401099 for more information.\n     *\n     * @param {string} text The text with markup to interpolate.\n     * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have\n     *    embedded expression in order to return an interpolation function. Strings with no\n     *    embedded expression will return null for the interpolation function.\n     * @param {string=} trustedContext when provided, the returned function passes the interpolated\n     *    result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,\n     *    trustedContext)} before returning it.  Refer to the {@link ng.$sce $sce} service that\n     *    provides Strict Contextual Escaping for details.\n     * @param {boolean=} allOrNothing if `true`, then the returned function returns undefined\n     *    unless all embedded expressions evaluate to a value other than `undefined`.\n     * @returns {function(context)} an interpolation function which is used to compute the\n     *    interpolated string. The function has these parameters:\n     *\n     * - `context`: evaluation context for all expressions embedded in the interpolated text\n     */\n    function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {\n      // Provide a quick exit and simplified result function for text with no interpolation\n      if (!text.length || text.indexOf(startSymbol) === -1) {\n        var constantInterp;\n        if (!mustHaveExpression) {\n          var unescapedText = unescapeText(text);\n          constantInterp = valueFn(unescapedText);\n          constantInterp.exp = text;\n          constantInterp.expressions = [];\n          constantInterp.$$watchDelegate = constantWatchDelegate;\n        }\n        return constantInterp;\n      }\n\n      allOrNothing = !!allOrNothing;\n      var startIndex,\n          endIndex,\n          index = 0,\n          expressions = [],\n          parseFns = [],\n          textLength = text.length,\n          exp,\n          concat = [],\n          expressionPositions = [];\n\n      while (index < textLength) {\n        if (((startIndex = text.indexOf(startSymbol, index)) !== -1) &&\n             ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) !== -1)) {\n          if (index !== startIndex) {\n            concat.push(unescapeText(text.substring(index, startIndex)));\n          }\n          exp = text.substring(startIndex + startSymbolLength, endIndex);\n          expressions.push(exp);\n          parseFns.push($parse(exp, parseStringifyInterceptor));\n          index = endIndex + endSymbolLength;\n          expressionPositions.push(concat.length);\n          concat.push('');\n        } else {\n          // we did not find an interpolation, so we have to add the remainder to the separators array\n          if (index !== textLength) {\n            concat.push(unescapeText(text.substring(index)));\n          }\n          break;\n        }\n      }\n\n      // Concatenating expressions makes it hard to reason about whether some combination of\n      // concatenated values are unsafe to use and could easily lead to XSS.  By requiring that a\n      // single expression be used for iframe[src], object[src], etc., we ensure that the value\n      // that's used is assigned or constructed by some JS code somewhere that is more testable or\n      // make it obvious that you bound the value to some user controlled value.  This helps reduce\n      // the load when auditing for XSS issues.\n      if (trustedContext && concat.length > 1) {\n          $interpolateMinErr.throwNoconcat(text);\n      }\n\n      if (!mustHaveExpression || expressions.length) {\n        var compute = function(values) {\n          for (var i = 0, ii = expressions.length; i < ii; i++) {\n            if (allOrNothing && isUndefined(values[i])) return;\n            concat[expressionPositions[i]] = values[i];\n          }\n          return concat.join('');\n        };\n\n        var getValue = function(value) {\n          return trustedContext ?\n            $sce.getTrusted(trustedContext, value) :\n            $sce.valueOf(value);\n        };\n\n        return extend(function interpolationFn(context) {\n            var i = 0;\n            var ii = expressions.length;\n            var values = new Array(ii);\n\n            try {\n              for (; i < ii; i++) {\n                values[i] = parseFns[i](context);\n              }\n\n              return compute(values);\n            } catch (err) {\n              $exceptionHandler($interpolateMinErr.interr(text, err));\n            }\n\n          }, {\n          // all of these properties are undocumented for now\n          exp: text, //just for compatibility with regular watchers created via $watch\n          expressions: expressions,\n          $$watchDelegate: function(scope, listener) {\n            var lastValue;\n            return scope.$watchGroup(parseFns, /** @this */ function interpolateFnWatcher(values, oldValues) {\n              var currValue = compute(values);\n              if (isFunction(listener)) {\n                listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);\n              }\n              lastValue = currValue;\n            });\n          }\n        });\n      }\n\n      function parseStringifyInterceptor(value) {\n        try {\n          value = getValue(value);\n          return allOrNothing && !isDefined(value) ? value : stringify(value);\n        } catch (err) {\n          $exceptionHandler($interpolateMinErr.interr(text, err));\n        }\n      }\n    }\n\n\n    /**\n     * @ngdoc method\n     * @name $interpolate#startSymbol\n     * @description\n     * Symbol to denote the start of expression in the interpolated string. Defaults to `{{`.\n     *\n     * Use {@link ng.$interpolateProvider#startSymbol `$interpolateProvider.startSymbol`} to change\n     * the symbol.\n     *\n     * @returns {string} start symbol.\n     */\n    $interpolate.startSymbol = function() {\n      return startSymbol;\n    };\n\n\n    /**\n     * @ngdoc method\n     * @name $interpolate#endSymbol\n     * @description\n     * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.\n     *\n     * Use {@link ng.$interpolateProvider#endSymbol `$interpolateProvider.endSymbol`} to change\n     * the symbol.\n     *\n     * @returns {string} end symbol.\n     */\n    $interpolate.endSymbol = function() {\n      return endSymbol;\n    };\n\n    return $interpolate;\n  }];\n}\n\n/** @this */\nfunction $IntervalProvider() {\n  this.$get = ['$rootScope', '$window', '$q', '$$q', '$browser',\n       function($rootScope,   $window,   $q,   $$q,   $browser) {\n    var intervals = {};\n\n\n     /**\n      * @ngdoc service\n      * @name $interval\n      *\n      * @description\n      * Angular's wrapper for `window.setInterval`. The `fn` function is executed every `delay`\n      * milliseconds.\n      *\n      * The return value of registering an interval function is a promise. This promise will be\n      * notified upon each tick of the interval, and will be resolved after `count` iterations, or\n      * run indefinitely if `count` is not defined. The value of the notification will be the\n      * number of iterations that have run.\n      * To cancel an interval, call `$interval.cancel(promise)`.\n      *\n      * In tests you can use {@link ngMock.$interval#flush `$interval.flush(millis)`} to\n      * move forward by `millis` milliseconds and trigger any functions scheduled to run in that\n      * time.\n      *\n      * <div class=\"alert alert-warning\">\n      * **Note**: Intervals created by this service must be explicitly destroyed when you are finished\n      * with them.  In particular they are not automatically destroyed when a controller's scope or a\n      * directive's element are destroyed.\n      * You should take this into consideration and make sure to always cancel the interval at the\n      * appropriate moment.  See the example below for more details on how and when to do this.\n      * </div>\n      *\n      * @param {function()} fn A function that should be called repeatedly. If no additional arguments\n      *   are passed (see below), the function is called with the current iteration count.\n      * @param {number} delay Number of milliseconds between each function call.\n      * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat\n      *   indefinitely.\n      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise\n      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.\n      * @param {...*=} Pass additional parameters to the executed function.\n      * @returns {promise} A promise which will be notified on each iteration.\n      *\n      * @example\n      * <example module=\"intervalExample\" name=\"interval-service\">\n      * <file name=\"index.html\">\n      *   <script>\n      *     angular.module('intervalExample', [])\n      *       .controller('ExampleController', ['$scope', '$interval',\n      *         function($scope, $interval) {\n      *           $scope.format = 'M/d/yy h:mm:ss a';\n      *           $scope.blood_1 = 100;\n      *           $scope.blood_2 = 120;\n      *\n      *           var stop;\n      *           $scope.fight = function() {\n      *             // Don't start a new fight if we are already fighting\n      *             if ( angular.isDefined(stop) ) return;\n      *\n      *             stop = $interval(function() {\n      *               if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {\n      *                 $scope.blood_1 = $scope.blood_1 - 3;\n      *                 $scope.blood_2 = $scope.blood_2 - 4;\n      *               } else {\n      *                 $scope.stopFight();\n      *               }\n      *             }, 100);\n      *           };\n      *\n      *           $scope.stopFight = function() {\n      *             if (angular.isDefined(stop)) {\n      *               $interval.cancel(stop);\n      *               stop = undefined;\n      *             }\n      *           };\n      *\n      *           $scope.resetFight = function() {\n      *             $scope.blood_1 = 100;\n      *             $scope.blood_2 = 120;\n      *           };\n      *\n      *           $scope.$on('$destroy', function() {\n      *             // Make sure that the interval is destroyed too\n      *             $scope.stopFight();\n      *           });\n      *         }])\n      *       // Register the 'myCurrentTime' directive factory method.\n      *       // We inject $interval and dateFilter service since the factory method is DI.\n      *       .directive('myCurrentTime', ['$interval', 'dateFilter',\n      *         function($interval, dateFilter) {\n      *           // return the directive link function. (compile function not needed)\n      *           return function(scope, element, attrs) {\n      *             var format,  // date format\n      *                 stopTime; // so that we can cancel the time updates\n      *\n      *             // used to update the UI\n      *             function updateTime() {\n      *               element.text(dateFilter(new Date(), format));\n      *             }\n      *\n      *             // watch the expression, and update the UI on change.\n      *             scope.$watch(attrs.myCurrentTime, function(value) {\n      *               format = value;\n      *               updateTime();\n      *             });\n      *\n      *             stopTime = $interval(updateTime, 1000);\n      *\n      *             // listen on DOM destroy (removal) event, and cancel the next UI update\n      *             // to prevent updating time after the DOM element was removed.\n      *             element.on('$destroy', function() {\n      *               $interval.cancel(stopTime);\n      *             });\n      *           }\n      *         }]);\n      *   </script>\n      *\n      *   <div>\n      *     <div ng-controller=\"ExampleController\">\n      *       <label>Date format: <input ng-model=\"format\"></label> <hr/>\n      *       Current time is: <span my-current-time=\"format\"></span>\n      *       <hr/>\n      *       Blood 1 : <font color='red'>{{blood_1}}</font>\n      *       Blood 2 : <font color='red'>{{blood_2}}</font>\n      *       <button type=\"button\" data-ng-click=\"fight()\">Fight</button>\n      *       <button type=\"button\" data-ng-click=\"stopFight()\">StopFight</button>\n      *       <button type=\"button\" data-ng-click=\"resetFight()\">resetFight</button>\n      *     </div>\n      *   </div>\n      *\n      * </file>\n      * </example>\n      */\n    function interval(fn, delay, count, invokeApply) {\n      var hasParams = arguments.length > 4,\n          args = hasParams ? sliceArgs(arguments, 4) : [],\n          setInterval = $window.setInterval,\n          clearInterval = $window.clearInterval,\n          iteration = 0,\n          skipApply = (isDefined(invokeApply) && !invokeApply),\n          deferred = (skipApply ? $$q : $q).defer(),\n          promise = deferred.promise;\n\n      count = isDefined(count) ? count : 0;\n\n      promise.$$intervalId = setInterval(function tick() {\n        if (skipApply) {\n          $browser.defer(callback);\n        } else {\n          $rootScope.$evalAsync(callback);\n        }\n        deferred.notify(iteration++);\n\n        if (count > 0 && iteration >= count) {\n          deferred.resolve(iteration);\n          clearInterval(promise.$$intervalId);\n          delete intervals[promise.$$intervalId];\n        }\n\n        if (!skipApply) $rootScope.$apply();\n\n      }, delay);\n\n      intervals[promise.$$intervalId] = deferred;\n\n      return promise;\n\n      function callback() {\n        if (!hasParams) {\n          fn(iteration);\n        } else {\n          fn.apply(null, args);\n        }\n      }\n    }\n\n\n     /**\n      * @ngdoc method\n      * @name $interval#cancel\n      *\n      * @description\n      * Cancels a task associated with the `promise`.\n      *\n      * @param {Promise=} promise returned by the `$interval` function.\n      * @returns {boolean} Returns `true` if the task was successfully canceled.\n      */\n    interval.cancel = function(promise) {\n      if (promise && promise.$$intervalId in intervals) {\n        // Interval cancels should not report as unhandled promise.\n        intervals[promise.$$intervalId].promise.catch(noop);\n        intervals[promise.$$intervalId].reject('canceled');\n        $window.clearInterval(promise.$$intervalId);\n        delete intervals[promise.$$intervalId];\n        return true;\n      }\n      return false;\n    };\n\n    return interval;\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $jsonpCallbacks\n * @requires $window\n * @description\n * This service handles the lifecycle of callbacks to handle JSONP requests.\n * Override this service if you wish to customise where the callbacks are stored and\n * how they vary compared to the requested url.\n */\nvar $jsonpCallbacksProvider = /** @this */ function() {\n  this.$get = function() {\n    var callbacks = angular.callbacks;\n    var callbackMap = {};\n\n    function createCallback(callbackId) {\n      var callback = function(data) {\n        callback.data = data;\n        callback.called = true;\n      };\n      callback.id = callbackId;\n      return callback;\n    }\n\n    return {\n      /**\n       * @ngdoc method\n       * @name $jsonpCallbacks#createCallback\n       * @param {string} url the url of the JSONP request\n       * @returns {string} the callback path to send to the server as part of the JSONP request\n       * @description\n       * {@link $httpBackend} calls this method to create a callback and get hold of the path to the callback\n       * to pass to the server, which will be used to call the callback with its payload in the JSONP response.\n       */\n      createCallback: function(url) {\n        var callbackId = '_' + (callbacks.$$counter++).toString(36);\n        var callbackPath = 'angular.callbacks.' + callbackId;\n        var callback = createCallback(callbackId);\n        callbackMap[callbackPath] = callbacks[callbackId] = callback;\n        return callbackPath;\n      },\n      /**\n       * @ngdoc method\n       * @name $jsonpCallbacks#wasCalled\n       * @param {string} callbackPath the path to the callback that was sent in the JSONP request\n       * @returns {boolean} whether the callback has been called, as a result of the JSONP response\n       * @description\n       * {@link $httpBackend} calls this method to find out whether the JSONP response actually called the\n       * callback that was passed in the request.\n       */\n      wasCalled: function(callbackPath) {\n        return callbackMap[callbackPath].called;\n      },\n      /**\n       * @ngdoc method\n       * @name $jsonpCallbacks#getResponse\n       * @param {string} callbackPath the path to the callback that was sent in the JSONP request\n       * @returns {*} the data received from the response via the registered callback\n       * @description\n       * {@link $httpBackend} calls this method to get hold of the data that was provided to the callback\n       * in the JSONP response.\n       */\n      getResponse: function(callbackPath) {\n        return callbackMap[callbackPath].data;\n      },\n      /**\n       * @ngdoc method\n       * @name $jsonpCallbacks#removeCallback\n       * @param {string} callbackPath the path to the callback that was sent in the JSONP request\n       * @description\n       * {@link $httpBackend} calls this method to remove the callback after the JSONP request has\n       * completed or timed-out.\n       */\n      removeCallback: function(callbackPath) {\n        var callback = callbackMap[callbackPath];\n        delete callbacks[callback.id];\n        delete callbackMap[callbackPath];\n      }\n    };\n  };\n};\n\n/**\n * @ngdoc service\n * @name $locale\n *\n * @description\n * $locale service provides localization rules for various Angular components. As of right now the\n * only public api is:\n *\n * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)\n */\n\nvar PATH_MATCH = /^([^?#]*)(\\?([^#]*))?(#(.*))?$/,\n    DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};\nvar $locationMinErr = minErr('$location');\n\n\n/**\n * Encode path using encodeUriSegment, ignoring forward slashes\n *\n * @param {string} path Path to encode\n * @returns {string}\n */\nfunction encodePath(path) {\n  var segments = path.split('/'),\n      i = segments.length;\n\n  while (i--) {\n    segments[i] = encodeUriSegment(segments[i]);\n  }\n\n  return segments.join('/');\n}\n\nfunction parseAbsoluteUrl(absoluteUrl, locationObj) {\n  var parsedUrl = urlResolve(absoluteUrl);\n\n  locationObj.$$protocol = parsedUrl.protocol;\n  locationObj.$$host = parsedUrl.hostname;\n  locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;\n}\n\nvar DOUBLE_SLASH_REGEX = /^\\s*[\\\\/]{2,}/;\nfunction parseAppUrl(url, locationObj) {\n\n  if (DOUBLE_SLASH_REGEX.test(url)) {\n    throw $locationMinErr('badpath', 'Invalid url \"{0}\".', url);\n  }\n\n  var prefixed = (url.charAt(0) !== '/');\n  if (prefixed) {\n    url = '/' + url;\n  }\n  var match = urlResolve(url);\n  locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?\n      match.pathname.substring(1) : match.pathname);\n  locationObj.$$search = parseKeyValue(match.search);\n  locationObj.$$hash = decodeURIComponent(match.hash);\n\n  // make sure path starts with '/';\n  if (locationObj.$$path && locationObj.$$path.charAt(0) !== '/') {\n    locationObj.$$path = '/' + locationObj.$$path;\n  }\n}\n\nfunction startsWith(str, search) {\n  return str.slice(0, search.length) === search;\n}\n\n/**\n *\n * @param {string} base\n * @param {string} url\n * @returns {string} returns text from `url` after `base` or `undefined` if it does not begin with\n *                   the expected string.\n */\nfunction stripBaseUrl(base, url) {\n  if (startsWith(url, base)) {\n    return url.substr(base.length);\n  }\n}\n\n\nfunction stripHash(url) {\n  var index = url.indexOf('#');\n  return index === -1 ? url : url.substr(0, index);\n}\n\nfunction trimEmptyHash(url) {\n  return url.replace(/(#.+)|#$/, '$1');\n}\n\n\nfunction stripFile(url) {\n  return url.substr(0, stripHash(url).lastIndexOf('/') + 1);\n}\n\n/* return the server only (scheme://host:port) */\nfunction serverBase(url) {\n  return url.substring(0, url.indexOf('/', url.indexOf('//') + 2));\n}\n\n\n/**\n * LocationHtml5Url represents a URL\n * This object is exposed as $location service when HTML5 mode is enabled and supported\n *\n * @constructor\n * @param {string} appBase application base URL\n * @param {string} appBaseNoFile application base URL stripped of any filename\n * @param {string} basePrefix URL path prefix\n */\nfunction LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {\n  this.$$html5 = true;\n  basePrefix = basePrefix || '';\n  parseAbsoluteUrl(appBase, this);\n\n\n  /**\n   * Parse given HTML5 (regular) URL string into properties\n   * @param {string} url HTML5 URL\n   * @private\n   */\n  this.$$parse = function(url) {\n    var pathUrl = stripBaseUrl(appBaseNoFile, url);\n    if (!isString(pathUrl)) {\n      throw $locationMinErr('ipthprfx', 'Invalid url \"{0}\", missing path prefix \"{1}\".', url,\n          appBaseNoFile);\n    }\n\n    parseAppUrl(pathUrl, this);\n\n    if (!this.$$path) {\n      this.$$path = '/';\n    }\n\n    this.$$compose();\n  };\n\n  /**\n   * Compose url and update `absUrl` property\n   * @private\n   */\n  this.$$compose = function() {\n    var search = toKeyValue(this.$$search),\n        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';\n\n    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;\n    this.$$absUrl = appBaseNoFile + this.$$url.substr(1); // first char is always '/'\n\n    this.$$urlUpdatedByLocation = true;\n  };\n\n  this.$$parseLinkUrl = function(url, relHref) {\n    if (relHref && relHref[0] === '#') {\n      // special case for links to hash fragments:\n      // keep the old url and only replace the hash fragment\n      this.hash(relHref.slice(1));\n      return true;\n    }\n    var appUrl, prevAppUrl;\n    var rewrittenUrl;\n\n\n    if (isDefined(appUrl = stripBaseUrl(appBase, url))) {\n      prevAppUrl = appUrl;\n      if (basePrefix && isDefined(appUrl = stripBaseUrl(basePrefix, appUrl))) {\n        rewrittenUrl = appBaseNoFile + (stripBaseUrl('/', appUrl) || appUrl);\n      } else {\n        rewrittenUrl = appBase + prevAppUrl;\n      }\n    } else if (isDefined(appUrl = stripBaseUrl(appBaseNoFile, url))) {\n      rewrittenUrl = appBaseNoFile + appUrl;\n    } else if (appBaseNoFile === url + '/') {\n      rewrittenUrl = appBaseNoFile;\n    }\n    if (rewrittenUrl) {\n      this.$$parse(rewrittenUrl);\n    }\n    return !!rewrittenUrl;\n  };\n}\n\n\n/**\n * LocationHashbangUrl represents URL\n * This object is exposed as $location service when developer doesn't opt into html5 mode.\n * It also serves as the base class for html5 mode fallback on legacy browsers.\n *\n * @constructor\n * @param {string} appBase application base URL\n * @param {string} appBaseNoFile application base URL stripped of any filename\n * @param {string} hashPrefix hashbang prefix\n */\nfunction LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) {\n\n  parseAbsoluteUrl(appBase, this);\n\n\n  /**\n   * Parse given hashbang URL into properties\n   * @param {string} url Hashbang URL\n   * @private\n   */\n  this.$$parse = function(url) {\n    var withoutBaseUrl = stripBaseUrl(appBase, url) || stripBaseUrl(appBaseNoFile, url);\n    var withoutHashUrl;\n\n    if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === '#') {\n\n      // The rest of the URL starts with a hash so we have\n      // got either a hashbang path or a plain hash fragment\n      withoutHashUrl = stripBaseUrl(hashPrefix, withoutBaseUrl);\n      if (isUndefined(withoutHashUrl)) {\n        // There was no hashbang prefix so we just have a hash fragment\n        withoutHashUrl = withoutBaseUrl;\n      }\n\n    } else {\n      // There was no hashbang path nor hash fragment:\n      // If we are in HTML5 mode we use what is left as the path;\n      // Otherwise we ignore what is left\n      if (this.$$html5) {\n        withoutHashUrl = withoutBaseUrl;\n      } else {\n        withoutHashUrl = '';\n        if (isUndefined(withoutBaseUrl)) {\n          appBase = url;\n          /** @type {?} */ (this).replace();\n        }\n      }\n    }\n\n    parseAppUrl(withoutHashUrl, this);\n\n    this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);\n\n    this.$$compose();\n\n    /*\n     * In Windows, on an anchor node on documents loaded from\n     * the filesystem, the browser will return a pathname\n     * prefixed with the drive name ('/C:/path') when a\n     * pathname without a drive is set:\n     *  * a.setAttribute('href', '/foo')\n     *   * a.pathname === '/C:/foo' //true\n     *\n     * Inside of Angular, we're always using pathnames that\n     * do not include drive names for routing.\n     */\n    function removeWindowsDriveName(path, url, base) {\n      /*\n      Matches paths for file protocol on windows,\n      such as /C:/foo/bar, and captures only /foo/bar.\n      */\n      var windowsFilePathExp = /^\\/[A-Z]:(\\/.*)/;\n\n      var firstPathSegmentMatch;\n\n      //Get the relative path from the input URL.\n      if (startsWith(url, base)) {\n        url = url.replace(base, '');\n      }\n\n      // The input URL intentionally contains a first path segment that ends with a colon.\n      if (windowsFilePathExp.exec(url)) {\n        return path;\n      }\n\n      firstPathSegmentMatch = windowsFilePathExp.exec(path);\n      return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;\n    }\n  };\n\n  /**\n   * Compose hashbang URL and update `absUrl` property\n   * @private\n   */\n  this.$$compose = function() {\n    var search = toKeyValue(this.$$search),\n        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';\n\n    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;\n    this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : '');\n\n    this.$$urlUpdatedByLocation = true;\n  };\n\n  this.$$parseLinkUrl = function(url, relHref) {\n    if (stripHash(appBase) === stripHash(url)) {\n      this.$$parse(url);\n      return true;\n    }\n    return false;\n  };\n}\n\n\n/**\n * LocationHashbangUrl represents URL\n * This object is exposed as $location service when html5 history api is enabled but the browser\n * does not support it.\n *\n * @constructor\n * @param {string} appBase application base URL\n * @param {string} appBaseNoFile application base URL stripped of any filename\n * @param {string} hashPrefix hashbang prefix\n */\nfunction LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) {\n  this.$$html5 = true;\n  LocationHashbangUrl.apply(this, arguments);\n\n  this.$$parseLinkUrl = function(url, relHref) {\n    if (relHref && relHref[0] === '#') {\n      // special case for links to hash fragments:\n      // keep the old url and only replace the hash fragment\n      this.hash(relHref.slice(1));\n      return true;\n    }\n\n    var rewrittenUrl;\n    var appUrl;\n\n    if (appBase === stripHash(url)) {\n      rewrittenUrl = url;\n    } else if ((appUrl = stripBaseUrl(appBaseNoFile, url))) {\n      rewrittenUrl = appBase + hashPrefix + appUrl;\n    } else if (appBaseNoFile === url + '/') {\n      rewrittenUrl = appBaseNoFile;\n    }\n    if (rewrittenUrl) {\n      this.$$parse(rewrittenUrl);\n    }\n    return !!rewrittenUrl;\n  };\n\n  this.$$compose = function() {\n    var search = toKeyValue(this.$$search),\n        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';\n\n    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;\n    // include hashPrefix in $$absUrl when $$url is empty so IE9 does not reload page because of removal of '#'\n    this.$$absUrl = appBase + hashPrefix + this.$$url;\n\n    this.$$urlUpdatedByLocation = true;\n  };\n\n}\n\n\nvar locationPrototype = {\n\n  /**\n   * Ensure absolute URL is initialized.\n   * @private\n   */\n  $$absUrl:'',\n\n  /**\n   * Are we in html5 mode?\n   * @private\n   */\n  $$html5: false,\n\n  /**\n   * Has any change been replacing?\n   * @private\n   */\n  $$replace: false,\n\n  /**\n   * @ngdoc method\n   * @name $location#absUrl\n   *\n   * @description\n   * This method is getter only.\n   *\n   * Return full URL representation with all segments encoded according to rules specified in\n   * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var absUrl = $location.absUrl();\n   * // => \"http://example.com/#/some/path?foo=bar&baz=xoxo\"\n   * ```\n   *\n   * @return {string} full URL\n   */\n  absUrl: locationGetter('$$absUrl'),\n\n  /**\n   * @ngdoc method\n   * @name $location#url\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.\n   *\n   * Change path, search and hash, when called with parameter and return `$location`.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var url = $location.url();\n   * // => \"/some/path?foo=bar&baz=xoxo\"\n   * ```\n   *\n   * @param {string=} url New URL without base prefix (e.g. `/path?a=b#hash`)\n   * @return {string} url\n   */\n  url: function(url) {\n    if (isUndefined(url)) {\n      return this.$$url;\n    }\n\n    var match = PATH_MATCH.exec(url);\n    if (match[1] || url === '') this.path(decodeURIComponent(match[1]));\n    if (match[2] || match[1] || url === '') this.search(match[3] || '');\n    this.hash(match[5] || '');\n\n    return this;\n  },\n\n  /**\n   * @ngdoc method\n   * @name $location#protocol\n   *\n   * @description\n   * This method is getter only.\n   *\n   * Return protocol of current URL.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var protocol = $location.protocol();\n   * // => \"http\"\n   * ```\n   *\n   * @return {string} protocol of current URL\n   */\n  protocol: locationGetter('$$protocol'),\n\n  /**\n   * @ngdoc method\n   * @name $location#host\n   *\n   * @description\n   * This method is getter only.\n   *\n   * Return host of current URL.\n   *\n   * Note: compared to the non-angular version `location.host` which returns `hostname:port`, this returns the `hostname` portion only.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var host = $location.host();\n   * // => \"example.com\"\n   *\n   * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo\n   * host = $location.host();\n   * // => \"example.com\"\n   * host = location.host;\n   * // => \"example.com:8080\"\n   * ```\n   *\n   * @return {string} host of current URL.\n   */\n  host: locationGetter('$$host'),\n\n  /**\n   * @ngdoc method\n   * @name $location#port\n   *\n   * @description\n   * This method is getter only.\n   *\n   * Return port of current URL.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var port = $location.port();\n   * // => 80\n   * ```\n   *\n   * @return {Number} port\n   */\n  port: locationGetter('$$port'),\n\n  /**\n   * @ngdoc method\n   * @name $location#path\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Return path of current URL when called without any parameter.\n   *\n   * Change path when called with parameter and return `$location`.\n   *\n   * Note: Path should always begin with forward slash (/), this method will add the forward slash\n   * if it is missing.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var path = $location.path();\n   * // => \"/some/path\"\n   * ```\n   *\n   * @param {(string|number)=} path New path\n   * @return {(string|object)} path if called with no parameters, or `$location` if called with a parameter\n   */\n  path: locationGetterSetter('$$path', function(path) {\n    path = path !== null ? path.toString() : '';\n    return path.charAt(0) === '/' ? path : '/' + path;\n  }),\n\n  /**\n   * @ngdoc method\n   * @name $location#search\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Return search part (as object) of current URL when called without any parameter.\n   *\n   * Change search part when called with parameter and return `$location`.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var searchObject = $location.search();\n   * // => {foo: 'bar', baz: 'xoxo'}\n   *\n   * // set foo to 'yipee'\n   * $location.search('foo', 'yipee');\n   * // $location.search() => {foo: 'yipee', baz: 'xoxo'}\n   * ```\n   *\n   * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or\n   * hash object.\n   *\n   * When called with a single argument the method acts as a setter, setting the `search` component\n   * of `$location` to the specified value.\n   *\n   * If the argument is a hash object containing an array of values, these values will be encoded\n   * as duplicate search parameters in the URL.\n   *\n   * @param {(string|Number|Array<string>|boolean)=} paramValue If `search` is a string or number, then `paramValue`\n   * will override only a single search property.\n   *\n   * If `paramValue` is an array, it will override the property of the `search` component of\n   * `$location` specified via the first argument.\n   *\n   * If `paramValue` is `null`, the property specified via the first argument will be deleted.\n   *\n   * If `paramValue` is `true`, the property specified via the first argument will be added with no\n   * value nor trailing equal sign.\n   *\n   * @return {Object} If called with no arguments returns the parsed `search` object. If called with\n   * one or more arguments returns `$location` object itself.\n   */\n  search: function(search, paramValue) {\n    switch (arguments.length) {\n      case 0:\n        return this.$$search;\n      case 1:\n        if (isString(search) || isNumber(search)) {\n          search = search.toString();\n          this.$$search = parseKeyValue(search);\n        } else if (isObject(search)) {\n          search = copy(search, {});\n          // remove object undefined or null properties\n          forEach(search, function(value, key) {\n            if (value == null) delete search[key];\n          });\n\n          this.$$search = search;\n        } else {\n          throw $locationMinErr('isrcharg',\n              'The first argument of the `$location#search()` call must be a string or an object.');\n        }\n        break;\n      default:\n        if (isUndefined(paramValue) || paramValue === null) {\n          delete this.$$search[search];\n        } else {\n          this.$$search[search] = paramValue;\n        }\n    }\n\n    this.$$compose();\n    return this;\n  },\n\n  /**\n   * @ngdoc method\n   * @name $location#hash\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Returns the hash fragment when called without any parameters.\n   *\n   * Changes the hash fragment when called with a parameter and returns `$location`.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue\n   * var hash = $location.hash();\n   * // => \"hashValue\"\n   * ```\n   *\n   * @param {(string|number)=} hash New hash fragment\n   * @return {string} hash\n   */\n  hash: locationGetterSetter('$$hash', function(hash) {\n    return hash !== null ? hash.toString() : '';\n  }),\n\n  /**\n   * @ngdoc method\n   * @name $location#replace\n   *\n   * @description\n   * If called, all changes to $location during the current `$digest` will replace the current history\n   * record, instead of adding a new one.\n   */\n  replace: function() {\n    this.$$replace = true;\n    return this;\n  }\n};\n\nforEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) {\n  Location.prototype = Object.create(locationPrototype);\n\n  /**\n   * @ngdoc method\n   * @name $location#state\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Return the history state object when called without any parameter.\n   *\n   * Change the history state object when called with one parameter and return `$location`.\n   * The state object is later passed to `pushState` or `replaceState`.\n   *\n   * NOTE: This method is supported only in HTML5 mode and only in browsers supporting\n   * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support\n   * older browsers (like IE9 or Android < 4.0), don't use this method.\n   *\n   * @param {object=} state State object for pushState or replaceState\n   * @return {object} state\n   */\n  Location.prototype.state = function(state) {\n    if (!arguments.length) {\n      return this.$$state;\n    }\n\n    if (Location !== LocationHtml5Url || !this.$$html5) {\n      throw $locationMinErr('nostate', 'History API state support is available only ' +\n        'in HTML5 mode and only in browsers supporting HTML5 History API');\n    }\n    // The user might modify `stateObject` after invoking `$location.state(stateObject)`\n    // but we're changing the $$state reference to $browser.state() during the $digest\n    // so the modification window is narrow.\n    this.$$state = isUndefined(state) ? null : state;\n    this.$$urlUpdatedByLocation = true;\n\n    return this;\n  };\n});\n\n\nfunction locationGetter(property) {\n  return /** @this */ function() {\n    return this[property];\n  };\n}\n\n\nfunction locationGetterSetter(property, preprocess) {\n  return /** @this */ function(value) {\n    if (isUndefined(value)) {\n      return this[property];\n    }\n\n    this[property] = preprocess(value);\n    this.$$compose();\n\n    return this;\n  };\n}\n\n\n/**\n * @ngdoc service\n * @name $location\n *\n * @requires $rootElement\n *\n * @description\n * The $location service parses the URL in the browser address bar (based on the\n * [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL\n * available to your application. Changes to the URL in the address bar are reflected into\n * $location service and changes to $location are reflected into the browser address bar.\n *\n * **The $location service:**\n *\n * - Exposes the current URL in the browser address bar, so you can\n *   - Watch and observe the URL.\n *   - Change the URL.\n * - Synchronizes the URL with the browser when the user\n *   - Changes the address bar.\n *   - Clicks the back or forward button (or clicks a History link).\n *   - Clicks on a link.\n * - Represents the URL object as a set of methods (protocol, host, port, path, search, hash).\n *\n * For more information see {@link guide/$location Developer Guide: Using $location}\n */\n\n/**\n * @ngdoc provider\n * @name $locationProvider\n * @this\n *\n * @description\n * Use the `$locationProvider` to configure how the application deep linking paths are stored.\n */\nfunction $LocationProvider() {\n  var hashPrefix = '!',\n      html5Mode = {\n        enabled: false,\n        requireBase: true,\n        rewriteLinks: true\n      };\n\n  /**\n   * @ngdoc method\n   * @name $locationProvider#hashPrefix\n   * @description\n   * The default value for the prefix is `'!'`.\n   * @param {string=} prefix Prefix for hash part (containing path and search)\n   * @returns {*} current value if used as getter or itself (chaining) if used as setter\n   */\n  this.hashPrefix = function(prefix) {\n    if (isDefined(prefix)) {\n      hashPrefix = prefix;\n      return this;\n    } else {\n      return hashPrefix;\n    }\n  };\n\n  /**\n   * @ngdoc method\n   * @name $locationProvider#html5Mode\n   * @description\n   * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value.\n   *   If object, sets `enabled`, `requireBase` and `rewriteLinks` to respective values. Supported\n   *   properties:\n   *   - **enabled** – `{boolean}` – (default: false) If true, will rely on `history.pushState` to\n   *     change urls where supported. Will fall back to hash-prefixed paths in browsers that do not\n   *     support `pushState`.\n   *   - **requireBase** - `{boolean}` - (default: `true`) When html5Mode is enabled, specifies\n   *     whether or not a <base> tag is required to be present. If `enabled` and `requireBase` are\n   *     true, and a base tag is not present, an error will be thrown when `$location` is injected.\n   *     See the {@link guide/$location $location guide for more information}\n   *   - **rewriteLinks** - `{boolean|string}` - (default: `true`) When html5Mode is enabled,\n   *     enables/disables URL rewriting for relative links. If set to a string, URL rewriting will\n   *     only happen on links with an attribute that matches the given string. For example, if set\n   *     to `'internal-link'`, then the URL will only be rewritten for `<a internal-link>` links.\n   *     Note that [attribute name normalization](guide/directive#normalization) does not apply\n   *     here, so `'internalLink'` will **not** match `'internal-link'`.\n   *\n   * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter\n   */\n  this.html5Mode = function(mode) {\n    if (isBoolean(mode)) {\n      html5Mode.enabled = mode;\n      return this;\n    } else if (isObject(mode)) {\n\n      if (isBoolean(mode.enabled)) {\n        html5Mode.enabled = mode.enabled;\n      }\n\n      if (isBoolean(mode.requireBase)) {\n        html5Mode.requireBase = mode.requireBase;\n      }\n\n      if (isBoolean(mode.rewriteLinks) || isString(mode.rewriteLinks)) {\n        html5Mode.rewriteLinks = mode.rewriteLinks;\n      }\n\n      return this;\n    } else {\n      return html5Mode;\n    }\n  };\n\n  /**\n   * @ngdoc event\n   * @name $location#$locationChangeStart\n   * @eventType broadcast on root scope\n   * @description\n   * Broadcasted before a URL will change.\n   *\n   * This change can be prevented by calling\n   * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more\n   * details about event object. Upon successful change\n   * {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired.\n   *\n   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when\n   * the browser supports the HTML5 History API.\n   *\n   * @param {Object} angularEvent Synthetic event object.\n   * @param {string} newUrl New URL\n   * @param {string=} oldUrl URL that was before it was changed.\n   * @param {string=} newState New history state object\n   * @param {string=} oldState History state object that was before it was changed.\n   */\n\n  /**\n   * @ngdoc event\n   * @name $location#$locationChangeSuccess\n   * @eventType broadcast on root scope\n   * @description\n   * Broadcasted after a URL was changed.\n   *\n   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when\n   * the browser supports the HTML5 History API.\n   *\n   * @param {Object} angularEvent Synthetic event object.\n   * @param {string} newUrl New URL\n   * @param {string=} oldUrl URL that was before it was changed.\n   * @param {string=} newState New history state object\n   * @param {string=} oldState History state object that was before it was changed.\n   */\n\n  this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', '$window',\n      function($rootScope, $browser, $sniffer, $rootElement, $window) {\n    var $location,\n        LocationMode,\n        baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''\n        initialUrl = $browser.url(),\n        appBase;\n\n    if (html5Mode.enabled) {\n      if (!baseHref && html5Mode.requireBase) {\n        throw $locationMinErr('nobase',\n          '$location in HTML5 mode requires a <base> tag to be present!');\n      }\n      appBase = serverBase(initialUrl) + (baseHref || '/');\n      LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url;\n    } else {\n      appBase = stripHash(initialUrl);\n      LocationMode = LocationHashbangUrl;\n    }\n    var appBaseNoFile = stripFile(appBase);\n\n    $location = new LocationMode(appBase, appBaseNoFile, '#' + hashPrefix);\n    $location.$$parseLinkUrl(initialUrl, initialUrl);\n\n    $location.$$state = $browser.state();\n\n    var IGNORE_URI_REGEXP = /^\\s*(javascript|mailto):/i;\n\n    function setBrowserUrlWithFallback(url, replace, state) {\n      var oldUrl = $location.url();\n      var oldState = $location.$$state;\n      try {\n        $browser.url(url, replace, state);\n\n        // Make sure $location.state() returns referentially identical (not just deeply equal)\n        // state object; this makes possible quick checking if the state changed in the digest\n        // loop. Checking deep equality would be too expensive.\n        $location.$$state = $browser.state();\n      } catch (e) {\n        // Restore old values if pushState fails\n        $location.url(oldUrl);\n        $location.$$state = oldState;\n\n        throw e;\n      }\n    }\n\n    $rootElement.on('click', function(event) {\n      var rewriteLinks = html5Mode.rewriteLinks;\n      // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)\n      // currently we open nice url link and redirect then\n\n      if (!rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 || event.button === 2) return;\n\n      var elm = jqLite(event.target);\n\n      // traverse the DOM up to find first A tag\n      while (nodeName_(elm[0]) !== 'a') {\n        // ignore rewriting if no A tag (reached root element, or no parent - removed from document)\n        if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return;\n      }\n\n      if (isString(rewriteLinks) && isUndefined(elm.attr(rewriteLinks))) return;\n\n      var absHref = elm.prop('href');\n      // get the actual href attribute - see\n      // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx\n      var relHref = elm.attr('href') || elm.attr('xlink:href');\n\n      if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {\n        // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during\n        // an animation.\n        absHref = urlResolve(absHref.animVal).href;\n      }\n\n      // Ignore when url is started with javascript: or mailto:\n      if (IGNORE_URI_REGEXP.test(absHref)) return;\n\n      if (absHref && !elm.attr('target') && !event.isDefaultPrevented()) {\n        if ($location.$$parseLinkUrl(absHref, relHref)) {\n          // We do a preventDefault for all urls that are part of the angular application,\n          // in html5mode and also without, so that we are able to abort navigation without\n          // getting double entries in the location history.\n          event.preventDefault();\n          // update location manually\n          if ($location.absUrl() !== $browser.url()) {\n            $rootScope.$apply();\n            // hack to work around FF6 bug 684208 when scenario runner clicks on links\n            $window.angular['ff-684208-preventDefault'] = true;\n          }\n        }\n      }\n    });\n\n\n    // rewrite hashbang url <> html5 url\n    if (trimEmptyHash($location.absUrl()) !== trimEmptyHash(initialUrl)) {\n      $browser.url($location.absUrl(), true);\n    }\n\n    var initializing = true;\n\n    // update $location when $browser url changes\n    $browser.onUrlChange(function(newUrl, newState) {\n\n      if (!startsWith(newUrl, appBaseNoFile)) {\n        // If we are navigating outside of the app then force a reload\n        $window.location.href = newUrl;\n        return;\n      }\n\n      $rootScope.$evalAsync(function() {\n        var oldUrl = $location.absUrl();\n        var oldState = $location.$$state;\n        var defaultPrevented;\n        newUrl = trimEmptyHash(newUrl);\n        $location.$$parse(newUrl);\n        $location.$$state = newState;\n\n        defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,\n            newState, oldState).defaultPrevented;\n\n        // if the location was changed by a `$locationChangeStart` handler then stop\n        // processing this location change\n        if ($location.absUrl() !== newUrl) return;\n\n        if (defaultPrevented) {\n          $location.$$parse(oldUrl);\n          $location.$$state = oldState;\n          setBrowserUrlWithFallback(oldUrl, false, oldState);\n        } else {\n          initializing = false;\n          afterLocationChange(oldUrl, oldState);\n        }\n      });\n      if (!$rootScope.$$phase) $rootScope.$digest();\n    });\n\n    // update browser\n    $rootScope.$watch(function $locationWatch() {\n      if (initializing || $location.$$urlUpdatedByLocation) {\n        $location.$$urlUpdatedByLocation = false;\n\n        var oldUrl = trimEmptyHash($browser.url());\n        var newUrl = trimEmptyHash($location.absUrl());\n        var oldState = $browser.state();\n        var currentReplace = $location.$$replace;\n        var urlOrStateChanged = oldUrl !== newUrl ||\n          ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);\n\n        if (initializing || urlOrStateChanged) {\n          initializing = false;\n\n          $rootScope.$evalAsync(function() {\n            var newUrl = $location.absUrl();\n            var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,\n                $location.$$state, oldState).defaultPrevented;\n\n            // if the location was changed by a `$locationChangeStart` handler then stop\n            // processing this location change\n            if ($location.absUrl() !== newUrl) return;\n\n            if (defaultPrevented) {\n              $location.$$parse(oldUrl);\n              $location.$$state = oldState;\n            } else {\n              if (urlOrStateChanged) {\n                setBrowserUrlWithFallback(newUrl, currentReplace,\n                                          oldState === $location.$$state ? null : $location.$$state);\n              }\n              afterLocationChange(oldUrl, oldState);\n            }\n          });\n        }\n      }\n\n      $location.$$replace = false;\n\n      // we don't need to return anything because $evalAsync will make the digest loop dirty when\n      // there is a change\n    });\n\n    return $location;\n\n    function afterLocationChange(oldUrl, oldState) {\n      $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl,\n        $location.$$state, oldState);\n    }\n}];\n}\n\n/**\n * @ngdoc service\n * @name $log\n * @requires $window\n *\n * @description\n * Simple service for logging. Default implementation safely writes the message\n * into the browser's console (if present).\n *\n * The main purpose of this service is to simplify debugging and troubleshooting.\n *\n * The default is to log `debug` messages. You can use\n * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.\n *\n * @example\n   <example module=\"logExample\" name=\"log-service\">\n     <file name=\"script.js\">\n       angular.module('logExample', [])\n         .controller('LogController', ['$scope', '$log', function($scope, $log) {\n           $scope.$log = $log;\n           $scope.message = 'Hello World!';\n         }]);\n     </file>\n     <file name=\"index.html\">\n       <div ng-controller=\"LogController\">\n         <p>Reload this page with open console, enter text and hit the log button...</p>\n         <label>Message:\n         <input type=\"text\" ng-model=\"message\" /></label>\n         <button ng-click=\"$log.log(message)\">log</button>\n         <button ng-click=\"$log.warn(message)\">warn</button>\n         <button ng-click=\"$log.info(message)\">info</button>\n         <button ng-click=\"$log.error(message)\">error</button>\n         <button ng-click=\"$log.debug(message)\">debug</button>\n       </div>\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc provider\n * @name $logProvider\n * @this\n *\n * @description\n * Use the `$logProvider` to configure how the application logs messages\n */\nfunction $LogProvider() {\n  var debug = true,\n      self = this;\n\n  /**\n   * @ngdoc method\n   * @name $logProvider#debugEnabled\n   * @description\n   * @param {boolean=} flag enable or disable debug level messages\n   * @returns {*} current value if used as getter or itself (chaining) if used as setter\n   */\n  this.debugEnabled = function(flag) {\n    if (isDefined(flag)) {\n      debug = flag;\n      return this;\n    } else {\n      return debug;\n    }\n  };\n\n  this.$get = ['$window', function($window) {\n    // Support: IE 9-11, Edge 12-14+\n    // IE/Edge display errors in such a way that it requires the user to click in 4 places\n    // to see the stack trace. There is no way to feature-detect it so there's a chance\n    // of the user agent sniffing to go wrong but since it's only about logging, this shouldn't\n    // break apps. Other browsers display errors in a sensible way and some of them map stack\n    // traces along source maps if available so it makes sense to let browsers display it\n    // as they want.\n    var formatStackTrace = msie || /\\bEdge\\//.test($window.navigator && $window.navigator.userAgent);\n\n    return {\n      /**\n       * @ngdoc method\n       * @name $log#log\n       *\n       * @description\n       * Write a log message\n       */\n      log: consoleLog('log'),\n\n      /**\n       * @ngdoc method\n       * @name $log#info\n       *\n       * @description\n       * Write an information message\n       */\n      info: consoleLog('info'),\n\n      /**\n       * @ngdoc method\n       * @name $log#warn\n       *\n       * @description\n       * Write a warning message\n       */\n      warn: consoleLog('warn'),\n\n      /**\n       * @ngdoc method\n       * @name $log#error\n       *\n       * @description\n       * Write an error message\n       */\n      error: consoleLog('error'),\n\n      /**\n       * @ngdoc method\n       * @name $log#debug\n       *\n       * @description\n       * Write a debug message\n       */\n      debug: (function() {\n        var fn = consoleLog('debug');\n\n        return function() {\n          if (debug) {\n            fn.apply(self, arguments);\n          }\n        };\n      })()\n    };\n\n    function formatError(arg) {\n      if (arg instanceof Error) {\n        if (arg.stack && formatStackTrace) {\n          arg = (arg.message && arg.stack.indexOf(arg.message) === -1)\n              ? 'Error: ' + arg.message + '\\n' + arg.stack\n              : arg.stack;\n        } else if (arg.sourceURL) {\n          arg = arg.message + '\\n' + arg.sourceURL + ':' + arg.line;\n        }\n      }\n      return arg;\n    }\n\n    function consoleLog(type) {\n      var console = $window.console || {},\n          logFn = console[type] || console.log || noop,\n          hasApply = false;\n\n      // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.\n      // The reason behind this is that console.log has type \"object\" in IE8...\n      try {\n        hasApply = !!logFn.apply;\n      } catch (e) { /* empty */ }\n\n      if (hasApply) {\n        return function() {\n          var args = [];\n          forEach(arguments, function(arg) {\n            args.push(formatError(arg));\n          });\n          return logFn.apply(console, args);\n        };\n      }\n\n      // we are IE which either doesn't have window.console => this is noop and we do nothing,\n      // or we are IE where console.log doesn't have apply so we log at least first 2 args\n      return function(arg1, arg2) {\n        logFn(arg1, arg2 == null ? '' : arg2);\n      };\n    }\n  }];\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *     Any commits to this file should be reviewed with security in mind.  *\n *   Changes to this file can potentially create security vulnerabilities. *\n *          An approval from 2 Core members with history of modifying      *\n *                         this file is required.                          *\n *                                                                         *\n *  Does the change somehow allow for arbitrary javascript to be executed? *\n *    Or allows for someone to change the prototype of built-in objects?   *\n *     Or gives undesired access to variables likes document or window?    *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\nvar $parseMinErr = minErr('$parse');\n\nvar objectValueOf = {}.constructor.prototype.valueOf;\n\n// Sandboxing Angular Expressions\n// ------------------------------\n// Angular expressions are no longer sandboxed. So it is now even easier to access arbitrary JS code by\n// various means such as obtaining a reference to native JS functions like the Function constructor.\n//\n// As an example, consider the following Angular expression:\n//\n//   {}.toString.constructor('alert(\"evil JS code\")')\n//\n// It is important to realize that if you create an expression from a string that contains user provided\n// content then it is possible that your application contains a security vulnerability to an XSS style attack.\n//\n// See https://docs.angularjs.org/guide/security\n\n\nfunction getStringValue(name) {\n  // Property names must be strings. This means that non-string objects cannot be used\n  // as keys in an object. Any non-string object, including a number, is typecasted\n  // into a string via the toString method.\n  // -- MDN, https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names\n  //\n  // So, to ensure that we are checking the same `name` that JavaScript would use, we cast it\n  // to a string. It's not always possible. If `name` is an object and its `toString` method is\n  // 'broken' (doesn't return a string, isn't a function, etc.), an error will be thrown:\n  //\n  // TypeError: Cannot convert object to primitive value\n  //\n  // For performance reasons, we don't catch this error here and allow it to propagate up the call\n  // stack. Note that you'll get the same error in JavaScript if you try to access a property using\n  // such a 'broken' object as a key.\n  return name + '';\n}\n\n\nvar OPERATORS = createMap();\nforEach('+ - * / % === !== == != < > <= >= && || ! = |'.split(' '), function(operator) { OPERATORS[operator] = true; });\nvar ESCAPE = {'n':'\\n', 'f':'\\f', 'r':'\\r', 't':'\\t', 'v':'\\v', '\\'':'\\'', '\"':'\"'};\n\n\n/////////////////////////////////////////\n\n\n/**\n * @constructor\n */\nvar Lexer = function Lexer(options) {\n  this.options = options;\n};\n\nLexer.prototype = {\n  constructor: Lexer,\n\n  lex: function(text) {\n    this.text = text;\n    this.index = 0;\n    this.tokens = [];\n\n    while (this.index < this.text.length) {\n      var ch = this.text.charAt(this.index);\n      if (ch === '\"' || ch === '\\'') {\n        this.readString(ch);\n      } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {\n        this.readNumber();\n      } else if (this.isIdentifierStart(this.peekMultichar())) {\n        this.readIdent();\n      } else if (this.is(ch, '(){}[].,;:?')) {\n        this.tokens.push({index: this.index, text: ch});\n        this.index++;\n      } else if (this.isWhitespace(ch)) {\n        this.index++;\n      } else {\n        var ch2 = ch + this.peek();\n        var ch3 = ch2 + this.peek(2);\n        var op1 = OPERATORS[ch];\n        var op2 = OPERATORS[ch2];\n        var op3 = OPERATORS[ch3];\n        if (op1 || op2 || op3) {\n          var token = op3 ? ch3 : (op2 ? ch2 : ch);\n          this.tokens.push({index: this.index, text: token, operator: true});\n          this.index += token.length;\n        } else {\n          this.throwError('Unexpected next character ', this.index, this.index + 1);\n        }\n      }\n    }\n    return this.tokens;\n  },\n\n  is: function(ch, chars) {\n    return chars.indexOf(ch) !== -1;\n  },\n\n  peek: function(i) {\n    var num = i || 1;\n    return (this.index + num < this.text.length) ? this.text.charAt(this.index + num) : false;\n  },\n\n  isNumber: function(ch) {\n    return ('0' <= ch && ch <= '9') && typeof ch === 'string';\n  },\n\n  isWhitespace: function(ch) {\n    // IE treats non-breaking space as \\u00A0\n    return (ch === ' ' || ch === '\\r' || ch === '\\t' ||\n            ch === '\\n' || ch === '\\v' || ch === '\\u00A0');\n  },\n\n  isIdentifierStart: function(ch) {\n    return this.options.isIdentifierStart ?\n        this.options.isIdentifierStart(ch, this.codePointAt(ch)) :\n        this.isValidIdentifierStart(ch);\n  },\n\n  isValidIdentifierStart: function(ch) {\n    return ('a' <= ch && ch <= 'z' ||\n            'A' <= ch && ch <= 'Z' ||\n            '_' === ch || ch === '$');\n  },\n\n  isIdentifierContinue: function(ch) {\n    return this.options.isIdentifierContinue ?\n        this.options.isIdentifierContinue(ch, this.codePointAt(ch)) :\n        this.isValidIdentifierContinue(ch);\n  },\n\n  isValidIdentifierContinue: function(ch, cp) {\n    return this.isValidIdentifierStart(ch, cp) || this.isNumber(ch);\n  },\n\n  codePointAt: function(ch) {\n    if (ch.length === 1) return ch.charCodeAt(0);\n    // eslint-disable-next-line no-bitwise\n    return (ch.charCodeAt(0) << 10) + ch.charCodeAt(1) - 0x35FDC00;\n  },\n\n  peekMultichar: function() {\n    var ch = this.text.charAt(this.index);\n    var peek = this.peek();\n    if (!peek) {\n      return ch;\n    }\n    var cp1 = ch.charCodeAt(0);\n    var cp2 = peek.charCodeAt(0);\n    if (cp1 >= 0xD800 && cp1 <= 0xDBFF && cp2 >= 0xDC00 && cp2 <= 0xDFFF) {\n      return ch + peek;\n    }\n    return ch;\n  },\n\n  isExpOperator: function(ch) {\n    return (ch === '-' || ch === '+' || this.isNumber(ch));\n  },\n\n  throwError: function(error, start, end) {\n    end = end || this.index;\n    var colStr = (isDefined(start)\n            ? 's ' + start +  '-' + this.index + ' [' + this.text.substring(start, end) + ']'\n            : ' ' + end);\n    throw $parseMinErr('lexerr', 'Lexer Error: {0} at column{1} in expression [{2}].',\n        error, colStr, this.text);\n  },\n\n  readNumber: function() {\n    var number = '';\n    var start = this.index;\n    while (this.index < this.text.length) {\n      var ch = lowercase(this.text.charAt(this.index));\n      if (ch === '.' || this.isNumber(ch)) {\n        number += ch;\n      } else {\n        var peekCh = this.peek();\n        if (ch === 'e' && this.isExpOperator(peekCh)) {\n          number += ch;\n        } else if (this.isExpOperator(ch) &&\n            peekCh && this.isNumber(peekCh) &&\n            number.charAt(number.length - 1) === 'e') {\n          number += ch;\n        } else if (this.isExpOperator(ch) &&\n            (!peekCh || !this.isNumber(peekCh)) &&\n            number.charAt(number.length - 1) === 'e') {\n          this.throwError('Invalid exponent');\n        } else {\n          break;\n        }\n      }\n      this.index++;\n    }\n    this.tokens.push({\n      index: start,\n      text: number,\n      constant: true,\n      value: Number(number)\n    });\n  },\n\n  readIdent: function() {\n    var start = this.index;\n    this.index += this.peekMultichar().length;\n    while (this.index < this.text.length) {\n      var ch = this.peekMultichar();\n      if (!this.isIdentifierContinue(ch)) {\n        break;\n      }\n      this.index += ch.length;\n    }\n    this.tokens.push({\n      index: start,\n      text: this.text.slice(start, this.index),\n      identifier: true\n    });\n  },\n\n  readString: function(quote) {\n    var start = this.index;\n    this.index++;\n    var string = '';\n    var rawString = quote;\n    var escape = false;\n    while (this.index < this.text.length) {\n      var ch = this.text.charAt(this.index);\n      rawString += ch;\n      if (escape) {\n        if (ch === 'u') {\n          var hex = this.text.substring(this.index + 1, this.index + 5);\n          if (!hex.match(/[\\da-f]{4}/i)) {\n            this.throwError('Invalid unicode escape [\\\\u' + hex + ']');\n          }\n          this.index += 4;\n          string += String.fromCharCode(parseInt(hex, 16));\n        } else {\n          var rep = ESCAPE[ch];\n          string = string + (rep || ch);\n        }\n        escape = false;\n      } else if (ch === '\\\\') {\n        escape = true;\n      } else if (ch === quote) {\n        this.index++;\n        this.tokens.push({\n          index: start,\n          text: rawString,\n          constant: true,\n          value: string\n        });\n        return;\n      } else {\n        string += ch;\n      }\n      this.index++;\n    }\n    this.throwError('Unterminated quote', start);\n  }\n};\n\nvar AST = function AST(lexer, options) {\n  this.lexer = lexer;\n  this.options = options;\n};\n\nAST.Program = 'Program';\nAST.ExpressionStatement = 'ExpressionStatement';\nAST.AssignmentExpression = 'AssignmentExpression';\nAST.ConditionalExpression = 'ConditionalExpression';\nAST.LogicalExpression = 'LogicalExpression';\nAST.BinaryExpression = 'BinaryExpression';\nAST.UnaryExpression = 'UnaryExpression';\nAST.CallExpression = 'CallExpression';\nAST.MemberExpression = 'MemberExpression';\nAST.Identifier = 'Identifier';\nAST.Literal = 'Literal';\nAST.ArrayExpression = 'ArrayExpression';\nAST.Property = 'Property';\nAST.ObjectExpression = 'ObjectExpression';\nAST.ThisExpression = 'ThisExpression';\nAST.LocalsExpression = 'LocalsExpression';\n\n// Internal use only\nAST.NGValueParameter = 'NGValueParameter';\n\nAST.prototype = {\n  ast: function(text) {\n    this.text = text;\n    this.tokens = this.lexer.lex(text);\n\n    var value = this.program();\n\n    if (this.tokens.length !== 0) {\n      this.throwError('is an unexpected token', this.tokens[0]);\n    }\n\n    return value;\n  },\n\n  program: function() {\n    var body = [];\n    while (true) {\n      if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))\n        body.push(this.expressionStatement());\n      if (!this.expect(';')) {\n        return { type: AST.Program, body: body};\n      }\n    }\n  },\n\n  expressionStatement: function() {\n    return { type: AST.ExpressionStatement, expression: this.filterChain() };\n  },\n\n  filterChain: function() {\n    var left = this.expression();\n    while (this.expect('|')) {\n      left = this.filter(left);\n    }\n    return left;\n  },\n\n  expression: function() {\n    return this.assignment();\n  },\n\n  assignment: function() {\n    var result = this.ternary();\n    if (this.expect('=')) {\n      if (!isAssignable(result)) {\n        throw $parseMinErr('lval', 'Trying to assign a value to a non l-value');\n      }\n\n      result = { type: AST.AssignmentExpression, left: result, right: this.assignment(), operator: '='};\n    }\n    return result;\n  },\n\n  ternary: function() {\n    var test = this.logicalOR();\n    var alternate;\n    var consequent;\n    if (this.expect('?')) {\n      alternate = this.expression();\n      if (this.consume(':')) {\n        consequent = this.expression();\n        return { type: AST.ConditionalExpression, test: test, alternate: alternate, consequent: consequent};\n      }\n    }\n    return test;\n  },\n\n  logicalOR: function() {\n    var left = this.logicalAND();\n    while (this.expect('||')) {\n      left = { type: AST.LogicalExpression, operator: '||', left: left, right: this.logicalAND() };\n    }\n    return left;\n  },\n\n  logicalAND: function() {\n    var left = this.equality();\n    while (this.expect('&&')) {\n      left = { type: AST.LogicalExpression, operator: '&&', left: left, right: this.equality()};\n    }\n    return left;\n  },\n\n  equality: function() {\n    var left = this.relational();\n    var token;\n    while ((token = this.expect('==','!=','===','!=='))) {\n      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.relational() };\n    }\n    return left;\n  },\n\n  relational: function() {\n    var left = this.additive();\n    var token;\n    while ((token = this.expect('<', '>', '<=', '>='))) {\n      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.additive() };\n    }\n    return left;\n  },\n\n  additive: function() {\n    var left = this.multiplicative();\n    var token;\n    while ((token = this.expect('+','-'))) {\n      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.multiplicative() };\n    }\n    return left;\n  },\n\n  multiplicative: function() {\n    var left = this.unary();\n    var token;\n    while ((token = this.expect('*','/','%'))) {\n      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.unary() };\n    }\n    return left;\n  },\n\n  unary: function() {\n    var token;\n    if ((token = this.expect('+', '-', '!'))) {\n      return { type: AST.UnaryExpression, operator: token.text, prefix: true, argument: this.unary() };\n    } else {\n      return this.primary();\n    }\n  },\n\n  primary: function() {\n    var primary;\n    if (this.expect('(')) {\n      primary = this.filterChain();\n      this.consume(')');\n    } else if (this.expect('[')) {\n      primary = this.arrayDeclaration();\n    } else if (this.expect('{')) {\n      primary = this.object();\n    } else if (this.selfReferential.hasOwnProperty(this.peek().text)) {\n      primary = copy(this.selfReferential[this.consume().text]);\n    } else if (this.options.literals.hasOwnProperty(this.peek().text)) {\n      primary = { type: AST.Literal, value: this.options.literals[this.consume().text]};\n    } else if (this.peek().identifier) {\n      primary = this.identifier();\n    } else if (this.peek().constant) {\n      primary = this.constant();\n    } else {\n      this.throwError('not a primary expression', this.peek());\n    }\n\n    var next;\n    while ((next = this.expect('(', '[', '.'))) {\n      if (next.text === '(') {\n        primary = {type: AST.CallExpression, callee: primary, arguments: this.parseArguments() };\n        this.consume(')');\n      } else if (next.text === '[') {\n        primary = { type: AST.MemberExpression, object: primary, property: this.expression(), computed: true };\n        this.consume(']');\n      } else if (next.text === '.') {\n        primary = { type: AST.MemberExpression, object: primary, property: this.identifier(), computed: false };\n      } else {\n        this.throwError('IMPOSSIBLE');\n      }\n    }\n    return primary;\n  },\n\n  filter: function(baseExpression) {\n    var args = [baseExpression];\n    var result = {type: AST.CallExpression, callee: this.identifier(), arguments: args, filter: true};\n\n    while (this.expect(':')) {\n      args.push(this.expression());\n    }\n\n    return result;\n  },\n\n  parseArguments: function() {\n    var args = [];\n    if (this.peekToken().text !== ')') {\n      do {\n        args.push(this.filterChain());\n      } while (this.expect(','));\n    }\n    return args;\n  },\n\n  identifier: function() {\n    var token = this.consume();\n    if (!token.identifier) {\n      this.throwError('is not a valid identifier', token);\n    }\n    return { type: AST.Identifier, name: token.text };\n  },\n\n  constant: function() {\n    // TODO check that it is a constant\n    return { type: AST.Literal, value: this.consume().value };\n  },\n\n  arrayDeclaration: function() {\n    var elements = [];\n    if (this.peekToken().text !== ']') {\n      do {\n        if (this.peek(']')) {\n          // Support trailing commas per ES5.1.\n          break;\n        }\n        elements.push(this.expression());\n      } while (this.expect(','));\n    }\n    this.consume(']');\n\n    return { type: AST.ArrayExpression, elements: elements };\n  },\n\n  object: function() {\n    var properties = [], property;\n    if (this.peekToken().text !== '}') {\n      do {\n        if (this.peek('}')) {\n          // Support trailing commas per ES5.1.\n          break;\n        }\n        property = {type: AST.Property, kind: 'init'};\n        if (this.peek().constant) {\n          property.key = this.constant();\n          property.computed = false;\n          this.consume(':');\n          property.value = this.expression();\n        } else if (this.peek().identifier) {\n          property.key = this.identifier();\n          property.computed = false;\n          if (this.peek(':')) {\n            this.consume(':');\n            property.value = this.expression();\n          } else {\n            property.value = property.key;\n          }\n        } else if (this.peek('[')) {\n          this.consume('[');\n          property.key = this.expression();\n          this.consume(']');\n          property.computed = true;\n          this.consume(':');\n          property.value = this.expression();\n        } else {\n          this.throwError('invalid key', this.peek());\n        }\n        properties.push(property);\n      } while (this.expect(','));\n    }\n    this.consume('}');\n\n    return {type: AST.ObjectExpression, properties: properties };\n  },\n\n  throwError: function(msg, token) {\n    throw $parseMinErr('syntax',\n        'Syntax Error: Token \\'{0}\\' {1} at column {2} of the expression [{3}] starting at [{4}].',\n          token.text, msg, (token.index + 1), this.text, this.text.substring(token.index));\n  },\n\n  consume: function(e1) {\n    if (this.tokens.length === 0) {\n      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);\n    }\n\n    var token = this.expect(e1);\n    if (!token) {\n      this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());\n    }\n    return token;\n  },\n\n  peekToken: function() {\n    if (this.tokens.length === 0) {\n      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);\n    }\n    return this.tokens[0];\n  },\n\n  peek: function(e1, e2, e3, e4) {\n    return this.peekAhead(0, e1, e2, e3, e4);\n  },\n\n  peekAhead: function(i, e1, e2, e3, e4) {\n    if (this.tokens.length > i) {\n      var token = this.tokens[i];\n      var t = token.text;\n      if (t === e1 || t === e2 || t === e3 || t === e4 ||\n          (!e1 && !e2 && !e3 && !e4)) {\n        return token;\n      }\n    }\n    return false;\n  },\n\n  expect: function(e1, e2, e3, e4) {\n    var token = this.peek(e1, e2, e3, e4);\n    if (token) {\n      this.tokens.shift();\n      return token;\n    }\n    return false;\n  },\n\n  selfReferential: {\n    'this': {type: AST.ThisExpression },\n    '$locals': {type: AST.LocalsExpression }\n  }\n};\n\nfunction ifDefined(v, d) {\n  return typeof v !== 'undefined' ? v : d;\n}\n\nfunction plusFn(l, r) {\n  if (typeof l === 'undefined') return r;\n  if (typeof r === 'undefined') return l;\n  return l + r;\n}\n\nfunction isStateless($filter, filterName) {\n  var fn = $filter(filterName);\n  return !fn.$stateful;\n}\n\nfunction findConstantAndWatchExpressions(ast, $filter) {\n  var allConstants;\n  var argsToWatch;\n  var isStatelessFilter;\n  switch (ast.type) {\n  case AST.Program:\n    allConstants = true;\n    forEach(ast.body, function(expr) {\n      findConstantAndWatchExpressions(expr.expression, $filter);\n      allConstants = allConstants && expr.expression.constant;\n    });\n    ast.constant = allConstants;\n    break;\n  case AST.Literal:\n    ast.constant = true;\n    ast.toWatch = [];\n    break;\n  case AST.UnaryExpression:\n    findConstantAndWatchExpressions(ast.argument, $filter);\n    ast.constant = ast.argument.constant;\n    ast.toWatch = ast.argument.toWatch;\n    break;\n  case AST.BinaryExpression:\n    findConstantAndWatchExpressions(ast.left, $filter);\n    findConstantAndWatchExpressions(ast.right, $filter);\n    ast.constant = ast.left.constant && ast.right.constant;\n    ast.toWatch = ast.left.toWatch.concat(ast.right.toWatch);\n    break;\n  case AST.LogicalExpression:\n    findConstantAndWatchExpressions(ast.left, $filter);\n    findConstantAndWatchExpressions(ast.right, $filter);\n    ast.constant = ast.left.constant && ast.right.constant;\n    ast.toWatch = ast.constant ? [] : [ast];\n    break;\n  case AST.ConditionalExpression:\n    findConstantAndWatchExpressions(ast.test, $filter);\n    findConstantAndWatchExpressions(ast.alternate, $filter);\n    findConstantAndWatchExpressions(ast.consequent, $filter);\n    ast.constant = ast.test.constant && ast.alternate.constant && ast.consequent.constant;\n    ast.toWatch = ast.constant ? [] : [ast];\n    break;\n  case AST.Identifier:\n    ast.constant = false;\n    ast.toWatch = [ast];\n    break;\n  case AST.MemberExpression:\n    findConstantAndWatchExpressions(ast.object, $filter);\n    if (ast.computed) {\n      findConstantAndWatchExpressions(ast.property, $filter);\n    }\n    ast.constant = ast.object.constant && (!ast.computed || ast.property.constant);\n    ast.toWatch = [ast];\n    break;\n  case AST.CallExpression:\n    isStatelessFilter = ast.filter ? isStateless($filter, ast.callee.name) : false;\n    allConstants = isStatelessFilter;\n    argsToWatch = [];\n    forEach(ast.arguments, function(expr) {\n      findConstantAndWatchExpressions(expr, $filter);\n      allConstants = allConstants && expr.constant;\n      if (!expr.constant) {\n        argsToWatch.push.apply(argsToWatch, expr.toWatch);\n      }\n    });\n    ast.constant = allConstants;\n    ast.toWatch = isStatelessFilter ? argsToWatch : [ast];\n    break;\n  case AST.AssignmentExpression:\n    findConstantAndWatchExpressions(ast.left, $filter);\n    findConstantAndWatchExpressions(ast.right, $filter);\n    ast.constant = ast.left.constant && ast.right.constant;\n    ast.toWatch = [ast];\n    break;\n  case AST.ArrayExpression:\n    allConstants = true;\n    argsToWatch = [];\n    forEach(ast.elements, function(expr) {\n      findConstantAndWatchExpressions(expr, $filter);\n      allConstants = allConstants && expr.constant;\n      if (!expr.constant) {\n        argsToWatch.push.apply(argsToWatch, expr.toWatch);\n      }\n    });\n    ast.constant = allConstants;\n    ast.toWatch = argsToWatch;\n    break;\n  case AST.ObjectExpression:\n    allConstants = true;\n    argsToWatch = [];\n    forEach(ast.properties, function(property) {\n      findConstantAndWatchExpressions(property.value, $filter);\n      allConstants = allConstants && property.value.constant && !property.computed;\n      if (!property.value.constant) {\n        argsToWatch.push.apply(argsToWatch, property.value.toWatch);\n      }\n      if (property.computed) {\n        findConstantAndWatchExpressions(property.key, $filter);\n        if (!property.key.constant) {\n          argsToWatch.push.apply(argsToWatch, property.key.toWatch);\n        }\n      }\n\n    });\n    ast.constant = allConstants;\n    ast.toWatch = argsToWatch;\n    break;\n  case AST.ThisExpression:\n    ast.constant = false;\n    ast.toWatch = [];\n    break;\n  case AST.LocalsExpression:\n    ast.constant = false;\n    ast.toWatch = [];\n    break;\n  }\n}\n\nfunction getInputs(body) {\n  if (body.length !== 1) return;\n  var lastExpression = body[0].expression;\n  var candidate = lastExpression.toWatch;\n  if (candidate.length !== 1) return candidate;\n  return candidate[0] !== lastExpression ? candidate : undefined;\n}\n\nfunction isAssignable(ast) {\n  return ast.type === AST.Identifier || ast.type === AST.MemberExpression;\n}\n\nfunction assignableAST(ast) {\n  if (ast.body.length === 1 && isAssignable(ast.body[0].expression)) {\n    return {type: AST.AssignmentExpression, left: ast.body[0].expression, right: {type: AST.NGValueParameter}, operator: '='};\n  }\n}\n\nfunction isLiteral(ast) {\n  return ast.body.length === 0 ||\n      ast.body.length === 1 && (\n      ast.body[0].expression.type === AST.Literal ||\n      ast.body[0].expression.type === AST.ArrayExpression ||\n      ast.body[0].expression.type === AST.ObjectExpression);\n}\n\nfunction isConstant(ast) {\n  return ast.constant;\n}\n\nfunction ASTCompiler(astBuilder, $filter) {\n  this.astBuilder = astBuilder;\n  this.$filter = $filter;\n}\n\nASTCompiler.prototype = {\n  compile: function(expression) {\n    var self = this;\n    var ast = this.astBuilder.ast(expression);\n    this.state = {\n      nextId: 0,\n      filters: {},\n      fn: {vars: [], body: [], own: {}},\n      assign: {vars: [], body: [], own: {}},\n      inputs: []\n    };\n    findConstantAndWatchExpressions(ast, self.$filter);\n    var extra = '';\n    var assignable;\n    this.stage = 'assign';\n    if ((assignable = assignableAST(ast))) {\n      this.state.computing = 'assign';\n      var result = this.nextId();\n      this.recurse(assignable, result);\n      this.return_(result);\n      extra = 'fn.assign=' + this.generateFunction('assign', 's,v,l');\n    }\n    var toWatch = getInputs(ast.body);\n    self.stage = 'inputs';\n    forEach(toWatch, function(watch, key) {\n      var fnKey = 'fn' + key;\n      self.state[fnKey] = {vars: [], body: [], own: {}};\n      self.state.computing = fnKey;\n      var intoId = self.nextId();\n      self.recurse(watch, intoId);\n      self.return_(intoId);\n      self.state.inputs.push(fnKey);\n      watch.watchId = key;\n    });\n    this.state.computing = 'fn';\n    this.stage = 'main';\n    this.recurse(ast);\n    var fnString =\n      // The build and minification steps remove the string \"use strict\" from the code, but this is done using a regex.\n      // This is a workaround for this until we do a better job at only removing the prefix only when we should.\n      '\"' + this.USE + ' ' + this.STRICT + '\";\\n' +\n      this.filterPrefix() +\n      'var fn=' + this.generateFunction('fn', 's,l,a,i') +\n      extra +\n      this.watchFns() +\n      'return fn;';\n\n    // eslint-disable-next-line no-new-func\n    var fn = (new Function('$filter',\n        'getStringValue',\n        'ifDefined',\n        'plus',\n        fnString))(\n          this.$filter,\n          getStringValue,\n          ifDefined,\n          plusFn);\n    this.state = this.stage = undefined;\n    fn.literal = isLiteral(ast);\n    fn.constant = isConstant(ast);\n    return fn;\n  },\n\n  USE: 'use',\n\n  STRICT: 'strict',\n\n  watchFns: function() {\n    var result = [];\n    var fns = this.state.inputs;\n    var self = this;\n    forEach(fns, function(name) {\n      result.push('var ' + name + '=' + self.generateFunction(name, 's'));\n    });\n    if (fns.length) {\n      result.push('fn.inputs=[' + fns.join(',') + '];');\n    }\n    return result.join('');\n  },\n\n  generateFunction: function(name, params) {\n    return 'function(' + params + '){' +\n        this.varsPrefix(name) +\n        this.body(name) +\n        '};';\n  },\n\n  filterPrefix: function() {\n    var parts = [];\n    var self = this;\n    forEach(this.state.filters, function(id, filter) {\n      parts.push(id + '=$filter(' + self.escape(filter) + ')');\n    });\n    if (parts.length) return 'var ' + parts.join(',') + ';';\n    return '';\n  },\n\n  varsPrefix: function(section) {\n    return this.state[section].vars.length ? 'var ' + this.state[section].vars.join(',') + ';' : '';\n  },\n\n  body: function(section) {\n    return this.state[section].body.join('');\n  },\n\n  recurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {\n    var left, right, self = this, args, expression, computed;\n    recursionFn = recursionFn || noop;\n    if (!skipWatchIdCheck && isDefined(ast.watchId)) {\n      intoId = intoId || this.nextId();\n      this.if_('i',\n        this.lazyAssign(intoId, this.computedMember('i', ast.watchId)),\n        this.lazyRecurse(ast, intoId, nameId, recursionFn, create, true)\n      );\n      return;\n    }\n    switch (ast.type) {\n    case AST.Program:\n      forEach(ast.body, function(expression, pos) {\n        self.recurse(expression.expression, undefined, undefined, function(expr) { right = expr; });\n        if (pos !== ast.body.length - 1) {\n          self.current().body.push(right, ';');\n        } else {\n          self.return_(right);\n        }\n      });\n      break;\n    case AST.Literal:\n      expression = this.escape(ast.value);\n      this.assign(intoId, expression);\n      recursionFn(intoId || expression);\n      break;\n    case AST.UnaryExpression:\n      this.recurse(ast.argument, undefined, undefined, function(expr) { right = expr; });\n      expression = ast.operator + '(' + this.ifDefined(right, 0) + ')';\n      this.assign(intoId, expression);\n      recursionFn(expression);\n      break;\n    case AST.BinaryExpression:\n      this.recurse(ast.left, undefined, undefined, function(expr) { left = expr; });\n      this.recurse(ast.right, undefined, undefined, function(expr) { right = expr; });\n      if (ast.operator === '+') {\n        expression = this.plus(left, right);\n      } else if (ast.operator === '-') {\n        expression = this.ifDefined(left, 0) + ast.operator + this.ifDefined(right, 0);\n      } else {\n        expression = '(' + left + ')' + ast.operator + '(' + right + ')';\n      }\n      this.assign(intoId, expression);\n      recursionFn(expression);\n      break;\n    case AST.LogicalExpression:\n      intoId = intoId || this.nextId();\n      self.recurse(ast.left, intoId);\n      self.if_(ast.operator === '&&' ? intoId : self.not(intoId), self.lazyRecurse(ast.right, intoId));\n      recursionFn(intoId);\n      break;\n    case AST.ConditionalExpression:\n      intoId = intoId || this.nextId();\n      self.recurse(ast.test, intoId);\n      self.if_(intoId, self.lazyRecurse(ast.alternate, intoId), self.lazyRecurse(ast.consequent, intoId));\n      recursionFn(intoId);\n      break;\n    case AST.Identifier:\n      intoId = intoId || this.nextId();\n      if (nameId) {\n        nameId.context = self.stage === 'inputs' ? 's' : this.assign(this.nextId(), this.getHasOwnProperty('l', ast.name) + '?l:s');\n        nameId.computed = false;\n        nameId.name = ast.name;\n      }\n      self.if_(self.stage === 'inputs' || self.not(self.getHasOwnProperty('l', ast.name)),\n        function() {\n          self.if_(self.stage === 'inputs' || 's', function() {\n            if (create && create !== 1) {\n              self.if_(\n                self.isNull(self.nonComputedMember('s', ast.name)),\n                self.lazyAssign(self.nonComputedMember('s', ast.name), '{}'));\n            }\n            self.assign(intoId, self.nonComputedMember('s', ast.name));\n          });\n        }, intoId && self.lazyAssign(intoId, self.nonComputedMember('l', ast.name))\n        );\n      recursionFn(intoId);\n      break;\n    case AST.MemberExpression:\n      left = nameId && (nameId.context = this.nextId()) || this.nextId();\n      intoId = intoId || this.nextId();\n      self.recurse(ast.object, left, undefined, function() {\n        self.if_(self.notNull(left), function() {\n          if (ast.computed) {\n            right = self.nextId();\n            self.recurse(ast.property, right);\n            self.getStringValue(right);\n            if (create && create !== 1) {\n              self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), '{}'));\n            }\n            expression = self.computedMember(left, right);\n            self.assign(intoId, expression);\n            if (nameId) {\n              nameId.computed = true;\n              nameId.name = right;\n            }\n          } else {\n            if (create && create !== 1) {\n              self.if_(self.isNull(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}'));\n            }\n            expression = self.nonComputedMember(left, ast.property.name);\n            self.assign(intoId, expression);\n            if (nameId) {\n              nameId.computed = false;\n              nameId.name = ast.property.name;\n            }\n          }\n        }, function() {\n          self.assign(intoId, 'undefined');\n        });\n        recursionFn(intoId);\n      }, !!create);\n      break;\n    case AST.CallExpression:\n      intoId = intoId || this.nextId();\n      if (ast.filter) {\n        right = self.filter(ast.callee.name);\n        args = [];\n        forEach(ast.arguments, function(expr) {\n          var argument = self.nextId();\n          self.recurse(expr, argument);\n          args.push(argument);\n        });\n        expression = right + '(' + args.join(',') + ')';\n        self.assign(intoId, expression);\n        recursionFn(intoId);\n      } else {\n        right = self.nextId();\n        left = {};\n        args = [];\n        self.recurse(ast.callee, right, left, function() {\n          self.if_(self.notNull(right), function() {\n            forEach(ast.arguments, function(expr) {\n              self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) {\n                args.push(argument);\n              });\n            });\n            if (left.name) {\n              expression = self.member(left.context, left.name, left.computed) + '(' + args.join(',') + ')';\n            } else {\n              expression = right + '(' + args.join(',') + ')';\n            }\n            self.assign(intoId, expression);\n          }, function() {\n            self.assign(intoId, 'undefined');\n          });\n          recursionFn(intoId);\n        });\n      }\n      break;\n    case AST.AssignmentExpression:\n      right = this.nextId();\n      left = {};\n      this.recurse(ast.left, undefined, left, function() {\n        self.if_(self.notNull(left.context), function() {\n          self.recurse(ast.right, right);\n          expression = self.member(left.context, left.name, left.computed) + ast.operator + right;\n          self.assign(intoId, expression);\n          recursionFn(intoId || expression);\n        });\n      }, 1);\n      break;\n    case AST.ArrayExpression:\n      args = [];\n      forEach(ast.elements, function(expr) {\n        self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) {\n          args.push(argument);\n        });\n      });\n      expression = '[' + args.join(',') + ']';\n      this.assign(intoId, expression);\n      recursionFn(intoId || expression);\n      break;\n    case AST.ObjectExpression:\n      args = [];\n      computed = false;\n      forEach(ast.properties, function(property) {\n        if (property.computed) {\n          computed = true;\n        }\n      });\n      if (computed) {\n        intoId = intoId || this.nextId();\n        this.assign(intoId, '{}');\n        forEach(ast.properties, function(property) {\n          if (property.computed) {\n            left = self.nextId();\n            self.recurse(property.key, left);\n          } else {\n            left = property.key.type === AST.Identifier ?\n                       property.key.name :\n                       ('' + property.key.value);\n          }\n          right = self.nextId();\n          self.recurse(property.value, right);\n          self.assign(self.member(intoId, left, property.computed), right);\n        });\n      } else {\n        forEach(ast.properties, function(property) {\n          self.recurse(property.value, ast.constant ? undefined : self.nextId(), undefined, function(expr) {\n            args.push(self.escape(\n                property.key.type === AST.Identifier ? property.key.name :\n                  ('' + property.key.value)) +\n                ':' + expr);\n          });\n        });\n        expression = '{' + args.join(',') + '}';\n        this.assign(intoId, expression);\n      }\n      recursionFn(intoId || expression);\n      break;\n    case AST.ThisExpression:\n      this.assign(intoId, 's');\n      recursionFn(intoId || 's');\n      break;\n    case AST.LocalsExpression:\n      this.assign(intoId, 'l');\n      recursionFn(intoId || 'l');\n      break;\n    case AST.NGValueParameter:\n      this.assign(intoId, 'v');\n      recursionFn(intoId || 'v');\n      break;\n    }\n  },\n\n  getHasOwnProperty: function(element, property) {\n    var key = element + '.' + property;\n    var own = this.current().own;\n    if (!own.hasOwnProperty(key)) {\n      own[key] = this.nextId(false, element + '&&(' + this.escape(property) + ' in ' + element + ')');\n    }\n    return own[key];\n  },\n\n  assign: function(id, value) {\n    if (!id) return;\n    this.current().body.push(id, '=', value, ';');\n    return id;\n  },\n\n  filter: function(filterName) {\n    if (!this.state.filters.hasOwnProperty(filterName)) {\n      this.state.filters[filterName] = this.nextId(true);\n    }\n    return this.state.filters[filterName];\n  },\n\n  ifDefined: function(id, defaultValue) {\n    return 'ifDefined(' + id + ',' + this.escape(defaultValue) + ')';\n  },\n\n  plus: function(left, right) {\n    return 'plus(' + left + ',' + right + ')';\n  },\n\n  return_: function(id) {\n    this.current().body.push('return ', id, ';');\n  },\n\n  if_: function(test, alternate, consequent) {\n    if (test === true) {\n      alternate();\n    } else {\n      var body = this.current().body;\n      body.push('if(', test, '){');\n      alternate();\n      body.push('}');\n      if (consequent) {\n        body.push('else{');\n        consequent();\n        body.push('}');\n      }\n    }\n  },\n\n  not: function(expression) {\n    return '!(' + expression + ')';\n  },\n\n  isNull: function(expression) {\n    return expression + '==null';\n  },\n\n  notNull: function(expression) {\n    return expression + '!=null';\n  },\n\n  nonComputedMember: function(left, right) {\n    var SAFE_IDENTIFIER = /^[$_a-zA-Z][$_a-zA-Z0-9]*$/;\n    var UNSAFE_CHARACTERS = /[^$_a-zA-Z0-9]/g;\n    if (SAFE_IDENTIFIER.test(right)) {\n      return left + '.' + right;\n    } else {\n      return left  + '[\"' + right.replace(UNSAFE_CHARACTERS, this.stringEscapeFn) + '\"]';\n    }\n  },\n\n  computedMember: function(left, right) {\n    return left + '[' + right + ']';\n  },\n\n  member: function(left, right, computed) {\n    if (computed) return this.computedMember(left, right);\n    return this.nonComputedMember(left, right);\n  },\n\n  getStringValue: function(item) {\n    this.assign(item, 'getStringValue(' + item + ')');\n  },\n\n  lazyRecurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {\n    var self = this;\n    return function() {\n      self.recurse(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck);\n    };\n  },\n\n  lazyAssign: function(id, value) {\n    var self = this;\n    return function() {\n      self.assign(id, value);\n    };\n  },\n\n  stringEscapeRegex: /[^ a-zA-Z0-9]/g,\n\n  stringEscapeFn: function(c) {\n    return '\\\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4);\n  },\n\n  escape: function(value) {\n    if (isString(value)) return '\\'' + value.replace(this.stringEscapeRegex, this.stringEscapeFn) + '\\'';\n    if (isNumber(value)) return value.toString();\n    if (value === true) return 'true';\n    if (value === false) return 'false';\n    if (value === null) return 'null';\n    if (typeof value === 'undefined') return 'undefined';\n\n    throw $parseMinErr('esc', 'IMPOSSIBLE');\n  },\n\n  nextId: function(skip, init) {\n    var id = 'v' + (this.state.nextId++);\n    if (!skip) {\n      this.current().vars.push(id + (init ? '=' + init : ''));\n    }\n    return id;\n  },\n\n  current: function() {\n    return this.state[this.state.computing];\n  }\n};\n\n\nfunction ASTInterpreter(astBuilder, $filter) {\n  this.astBuilder = astBuilder;\n  this.$filter = $filter;\n}\n\nASTInterpreter.prototype = {\n  compile: function(expression) {\n    var self = this;\n    var ast = this.astBuilder.ast(expression);\n    findConstantAndWatchExpressions(ast, self.$filter);\n    var assignable;\n    var assign;\n    if ((assignable = assignableAST(ast))) {\n      assign = this.recurse(assignable);\n    }\n    var toWatch = getInputs(ast.body);\n    var inputs;\n    if (toWatch) {\n      inputs = [];\n      forEach(toWatch, function(watch, key) {\n        var input = self.recurse(watch);\n        watch.input = input;\n        inputs.push(input);\n        watch.watchId = key;\n      });\n    }\n    var expressions = [];\n    forEach(ast.body, function(expression) {\n      expressions.push(self.recurse(expression.expression));\n    });\n    var fn = ast.body.length === 0 ? noop :\n             ast.body.length === 1 ? expressions[0] :\n             function(scope, locals) {\n               var lastValue;\n               forEach(expressions, function(exp) {\n                 lastValue = exp(scope, locals);\n               });\n               return lastValue;\n             };\n    if (assign) {\n      fn.assign = function(scope, value, locals) {\n        return assign(scope, locals, value);\n      };\n    }\n    if (inputs) {\n      fn.inputs = inputs;\n    }\n    fn.literal = isLiteral(ast);\n    fn.constant = isConstant(ast);\n    return fn;\n  },\n\n  recurse: function(ast, context, create) {\n    var left, right, self = this, args;\n    if (ast.input) {\n      return this.inputs(ast.input, ast.watchId);\n    }\n    switch (ast.type) {\n    case AST.Literal:\n      return this.value(ast.value, context);\n    case AST.UnaryExpression:\n      right = this.recurse(ast.argument);\n      return this['unary' + ast.operator](right, context);\n    case AST.BinaryExpression:\n      left = this.recurse(ast.left);\n      right = this.recurse(ast.right);\n      return this['binary' + ast.operator](left, right, context);\n    case AST.LogicalExpression:\n      left = this.recurse(ast.left);\n      right = this.recurse(ast.right);\n      return this['binary' + ast.operator](left, right, context);\n    case AST.ConditionalExpression:\n      return this['ternary?:'](\n        this.recurse(ast.test),\n        this.recurse(ast.alternate),\n        this.recurse(ast.consequent),\n        context\n      );\n    case AST.Identifier:\n      return self.identifier(ast.name, context, create);\n    case AST.MemberExpression:\n      left = this.recurse(ast.object, false, !!create);\n      if (!ast.computed) {\n        right = ast.property.name;\n      }\n      if (ast.computed) right = this.recurse(ast.property);\n      return ast.computed ?\n        this.computedMember(left, right, context, create) :\n        this.nonComputedMember(left, right, context, create);\n    case AST.CallExpression:\n      args = [];\n      forEach(ast.arguments, function(expr) {\n        args.push(self.recurse(expr));\n      });\n      if (ast.filter) right = this.$filter(ast.callee.name);\n      if (!ast.filter) right = this.recurse(ast.callee, true);\n      return ast.filter ?\n        function(scope, locals, assign, inputs) {\n          var values = [];\n          for (var i = 0; i < args.length; ++i) {\n            values.push(args[i](scope, locals, assign, inputs));\n          }\n          var value = right.apply(undefined, values, inputs);\n          return context ? {context: undefined, name: undefined, value: value} : value;\n        } :\n        function(scope, locals, assign, inputs) {\n          var rhs = right(scope, locals, assign, inputs);\n          var value;\n          if (rhs.value != null) {\n            var values = [];\n            for (var i = 0; i < args.length; ++i) {\n              values.push(args[i](scope, locals, assign, inputs));\n            }\n            value = rhs.value.apply(rhs.context, values);\n          }\n          return context ? {value: value} : value;\n        };\n    case AST.AssignmentExpression:\n      left = this.recurse(ast.left, true, 1);\n      right = this.recurse(ast.right);\n      return function(scope, locals, assign, inputs) {\n        var lhs = left(scope, locals, assign, inputs);\n        var rhs = right(scope, locals, assign, inputs);\n        lhs.context[lhs.name] = rhs;\n        return context ? {value: rhs} : rhs;\n      };\n    case AST.ArrayExpression:\n      args = [];\n      forEach(ast.elements, function(expr) {\n        args.push(self.recurse(expr));\n      });\n      return function(scope, locals, assign, inputs) {\n        var value = [];\n        for (var i = 0; i < args.length; ++i) {\n          value.push(args[i](scope, locals, assign, inputs));\n        }\n        return context ? {value: value} : value;\n      };\n    case AST.ObjectExpression:\n      args = [];\n      forEach(ast.properties, function(property) {\n        if (property.computed) {\n          args.push({key: self.recurse(property.key),\n                     computed: true,\n                     value: self.recurse(property.value)\n          });\n        } else {\n          args.push({key: property.key.type === AST.Identifier ?\n                          property.key.name :\n                          ('' + property.key.value),\n                     computed: false,\n                     value: self.recurse(property.value)\n          });\n        }\n      });\n      return function(scope, locals, assign, inputs) {\n        var value = {};\n        for (var i = 0; i < args.length; ++i) {\n          if (args[i].computed) {\n            value[args[i].key(scope, locals, assign, inputs)] = args[i].value(scope, locals, assign, inputs);\n          } else {\n            value[args[i].key] = args[i].value(scope, locals, assign, inputs);\n          }\n        }\n        return context ? {value: value} : value;\n      };\n    case AST.ThisExpression:\n      return function(scope) {\n        return context ? {value: scope} : scope;\n      };\n    case AST.LocalsExpression:\n      return function(scope, locals) {\n        return context ? {value: locals} : locals;\n      };\n    case AST.NGValueParameter:\n      return function(scope, locals, assign) {\n        return context ? {value: assign} : assign;\n      };\n    }\n  },\n\n  'unary+': function(argument, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = argument(scope, locals, assign, inputs);\n      if (isDefined(arg)) {\n        arg = +arg;\n      } else {\n        arg = 0;\n      }\n      return context ? {value: arg} : arg;\n    };\n  },\n  'unary-': function(argument, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = argument(scope, locals, assign, inputs);\n      if (isDefined(arg)) {\n        arg = -arg;\n      } else {\n        arg = -0;\n      }\n      return context ? {value: arg} : arg;\n    };\n  },\n  'unary!': function(argument, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = !argument(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary+': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var lhs = left(scope, locals, assign, inputs);\n      var rhs = right(scope, locals, assign, inputs);\n      var arg = plusFn(lhs, rhs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary-': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var lhs = left(scope, locals, assign, inputs);\n      var rhs = right(scope, locals, assign, inputs);\n      var arg = (isDefined(lhs) ? lhs : 0) - (isDefined(rhs) ? rhs : 0);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary*': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) * right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary/': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) / right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary%': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) % right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary===': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) === right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary!==': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) !== right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary==': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      // eslint-disable-next-line eqeqeq\n      var arg = left(scope, locals, assign, inputs) == right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary!=': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      // eslint-disable-next-line eqeqeq\n      var arg = left(scope, locals, assign, inputs) != right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary<': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) < right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary>': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) > right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary<=': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) <= right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary>=': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) >= right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary&&': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) && right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary||': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) || right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'ternary?:': function(test, alternate, consequent, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = test(scope, locals, assign, inputs) ? alternate(scope, locals, assign, inputs) : consequent(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  value: function(value, context) {\n    return function() { return context ? {context: undefined, name: undefined, value: value} : value; };\n  },\n  identifier: function(name, context, create) {\n    return function(scope, locals, assign, inputs) {\n      var base = locals && (name in locals) ? locals : scope;\n      if (create && create !== 1 && base && base[name] == null) {\n        base[name] = {};\n      }\n      var value = base ? base[name] : undefined;\n      if (context) {\n        return {context: base, name: name, value: value};\n      } else {\n        return value;\n      }\n    };\n  },\n  computedMember: function(left, right, context, create) {\n    return function(scope, locals, assign, inputs) {\n      var lhs = left(scope, locals, assign, inputs);\n      var rhs;\n      var value;\n      if (lhs != null) {\n        rhs = right(scope, locals, assign, inputs);\n        rhs = getStringValue(rhs);\n        if (create && create !== 1) {\n          if (lhs && !(lhs[rhs])) {\n            lhs[rhs] = {};\n          }\n        }\n        value = lhs[rhs];\n      }\n      if (context) {\n        return {context: lhs, name: rhs, value: value};\n      } else {\n        return value;\n      }\n    };\n  },\n  nonComputedMember: function(left, right, context, create) {\n    return function(scope, locals, assign, inputs) {\n      var lhs = left(scope, locals, assign, inputs);\n      if (create && create !== 1) {\n        if (lhs && lhs[right] == null) {\n          lhs[right] = {};\n        }\n      }\n      var value = lhs != null ? lhs[right] : undefined;\n      if (context) {\n        return {context: lhs, name: right, value: value};\n      } else {\n        return value;\n      }\n    };\n  },\n  inputs: function(input, watchId) {\n    return function(scope, value, locals, inputs) {\n      if (inputs) return inputs[watchId];\n      return input(scope, value, locals);\n    };\n  }\n};\n\n/**\n * @constructor\n */\nvar Parser = function Parser(lexer, $filter, options) {\n  this.lexer = lexer;\n  this.$filter = $filter;\n  this.options = options;\n  this.ast = new AST(lexer, options);\n  this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) :\n                                   new ASTCompiler(this.ast, $filter);\n};\n\nParser.prototype = {\n  constructor: Parser,\n\n  parse: function(text) {\n    return this.astCompiler.compile(text);\n  }\n};\n\nfunction getValueOf(value) {\n  return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);\n}\n\n///////////////////////////////////\n\n/**\n * @ngdoc service\n * @name $parse\n * @kind function\n *\n * @description\n *\n * Converts Angular {@link guide/expression expression} into a function.\n *\n * ```js\n *   var getter = $parse('user.name');\n *   var setter = getter.assign;\n *   var context = {user:{name:'angular'}};\n *   var locals = {user:{name:'local'}};\n *\n *   expect(getter(context)).toEqual('angular');\n *   setter(context, 'newValue');\n *   expect(context.user.name).toEqual('newValue');\n *   expect(getter(context, locals)).toEqual('local');\n * ```\n *\n *\n * @param {string} expression String expression to compile.\n * @returns {function(context, locals)} a function which represents the compiled expression:\n *\n *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n *      are evaluated against (typically a scope object).\n *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n *      `context`.\n *\n *    The returned function also has the following properties:\n *      * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript\n *        literal.\n *      * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript\n *        constant literals.\n *      * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be\n *        set to a function to change its value on the given context.\n *\n */\n\n\n/**\n * @ngdoc provider\n * @name $parseProvider\n * @this\n *\n * @description\n * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse}\n *  service.\n */\nfunction $ParseProvider() {\n  var cache = createMap();\n  var literals = {\n    'true': true,\n    'false': false,\n    'null': null,\n    'undefined': undefined\n  };\n  var identStart, identContinue;\n\n  /**\n   * @ngdoc method\n   * @name $parseProvider#addLiteral\n   * @description\n   *\n   * Configure $parse service to add literal values that will be present as literal at expressions.\n   *\n   * @param {string} literalName Token for the literal value. The literal name value must be a valid literal name.\n   * @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`.\n   *\n   **/\n  this.addLiteral = function(literalName, literalValue) {\n    literals[literalName] = literalValue;\n  };\n\n /**\n  * @ngdoc method\n  * @name $parseProvider#setIdentifierFns\n  *\n  * @description\n  *\n  * Allows defining the set of characters that are allowed in Angular expressions. The function\n  * `identifierStart` will get called to know if a given character is a valid character to be the\n  * first character for an identifier. The function `identifierContinue` will get called to know if\n  * a given character is a valid character to be a follow-up identifier character. The functions\n  * `identifierStart` and `identifierContinue` will receive as arguments the single character to be\n  * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in\n  * mind that the `string` parameter can be two characters long depending on the character\n  * representation. It is expected for the function to return `true` or `false`, whether that\n  * character is allowed or not.\n  *\n  * Since this function will be called extensively, keep the implementation of these functions fast,\n  * as the performance of these functions have a direct impact on the expressions parsing speed.\n  *\n  * @param {function=} identifierStart The function that will decide whether the given character is\n  *   a valid identifier start character.\n  * @param {function=} identifierContinue The function that will decide whether the given character is\n  *   a valid identifier continue character.\n  */\n  this.setIdentifierFns = function(identifierStart, identifierContinue) {\n    identStart = identifierStart;\n    identContinue = identifierContinue;\n    return this;\n  };\n\n  this.$get = ['$filter', function($filter) {\n    var noUnsafeEval = csp().noUnsafeEval;\n    var $parseOptions = {\n          csp: noUnsafeEval,\n          literals: copy(literals),\n          isIdentifierStart: isFunction(identStart) && identStart,\n          isIdentifierContinue: isFunction(identContinue) && identContinue\n        };\n    return $parse;\n\n    function $parse(exp, interceptorFn) {\n      var parsedExpression, oneTime, cacheKey;\n\n      switch (typeof exp) {\n        case 'string':\n          exp = exp.trim();\n          cacheKey = exp;\n\n          parsedExpression = cache[cacheKey];\n\n          if (!parsedExpression) {\n            if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {\n              oneTime = true;\n              exp = exp.substring(2);\n            }\n            var lexer = new Lexer($parseOptions);\n            var parser = new Parser(lexer, $filter, $parseOptions);\n            parsedExpression = parser.parse(exp);\n            if (parsedExpression.constant) {\n              parsedExpression.$$watchDelegate = constantWatchDelegate;\n            } else if (oneTime) {\n              parsedExpression.$$watchDelegate = parsedExpression.literal ?\n                  oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;\n            } else if (parsedExpression.inputs) {\n              parsedExpression.$$watchDelegate = inputsWatchDelegate;\n            }\n            cache[cacheKey] = parsedExpression;\n          }\n          return addInterceptor(parsedExpression, interceptorFn);\n\n        case 'function':\n          return addInterceptor(exp, interceptorFn);\n\n        default:\n          return addInterceptor(noop, interceptorFn);\n      }\n    }\n\n    function expressionInputDirtyCheck(newValue, oldValueOfValue, compareObjectIdentity) {\n\n      if (newValue == null || oldValueOfValue == null) { // null/undefined\n        return newValue === oldValueOfValue;\n      }\n\n      if (typeof newValue === 'object' && !compareObjectIdentity) {\n\n        // attempt to convert the value to a primitive type\n        // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can\n        //             be cheaply dirty-checked\n        newValue = getValueOf(newValue);\n\n        if (typeof newValue === 'object') {\n          // objects/arrays are not supported - deep-watching them would be too expensive\n          return false;\n        }\n\n        // fall-through to the primitive equality check\n      }\n\n      //Primitive or NaN\n      // eslint-disable-next-line no-self-compare\n      return newValue === oldValueOfValue || (newValue !== newValue && oldValueOfValue !== oldValueOfValue);\n    }\n\n    function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {\n      var inputExpressions = parsedExpression.inputs;\n      var lastResult;\n\n      if (inputExpressions.length === 1) {\n        var oldInputValueOf = expressionInputDirtyCheck; // init to something unique so that equals check fails\n        inputExpressions = inputExpressions[0];\n        return scope.$watch(function expressionInputWatch(scope) {\n          var newInputValue = inputExpressions(scope);\n          if (!expressionInputDirtyCheck(newInputValue, oldInputValueOf, parsedExpression.literal)) {\n            lastResult = parsedExpression(scope, undefined, undefined, [newInputValue]);\n            oldInputValueOf = newInputValue && getValueOf(newInputValue);\n          }\n          return lastResult;\n        }, listener, objectEquality, prettyPrintExpression);\n      }\n\n      var oldInputValueOfValues = [];\n      var oldInputValues = [];\n      for (var i = 0, ii = inputExpressions.length; i < ii; i++) {\n        oldInputValueOfValues[i] = expressionInputDirtyCheck; // init to something unique so that equals check fails\n        oldInputValues[i] = null;\n      }\n\n      return scope.$watch(function expressionInputsWatch(scope) {\n        var changed = false;\n\n        for (var i = 0, ii = inputExpressions.length; i < ii; i++) {\n          var newInputValue = inputExpressions[i](scope);\n          if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i], parsedExpression.literal))) {\n            oldInputValues[i] = newInputValue;\n            oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);\n          }\n        }\n\n        if (changed) {\n          lastResult = parsedExpression(scope, undefined, undefined, oldInputValues);\n        }\n\n        return lastResult;\n      }, listener, objectEquality, prettyPrintExpression);\n    }\n\n    function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {\n      var unwatch, lastValue;\n      if (parsedExpression.inputs) {\n        unwatch = inputsWatchDelegate(scope, oneTimeListener, objectEquality, parsedExpression, prettyPrintExpression);\n      } else {\n        unwatch = scope.$watch(oneTimeWatch, oneTimeListener, objectEquality);\n      }\n      return unwatch;\n\n      function oneTimeWatch(scope) {\n        return parsedExpression(scope);\n      }\n      function oneTimeListener(value, old, scope) {\n        lastValue = value;\n        if (isFunction(listener)) {\n          listener(value, old, scope);\n        }\n        if (isDefined(value)) {\n          scope.$$postDigest(function() {\n            if (isDefined(lastValue)) {\n              unwatch();\n            }\n          });\n        }\n      }\n    }\n\n    function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) {\n      var unwatch, lastValue;\n      unwatch = scope.$watch(function oneTimeWatch(scope) {\n        return parsedExpression(scope);\n      }, function oneTimeListener(value, old, scope) {\n        lastValue = value;\n        if (isFunction(listener)) {\n          listener(value, old, scope);\n        }\n        if (isAllDefined(value)) {\n          scope.$$postDigest(function() {\n            if (isAllDefined(lastValue)) unwatch();\n          });\n        }\n      }, objectEquality);\n\n      return unwatch;\n\n      function isAllDefined(value) {\n        var allDefined = true;\n        forEach(value, function(val) {\n          if (!isDefined(val)) allDefined = false;\n        });\n        return allDefined;\n      }\n    }\n\n    function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) {\n      var unwatch = scope.$watch(function constantWatch(scope) {\n        unwatch();\n        return parsedExpression(scope);\n      }, listener, objectEquality);\n      return unwatch;\n    }\n\n    function addInterceptor(parsedExpression, interceptorFn) {\n      if (!interceptorFn) return parsedExpression;\n      var watchDelegate = parsedExpression.$$watchDelegate;\n      var useInputs = false;\n\n      var regularWatch =\n          watchDelegate !== oneTimeLiteralWatchDelegate &&\n          watchDelegate !== oneTimeWatchDelegate;\n\n      var fn = regularWatch ? function regularInterceptedExpression(scope, locals, assign, inputs) {\n        var value = useInputs && inputs ? inputs[0] : parsedExpression(scope, locals, assign, inputs);\n        return interceptorFn(value, scope, locals);\n      } : function oneTimeInterceptedExpression(scope, locals, assign, inputs) {\n        var value = parsedExpression(scope, locals, assign, inputs);\n        var result = interceptorFn(value, scope, locals);\n        // we only return the interceptor's result if the\n        // initial value is defined (for bind-once)\n        return isDefined(value) ? result : value;\n      };\n\n      // Propagate $$watchDelegates other then inputsWatchDelegate\n      useInputs = !parsedExpression.inputs;\n      if (parsedExpression.$$watchDelegate &&\n          parsedExpression.$$watchDelegate !== inputsWatchDelegate) {\n        fn.$$watchDelegate = parsedExpression.$$watchDelegate;\n        fn.inputs = parsedExpression.inputs;\n      } else if (!interceptorFn.$stateful) {\n        // If there is an interceptor, but no watchDelegate then treat the interceptor like\n        // we treat filters - it is assumed to be a pure function unless flagged with $stateful\n        fn.$$watchDelegate = inputsWatchDelegate;\n        fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression];\n      }\n\n      return fn;\n    }\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $q\n * @requires $rootScope\n *\n * @description\n * A service that helps you run functions asynchronously, and use their return values (or exceptions)\n * when they are done processing.\n *\n * This is a [Promises/A+](https://promisesaplus.com/)-compliant implementation of promises/deferred\n * objects inspired by [Kris Kowal's Q](https://github.com/kriskowal/q).\n *\n * $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred\n * implementations, and the other which resembles ES6 (ES2015) promises to some degree.\n *\n * # $q constructor\n *\n * The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`\n * function as the first argument. This is similar to the native Promise implementation from ES6,\n * see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).\n *\n * While the constructor-style use is supported, not all of the supporting methods from ES6 promises are\n * available yet.\n *\n * It can be used like so:\n *\n * ```js\n *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`\n *   // are available in the current lexical scope (they could have been injected or passed in).\n *\n *   function asyncGreet(name) {\n *     // perform some asynchronous operation, resolve or reject the promise when appropriate.\n *     return $q(function(resolve, reject) {\n *       setTimeout(function() {\n *         if (okToGreet(name)) {\n *           resolve('Hello, ' + name + '!');\n *         } else {\n *           reject('Greeting ' + name + ' is not allowed.');\n *         }\n *       }, 1000);\n *     });\n *   }\n *\n *   var promise = asyncGreet('Robin Hood');\n *   promise.then(function(greeting) {\n *     alert('Success: ' + greeting);\n *   }, function(reason) {\n *     alert('Failed: ' + reason);\n *   });\n * ```\n *\n * Note: progress/notify callbacks are not currently supported via the ES6-style interface.\n *\n * Note: unlike ES6 behavior, an exception thrown in the constructor function will NOT implicitly reject the promise.\n *\n * However, the more traditional CommonJS-style usage is still available, and documented below.\n *\n * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an\n * interface for interacting with an object that represents the result of an action that is\n * performed asynchronously, and may or may not be finished at any given point in time.\n *\n * From the perspective of dealing with error handling, deferred and promise APIs are to\n * asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.\n *\n * ```js\n *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`\n *   // are available in the current lexical scope (they could have been injected or passed in).\n *\n *   function asyncGreet(name) {\n *     var deferred = $q.defer();\n *\n *     setTimeout(function() {\n *       deferred.notify('About to greet ' + name + '.');\n *\n *       if (okToGreet(name)) {\n *         deferred.resolve('Hello, ' + name + '!');\n *       } else {\n *         deferred.reject('Greeting ' + name + ' is not allowed.');\n *       }\n *     }, 1000);\n *\n *     return deferred.promise;\n *   }\n *\n *   var promise = asyncGreet('Robin Hood');\n *   promise.then(function(greeting) {\n *     alert('Success: ' + greeting);\n *   }, function(reason) {\n *     alert('Failed: ' + reason);\n *   }, function(update) {\n *     alert('Got notification: ' + update);\n *   });\n * ```\n *\n * At first it might not be obvious why this extra complexity is worth the trouble. The payoff\n * comes in the way of guarantees that promise and deferred APIs make, see\n * https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md.\n *\n * Additionally the promise api allows for composition that is very hard to do with the\n * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.\n * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the\n * section on serial or parallel joining of promises.\n *\n * # The Deferred API\n *\n * A new instance of deferred is constructed by calling `$q.defer()`.\n *\n * The purpose of the deferred object is to expose the associated Promise instance as well as APIs\n * that can be used for signaling the successful or unsuccessful completion, as well as the status\n * of the task.\n *\n * **Methods**\n *\n * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection\n *   constructed via `$q.reject`, the promise will be rejected instead.\n * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to\n *   resolving it with a rejection constructed via `$q.reject`.\n * - `notify(value)` - provides updates on the status of the promise's execution. This may be called\n *   multiple times before the promise is either resolved or rejected.\n *\n * **Properties**\n *\n * - promise – `{Promise}` – promise object associated with this deferred.\n *\n *\n * # The Promise API\n *\n * A new promise instance is created when a deferred instance is created and can be retrieved by\n * calling `deferred.promise`.\n *\n * The purpose of the promise object is to allow for interested parties to get access to the result\n * of the deferred task when it completes.\n *\n * **Methods**\n *\n * - `then(successCallback, [errorCallback], [notifyCallback])` – regardless of when the promise was or\n *   will be resolved or rejected, `then` calls one of the success or error callbacks asynchronously\n *   as soon as the result is available. The callbacks are called with a single argument: the result\n *   or rejection reason. Additionally, the notify callback may be called zero or more times to\n *   provide a progress indication, before the promise is resolved or rejected.\n *\n *   This method *returns a new promise* which is resolved or rejected via the return value of the\n *   `successCallback`, `errorCallback` (unless that value is a promise, in which case it is resolved\n *   with the value which is resolved in that promise using\n *   [promise chaining](http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promises-queues)).\n *   It also notifies via the return value of the `notifyCallback` method. The promise cannot be\n *   resolved or rejected from the notifyCallback method. The errorCallback and notifyCallback\n *   arguments are optional.\n *\n * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`\n *\n * - `finally(callback, notifyCallback)` – allows you to observe either the fulfillment or rejection of a promise,\n *   but to do so without modifying the final value. This is useful to release resources or do some\n *   clean-up that needs to be done whether the promise was rejected or resolved. See the [full\n *   specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for\n *   more information.\n *\n * # Chaining promises\n *\n * Because calling the `then` method of a promise returns a new derived promise, it is easily\n * possible to create a chain of promises:\n *\n * ```js\n *   promiseB = promiseA.then(function(result) {\n *     return result + 1;\n *   });\n *\n *   // promiseB will be resolved immediately after promiseA is resolved and its value\n *   // will be the result of promiseA incremented by 1\n * ```\n *\n * It is possible to create chains of any length and since a promise can be resolved with another\n * promise (which will defer its resolution further), it is possible to pause/defer resolution of\n * the promises at any point in the chain. This makes it possible to implement powerful APIs like\n * $http's response interceptors.\n *\n *\n * # Differences between Kris Kowal's Q and $q\n *\n *  There are two main differences:\n *\n * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation\n *   mechanism in angular, which means faster propagation of resolution or rejection into your\n *   models and avoiding unnecessary browser repaints, which would result in flickering UI.\n * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains\n *   all the important functionality needed for common async tasks.\n *\n * # Testing\n *\n *  ```js\n *    it('should simulate promise', inject(function($q, $rootScope) {\n *      var deferred = $q.defer();\n *      var promise = deferred.promise;\n *      var resolvedValue;\n *\n *      promise.then(function(value) { resolvedValue = value; });\n *      expect(resolvedValue).toBeUndefined();\n *\n *      // Simulate resolving of promise\n *      deferred.resolve(123);\n *      // Note that the 'then' function does not get called synchronously.\n *      // This is because we want the promise API to always be async, whether or not\n *      // it got called synchronously or asynchronously.\n *      expect(resolvedValue).toBeUndefined();\n *\n *      // Propagate promise resolution to 'then' functions using $apply().\n *      $rootScope.$apply();\n *      expect(resolvedValue).toEqual(123);\n *    }));\n *  ```\n *\n * @param {function(function, function)} resolver Function which is responsible for resolving or\n *   rejecting the newly created promise. The first parameter is a function which resolves the\n *   promise, the second parameter is a function which rejects the promise.\n *\n * @returns {Promise} The newly created promise.\n */\n/**\n * @ngdoc provider\n * @name $qProvider\n * @this\n *\n * @description\n */\nfunction $QProvider() {\n  var errorOnUnhandledRejections = true;\n  this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {\n    return qFactory(function(callback) {\n      $rootScope.$evalAsync(callback);\n    }, $exceptionHandler, errorOnUnhandledRejections);\n  }];\n\n  /**\n   * @ngdoc method\n   * @name $qProvider#errorOnUnhandledRejections\n   * @kind function\n   *\n   * @description\n   * Retrieves or overrides whether to generate an error when a rejected promise is not handled.\n   * This feature is enabled by default.\n   *\n   * @param {boolean=} value Whether to generate an error when a rejected promise is not handled.\n   * @returns {boolean|ng.$qProvider} Current value when called without a new value or self for\n   *    chaining otherwise.\n   */\n  this.errorOnUnhandledRejections = function(value) {\n    if (isDefined(value)) {\n      errorOnUnhandledRejections = value;\n      return this;\n    } else {\n      return errorOnUnhandledRejections;\n    }\n  };\n}\n\n/** @this */\nfunction $$QProvider() {\n  var errorOnUnhandledRejections = true;\n  this.$get = ['$browser', '$exceptionHandler', function($browser, $exceptionHandler) {\n    return qFactory(function(callback) {\n      $browser.defer(callback);\n    }, $exceptionHandler, errorOnUnhandledRejections);\n  }];\n\n  this.errorOnUnhandledRejections = function(value) {\n    if (isDefined(value)) {\n      errorOnUnhandledRejections = value;\n      return this;\n    } else {\n      return errorOnUnhandledRejections;\n    }\n  };\n}\n\n/**\n * Constructs a promise manager.\n *\n * @param {function(function)} nextTick Function for executing functions in the next turn.\n * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for\n *     debugging purposes.\n @ param {=boolean} errorOnUnhandledRejections Whether an error should be generated on unhandled\n *     promises rejections.\n * @returns {object} Promise manager.\n */\nfunction qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {\n  var $qMinErr = minErr('$q', TypeError);\n  var queueSize = 0;\n  var checkQueue = [];\n\n  /**\n   * @ngdoc method\n   * @name ng.$q#defer\n   * @kind function\n   *\n   * @description\n   * Creates a `Deferred` object which represents a task which will finish in the future.\n   *\n   * @returns {Deferred} Returns a new instance of deferred.\n   */\n  function defer() {\n    return new Deferred();\n  }\n\n  function Deferred() {\n    var promise = this.promise = new Promise();\n    //Non prototype methods necessary to support unbound execution :/\n    this.resolve = function(val) { resolvePromise(promise, val); };\n    this.reject = function(reason) { rejectPromise(promise, reason); };\n    this.notify = function(progress) { notifyPromise(promise, progress); };\n  }\n\n\n  function Promise() {\n    this.$$state = { status: 0 };\n  }\n\n  extend(Promise.prototype, {\n    then: function(onFulfilled, onRejected, progressBack) {\n      if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) {\n        return this;\n      }\n      var result = new Promise();\n\n      this.$$state.pending = this.$$state.pending || [];\n      this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);\n      if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);\n\n      return result;\n    },\n\n    'catch': function(callback) {\n      return this.then(null, callback);\n    },\n\n    'finally': function(callback, progressBack) {\n      return this.then(function(value) {\n        return handleCallback(value, resolve, callback);\n      }, function(error) {\n        return handleCallback(error, reject, callback);\n      }, progressBack);\n    }\n  });\n\n  function processQueue(state) {\n    var fn, promise, pending;\n\n    pending = state.pending;\n    state.processScheduled = false;\n    state.pending = undefined;\n    try {\n      for (var i = 0, ii = pending.length; i < ii; ++i) {\n        state.pur = true;\n        promise = pending[i][0];\n        fn = pending[i][state.status];\n        try {\n          if (isFunction(fn)) {\n            resolvePromise(promise, fn(state.value));\n          } else if (state.status === 1) {\n            resolvePromise(promise, state.value);\n          } else {\n            rejectPromise(promise, state.value);\n          }\n        } catch (e) {\n          rejectPromise(promise, e);\n        }\n      }\n    } finally {\n      --queueSize;\n      if (errorOnUnhandledRejections && queueSize === 0) {\n        nextTick(processChecks);\n      }\n    }\n  }\n\n  function processChecks() {\n    // eslint-disable-next-line no-unmodified-loop-condition\n    while (!queueSize && checkQueue.length) {\n      var toCheck = checkQueue.shift();\n      if (!toCheck.pur) {\n        toCheck.pur = true;\n        var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value);\n        if (toCheck.value instanceof Error) {\n          exceptionHandler(toCheck.value, errorMessage);\n        } else {\n          exceptionHandler(errorMessage);\n        }\n      }\n    }\n  }\n\n  function scheduleProcessQueue(state) {\n    if (errorOnUnhandledRejections && !state.pending && state.status === 2 && !state.pur) {\n      if (queueSize === 0 && checkQueue.length === 0) {\n        nextTick(processChecks);\n      }\n      checkQueue.push(state);\n    }\n    if (state.processScheduled || !state.pending) return;\n    state.processScheduled = true;\n    ++queueSize;\n    nextTick(function() { processQueue(state); });\n  }\n\n  function resolvePromise(promise, val) {\n    if (promise.$$state.status) return;\n    if (val === promise) {\n      $$reject(promise, $qMinErr(\n        'qcycle',\n        'Expected promise to be resolved with value other than itself \\'{0}\\'',\n        val));\n    } else {\n      $$resolve(promise, val);\n    }\n\n  }\n\n  function $$resolve(promise, val) {\n    var then;\n    var done = false;\n    try {\n      if (isObject(val) || isFunction(val)) then = val.then;\n      if (isFunction(then)) {\n        promise.$$state.status = -1;\n        then.call(val, doResolve, doReject, doNotify);\n      } else {\n        promise.$$state.value = val;\n        promise.$$state.status = 1;\n        scheduleProcessQueue(promise.$$state);\n      }\n    } catch (e) {\n      doReject(e);\n    }\n\n    function doResolve(val) {\n      if (done) return;\n      done = true;\n      $$resolve(promise, val);\n    }\n    function doReject(val) {\n      if (done) return;\n      done = true;\n      $$reject(promise, val);\n    }\n    function doNotify(progress) {\n      notifyPromise(promise, progress);\n    }\n  }\n\n  function rejectPromise(promise, reason) {\n    if (promise.$$state.status) return;\n    $$reject(promise, reason);\n  }\n\n  function $$reject(promise, reason) {\n    promise.$$state.value = reason;\n    promise.$$state.status = 2;\n    scheduleProcessQueue(promise.$$state);\n  }\n\n  function notifyPromise(promise, progress) {\n    var callbacks = promise.$$state.pending;\n\n    if ((promise.$$state.status <= 0) && callbacks && callbacks.length) {\n      nextTick(function() {\n        var callback, result;\n        for (var i = 0, ii = callbacks.length; i < ii; i++) {\n          result = callbacks[i][0];\n          callback = callbacks[i][3];\n          try {\n            notifyPromise(result, isFunction(callback) ? callback(progress) : progress);\n          } catch (e) {\n            exceptionHandler(e);\n          }\n        }\n      });\n    }\n  }\n\n  /**\n   * @ngdoc method\n   * @name $q#reject\n   * @kind function\n   *\n   * @description\n   * Creates a promise that is resolved as rejected with the specified `reason`. This api should be\n   * used to forward rejection in a chain of promises. If you are dealing with the last promise in\n   * a promise chain, you don't need to worry about it.\n   *\n   * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of\n   * `reject` as the `throw` keyword in JavaScript. This also means that if you \"catch\" an error via\n   * a promise error callback and you want to forward the error to the promise derived from the\n   * current promise, you have to \"rethrow\" the error by returning a rejection constructed via\n   * `reject`.\n   *\n   * ```js\n   *   promiseB = promiseA.then(function(result) {\n   *     // success: do something and resolve promiseB\n   *     //          with the old or a new result\n   *     return result;\n   *   }, function(reason) {\n   *     // error: handle the error if possible and\n   *     //        resolve promiseB with newPromiseOrValue,\n   *     //        otherwise forward the rejection to promiseB\n   *     if (canHandle(reason)) {\n   *      // handle the error and recover\n   *      return newPromiseOrValue;\n   *     }\n   *     return $q.reject(reason);\n   *   });\n   * ```\n   *\n   * @param {*} reason Constant, message, exception or an object representing the rejection reason.\n   * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.\n   */\n  function reject(reason) {\n    var result = new Promise();\n    rejectPromise(result, reason);\n    return result;\n  }\n\n  function handleCallback(value, resolver, callback) {\n    var callbackOutput = null;\n    try {\n      if (isFunction(callback)) callbackOutput = callback();\n    } catch (e) {\n      return reject(e);\n    }\n    if (isPromiseLike(callbackOutput)) {\n      return callbackOutput.then(function() {\n        return resolver(value);\n      }, reject);\n    } else {\n      return resolver(value);\n    }\n  }\n\n  /**\n   * @ngdoc method\n   * @name $q#when\n   * @kind function\n   *\n   * @description\n   * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.\n   * This is useful when you are dealing with an object that might or might not be a promise, or if\n   * the promise comes from a source that can't be trusted.\n   *\n   * @param {*} value Value or a promise\n   * @param {Function=} successCallback\n   * @param {Function=} errorCallback\n   * @param {Function=} progressCallback\n   * @returns {Promise} Returns a promise of the passed value or promise\n   */\n\n\n  function when(value, callback, errback, progressBack) {\n    var result = new Promise();\n    resolvePromise(result, value);\n    return result.then(callback, errback, progressBack);\n  }\n\n  /**\n   * @ngdoc method\n   * @name $q#resolve\n   * @kind function\n   *\n   * @description\n   * Alias of {@link ng.$q#when when} to maintain naming consistency with ES6.\n   *\n   * @param {*} value Value or a promise\n   * @param {Function=} successCallback\n   * @param {Function=} errorCallback\n   * @param {Function=} progressCallback\n   * @returns {Promise} Returns a promise of the passed value or promise\n   */\n  var resolve = when;\n\n  /**\n   * @ngdoc method\n   * @name $q#all\n   * @kind function\n   *\n   * @description\n   * Combines multiple promises into a single promise that is resolved when all of the input\n   * promises are resolved.\n   *\n   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.\n   * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values,\n   *   each value corresponding to the promise at the same index/key in the `promises` array/hash.\n   *   If any of the promises is resolved with a rejection, this resulting promise will be rejected\n   *   with the same rejection value.\n   */\n\n  function all(promises) {\n    var result = new Promise(),\n        counter = 0,\n        results = isArray(promises) ? [] : {};\n\n    forEach(promises, function(promise, key) {\n      counter++;\n      when(promise).then(function(value) {\n        results[key] = value;\n        if (!(--counter)) resolvePromise(result, results);\n      }, function(reason) {\n        rejectPromise(result, reason);\n      });\n    });\n\n    if (counter === 0) {\n      resolvePromise(result, results);\n    }\n\n    return result;\n  }\n\n  /**\n   * @ngdoc method\n   * @name $q#race\n   * @kind function\n   *\n   * @description\n   * Returns a promise that resolves or rejects as soon as one of those promises\n   * resolves or rejects, with the value or reason from that promise.\n   *\n   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.\n   * @returns {Promise} a promise that resolves or rejects as soon as one of the `promises`\n   * resolves or rejects, with the value or reason from that promise.\n   */\n\n  function race(promises) {\n    var deferred = defer();\n\n    forEach(promises, function(promise) {\n      when(promise).then(deferred.resolve, deferred.reject);\n    });\n\n    return deferred.promise;\n  }\n\n  function $Q(resolver) {\n    if (!isFunction(resolver)) {\n      throw $qMinErr('norslvr', 'Expected resolverFn, got \\'{0}\\'', resolver);\n    }\n\n    var promise = new Promise();\n\n    function resolveFn(value) {\n      resolvePromise(promise, value);\n    }\n\n    function rejectFn(reason) {\n      rejectPromise(promise, reason);\n    }\n\n    resolver(resolveFn, rejectFn);\n\n    return promise;\n  }\n\n  // Let's make the instanceof operator work for promises, so that\n  // `new $q(fn) instanceof $q` would evaluate to true.\n  $Q.prototype = Promise.prototype;\n\n  $Q.defer = defer;\n  $Q.reject = reject;\n  $Q.when = when;\n  $Q.resolve = resolve;\n  $Q.all = all;\n  $Q.race = race;\n\n  return $Q;\n}\n\n/** @this */\nfunction $$RAFProvider() { //rAF\n  this.$get = ['$window', '$timeout', function($window, $timeout) {\n    var requestAnimationFrame = $window.requestAnimationFrame ||\n                                $window.webkitRequestAnimationFrame;\n\n    var cancelAnimationFrame = $window.cancelAnimationFrame ||\n                               $window.webkitCancelAnimationFrame ||\n                               $window.webkitCancelRequestAnimationFrame;\n\n    var rafSupported = !!requestAnimationFrame;\n    var raf = rafSupported\n      ? function(fn) {\n          var id = requestAnimationFrame(fn);\n          return function() {\n            cancelAnimationFrame(id);\n          };\n        }\n      : function(fn) {\n          var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n          return function() {\n            $timeout.cancel(timer);\n          };\n        };\n\n    raf.supported = rafSupported;\n\n    return raf;\n  }];\n}\n\n/**\n * DESIGN NOTES\n *\n * The design decisions behind the scope are heavily favored for speed and memory consumption.\n *\n * The typical use of scope is to watch the expressions, which most of the time return the same\n * value as last time so we optimize the operation.\n *\n * Closures construction is expensive in terms of speed as well as memory:\n *   - No closures, instead use prototypical inheritance for API\n *   - Internal state needs to be stored on scope directly, which means that private state is\n *     exposed as $$____ properties\n *\n * Loop operations are optimized by using while(count--) { ... }\n *   - This means that in order to keep the same order of execution as addition we have to add\n *     items to the array at the beginning (unshift) instead of at the end (push)\n *\n * Child scopes are created and removed often\n *   - Using an array would be slow since inserts in the middle are expensive; so we use linked lists\n *\n * There are fewer watches than observers. This is why you don't want the observer to be implemented\n * in the same way as watch. Watch requires return of the initialization function which is expensive\n * to construct.\n */\n\n\n/**\n * @ngdoc provider\n * @name $rootScopeProvider\n * @description\n *\n * Provider for the $rootScope service.\n */\n\n/**\n * @ngdoc method\n * @name $rootScopeProvider#digestTtl\n * @description\n *\n * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and\n * assuming that the model is unstable.\n *\n * The current default is 10 iterations.\n *\n * In complex applications it's possible that the dependencies between `$watch`s will result in\n * several digest iterations. However if an application needs more than the default 10 digest\n * iterations for its model to stabilize then you should investigate what is causing the model to\n * continuously change during the digest.\n *\n * Increasing the TTL could have performance implications, so you should not change it without\n * proper justification.\n *\n * @param {number} limit The number of digest iterations.\n */\n\n\n/**\n * @ngdoc service\n * @name $rootScope\n * @this\n *\n * @description\n *\n * Every application has a single root {@link ng.$rootScope.Scope scope}.\n * All other scopes are descendant scopes of the root scope. Scopes provide separation\n * between the model and the view, via a mechanism for watching the model for changes.\n * They also provide event emission/broadcast and subscription facility. See the\n * {@link guide/scope developer guide on scopes}.\n */\nfunction $RootScopeProvider() {\n  var TTL = 10;\n  var $rootScopeMinErr = minErr('$rootScope');\n  var lastDirtyWatch = null;\n  var applyAsyncId = null;\n\n  this.digestTtl = function(value) {\n    if (arguments.length) {\n      TTL = value;\n    }\n    return TTL;\n  };\n\n  function createChildScopeClass(parent) {\n    function ChildScope() {\n      this.$$watchers = this.$$nextSibling =\n          this.$$childHead = this.$$childTail = null;\n      this.$$listeners = {};\n      this.$$listenerCount = {};\n      this.$$watchersCount = 0;\n      this.$id = nextUid();\n      this.$$ChildScope = null;\n    }\n    ChildScope.prototype = parent;\n    return ChildScope;\n  }\n\n  this.$get = ['$exceptionHandler', '$parse', '$browser',\n      function($exceptionHandler, $parse, $browser) {\n\n    function destroyChildScope($event) {\n        $event.currentScope.$$destroyed = true;\n    }\n\n    function cleanUpScope($scope) {\n\n      // Support: IE 9 only\n      if (msie === 9) {\n        // There is a memory leak in IE9 if all child scopes are not disconnected\n        // completely when a scope is destroyed. So this code will recurse up through\n        // all this scopes children\n        //\n        // See issue https://github.com/angular/angular.js/issues/10706\n        if ($scope.$$childHead) {\n          cleanUpScope($scope.$$childHead);\n        }\n        if ($scope.$$nextSibling) {\n          cleanUpScope($scope.$$nextSibling);\n        }\n      }\n\n      // The code below works around IE9 and V8's memory leaks\n      //\n      // See:\n      // - https://code.google.com/p/v8/issues/detail?id=2073#c26\n      // - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909\n      // - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451\n\n      $scope.$parent = $scope.$$nextSibling = $scope.$$prevSibling = $scope.$$childHead =\n          $scope.$$childTail = $scope.$root = $scope.$$watchers = null;\n    }\n\n    /**\n     * @ngdoc type\n     * @name $rootScope.Scope\n     *\n     * @description\n     * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the\n     * {@link auto.$injector $injector}. Child scopes are created using the\n     * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when\n     * compiled HTML template is executed.) See also the {@link guide/scope Scopes guide} for\n     * an in-depth introduction and usage examples.\n     *\n     *\n     * # Inheritance\n     * A scope can inherit from a parent scope, as in this example:\n     * ```js\n         var parent = $rootScope;\n         var child = parent.$new();\n\n         parent.salutation = \"Hello\";\n         expect(child.salutation).toEqual('Hello');\n\n         child.salutation = \"Welcome\";\n         expect(child.salutation).toEqual('Welcome');\n         expect(parent.salutation).toEqual('Hello');\n     * ```\n     *\n     * When interacting with `Scope` in tests, additional helper methods are available on the\n     * instances of `Scope` type. See {@link ngMock.$rootScope.Scope ngMock Scope} for additional\n     * details.\n     *\n     *\n     * @param {Object.<string, function()>=} providers Map of service factory which need to be\n     *                                       provided for the current scope. Defaults to {@link ng}.\n     * @param {Object.<string, *>=} instanceCache Provides pre-instantiated services which should\n     *                              append/override services provided by `providers`. This is handy\n     *                              when unit-testing and having the need to override a default\n     *                              service.\n     * @returns {Object} Newly created scope.\n     *\n     */\n    function Scope() {\n      this.$id = nextUid();\n      this.$$phase = this.$parent = this.$$watchers =\n                     this.$$nextSibling = this.$$prevSibling =\n                     this.$$childHead = this.$$childTail = null;\n      this.$root = this;\n      this.$$destroyed = false;\n      this.$$listeners = {};\n      this.$$listenerCount = {};\n      this.$$watchersCount = 0;\n      this.$$isolateBindings = null;\n    }\n\n    /**\n     * @ngdoc property\n     * @name $rootScope.Scope#$id\n     *\n     * @description\n     * Unique scope ID (monotonically increasing) useful for debugging.\n     */\n\n     /**\n      * @ngdoc property\n      * @name $rootScope.Scope#$parent\n      *\n      * @description\n      * Reference to the parent scope.\n      */\n\n      /**\n       * @ngdoc property\n       * @name $rootScope.Scope#$root\n       *\n       * @description\n       * Reference to the root scope.\n       */\n\n    Scope.prototype = {\n      constructor: Scope,\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$new\n       * @kind function\n       *\n       * @description\n       * Creates a new child {@link ng.$rootScope.Scope scope}.\n       *\n       * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} event.\n       * The scope can be removed from the scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}.\n       *\n       * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is\n       * desired for the scope and its child scopes to be permanently detached from the parent and\n       * thus stop participating in model change detection and listener notification by invoking.\n       *\n       * @param {boolean} isolate If true, then the scope does not prototypically inherit from the\n       *         parent scope. The scope is isolated, as it can not see parent scope properties.\n       *         When creating widgets, it is useful for the widget to not accidentally read parent\n       *         state.\n       *\n       * @param {Scope} [parent=this] The {@link ng.$rootScope.Scope `Scope`} that will be the `$parent`\n       *                              of the newly created scope. Defaults to `this` scope if not provided.\n       *                              This is used when creating a transclude scope to correctly place it\n       *                              in the scope hierarchy while maintaining the correct prototypical\n       *                              inheritance.\n       *\n       * @returns {Object} The newly created child scope.\n       *\n       */\n      $new: function(isolate, parent) {\n        var child;\n\n        parent = parent || this;\n\n        if (isolate) {\n          child = new Scope();\n          child.$root = this.$root;\n        } else {\n          // Only create a child scope class if somebody asks for one,\n          // but cache it to allow the VM to optimize lookups.\n          if (!this.$$ChildScope) {\n            this.$$ChildScope = createChildScopeClass(this);\n          }\n          child = new this.$$ChildScope();\n        }\n        child.$parent = parent;\n        child.$$prevSibling = parent.$$childTail;\n        if (parent.$$childHead) {\n          parent.$$childTail.$$nextSibling = child;\n          parent.$$childTail = child;\n        } else {\n          parent.$$childHead = parent.$$childTail = child;\n        }\n\n        // When the new scope is not isolated or we inherit from `this`, and\n        // the parent scope is destroyed, the property `$$destroyed` is inherited\n        // prototypically. In all other cases, this property needs to be set\n        // when the parent scope is destroyed.\n        // The listener needs to be added after the parent is set\n        if (isolate || parent !== this) child.$on('$destroy', destroyChildScope);\n\n        return child;\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$watch\n       * @kind function\n       *\n       * @description\n       * Registers a `listener` callback to be executed whenever the `watchExpression` changes.\n       *\n       * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest\n       *   $digest()} and should return the value that will be watched. (`watchExpression` should not change\n       *   its value when executed multiple times with the same input because it may be executed multiple\n       *   times by {@link ng.$rootScope.Scope#$digest $digest()}. That is, `watchExpression` should be\n       *   [idempotent](http://en.wikipedia.org/wiki/Idempotence).)\n       * - The `listener` is called only when the value from the current `watchExpression` and the\n       *   previous call to `watchExpression` are not equal (with the exception of the initial run,\n       *   see below). Inequality is determined according to reference inequality,\n       *   [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)\n       *    via the `!==` Javascript operator, unless `objectEquality == true`\n       *   (see next point)\n       * - When `objectEquality == true`, inequality of the `watchExpression` is determined\n       *   according to the {@link angular.equals} function. To save the value of the object for\n       *   later comparison, the {@link angular.copy} function is used. This therefore means that\n       *   watching complex objects will have adverse memory and performance implications.\n       * - This should not be used to watch for changes in objects that are\n       *   or contain [File](https://developer.mozilla.org/docs/Web/API/File) objects due to limitations with {@link angular.copy `angular.copy`}.\n       * - The watch `listener` may change the model, which may trigger other `listener`s to fire.\n       *   This is achieved by rerunning the watchers until no changes are detected. The rerun\n       *   iteration limit is 10 to prevent an infinite loop deadlock.\n       *\n       *\n       * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called,\n       * you can register a `watchExpression` function with no `listener`. (Be prepared for\n       * multiple calls to your `watchExpression` because it will execute multiple times in a\n       * single {@link ng.$rootScope.Scope#$digest $digest} cycle if a change is detected.)\n       *\n       * After a watcher is registered with the scope, the `listener` fn is called asynchronously\n       * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the\n       * watcher. In rare cases, this is undesirable because the listener is called when the result\n       * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you\n       * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the\n       * listener was called due to initialization.\n       *\n       *\n       *\n       * # Example\n       * ```js\n           // let's assume that scope was dependency injected as the $rootScope\n           var scope = $rootScope;\n           scope.name = 'misko';\n           scope.counter = 0;\n\n           expect(scope.counter).toEqual(0);\n           scope.$watch('name', function(newValue, oldValue) {\n             scope.counter = scope.counter + 1;\n           });\n           expect(scope.counter).toEqual(0);\n\n           scope.$digest();\n           // the listener is always called during the first $digest loop after it was registered\n           expect(scope.counter).toEqual(1);\n\n           scope.$digest();\n           // but now it will not be called unless the value changes\n           expect(scope.counter).toEqual(1);\n\n           scope.name = 'adam';\n           scope.$digest();\n           expect(scope.counter).toEqual(2);\n\n\n\n           // Using a function as a watchExpression\n           var food;\n           scope.foodCounter = 0;\n           expect(scope.foodCounter).toEqual(0);\n           scope.$watch(\n             // This function returns the value being watched. It is called for each turn of the $digest loop\n             function() { return food; },\n             // This is the change listener, called when the value returned from the above function changes\n             function(newValue, oldValue) {\n               if ( newValue !== oldValue ) {\n                 // Only increment the counter if the value changed\n                 scope.foodCounter = scope.foodCounter + 1;\n               }\n             }\n           );\n           // No digest has been run so the counter will be zero\n           expect(scope.foodCounter).toEqual(0);\n\n           // Run the digest but since food has not changed count will still be zero\n           scope.$digest();\n           expect(scope.foodCounter).toEqual(0);\n\n           // Update food and run digest.  Now the counter will increment\n           food = 'cheeseburger';\n           scope.$digest();\n           expect(scope.foodCounter).toEqual(1);\n\n       * ```\n       *\n       *\n       *\n       * @param {(function()|string)} watchExpression Expression that is evaluated on each\n       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers\n       *    a call to the `listener`.\n       *\n       *    - `string`: Evaluated as {@link guide/expression expression}\n       *    - `function(scope)`: called with current `scope` as a parameter.\n       * @param {function(newVal, oldVal, scope)} listener Callback called whenever the value\n       *    of `watchExpression` changes.\n       *\n       *    - `newVal` contains the current value of the `watchExpression`\n       *    - `oldVal` contains the previous value of the `watchExpression`\n       *    - `scope` refers to the current scope\n       * @param {boolean=} [objectEquality=false] Compare for object equality using {@link angular.equals} instead of\n       *     comparing for reference equality.\n       * @returns {function()} Returns a deregistration function for this listener.\n       */\n      $watch: function(watchExp, listener, objectEquality, prettyPrintExpression) {\n        var get = $parse(watchExp);\n\n        if (get.$$watchDelegate) {\n          return get.$$watchDelegate(this, listener, objectEquality, get, watchExp);\n        }\n        var scope = this,\n            array = scope.$$watchers,\n            watcher = {\n              fn: listener,\n              last: initWatchVal,\n              get: get,\n              exp: prettyPrintExpression || watchExp,\n              eq: !!objectEquality\n            };\n\n        lastDirtyWatch = null;\n\n        if (!isFunction(listener)) {\n          watcher.fn = noop;\n        }\n\n        if (!array) {\n          array = scope.$$watchers = [];\n          array.$$digestWatchIndex = -1;\n        }\n        // we use unshift since we use a while loop in $digest for speed.\n        // the while loop reads in reverse order.\n        array.unshift(watcher);\n        array.$$digestWatchIndex++;\n        incrementWatchersCount(this, 1);\n\n        return function deregisterWatch() {\n          var index = arrayRemove(array, watcher);\n          if (index >= 0) {\n            incrementWatchersCount(scope, -1);\n            if (index < array.$$digestWatchIndex) {\n              array.$$digestWatchIndex--;\n            }\n          }\n          lastDirtyWatch = null;\n        };\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$watchGroup\n       * @kind function\n       *\n       * @description\n       * A variant of {@link ng.$rootScope.Scope#$watch $watch()} where it watches an array of `watchExpressions`.\n       * If any one expression in the collection changes the `listener` is executed.\n       *\n       * - The items in the `watchExpressions` array are observed via the standard `$watch` operation. Their return\n       *   values are examined for changes on every call to `$digest`.\n       * - The `listener` is called whenever any expression in the `watchExpressions` array changes.\n       *\n       * @param {Array.<string|Function(scope)>} watchExpressions Array of expressions that will be individually\n       * watched using {@link ng.$rootScope.Scope#$watch $watch()}\n       *\n       * @param {function(newValues, oldValues, scope)} listener Callback called whenever the return value of any\n       *    expression in `watchExpressions` changes\n       *    The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching\n       *    those of `watchExpression`\n       *    and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching\n       *    those of `watchExpression`\n       *    The `scope` refers to the current scope.\n       * @returns {function()} Returns a de-registration function for all listeners.\n       */\n      $watchGroup: function(watchExpressions, listener) {\n        var oldValues = new Array(watchExpressions.length);\n        var newValues = new Array(watchExpressions.length);\n        var deregisterFns = [];\n        var self = this;\n        var changeReactionScheduled = false;\n        var firstRun = true;\n\n        if (!watchExpressions.length) {\n          // No expressions means we call the listener ASAP\n          var shouldCall = true;\n          self.$evalAsync(function() {\n            if (shouldCall) listener(newValues, newValues, self);\n          });\n          return function deregisterWatchGroup() {\n            shouldCall = false;\n          };\n        }\n\n        if (watchExpressions.length === 1) {\n          // Special case size of one\n          return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {\n            newValues[0] = value;\n            oldValues[0] = oldValue;\n            listener(newValues, (value === oldValue) ? newValues : oldValues, scope);\n          });\n        }\n\n        forEach(watchExpressions, function(expr, i) {\n          var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) {\n            newValues[i] = value;\n            oldValues[i] = oldValue;\n            if (!changeReactionScheduled) {\n              changeReactionScheduled = true;\n              self.$evalAsync(watchGroupAction);\n            }\n          });\n          deregisterFns.push(unwatchFn);\n        });\n\n        function watchGroupAction() {\n          changeReactionScheduled = false;\n\n          if (firstRun) {\n            firstRun = false;\n            listener(newValues, newValues, self);\n          } else {\n            listener(newValues, oldValues, self);\n          }\n        }\n\n        return function deregisterWatchGroup() {\n          while (deregisterFns.length) {\n            deregisterFns.shift()();\n          }\n        };\n      },\n\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$watchCollection\n       * @kind function\n       *\n       * @description\n       * Shallow watches the properties of an object and fires whenever any of the properties change\n       * (for arrays, this implies watching the array items; for object maps, this implies watching\n       * the properties). If a change is detected, the `listener` callback is fired.\n       *\n       * - The `obj` collection is observed via standard $watch operation and is examined on every\n       *   call to $digest() to see if any items have been added, removed, or moved.\n       * - The `listener` is called whenever anything within the `obj` has changed. Examples include\n       *   adding, removing, and moving items belonging to an object or array.\n       *\n       *\n       * # Example\n       * ```js\n          $scope.names = ['igor', 'matias', 'misko', 'james'];\n          $scope.dataCount = 4;\n\n          $scope.$watchCollection('names', function(newNames, oldNames) {\n            $scope.dataCount = newNames.length;\n          });\n\n          expect($scope.dataCount).toEqual(4);\n          $scope.$digest();\n\n          //still at 4 ... no changes\n          expect($scope.dataCount).toEqual(4);\n\n          $scope.names.pop();\n          $scope.$digest();\n\n          //now there's been a change\n          expect($scope.dataCount).toEqual(3);\n       * ```\n       *\n       *\n       * @param {string|function(scope)} obj Evaluated as {@link guide/expression expression}. The\n       *    expression value should evaluate to an object or an array which is observed on each\n       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the\n       *    collection will trigger a call to the `listener`.\n       *\n       * @param {function(newCollection, oldCollection, scope)} listener a callback function called\n       *    when a change is detected.\n       *    - The `newCollection` object is the newly modified data obtained from the `obj` expression\n       *    - The `oldCollection` object is a copy of the former collection data.\n       *      Due to performance considerations, the`oldCollection` value is computed only if the\n       *      `listener` function declares two or more arguments.\n       *    - The `scope` argument refers to the current scope.\n       *\n       * @returns {function()} Returns a de-registration function for this listener. When the\n       *    de-registration function is executed, the internal watch operation is terminated.\n       */\n      $watchCollection: function(obj, listener) {\n        $watchCollectionInterceptor.$stateful = true;\n\n        var self = this;\n        // the current value, updated on each dirty-check run\n        var newValue;\n        // a shallow copy of the newValue from the last dirty-check run,\n        // updated to match newValue during dirty-check run\n        var oldValue;\n        // a shallow copy of the newValue from when the last change happened\n        var veryOldValue;\n        // only track veryOldValue if the listener is asking for it\n        var trackVeryOldValue = (listener.length > 1);\n        var changeDetected = 0;\n        var changeDetector = $parse(obj, $watchCollectionInterceptor);\n        var internalArray = [];\n        var internalObject = {};\n        var initRun = true;\n        var oldLength = 0;\n\n        function $watchCollectionInterceptor(_value) {\n          newValue = _value;\n          var newLength, key, bothNaN, newItem, oldItem;\n\n          // If the new value is undefined, then return undefined as the watch may be a one-time watch\n          if (isUndefined(newValue)) return;\n\n          if (!isObject(newValue)) { // if primitive\n            if (oldValue !== newValue) {\n              oldValue = newValue;\n              changeDetected++;\n            }\n          } else if (isArrayLike(newValue)) {\n            if (oldValue !== internalArray) {\n              // we are transitioning from something which was not an array into array.\n              oldValue = internalArray;\n              oldLength = oldValue.length = 0;\n              changeDetected++;\n            }\n\n            newLength = newValue.length;\n\n            if (oldLength !== newLength) {\n              // if lengths do not match we need to trigger change notification\n              changeDetected++;\n              oldValue.length = oldLength = newLength;\n            }\n            // copy the items to oldValue and look for changes.\n            for (var i = 0; i < newLength; i++) {\n              oldItem = oldValue[i];\n              newItem = newValue[i];\n\n              // eslint-disable-next-line no-self-compare\n              bothNaN = (oldItem !== oldItem) && (newItem !== newItem);\n              if (!bothNaN && (oldItem !== newItem)) {\n                changeDetected++;\n                oldValue[i] = newItem;\n              }\n            }\n          } else {\n            if (oldValue !== internalObject) {\n              // we are transitioning from something which was not an object into object.\n              oldValue = internalObject = {};\n              oldLength = 0;\n              changeDetected++;\n            }\n            // copy the items to oldValue and look for changes.\n            newLength = 0;\n            for (key in newValue) {\n              if (hasOwnProperty.call(newValue, key)) {\n                newLength++;\n                newItem = newValue[key];\n                oldItem = oldValue[key];\n\n                if (key in oldValue) {\n                  // eslint-disable-next-line no-self-compare\n                  bothNaN = (oldItem !== oldItem) && (newItem !== newItem);\n                  if (!bothNaN && (oldItem !== newItem)) {\n                    changeDetected++;\n                    oldValue[key] = newItem;\n                  }\n                } else {\n                  oldLength++;\n                  oldValue[key] = newItem;\n                  changeDetected++;\n                }\n              }\n            }\n            if (oldLength > newLength) {\n              // we used to have more keys, need to find them and destroy them.\n              changeDetected++;\n              for (key in oldValue) {\n                if (!hasOwnProperty.call(newValue, key)) {\n                  oldLength--;\n                  delete oldValue[key];\n                }\n              }\n            }\n          }\n          return changeDetected;\n        }\n\n        function $watchCollectionAction() {\n          if (initRun) {\n            initRun = false;\n            listener(newValue, newValue, self);\n          } else {\n            listener(newValue, veryOldValue, self);\n          }\n\n          // make a copy for the next time a collection is changed\n          if (trackVeryOldValue) {\n            if (!isObject(newValue)) {\n              //primitive\n              veryOldValue = newValue;\n            } else if (isArrayLike(newValue)) {\n              veryOldValue = new Array(newValue.length);\n              for (var i = 0; i < newValue.length; i++) {\n                veryOldValue[i] = newValue[i];\n              }\n            } else { // if object\n              veryOldValue = {};\n              for (var key in newValue) {\n                if (hasOwnProperty.call(newValue, key)) {\n                  veryOldValue[key] = newValue[key];\n                }\n              }\n            }\n          }\n        }\n\n        return this.$watch(changeDetector, $watchCollectionAction);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$digest\n       * @kind function\n       *\n       * @description\n       * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and\n       * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change\n       * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers}\n       * until no more listeners are firing. This means that it is possible to get into an infinite\n       * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of\n       * iterations exceeds 10.\n       *\n       * Usually, you don't call `$digest()` directly in\n       * {@link ng.directive:ngController controllers} or in\n       * {@link ng.$compileProvider#directive directives}.\n       * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within\n       * a {@link ng.$compileProvider#directive directive}), which will force a `$digest()`.\n       *\n       * If you want to be notified whenever `$digest()` is called,\n       * you can register a `watchExpression` function with\n       * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`.\n       *\n       * In unit tests, you may need to call `$digest()` to simulate the scope life cycle.\n       *\n       * # Example\n       * ```js\n           var scope = ...;\n           scope.name = 'misko';\n           scope.counter = 0;\n\n           expect(scope.counter).toEqual(0);\n           scope.$watch('name', function(newValue, oldValue) {\n             scope.counter = scope.counter + 1;\n           });\n           expect(scope.counter).toEqual(0);\n\n           scope.$digest();\n           // the listener is always called during the first $digest loop after it was registered\n           expect(scope.counter).toEqual(1);\n\n           scope.$digest();\n           // but now it will not be called unless the value changes\n           expect(scope.counter).toEqual(1);\n\n           scope.name = 'adam';\n           scope.$digest();\n           expect(scope.counter).toEqual(2);\n       * ```\n       *\n       */\n      $digest: function() {\n        var watch, value, last, fn, get,\n            watchers,\n            dirty, ttl = TTL,\n            next, current, target = this,\n            watchLog = [],\n            logIdx, asyncTask;\n\n        beginPhase('$digest');\n        // Check for changes to browser url that happened in sync before the call to $digest\n        $browser.$$checkUrlChange();\n\n        if (this === $rootScope && applyAsyncId !== null) {\n          // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then\n          // cancel the scheduled $apply and flush the queue of expressions to be evaluated.\n          $browser.defer.cancel(applyAsyncId);\n          flushApplyAsync();\n        }\n\n        lastDirtyWatch = null;\n\n        do { // \"while dirty\" loop\n          dirty = false;\n          current = target;\n\n          // It's safe for asyncQueuePosition to be a local variable here because this loop can't\n          // be reentered recursively. Calling $digest from a function passed to $evalAsync would\n          // lead to a '$digest already in progress' error.\n          for (var asyncQueuePosition = 0; asyncQueuePosition < asyncQueue.length; asyncQueuePosition++) {\n            try {\n              asyncTask = asyncQueue[asyncQueuePosition];\n              fn = asyncTask.fn;\n              fn(asyncTask.scope, asyncTask.locals);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n            lastDirtyWatch = null;\n          }\n          asyncQueue.length = 0;\n\n          traverseScopesLoop:\n          do { // \"traverse the scopes\" loop\n            if ((watchers = current.$$watchers)) {\n              // process our watches\n              watchers.$$digestWatchIndex = watchers.length;\n              while (watchers.$$digestWatchIndex--) {\n                try {\n                  watch = watchers[watchers.$$digestWatchIndex];\n                  // Most common watches are on primitives, in which case we can short\n                  // circuit it with === operator, only when === fails do we use .equals\n                  if (watch) {\n                    get = watch.get;\n                    if ((value = get(current)) !== (last = watch.last) &&\n                        !(watch.eq\n                            ? equals(value, last)\n                            : (isNumberNaN(value) && isNumberNaN(last)))) {\n                      dirty = true;\n                      lastDirtyWatch = watch;\n                      watch.last = watch.eq ? copy(value, null) : value;\n                      fn = watch.fn;\n                      fn(value, ((last === initWatchVal) ? value : last), current);\n                      if (ttl < 5) {\n                        logIdx = 4 - ttl;\n                        if (!watchLog[logIdx]) watchLog[logIdx] = [];\n                        watchLog[logIdx].push({\n                          msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,\n                          newVal: value,\n                          oldVal: last\n                        });\n                      }\n                    } else if (watch === lastDirtyWatch) {\n                      // If the most recently dirty watcher is now clean, short circuit since the remaining watchers\n                      // have already been tested.\n                      dirty = false;\n                      break traverseScopesLoop;\n                    }\n                  }\n                } catch (e) {\n                  $exceptionHandler(e);\n                }\n              }\n            }\n\n            // Insanity Warning: scope depth-first traversal\n            // yes, this code is a bit crazy, but it works and we have tests to prove it!\n            // this piece should be kept in sync with the traversal in $broadcast\n            if (!(next = ((current.$$watchersCount && current.$$childHead) ||\n                (current !== target && current.$$nextSibling)))) {\n              while (current !== target && !(next = current.$$nextSibling)) {\n                current = current.$parent;\n              }\n            }\n          } while ((current = next));\n\n          // `break traverseScopesLoop;` takes us to here\n\n          if ((dirty || asyncQueue.length) && !(ttl--)) {\n            clearPhase();\n            throw $rootScopeMinErr('infdig',\n                '{0} $digest() iterations reached. Aborting!\\n' +\n                'Watchers fired in the last 5 iterations: {1}',\n                TTL, watchLog);\n          }\n\n        } while (dirty || asyncQueue.length);\n\n        clearPhase();\n\n        // postDigestQueuePosition isn't local here because this loop can be reentered recursively.\n        while (postDigestQueuePosition < postDigestQueue.length) {\n          try {\n            postDigestQueue[postDigestQueuePosition++]();\n          } catch (e) {\n            $exceptionHandler(e);\n          }\n        }\n        postDigestQueue.length = postDigestQueuePosition = 0;\n\n        // Check for changes to browser url that happened during the $digest\n        // (for which no event is fired; e.g. via `history.pushState()`)\n        $browser.$$checkUrlChange();\n      },\n\n\n      /**\n       * @ngdoc event\n       * @name $rootScope.Scope#$destroy\n       * @eventType broadcast on scope being destroyed\n       *\n       * @description\n       * Broadcasted when a scope and its children are being destroyed.\n       *\n       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to\n       * clean up DOM bindings before an element is removed from the DOM.\n       */\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$destroy\n       * @kind function\n       *\n       * @description\n       * Removes the current scope (and all of its children) from the parent scope. Removal implies\n       * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer\n       * propagate to the current scope and its children. Removal also implies that the current\n       * scope is eligible for garbage collection.\n       *\n       * The `$destroy()` is usually used by directives such as\n       * {@link ng.directive:ngRepeat ngRepeat} for managing the\n       * unrolling of the loop.\n       *\n       * Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope.\n       * Application code can register a `$destroy` event handler that will give it a chance to\n       * perform any necessary cleanup.\n       *\n       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to\n       * clean up DOM bindings before an element is removed from the DOM.\n       */\n      $destroy: function() {\n        // We can't destroy a scope that has been already destroyed.\n        if (this.$$destroyed) return;\n        var parent = this.$parent;\n\n        this.$broadcast('$destroy');\n        this.$$destroyed = true;\n\n        if (this === $rootScope) {\n          //Remove handlers attached to window when $rootScope is removed\n          $browser.$$applicationDestroyed();\n        }\n\n        incrementWatchersCount(this, -this.$$watchersCount);\n        for (var eventName in this.$$listenerCount) {\n          decrementListenerCount(this, this.$$listenerCount[eventName], eventName);\n        }\n\n        // sever all the references to parent scopes (after this cleanup, the current scope should\n        // not be retained by any of our references and should be eligible for garbage collection)\n        if (parent && parent.$$childHead === this) parent.$$childHead = this.$$nextSibling;\n        if (parent && parent.$$childTail === this) parent.$$childTail = this.$$prevSibling;\n        if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;\n        if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;\n\n        // Disable listeners, watchers and apply/digest methods\n        this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop;\n        this.$on = this.$watch = this.$watchGroup = function() { return noop; };\n        this.$$listeners = {};\n\n        // Disconnect the next sibling to prevent `cleanUpScope` destroying those too\n        this.$$nextSibling = null;\n        cleanUpScope(this);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$eval\n       * @kind function\n       *\n       * @description\n       * Executes the `expression` on the current scope and returns the result. Any exceptions in\n       * the expression are propagated (uncaught). This is useful when evaluating Angular\n       * expressions.\n       *\n       * # Example\n       * ```js\n           var scope = ng.$rootScope.Scope();\n           scope.a = 1;\n           scope.b = 2;\n\n           expect(scope.$eval('a+b')).toEqual(3);\n           expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);\n       * ```\n       *\n       * @param {(string|function())=} expression An angular expression to be executed.\n       *\n       *    - `string`: execute using the rules as defined in  {@link guide/expression expression}.\n       *    - `function(scope)`: execute the function with the current `scope` parameter.\n       *\n       * @param {(object)=} locals Local variables object, useful for overriding values in scope.\n       * @returns {*} The result of evaluating the expression.\n       */\n      $eval: function(expr, locals) {\n        return $parse(expr)(this, locals);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$evalAsync\n       * @kind function\n       *\n       * @description\n       * Executes the expression on the current scope at a later point in time.\n       *\n       * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only\n       * that:\n       *\n       *   - it will execute after the function that scheduled the evaluation (preferably before DOM\n       *     rendering).\n       *   - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after\n       *     `expression` execution.\n       *\n       * Any exceptions from the execution of the expression are forwarded to the\n       * {@link ng.$exceptionHandler $exceptionHandler} service.\n       *\n       * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle\n       * will be scheduled. However, it is encouraged to always call code that changes the model\n       * from within an `$apply` call. That includes code evaluated via `$evalAsync`.\n       *\n       * @param {(string|function())=} expression An angular expression to be executed.\n       *\n       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.\n       *    - `function(scope)`: execute the function with the current `scope` parameter.\n       *\n       * @param {(object)=} locals Local variables object, useful for overriding values in scope.\n       */\n      $evalAsync: function(expr, locals) {\n        // if we are outside of an $digest loop and this is the first time we are scheduling async\n        // task also schedule async auto-flush\n        if (!$rootScope.$$phase && !asyncQueue.length) {\n          $browser.defer(function() {\n            if (asyncQueue.length) {\n              $rootScope.$digest();\n            }\n          });\n        }\n\n        asyncQueue.push({scope: this, fn: $parse(expr), locals: locals});\n      },\n\n      $$postDigest: function(fn) {\n        postDigestQueue.push(fn);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$apply\n       * @kind function\n       *\n       * @description\n       * `$apply()` is used to execute an expression in angular from outside of the angular\n       * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).\n       * Because we are calling into the angular framework we need to perform proper scope life\n       * cycle of {@link ng.$exceptionHandler exception handling},\n       * {@link ng.$rootScope.Scope#$digest executing watches}.\n       *\n       * ## Life cycle\n       *\n       * # Pseudo-Code of `$apply()`\n       * ```js\n           function $apply(expr) {\n             try {\n               return $eval(expr);\n             } catch (e) {\n               $exceptionHandler(e);\n             } finally {\n               $root.$digest();\n             }\n           }\n       * ```\n       *\n       *\n       * Scope's `$apply()` method transitions through the following stages:\n       *\n       * 1. The {@link guide/expression expression} is executed using the\n       *    {@link ng.$rootScope.Scope#$eval $eval()} method.\n       * 2. Any exceptions from the execution of the expression are forwarded to the\n       *    {@link ng.$exceptionHandler $exceptionHandler} service.\n       * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the\n       *    expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method.\n       *\n       *\n       * @param {(string|function())=} exp An angular expression to be executed.\n       *\n       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.\n       *    - `function(scope)`: execute the function with current `scope` parameter.\n       *\n       * @returns {*} The result of evaluating the expression.\n       */\n      $apply: function(expr) {\n        try {\n          beginPhase('$apply');\n          try {\n            return this.$eval(expr);\n          } finally {\n            clearPhase();\n          }\n        } catch (e) {\n          $exceptionHandler(e);\n        } finally {\n          try {\n            $rootScope.$digest();\n          } catch (e) {\n            $exceptionHandler(e);\n            // eslint-disable-next-line no-unsafe-finally\n            throw e;\n          }\n        }\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$applyAsync\n       * @kind function\n       *\n       * @description\n       * Schedule the invocation of $apply to occur at a later time. The actual time difference\n       * varies across browsers, but is typically around ~10 milliseconds.\n       *\n       * This can be used to queue up multiple expressions which need to be evaluated in the same\n       * digest.\n       *\n       * @param {(string|function())=} exp An angular expression to be executed.\n       *\n       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.\n       *    - `function(scope)`: execute the function with current `scope` parameter.\n       */\n      $applyAsync: function(expr) {\n        var scope = this;\n        if (expr) {\n          applyAsyncQueue.push($applyAsyncExpression);\n        }\n        expr = $parse(expr);\n        scheduleApplyAsync();\n\n        function $applyAsyncExpression() {\n          scope.$eval(expr);\n        }\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$on\n       * @kind function\n       *\n       * @description\n       * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for\n       * discussion of event life cycle.\n       *\n       * The event listener function format is: `function(event, args...)`. The `event` object\n       * passed into the listener has the following attributes:\n       *\n       *   - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or\n       *     `$broadcast`-ed.\n       *   - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the\n       *     event propagates through the scope hierarchy, this property is set to null.\n       *   - `name` - `{string}`: name of the event.\n       *   - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel\n       *     further event propagation (available only for events that were `$emit`-ed).\n       *   - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag\n       *     to true.\n       *   - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.\n       *\n       * @param {string} name Event name to listen on.\n       * @param {function(event, ...args)} listener Function to call when the event is emitted.\n       * @returns {function()} Returns a deregistration function for this listener.\n       */\n      $on: function(name, listener) {\n        var namedListeners = this.$$listeners[name];\n        if (!namedListeners) {\n          this.$$listeners[name] = namedListeners = [];\n        }\n        namedListeners.push(listener);\n\n        var current = this;\n        do {\n          if (!current.$$listenerCount[name]) {\n            current.$$listenerCount[name] = 0;\n          }\n          current.$$listenerCount[name]++;\n        } while ((current = current.$parent));\n\n        var self = this;\n        return function() {\n          var indexOfListener = namedListeners.indexOf(listener);\n          if (indexOfListener !== -1) {\n            namedListeners[indexOfListener] = null;\n            decrementListenerCount(self, 1, name);\n          }\n        };\n      },\n\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$emit\n       * @kind function\n       *\n       * @description\n       * Dispatches an event `name` upwards through the scope hierarchy notifying the\n       * registered {@link ng.$rootScope.Scope#$on} listeners.\n       *\n       * The event life cycle starts at the scope on which `$emit` was called. All\n       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get\n       * notified. Afterwards, the event traverses upwards toward the root scope and calls all\n       * registered listeners along the way. The event will stop propagating if one of the listeners\n       * cancels it.\n       *\n       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed\n       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.\n       *\n       * @param {string} name Event name to emit.\n       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.\n       * @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}).\n       */\n      $emit: function(name, args) {\n        var empty = [],\n            namedListeners,\n            scope = this,\n            stopPropagation = false,\n            event = {\n              name: name,\n              targetScope: scope,\n              stopPropagation: function() {stopPropagation = true;},\n              preventDefault: function() {\n                event.defaultPrevented = true;\n              },\n              defaultPrevented: false\n            },\n            listenerArgs = concat([event], arguments, 1),\n            i, length;\n\n        do {\n          namedListeners = scope.$$listeners[name] || empty;\n          event.currentScope = scope;\n          for (i = 0, length = namedListeners.length; i < length; i++) {\n\n            // if listeners were deregistered, defragment the array\n            if (!namedListeners[i]) {\n              namedListeners.splice(i, 1);\n              i--;\n              length--;\n              continue;\n            }\n            try {\n              //allow all listeners attached to the current scope to run\n              namedListeners[i].apply(null, listenerArgs);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          }\n          //if any listener on the current scope stops propagation, prevent bubbling\n          if (stopPropagation) {\n            event.currentScope = null;\n            return event;\n          }\n          //traverse upwards\n          scope = scope.$parent;\n        } while (scope);\n\n        event.currentScope = null;\n\n        return event;\n      },\n\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$broadcast\n       * @kind function\n       *\n       * @description\n       * Dispatches an event `name` downwards to all child scopes (and their children) notifying the\n       * registered {@link ng.$rootScope.Scope#$on} listeners.\n       *\n       * The event life cycle starts at the scope on which `$broadcast` was called. All\n       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get\n       * notified. Afterwards, the event propagates to all direct and indirect scopes of the current\n       * scope and calls all registered listeners along the way. The event cannot be canceled.\n       *\n       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed\n       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.\n       *\n       * @param {string} name Event name to broadcast.\n       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.\n       * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}\n       */\n      $broadcast: function(name, args) {\n        var target = this,\n            current = target,\n            next = target,\n            event = {\n              name: name,\n              targetScope: target,\n              preventDefault: function() {\n                event.defaultPrevented = true;\n              },\n              defaultPrevented: false\n            };\n\n        if (!target.$$listenerCount[name]) return event;\n\n        var listenerArgs = concat([event], arguments, 1),\n            listeners, i, length;\n\n        //down while you can, then up and next sibling or up and next sibling until back at root\n        while ((current = next)) {\n          event.currentScope = current;\n          listeners = current.$$listeners[name] || [];\n          for (i = 0, length = listeners.length; i < length; i++) {\n            // if listeners were deregistered, defragment the array\n            if (!listeners[i]) {\n              listeners.splice(i, 1);\n              i--;\n              length--;\n              continue;\n            }\n\n            try {\n              listeners[i].apply(null, listenerArgs);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          }\n\n          // Insanity Warning: scope depth-first traversal\n          // yes, this code is a bit crazy, but it works and we have tests to prove it!\n          // this piece should be kept in sync with the traversal in $digest\n          // (though it differs due to having the extra check for $$listenerCount)\n          if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||\n              (current !== target && current.$$nextSibling)))) {\n            while (current !== target && !(next = current.$$nextSibling)) {\n              current = current.$parent;\n            }\n          }\n        }\n\n        event.currentScope = null;\n        return event;\n      }\n    };\n\n    var $rootScope = new Scope();\n\n    //The internal queues. Expose them on the $rootScope for debugging/testing purposes.\n    var asyncQueue = $rootScope.$$asyncQueue = [];\n    var postDigestQueue = $rootScope.$$postDigestQueue = [];\n    var applyAsyncQueue = $rootScope.$$applyAsyncQueue = [];\n\n    var postDigestQueuePosition = 0;\n\n    return $rootScope;\n\n\n    function beginPhase(phase) {\n      if ($rootScope.$$phase) {\n        throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);\n      }\n\n      $rootScope.$$phase = phase;\n    }\n\n    function clearPhase() {\n      $rootScope.$$phase = null;\n    }\n\n    function incrementWatchersCount(current, count) {\n      do {\n        current.$$watchersCount += count;\n      } while ((current = current.$parent));\n    }\n\n    function decrementListenerCount(current, count, name) {\n      do {\n        current.$$listenerCount[name] -= count;\n\n        if (current.$$listenerCount[name] === 0) {\n          delete current.$$listenerCount[name];\n        }\n      } while ((current = current.$parent));\n    }\n\n    /**\n     * function used as an initial value for watchers.\n     * because it's unique we can easily tell it apart from other values\n     */\n    function initWatchVal() {}\n\n    function flushApplyAsync() {\n      while (applyAsyncQueue.length) {\n        try {\n          applyAsyncQueue.shift()();\n        } catch (e) {\n          $exceptionHandler(e);\n        }\n      }\n      applyAsyncId = null;\n    }\n\n    function scheduleApplyAsync() {\n      if (applyAsyncId === null) {\n        applyAsyncId = $browser.defer(function() {\n          $rootScope.$apply(flushApplyAsync);\n        });\n      }\n    }\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $rootElement\n *\n * @description\n * The root element of Angular application. This is either the element where {@link\n * ng.directive:ngApp ngApp} was declared or the element passed into\n * {@link angular.bootstrap}. The element represents the root element of application. It is also the\n * location where the application's {@link auto.$injector $injector} service gets\n * published, and can be retrieved using `$rootElement.injector()`.\n */\n\n\n// the implementation is in angular.bootstrap\n\n/**\n * @this\n * @description\n * Private service to sanitize uris for links and images. Used by $compile and $sanitize.\n */\nfunction $$SanitizeUriProvider() {\n  var aHrefSanitizationWhitelist = /^\\s*(https?|ftp|mailto|tel|file):/,\n    imgSrcSanitizationWhitelist = /^\\s*((https?|ftp|file|blob):|data:image\\/)/;\n\n  /**\n   * @description\n   * Retrieves or overrides the default regular expression that is used for whitelisting of safe\n   * urls during a[href] sanitization.\n   *\n   * The sanitization is a security measure aimed at prevent XSS attacks via html links.\n   *\n   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into\n   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`\n   * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n   *\n   * @param {RegExp=} regexp New regexp to whitelist urls with.\n   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for\n   *    chaining otherwise.\n   */\n  this.aHrefSanitizationWhitelist = function(regexp) {\n    if (isDefined(regexp)) {\n      aHrefSanitizationWhitelist = regexp;\n      return this;\n    }\n    return aHrefSanitizationWhitelist;\n  };\n\n\n  /**\n   * @description\n   * Retrieves or overrides the default regular expression that is used for whitelisting of safe\n   * urls during img[src] sanitization.\n   *\n   * The sanitization is a security measure aimed at prevent XSS attacks via html links.\n   *\n   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into\n   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`\n   * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n   *\n   * @param {RegExp=} regexp New regexp to whitelist urls with.\n   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for\n   *    chaining otherwise.\n   */\n  this.imgSrcSanitizationWhitelist = function(regexp) {\n    if (isDefined(regexp)) {\n      imgSrcSanitizationWhitelist = regexp;\n      return this;\n    }\n    return imgSrcSanitizationWhitelist;\n  };\n\n  this.$get = function() {\n    return function sanitizeUri(uri, isImage) {\n      var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;\n      var normalizedVal;\n      normalizedVal = urlResolve(uri).href;\n      if (normalizedVal !== '' && !normalizedVal.match(regex)) {\n        return 'unsafe:' + normalizedVal;\n      }\n      return uri;\n    };\n  };\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *     Any commits to this file should be reviewed with security in mind.  *\n *   Changes to this file can potentially create security vulnerabilities. *\n *          An approval from 2 Core members with history of modifying      *\n *                         this file is required.                          *\n *                                                                         *\n *  Does the change somehow allow for arbitrary javascript to be executed? *\n *    Or allows for someone to change the prototype of built-in objects?   *\n *     Or gives undesired access to variables likes document or window?    *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/* exported $SceProvider, $SceDelegateProvider */\n\nvar $sceMinErr = minErr('$sce');\n\nvar SCE_CONTEXTS = {\n  HTML: 'html',\n  CSS: 'css',\n  URL: 'url',\n  // RESOURCE_URL is a subtype of URL used in contexts where a privileged resource is sourced from a\n  // url.  (e.g. ng-include, script src, templateUrl)\n  RESOURCE_URL: 'resourceUrl',\n  JS: 'js'\n};\n\n// Helper functions follow.\n\nvar UNDERSCORE_LOWERCASE_REGEXP = /_([a-z])/g;\n\nfunction snakeToCamel(name) {\n  return name\n    .replace(UNDERSCORE_LOWERCASE_REGEXP, fnCamelCaseReplace);\n}\n\nfunction adjustMatcher(matcher) {\n  if (matcher === 'self') {\n    return matcher;\n  } else if (isString(matcher)) {\n    // Strings match exactly except for 2 wildcards - '*' and '**'.\n    // '*' matches any character except those from the set ':/.?&'.\n    // '**' matches any character (like .* in a RegExp).\n    // More than 2 *'s raises an error as it's ill defined.\n    if (matcher.indexOf('***') > -1) {\n      throw $sceMinErr('iwcard',\n          'Illegal sequence *** in string matcher.  String: {0}', matcher);\n    }\n    matcher = escapeForRegexp(matcher).\n                  replace(/\\\\\\*\\\\\\*/g, '.*').\n                  replace(/\\\\\\*/g, '[^:/.?&;]*');\n    return new RegExp('^' + matcher + '$');\n  } else if (isRegExp(matcher)) {\n    // The only other type of matcher allowed is a Regexp.\n    // Match entire URL / disallow partial matches.\n    // Flags are reset (i.e. no global, ignoreCase or multiline)\n    return new RegExp('^' + matcher.source + '$');\n  } else {\n    throw $sceMinErr('imatcher',\n        'Matchers may only be \"self\", string patterns or RegExp objects');\n  }\n}\n\n\nfunction adjustMatchers(matchers) {\n  var adjustedMatchers = [];\n  if (isDefined(matchers)) {\n    forEach(matchers, function(matcher) {\n      adjustedMatchers.push(adjustMatcher(matcher));\n    });\n  }\n  return adjustedMatchers;\n}\n\n\n/**\n * @ngdoc service\n * @name $sceDelegate\n * @kind function\n *\n * @description\n *\n * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict\n * Contextual Escaping (SCE)} services to AngularJS.\n *\n * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of\n * the `$sce` service to customize the way Strict Contextual Escaping works in AngularJS.  This is\n * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to\n * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things\n * work because `$sce` delegates to `$sceDelegate` for these operations.\n *\n * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.\n *\n * The default instance of `$sceDelegate` should work out of the box with little pain.  While you\n * can override it completely to change the behavior of `$sce`, the common case would\n * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting\n * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as\n * templates.  Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist\n * $sceDelegateProvider.resourceUrlWhitelist} and {@link\n * ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}\n */\n\n/**\n * @ngdoc provider\n * @name $sceDelegateProvider\n * @this\n *\n * @description\n *\n * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate\n * $sceDelegate} service.  This allows one to get/set the whitelists and blacklists used to ensure\n * that the URLs used for sourcing Angular templates are safe.  Refer {@link\n * ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and\n * {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}\n *\n * For the general details about this service in Angular, read the main page for {@link ng.$sce\n * Strict Contextual Escaping (SCE)}.\n *\n * **Example**:  Consider the following case. <a name=\"example\"></a>\n *\n * - your app is hosted at url `http://myapp.example.com/`\n * - but some of your templates are hosted on other domains you control such as\n *   `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc.\n * - and you have an open redirect at `http://myapp.example.com/clickThru?...`.\n *\n * Here is what a secure configuration for this scenario might look like:\n *\n * ```\n *  angular.module('myApp', []).config(function($sceDelegateProvider) {\n *    $sceDelegateProvider.resourceUrlWhitelist([\n *      // Allow same origin resource loads.\n *      'self',\n *      // Allow loading from our assets domain.  Notice the difference between * and **.\n *      'http://srv*.assets.example.com/**'\n *    ]);\n *\n *    // The blacklist overrides the whitelist so the open redirect here is blocked.\n *    $sceDelegateProvider.resourceUrlBlacklist([\n *      'http://myapp.example.com/clickThru**'\n *    ]);\n *  });\n * ```\n */\n\nfunction $SceDelegateProvider() {\n  this.SCE_CONTEXTS = SCE_CONTEXTS;\n\n  // Resource URLs can also be trusted by policy.\n  var resourceUrlWhitelist = ['self'],\n      resourceUrlBlacklist = [];\n\n  /**\n   * @ngdoc method\n   * @name $sceDelegateProvider#resourceUrlWhitelist\n   * @kind function\n   *\n   * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value\n   *    provided.  This must be an array or null.  A snapshot of this array is used so further\n   *    changes to the array are ignored.\n   *\n   *    Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items\n   *    allowed in this array.\n   *\n   *    <div class=\"alert alert-warning\">\n   *    **Note:** an empty whitelist array will block all URLs!\n   *    </div>\n   *\n   * @return {Array} the currently set whitelist array.\n   *\n   * The **default value** when no whitelist has been explicitly set is `['self']` allowing only\n   * same origin resource requests.\n   *\n   * @description\n   * Sets/Gets the whitelist of trusted resource URLs.\n   */\n  this.resourceUrlWhitelist = function(value) {\n    if (arguments.length) {\n      resourceUrlWhitelist = adjustMatchers(value);\n    }\n    return resourceUrlWhitelist;\n  };\n\n  /**\n   * @ngdoc method\n   * @name $sceDelegateProvider#resourceUrlBlacklist\n   * @kind function\n   *\n   * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value\n   *    provided.  This must be an array or null.  A snapshot of this array is used so further\n   *    changes to the array are ignored.\n   *\n   *    Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items\n   *    allowed in this array.\n   *\n   *    The typical usage for the blacklist is to **block\n   *    [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as\n   *    these would otherwise be trusted but actually return content from the redirected domain.\n   *\n   *    Finally, **the blacklist overrides the whitelist** and has the final say.\n   *\n   * @return {Array} the currently set blacklist array.\n   *\n   * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there\n   * is no blacklist.)\n   *\n   * @description\n   * Sets/Gets the blacklist of trusted resource URLs.\n   */\n\n  this.resourceUrlBlacklist = function(value) {\n    if (arguments.length) {\n      resourceUrlBlacklist = adjustMatchers(value);\n    }\n    return resourceUrlBlacklist;\n  };\n\n  this.$get = ['$injector', function($injector) {\n\n    var htmlSanitizer = function htmlSanitizer(html) {\n      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');\n    };\n\n    if ($injector.has('$sanitize')) {\n      htmlSanitizer = $injector.get('$sanitize');\n    }\n\n\n    function matchUrl(matcher, parsedUrl) {\n      if (matcher === 'self') {\n        return urlIsSameOrigin(parsedUrl);\n      } else {\n        // definitely a regex.  See adjustMatchers()\n        return !!matcher.exec(parsedUrl.href);\n      }\n    }\n\n    function isResourceUrlAllowedByPolicy(url) {\n      var parsedUrl = urlResolve(url.toString());\n      var i, n, allowed = false;\n      // Ensure that at least one item from the whitelist allows this url.\n      for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {\n        if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {\n          allowed = true;\n          break;\n        }\n      }\n      if (allowed) {\n        // Ensure that no item from the blacklist blocked this url.\n        for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {\n          if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {\n            allowed = false;\n            break;\n          }\n        }\n      }\n      return allowed;\n    }\n\n    function generateHolderType(Base) {\n      var holderType = function TrustedValueHolderType(trustedValue) {\n        this.$$unwrapTrustedValue = function() {\n          return trustedValue;\n        };\n      };\n      if (Base) {\n        holderType.prototype = new Base();\n      }\n      holderType.prototype.valueOf = function sceValueOf() {\n        return this.$$unwrapTrustedValue();\n      };\n      holderType.prototype.toString = function sceToString() {\n        return this.$$unwrapTrustedValue().toString();\n      };\n      return holderType;\n    }\n\n    var trustedValueHolderBase = generateHolderType(),\n        byType = {};\n\n    byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);\n    byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);\n    byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase);\n    byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);\n    byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]);\n\n    /**\n     * @ngdoc method\n     * @name $sceDelegate#trustAs\n     *\n     * @description\n     * Returns an object that is trusted by angular for use in specified strict\n     * contextual escaping contexts (such as ng-bind-html, ng-include, any src\n     * attribute interpolation, any dom event binding attribute interpolation\n     * such as for onclick,  etc.) that uses the provided value.\n     * See {@link ng.$sce $sce} for enabling strict contextual escaping.\n     *\n     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,\n     *   resourceUrl, html, js and css.\n     * @param {*} value The value that that should be considered trusted/safe.\n     * @returns {*} A value that can be used to stand in for the provided `value` in places\n     * where Angular expects a $sce.trustAs() return value.\n     */\n    function trustAs(type, trustedValue) {\n      var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null);\n      if (!Constructor) {\n        throw $sceMinErr('icontext',\n            'Attempted to trust a value in invalid context. Context: {0}; Value: {1}',\n            type, trustedValue);\n      }\n      if (trustedValue === null || isUndefined(trustedValue) || trustedValue === '') {\n        return trustedValue;\n      }\n      // All the current contexts in SCE_CONTEXTS happen to be strings.  In order to avoid trusting\n      // mutable objects, we ensure here that the value passed in is actually a string.\n      if (typeof trustedValue !== 'string') {\n        throw $sceMinErr('itype',\n            'Attempted to trust a non-string value in a content requiring a string: Context: {0}',\n            type);\n      }\n      return new Constructor(trustedValue);\n    }\n\n    /**\n     * @ngdoc method\n     * @name $sceDelegate#valueOf\n     *\n     * @description\n     * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs\n     * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link\n     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.\n     *\n     * If the passed parameter is not a value that had been returned by {@link\n     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, returns it as-is.\n     *\n     * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}\n     *      call or anything else.\n     * @returns {*} The `value` that was originally provided to {@link ng.$sceDelegate#trustAs\n     *     `$sceDelegate.trustAs`} if `value` is the result of such a call.  Otherwise, returns\n     *     `value` unchanged.\n     */\n    function valueOf(maybeTrusted) {\n      if (maybeTrusted instanceof trustedValueHolderBase) {\n        return maybeTrusted.$$unwrapTrustedValue();\n      } else {\n        return maybeTrusted;\n      }\n    }\n\n    /**\n     * @ngdoc method\n     * @name $sceDelegate#getTrusted\n     *\n     * @description\n     * Takes the result of a {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call and\n     * returns the originally supplied value if the queried context type is a supertype of the\n     * created type.  If this condition isn't satisfied, throws an exception.\n     *\n     * <div class=\"alert alert-danger\">\n     * Disabling auto-escaping is extremely dangerous, it usually creates a Cross Site Scripting\n     * (XSS) vulnerability in your application.\n     * </div>\n     *\n     * @param {string} type The kind of context in which this value is to be used.\n     * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs\n     *     `$sceDelegate.trustAs`} call.\n     * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs\n     *     `$sceDelegate.trustAs`} if valid in this context.  Otherwise, throws an exception.\n     */\n    function getTrusted(type, maybeTrusted) {\n      if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') {\n        return maybeTrusted;\n      }\n      var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);\n      if (constructor && maybeTrusted instanceof constructor) {\n        return maybeTrusted.$$unwrapTrustedValue();\n      }\n      // If we get here, then we may only take one of two actions.\n      // 1. sanitize the value for the requested type, or\n      // 2. throw an exception.\n      if (type === SCE_CONTEXTS.RESOURCE_URL) {\n        if (isResourceUrlAllowedByPolicy(maybeTrusted)) {\n          return maybeTrusted;\n        } else {\n          throw $sceMinErr('insecurl',\n              'Blocked loading resource from url not allowed by $sceDelegate policy.  URL: {0}',\n              maybeTrusted.toString());\n        }\n      } else if (type === SCE_CONTEXTS.HTML) {\n        return htmlSanitizer(maybeTrusted);\n      }\n      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');\n    }\n\n    return { trustAs: trustAs,\n             getTrusted: getTrusted,\n             valueOf: valueOf };\n  }];\n}\n\n\n/**\n * @ngdoc provider\n * @name $sceProvider\n * @this\n *\n * @description\n *\n * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service.\n * -   enable/disable Strict Contextual Escaping (SCE) in a module\n * -   override the default implementation with a custom delegate\n *\n * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}.\n */\n\n/**\n * @ngdoc service\n * @name $sce\n * @kind function\n *\n * @description\n *\n * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS.\n *\n * # Strict Contextual Escaping\n *\n * Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain\n * contexts to result in a value that is marked as safe to use for that context.  One example of\n * such a context is binding arbitrary html controlled by the user via `ng-bind-html`.  We refer\n * to these contexts as privileged or SCE contexts.\n *\n * As of version 1.2, Angular ships with SCE enabled by default.\n *\n * Note:  When enabled (the default), IE<11 in quirks mode is not supported.  In this mode, IE<11 allow\n * one to execute arbitrary javascript by the use of the expression() syntax.  Refer\n * <http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx> to learn more about them.\n * You can ensure your document is in standards mode and not quirks mode by adding `<!doctype html>`\n * to the top of your HTML document.\n *\n * SCE assists in writing code in a way that (a) is secure by default and (b) makes auditing for\n * security vulnerabilities such as XSS, clickjacking, etc. a lot easier.\n *\n * Here's an example of a binding in a privileged context:\n *\n * ```\n * <input ng-model=\"userHtml\" aria-label=\"User input\">\n * <div ng-bind-html=\"userHtml\"></div>\n * ```\n *\n * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user.  With SCE\n * disabled, this application allows the user to render arbitrary HTML into the DIV.\n * In a more realistic example, one may be rendering user comments, blog articles, etc. via\n * bindings.  (HTML is just one example of a context where rendering user controlled input creates\n * security vulnerabilities.)\n *\n * For the case of HTML, you might use a library, either on the client side, or on the server side,\n * to sanitize unsafe HTML before binding to the value and rendering it in the document.\n *\n * How would you ensure that every place that used these types of bindings was bound to a value that\n * was sanitized by your library (or returned as safe for rendering by your server?)  How can you\n * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some\n * properties/fields and forgot to update the binding to the sanitized value?\n *\n * To be secure by default, you want to ensure that any such bindings are disallowed unless you can\n * determine that something explicitly says it's safe to use a value for binding in that\n * context.  You can then audit your code (a simple grep would do) to ensure that this is only done\n * for those values that you can easily tell are safe - because they were received from your server,\n * sanitized by your library, etc.  You can organize your codebase to help with this - perhaps\n * allowing only the files in a specific directory to do this.  Ensuring that the internal API\n * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task.\n *\n * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs}\n * (and shorthand methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to\n * obtain values that will be accepted by SCE / privileged contexts.\n *\n *\n * ## How does it work?\n *\n * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted\n * $sce.getTrusted(context, value)} rather than to the value directly.  Directives use {@link\n * ng.$sce#parseAs $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the\n * {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals.\n *\n * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link\n * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}.  Here's the actual code (slightly\n * simplified):\n *\n * ```\n * var ngBindHtmlDirective = ['$sce', function($sce) {\n *   return function(scope, element, attr) {\n *     scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {\n *       element.html(value || '');\n *     });\n *   };\n * }];\n * ```\n *\n * ## Impact on loading templates\n *\n * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as\n * `templateUrl`'s specified by {@link guide/directive directives}.\n *\n * By default, Angular only loads templates from the same domain and protocol as the application\n * document.  This is done by calling {@link ng.$sce#getTrustedResourceUrl\n * $sce.getTrustedResourceUrl} on the template URL.  To load templates from other domains and/or\n * protocols, you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist\n * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value.\n *\n * *Please note*:\n * The browser's\n * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)\n * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)\n * policy apply in addition to this and may further restrict whether the template is successfully\n * loaded.  This means that without the right CORS policy, loading templates from a different domain\n * won't work on all browsers.  Also, loading templates from `file://` URL does not work on some\n * browsers.\n *\n * ## This feels like too much overhead\n *\n * It's important to remember that SCE only applies to interpolation expressions.\n *\n * If your expressions are constant literals, they're automatically trusted and you don't need to\n * call `$sce.trustAs` on them (remember to include the `ngSanitize` module) (e.g.\n * `<div ng-bind-html=\"'<b>implicitly trusted</b>'\"></div>`) just works.\n *\n * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them\n * through {@link ng.$sce#getTrusted $sce.getTrusted}.  SCE doesn't play a role here.\n *\n * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load\n * templates in `ng-include` from your application's domain without having to even know about SCE.\n * It blocks loading templates from other domains or loading templates over http from an https\n * served document.  You can change these by setting your own custom {@link\n * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link\n * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs.\n *\n * This significantly reduces the overhead.  It is far easier to pay the small overhead and have an\n * application that's secure and can be audited to verify that with much more ease than bolting\n * security onto an application later.\n *\n * <a name=\"contexts\"></a>\n * ## What trusted context types are supported?\n *\n * | Context             | Notes          |\n * |---------------------|----------------|\n * | `$sce.HTML`         | For HTML that's safe to source into the application.  The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. |\n * | `$sce.CSS`          | For CSS that's safe to source into the application.  Currently unused.  Feel free to use it in your own directives. |\n * | `$sce.URL`          | For URLs that are safe to follow as links.  Currently unused (`<a href=` and `<img src=` sanitize their urls and don't constitute an SCE context. |\n * | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application.  Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG`, `VIDEO`, `AUDIO`, `SOURCE`, and `TRACK` (e.g. `IFRAME`, `OBJECT`, etc.)  <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |\n * | `$sce.JS`           | For JavaScript that is safe to execute in your application's context.  Currently unused.  Feel free to use it in your own directives. |\n *\n * ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist} <a name=\"resourceUrlPatternItem\"></a>\n *\n *  Each element in these arrays must be one of the following:\n *\n *  - **'self'**\n *    - The special **string**, `'self'`, can be used to match against all URLs of the **same\n *      domain** as the application document using the **same protocol**.\n *  - **String** (except the special value `'self'`)\n *    - The string is matched against the full *normalized / absolute URL* of the resource\n *      being tested (substring matches are not good enough.)\n *    - There are exactly **two wildcard sequences** - `*` and `**`.  All other characters\n *      match themselves.\n *    - `*`: matches zero or more occurrences of any character other than one of the following 6\n *      characters: '`:`', '`/`', '`.`', '`?`', '`&`' and '`;`'.  It's a useful wildcard for use\n *      in a whitelist.\n *    - `**`: matches zero or more occurrences of *any* character.  As such, it's not\n *      appropriate for use in a scheme, domain, etc. as it would match too much.  (e.g.\n *      http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might\n *      not have been the intention.)  Its usage at the very end of the path is ok.  (e.g.\n *      http://foo.example.com/templates/**).\n *  - **RegExp** (*see caveat below*)\n *    - *Caveat*:  While regular expressions are powerful and offer great flexibility,  their syntax\n *      (and all the inevitable escaping) makes them *harder to maintain*.  It's easy to\n *      accidentally introduce a bug when one updates a complex expression (imho, all regexes should\n *      have good test coverage).  For instance, the use of `.` in the regex is correct only in a\n *      small number of cases.  A `.` character in the regex used when matching the scheme or a\n *      subdomain could be matched against a `:` or literal `.` that was likely not intended.   It\n *      is highly recommended to use the string patterns and only fall back to regular expressions\n *      as a last resort.\n *    - The regular expression must be an instance of RegExp (i.e. not a string.)  It is\n *      matched against the **entire** *normalized / absolute URL* of the resource being tested\n *      (even when the RegExp did not have the `^` and `$` codes.)  In addition, any flags\n *      present on the RegExp (such as multiline, global, ignoreCase) are ignored.\n *    - If you are generating your JavaScript from some other templating engine (not\n *      recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)),\n *      remember to escape your regular expression (and be aware that you might need more than\n *      one level of escaping depending on your templating engine and the way you interpolated\n *      the value.)  Do make use of your platform's escaping mechanism as it might be good\n *      enough before coding your own.  E.g. Ruby has\n *      [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape)\n *      and Python has [re.escape](http://docs.python.org/library/re.html#re.escape).\n *      Javascript lacks a similar built in function for escaping.  Take a look at Google\n *      Closure library's [goog.string.regExpEscape(s)](\n *      http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962).\n *\n * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example.\n *\n * ## Show me an example using SCE.\n *\n * <example module=\"mySceApp\" deps=\"angular-sanitize.js\" name=\"sce-service\">\n * <file name=\"index.html\">\n *   <div ng-controller=\"AppController as myCtrl\">\n *     <i ng-bind-html=\"myCtrl.explicitlyTrustedHtml\" id=\"explicitlyTrustedHtml\"></i><br><br>\n *     <b>User comments</b><br>\n *     By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when\n *     $sanitize is available.  If $sanitize isn't available, this results in an error instead of an\n *     exploit.\n *     <div class=\"well\">\n *       <div ng-repeat=\"userComment in myCtrl.userComments\">\n *         <b>{{userComment.name}}</b>:\n *         <span ng-bind-html=\"userComment.htmlComment\" class=\"htmlComment\"></span>\n *         <br>\n *       </div>\n *     </div>\n *   </div>\n * </file>\n *\n * <file name=\"script.js\">\n *   angular.module('mySceApp', ['ngSanitize'])\n *     .controller('AppController', ['$http', '$templateCache', '$sce',\n *       function AppController($http, $templateCache, $sce) {\n *         var self = this;\n *         $http.get('test_data.json', {cache: $templateCache}).then(function(response) {\n *           self.userComments = response.data;\n *         });\n *         self.explicitlyTrustedHtml = $sce.trustAsHtml(\n *             '<span onmouseover=\"this.textContent=&quot;Explicitly trusted HTML bypasses ' +\n *             'sanitization.&quot;\">Hover over this text.</span>');\n *       }]);\n * </file>\n *\n * <file name=\"test_data.json\">\n * [\n *   { \"name\": \"Alice\",\n *     \"htmlComment\":\n *         \"<span onmouseover='this.textContent=\\\"PWN3D!\\\"'>Is <i>anyone</i> reading this?</span>\"\n *   },\n *   { \"name\": \"Bob\",\n *     \"htmlComment\": \"<i>Yes!</i>  Am I the only other one?\"\n *   }\n * ]\n * </file>\n *\n * <file name=\"protractor.js\" type=\"protractor\">\n *   describe('SCE doc demo', function() {\n *     it('should sanitize untrusted values', function() {\n *       expect(element.all(by.css('.htmlComment')).first().getAttribute('innerHTML'))\n *           .toBe('<span>Is <i>anyone</i> reading this?</span>');\n *     });\n *\n *     it('should NOT sanitize explicitly trusted values', function() {\n *       expect(element(by.id('explicitlyTrustedHtml')).getAttribute('innerHTML')).toBe(\n *           '<span onmouseover=\"this.textContent=&quot;Explicitly trusted HTML bypasses ' +\n *           'sanitization.&quot;\">Hover over this text.</span>');\n *     });\n *   });\n * </file>\n * </example>\n *\n *\n *\n * ## Can I disable SCE completely?\n *\n * Yes, you can.  However, this is strongly discouraged.  SCE gives you a lot of security benefits\n * for little coding overhead.  It will be much harder to take an SCE disabled application and\n * either secure it on your own or enable SCE at a later stage.  It might make sense to disable SCE\n * for cases where you have a lot of existing code that was written before SCE was introduced and\n * you're migrating them a module at a time.\n *\n * That said, here's how you can completely disable SCE:\n *\n * ```\n * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {\n *   // Completely disable SCE.  For demonstration purposes only!\n *   // Do not use in new projects.\n *   $sceProvider.enabled(false);\n * });\n * ```\n *\n */\n\nfunction $SceProvider() {\n  var enabled = true;\n\n  /**\n   * @ngdoc method\n   * @name $sceProvider#enabled\n   * @kind function\n   *\n   * @param {boolean=} value If provided, then enables/disables SCE.\n   * @return {boolean} true if SCE is enabled, false otherwise.\n   *\n   * @description\n   * Enables/disables SCE and returns the current value.\n   */\n  this.enabled = function(value) {\n    if (arguments.length) {\n      enabled = !!value;\n    }\n    return enabled;\n  };\n\n\n  /* Design notes on the default implementation for SCE.\n   *\n   * The API contract for the SCE delegate\n   * -------------------------------------\n   * The SCE delegate object must provide the following 3 methods:\n   *\n   * - trustAs(contextEnum, value)\n   *     This method is used to tell the SCE service that the provided value is OK to use in the\n   *     contexts specified by contextEnum.  It must return an object that will be accepted by\n   *     getTrusted() for a compatible contextEnum and return this value.\n   *\n   * - valueOf(value)\n   *     For values that were not produced by trustAs(), return them as is.  For values that were\n   *     produced by trustAs(), return the corresponding input value to trustAs.  Basically, if\n   *     trustAs is wrapping the given values into some type, this operation unwraps it when given\n   *     such a value.\n   *\n   * - getTrusted(contextEnum, value)\n   *     This function should return the a value that is safe to use in the context specified by\n   *     contextEnum or throw and exception otherwise.\n   *\n   * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be\n   * opaque or wrapped in some holder object.  That happens to be an implementation detail.  For\n   * instance, an implementation could maintain a registry of all trusted objects by context.  In\n   * such a case, trustAs() would return the same object that was passed in.  getTrusted() would\n   * return the same object passed in if it was found in the registry under a compatible context or\n   * throw an exception otherwise.  An implementation might only wrap values some of the time based\n   * on some criteria.  getTrusted() might return a value and not throw an exception for special\n   * constants or objects even if not wrapped.  All such implementations fulfill this contract.\n   *\n   *\n   * A note on the inheritance model for SCE contexts\n   * ------------------------------------------------\n   * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types.  This\n   * is purely an implementation details.\n   *\n   * The contract is simply this:\n   *\n   *     getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value)\n   *     will also succeed.\n   *\n   * Inheritance happens to capture this in a natural way.  In some future, we\n   * may not use inheritance anymore.  That is OK because no code outside of\n   * sce.js and sceSpecs.js would need to be aware of this detail.\n   */\n\n  this.$get = ['$parse', '$sceDelegate', function(\n                $parse,   $sceDelegate) {\n    // Support: IE 9-11 only\n    // Prereq: Ensure that we're not running in IE<11 quirks mode.  In that mode, IE < 11 allow\n    // the \"expression(javascript expression)\" syntax which is insecure.\n    if (enabled && msie < 8) {\n      throw $sceMinErr('iequirks',\n        'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +\n        'mode.  You can fix this by adding the text <!doctype html> to the top of your HTML ' +\n        'document.  See http://docs.angularjs.org/api/ng.$sce for more information.');\n    }\n\n    var sce = shallowCopy(SCE_CONTEXTS);\n\n    /**\n     * @ngdoc method\n     * @name $sce#isEnabled\n     * @kind function\n     *\n     * @return {Boolean} true if SCE is enabled, false otherwise.  If you want to set the value, you\n     * have to do it at module config time on {@link ng.$sceProvider $sceProvider}.\n     *\n     * @description\n     * Returns a boolean indicating if SCE is enabled.\n     */\n    sce.isEnabled = function() {\n      return enabled;\n    };\n    sce.trustAs = $sceDelegate.trustAs;\n    sce.getTrusted = $sceDelegate.getTrusted;\n    sce.valueOf = $sceDelegate.valueOf;\n\n    if (!enabled) {\n      sce.trustAs = sce.getTrusted = function(type, value) { return value; };\n      sce.valueOf = identity;\n    }\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAs\n     *\n     * @description\n     * Converts Angular {@link guide/expression expression} into a function.  This is like {@link\n     * ng.$parse $parse} and is identical when the expression is a literal constant.  Otherwise, it\n     * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*,\n     * *result*)}\n     *\n     * @param {string} type The kind of SCE context in which this result will be used.\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n    sce.parseAs = function sceParseAs(type, expr) {\n      var parsed = $parse(expr);\n      if (parsed.literal && parsed.constant) {\n        return parsed;\n      } else {\n        return $parse(expr, function(value) {\n          return sce.getTrusted(type, value);\n        });\n      }\n    };\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAs\n     *\n     * @description\n     * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.  As such,\n     * returns an object that is trusted by angular for use in specified strict contextual\n     * escaping contexts (such as ng-bind-html, ng-include, any src attribute\n     * interpolation, any dom event binding attribute interpolation such as for onclick,  etc.)\n     * that uses the provided value.  See * {@link ng.$sce $sce} for enabling strict contextual\n     * escaping.\n     *\n     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,\n     *   resourceUrl, html, js and css.\n     * @param {*} value The value that that should be considered trusted/safe.\n     * @returns {*} A value that can be used to stand in for the provided `value` in places\n     * where Angular expects a $sce.trustAs() return value.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAsHtml\n     *\n     * @description\n     * Shorthand method.  `$sce.trustAsHtml(value)` →\n     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`}\n     *\n     * @param {*} value The value to trustAs.\n     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedHtml\n     *     $sce.getTrustedHtml(value)} to obtain the original value.  (privileged directives\n     *     only accept expressions that are either literal constants or are the\n     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAsUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.trustAsUrl(value)` →\n     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`}\n     *\n     * @param {*} value The value to trustAs.\n     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedUrl\n     *     $sce.getTrustedUrl(value)} to obtain the original value.  (privileged directives\n     *     only accept expressions that are either literal constants or are the\n     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAsResourceUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.trustAsResourceUrl(value)` →\n     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`}\n     *\n     * @param {*} value The value to trustAs.\n     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedResourceUrl\n     *     $sce.getTrustedResourceUrl(value)} to obtain the original value.  (privileged directives\n     *     only accept expressions that are either literal constants or are the return\n     *     value of {@link ng.$sce#trustAs $sce.trustAs}.)\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAsJs\n     *\n     * @description\n     * Shorthand method.  `$sce.trustAsJs(value)` →\n     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`}\n     *\n     * @param {*} value The value to trustAs.\n     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedJs\n     *     $sce.getTrustedJs(value)} to obtain the original value.  (privileged directives\n     *     only accept expressions that are either literal constants or are the\n     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrusted\n     *\n     * @description\n     * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}.  As such,\n     * takes the result of a {@link ng.$sce#trustAs `$sce.trustAs`}() call and returns the\n     * originally supplied value if the queried context type is a supertype of the created type.\n     * If this condition isn't satisfied, throws an exception.\n     *\n     * @param {string} type The kind of context in which this value is to be used.\n     * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs `$sce.trustAs`}\n     *                         call.\n     * @returns {*} The value the was originally provided to\n     *              {@link ng.$sce#trustAs `$sce.trustAs`} if valid in this context.\n     *              Otherwise, throws an exception.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedHtml\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedHtml(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`}\n     *\n     * @param {*} value The value to pass to `$sce.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedCss\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedCss(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`}\n     *\n     * @param {*} value The value to pass to `$sce.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedUrl(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`}\n     *\n     * @param {*} value The value to pass to `$sce.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedResourceUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedResourceUrl(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`}\n     *\n     * @param {*} value The value to pass to `$sceDelegate.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedJs\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedJs(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`}\n     *\n     * @param {*} value The value to pass to `$sce.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsHtml\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsHtml(expression string)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsCss\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsCss(value)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsUrl(value)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsResourceUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsResourceUrl(value)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsJs\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsJs(value)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    // Shorthand delegations.\n    var parse = sce.parseAs,\n        getTrusted = sce.getTrusted,\n        trustAs = sce.trustAs;\n\n    forEach(SCE_CONTEXTS, function(enumValue, name) {\n      var lName = lowercase(name);\n      sce[snakeToCamel('parse_as_' + lName)] = function(expr) {\n        return parse(enumValue, expr);\n      };\n      sce[snakeToCamel('get_trusted_' + lName)] = function(value) {\n        return getTrusted(enumValue, value);\n      };\n      sce[snakeToCamel('trust_as_' + lName)] = function(value) {\n        return trustAs(enumValue, value);\n      };\n    });\n\n    return sce;\n  }];\n}\n\n/* exported $SnifferProvider */\n\n/**\n * !!! This is an undocumented \"private\" service !!!\n *\n * @name $sniffer\n * @requires $window\n * @requires $document\n * @this\n *\n * @property {boolean} history Does the browser support html5 history api ?\n * @property {boolean} transitions Does the browser support CSS transition events ?\n * @property {boolean} animations Does the browser support CSS animation events ?\n *\n * @description\n * This is very simple implementation of testing browser's features.\n */\nfunction $SnifferProvider() {\n  this.$get = ['$window', '$document', function($window, $document) {\n    var eventSupport = {},\n        // Chrome Packaged Apps are not allowed to access `history.pushState`.\n        // If not sandboxed, they can be detected by the presence of `chrome.app.runtime`\n        // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by\n        // the presence of an extension runtime ID and the absence of other Chrome runtime APIs\n        // (see https://developer.chrome.com/apps/manifest/sandbox).\n        // (NW.js apps have access to Chrome APIs, but do support `history`.)\n        isNw = $window.nw && $window.nw.process,\n        isChromePackagedApp =\n            !isNw &&\n            $window.chrome &&\n            ($window.chrome.app && $window.chrome.app.runtime ||\n                !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id),\n        hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,\n        android =\n          toInt((/android (\\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),\n        boxee = /Boxee/i.test(($window.navigator || {}).userAgent),\n        document = $document[0] || {},\n        bodyStyle = document.body && document.body.style,\n        transitions = false,\n        animations = false;\n\n    if (bodyStyle) {\n      // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x\n      // Mentioned browsers need a -webkit- prefix for transitions & animations.\n      transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle);\n      animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle);\n    }\n\n\n    return {\n      // Android has history.pushState, but it does not update location correctly\n      // so let's not use the history API at all.\n      // http://code.google.com/p/android/issues/detail?id=17471\n      // https://github.com/angular/angular.js/issues/904\n\n      // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has\n      // so let's not use the history API also\n      // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined\n      history: !!(hasHistoryPushState && !(android < 4) && !boxee),\n      hasEvent: function(event) {\n        // Support: IE 9-11 only\n        // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have\n        // it. In particular the event is not fired when backspace or delete key are pressed or\n        // when cut operation is performed.\n        // IE10+ implements 'input' event but it erroneously fires under various situations,\n        // e.g. when placeholder changes, or a form is focused.\n        if (event === 'input' && msie) return false;\n\n        if (isUndefined(eventSupport[event])) {\n          var divElm = document.createElement('div');\n          eventSupport[event] = 'on' + event in divElm;\n        }\n\n        return eventSupport[event];\n      },\n      csp: csp(),\n      transitions: transitions,\n      animations: animations,\n      android: android\n    };\n  }];\n}\n\nvar $templateRequestMinErr = minErr('$compile');\n\n/**\n * @ngdoc provider\n * @name $templateRequestProvider\n * @this\n *\n * @description\n * Used to configure the options passed to the {@link $http} service when making a template request.\n *\n * For example, it can be used for specifying the \"Accept\" header that is sent to the server, when\n * requesting a template.\n */\nfunction $TemplateRequestProvider() {\n\n  var httpOptions;\n\n  /**\n   * @ngdoc method\n   * @name $templateRequestProvider#httpOptions\n   * @description\n   * The options to be passed to the {@link $http} service when making the request.\n   * You can use this to override options such as the \"Accept\" header for template requests.\n   *\n   * The {@link $templateRequest} will set the `cache` and the `transformResponse` properties of the\n   * options if not overridden here.\n   *\n   * @param {string=} value new value for the {@link $http} options.\n   * @returns {string|self} Returns the {@link $http} options when used as getter and self if used as setter.\n   */\n  this.httpOptions = function(val) {\n    if (val) {\n      httpOptions = val;\n      return this;\n    }\n    return httpOptions;\n  };\n\n  /**\n   * @ngdoc service\n   * @name $templateRequest\n   *\n   * @description\n   * The `$templateRequest` service runs security checks then downloads the provided template using\n   * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request\n   * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the\n   * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the\n   * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted\n   * when `tpl` is of type string and `$templateCache` has the matching entry.\n   *\n   * If you want to pass custom options to the `$http` service, such as setting the Accept header you\n   * can configure this via {@link $templateRequestProvider#httpOptions}.\n   *\n   * @param {string|TrustedResourceUrl} tpl The HTTP request template URL\n   * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty\n   *\n   * @return {Promise} a promise for the HTTP response data of the given URL.\n   *\n   * @property {number} totalPendingRequests total amount of pending template requests being downloaded.\n   */\n  this.$get = ['$exceptionHandler', '$templateCache', '$http', '$q', '$sce',\n    function($exceptionHandler, $templateCache, $http, $q, $sce) {\n\n      function handleRequestFn(tpl, ignoreRequestError) {\n        handleRequestFn.totalPendingRequests++;\n\n        // We consider the template cache holds only trusted templates, so\n        // there's no need to go through whitelisting again for keys that already\n        // are included in there. This also makes Angular accept any script\n        // directive, no matter its name. However, we still need to unwrap trusted\n        // types.\n        if (!isString(tpl) || isUndefined($templateCache.get(tpl))) {\n          tpl = $sce.getTrustedResourceUrl(tpl);\n        }\n\n        var transformResponse = $http.defaults && $http.defaults.transformResponse;\n\n        if (isArray(transformResponse)) {\n          transformResponse = transformResponse.filter(function(transformer) {\n            return transformer !== defaultHttpResponseTransform;\n          });\n        } else if (transformResponse === defaultHttpResponseTransform) {\n          transformResponse = null;\n        }\n\n        return $http.get(tpl, extend({\n            cache: $templateCache,\n            transformResponse: transformResponse\n          }, httpOptions))\n          .finally(function() {\n            handleRequestFn.totalPendingRequests--;\n          })\n          .then(function(response) {\n            $templateCache.put(tpl, response.data);\n            return response.data;\n          }, handleError);\n\n        function handleError(resp) {\n          if (!ignoreRequestError) {\n            resp = $templateRequestMinErr('tpload',\n                'Failed to load template: {0} (HTTP status: {1} {2})',\n                tpl, resp.status, resp.statusText);\n\n            $exceptionHandler(resp);\n          }\n\n          return $q.reject(resp);\n        }\n      }\n\n      handleRequestFn.totalPendingRequests = 0;\n\n      return handleRequestFn;\n    }\n  ];\n}\n\n/** @this */\nfunction $$TestabilityProvider() {\n  this.$get = ['$rootScope', '$browser', '$location',\n       function($rootScope,   $browser,   $location) {\n\n    /**\n     * @name $testability\n     *\n     * @description\n     * The private $$testability service provides a collection of methods for use when debugging\n     * or by automated test and debugging tools.\n     */\n    var testability = {};\n\n    /**\n     * @name $$testability#findBindings\n     *\n     * @description\n     * Returns an array of elements that are bound (via ng-bind or {{}})\n     * to expressions matching the input.\n     *\n     * @param {Element} element The element root to search from.\n     * @param {string} expression The binding expression to match.\n     * @param {boolean} opt_exactMatch If true, only returns exact matches\n     *     for the expression. Filters and whitespace are ignored.\n     */\n    testability.findBindings = function(element, expression, opt_exactMatch) {\n      var bindings = element.getElementsByClassName('ng-binding');\n      var matches = [];\n      forEach(bindings, function(binding) {\n        var dataBinding = angular.element(binding).data('$binding');\n        if (dataBinding) {\n          forEach(dataBinding, function(bindingName) {\n            if (opt_exactMatch) {\n              var matcher = new RegExp('(^|\\\\s)' + escapeForRegexp(expression) + '(\\\\s|\\\\||$)');\n              if (matcher.test(bindingName)) {\n                matches.push(binding);\n              }\n            } else {\n              if (bindingName.indexOf(expression) !== -1) {\n                matches.push(binding);\n              }\n            }\n          });\n        }\n      });\n      return matches;\n    };\n\n    /**\n     * @name $$testability#findModels\n     *\n     * @description\n     * Returns an array of elements that are two-way found via ng-model to\n     * expressions matching the input.\n     *\n     * @param {Element} element The element root to search from.\n     * @param {string} expression The model expression to match.\n     * @param {boolean} opt_exactMatch If true, only returns exact matches\n     *     for the expression.\n     */\n    testability.findModels = function(element, expression, opt_exactMatch) {\n      var prefixes = ['ng-', 'data-ng-', 'ng\\\\:'];\n      for (var p = 0; p < prefixes.length; ++p) {\n        var attributeEquals = opt_exactMatch ? '=' : '*=';\n        var selector = '[' + prefixes[p] + 'model' + attributeEquals + '\"' + expression + '\"]';\n        var elements = element.querySelectorAll(selector);\n        if (elements.length) {\n          return elements;\n        }\n      }\n    };\n\n    /**\n     * @name $$testability#getLocation\n     *\n     * @description\n     * Shortcut for getting the location in a browser agnostic way. Returns\n     *     the path, search, and hash. (e.g. /path?a=b#hash)\n     */\n    testability.getLocation = function() {\n      return $location.url();\n    };\n\n    /**\n     * @name $$testability#setLocation\n     *\n     * @description\n     * Shortcut for navigating to a location without doing a full page reload.\n     *\n     * @param {string} url The location url (path, search and hash,\n     *     e.g. /path?a=b#hash) to go to.\n     */\n    testability.setLocation = function(url) {\n      if (url !== $location.url()) {\n        $location.url(url);\n        $rootScope.$digest();\n      }\n    };\n\n    /**\n     * @name $$testability#whenStable\n     *\n     * @description\n     * Calls the callback when $timeout and $http requests are completed.\n     *\n     * @param {function} callback\n     */\n    testability.whenStable = function(callback) {\n      $browser.notifyWhenNoOutstandingRequests(callback);\n    };\n\n    return testability;\n  }];\n}\n\n/** @this */\nfunction $TimeoutProvider() {\n  this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',\n       function($rootScope,   $browser,   $q,   $$q,   $exceptionHandler) {\n\n    var deferreds = {};\n\n\n     /**\n      * @ngdoc service\n      * @name $timeout\n      *\n      * @description\n      * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch\n      * block and delegates any exceptions to\n      * {@link ng.$exceptionHandler $exceptionHandler} service.\n      *\n      * The return value of calling `$timeout` is a promise, which will be resolved when\n      * the delay has passed and the timeout function, if provided, is executed.\n      *\n      * To cancel a timeout request, call `$timeout.cancel(promise)`.\n      *\n      * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to\n      * synchronously flush the queue of deferred functions.\n      *\n      * If you only want a promise that will be resolved after some specified delay\n      * then you can call `$timeout` without the `fn` function.\n      *\n      * @param {function()=} fn A function, whose execution should be delayed.\n      * @param {number=} [delay=0] Delay in milliseconds.\n      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise\n      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.\n      * @param {...*=} Pass additional parameters to the executed function.\n      * @returns {Promise} Promise that will be resolved when the timeout is reached. The promise\n      *   will be resolved with the return value of the `fn` function.\n      *\n      */\n    function timeout(fn, delay, invokeApply) {\n      if (!isFunction(fn)) {\n        invokeApply = delay;\n        delay = fn;\n        fn = noop;\n      }\n\n      var args = sliceArgs(arguments, 3),\n          skipApply = (isDefined(invokeApply) && !invokeApply),\n          deferred = (skipApply ? $$q : $q).defer(),\n          promise = deferred.promise,\n          timeoutId;\n\n      timeoutId = $browser.defer(function() {\n        try {\n          deferred.resolve(fn.apply(null, args));\n        } catch (e) {\n          deferred.reject(e);\n          $exceptionHandler(e);\n        } finally {\n          delete deferreds[promise.$$timeoutId];\n        }\n\n        if (!skipApply) $rootScope.$apply();\n      }, delay);\n\n      promise.$$timeoutId = timeoutId;\n      deferreds[timeoutId] = deferred;\n\n      return promise;\n    }\n\n\n     /**\n      * @ngdoc method\n      * @name $timeout#cancel\n      *\n      * @description\n      * Cancels a task associated with the `promise`. As a result of this, the promise will be\n      * resolved with a rejection.\n      *\n      * @param {Promise=} promise Promise returned by the `$timeout` function.\n      * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully\n      *   canceled.\n      */\n    timeout.cancel = function(promise) {\n      if (promise && promise.$$timeoutId in deferreds) {\n        // Timeout cancels should not report an unhandled promise.\n        deferreds[promise.$$timeoutId].promise.catch(noop);\n        deferreds[promise.$$timeoutId].reject('canceled');\n        delete deferreds[promise.$$timeoutId];\n        return $browser.defer.cancel(promise.$$timeoutId);\n      }\n      return false;\n    };\n\n    return timeout;\n  }];\n}\n\n// NOTE:  The usage of window and document instead of $window and $document here is\n// deliberate.  This service depends on the specific behavior of anchor nodes created by the\n// browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and\n// cause us to break tests.  In addition, when the browser resolves a URL for XHR, it\n// doesn't know about mocked locations and resolves URLs to the real document - which is\n// exactly the behavior needed here.  There is little value is mocking these out for this\n// service.\nvar urlParsingNode = window.document.createElement('a');\nvar originUrl = urlResolve(window.location.href);\n\n\n/**\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL.  Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL.  This approach has wide\n * compatibility - Safari 1+, Mozilla 1+ etc.  See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers.  However, the parsed components will not be set if the URL assigned did not specify\n * them.  (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.)  We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again.  This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * References:\n *   http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n *   http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *   http://url.spec.whatwg.org/#urlutils\n *   https://github.com/angular/angular.js/pull/2902\n *   http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n *   | member name   | Description    |\n *   |---------------|----------------|\n *   | href          | A normalized version of the provided URL if it was not an absolute URL |\n *   | protocol      | The protocol including the trailing colon                              |\n *   | host          | The host and port (if the port is non-default) of the normalizedUrl    |\n *   | search        | The search params, minus the question mark                             |\n *   | hash          | The hash string, minus the hash symbol\n *   | hostname      | The hostname\n *   | port          | The port, without \":\"\n *   | pathname      | The pathname, beginning with \"/\"\n *\n */\nfunction urlResolve(url) {\n  var href = url;\n\n  // Support: IE 9-11 only\n  if (msie) {\n    // Normalize before parse.  Refer Implementation Notes on why this is\n    // done in two steps on IE.\n    urlParsingNode.setAttribute('href', href);\n    href = urlParsingNode.href;\n  }\n\n  urlParsingNode.setAttribute('href', href);\n\n  // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n  return {\n    href: urlParsingNode.href,\n    protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n    host: urlParsingNode.host,\n    search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n    hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n    hostname: urlParsingNode.hostname,\n    port: urlParsingNode.port,\n    pathname: (urlParsingNode.pathname.charAt(0) === '/')\n      ? urlParsingNode.pathname\n      : '/' + urlParsingNode.pathname\n  };\n}\n\n/**\n * Parse a request URL and determine whether this is a same-origin request as the application document.\n *\n * @param {string|object} requestUrl The url of the request as a string that will be resolved\n * or a parsed URL object.\n * @returns {boolean} Whether the request is for the same origin as the application document.\n */\nfunction urlIsSameOrigin(requestUrl) {\n  var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl;\n  return (parsed.protocol === originUrl.protocol &&\n          parsed.host === originUrl.host);\n}\n\n/**\n * @ngdoc service\n * @name $window\n * @this\n *\n * @description\n * A reference to the browser's `window` object. While `window`\n * is globally available in JavaScript, it causes testability problems, because\n * it is a global variable. In angular we always refer to it through the\n * `$window` service, so it may be overridden, removed or mocked for testing.\n *\n * Expressions, like the one defined for the `ngClick` directive in the example\n * below, are evaluated with respect to the current scope.  Therefore, there is\n * no risk of inadvertently coding in a dependency on a global value in such an\n * expression.\n *\n * @example\n   <example module=\"windowExample\" name=\"window-service\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('windowExample', [])\n           .controller('ExampleController', ['$scope', '$window', function($scope, $window) {\n             $scope.greeting = 'Hello, World!';\n             $scope.doGreeting = function(greeting) {\n               $window.alert(greeting);\n             };\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <input type=\"text\" ng-model=\"greeting\" aria-label=\"greeting\" />\n         <button ng-click=\"doGreeting(greeting)\">ALERT</button>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n      it('should display the greeting in the input box', function() {\n       element(by.model('greeting')).sendKeys('Hello, E2E Tests');\n       // If we click the button it will block the test runner\n       // element(':button').click();\n      });\n     </file>\n   </example>\n */\nfunction $WindowProvider() {\n  this.$get = valueFn(window);\n}\n\n/**\n * @name $$cookieReader\n * @requires $document\n *\n * @description\n * This is a private service for reading cookies used by $http and ngCookies\n *\n * @return {Object} a key/value map of the current cookies\n */\nfunction $$CookieReader($document) {\n  var rawDocument = $document[0] || {};\n  var lastCookies = {};\n  var lastCookieString = '';\n\n  function safeGetCookie(rawDocument) {\n    try {\n      return rawDocument.cookie || '';\n    } catch (e) {\n      return '';\n    }\n  }\n\n  function safeDecodeURIComponent(str) {\n    try {\n      return decodeURIComponent(str);\n    } catch (e) {\n      return str;\n    }\n  }\n\n  return function() {\n    var cookieArray, cookie, i, index, name;\n    var currentCookieString = safeGetCookie(rawDocument);\n\n    if (currentCookieString !== lastCookieString) {\n      lastCookieString = currentCookieString;\n      cookieArray = lastCookieString.split('; ');\n      lastCookies = {};\n\n      for (i = 0; i < cookieArray.length; i++) {\n        cookie = cookieArray[i];\n        index = cookie.indexOf('=');\n        if (index > 0) { //ignore nameless cookies\n          name = safeDecodeURIComponent(cookie.substring(0, index));\n          // the first value that is seen for a cookie is the most\n          // specific one.  values for the same cookie name that\n          // follow are for less specific paths.\n          if (isUndefined(lastCookies[name])) {\n            lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));\n          }\n        }\n      }\n    }\n    return lastCookies;\n  };\n}\n\n$$CookieReader.$inject = ['$document'];\n\n/** @this */\nfunction $$CookieReaderProvider() {\n  this.$get = $$CookieReader;\n}\n\n/* global currencyFilter: true,\n dateFilter: true,\n filterFilter: true,\n jsonFilter: true,\n limitToFilter: true,\n lowercaseFilter: true,\n numberFilter: true,\n orderByFilter: true,\n uppercaseFilter: true,\n */\n\n/**\n * @ngdoc provider\n * @name $filterProvider\n * @description\n *\n * Filters are just functions which transform input to an output. However filters need to be\n * Dependency Injected. To achieve this a filter definition consists of a factory function which is\n * annotated with dependencies and is responsible for creating a filter function.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.\n * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace\n * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores\n * (`myapp_subsection_filterx`).\n * </div>\n *\n * ```js\n *   // Filter registration\n *   function MyModule($provide, $filterProvider) {\n *     // create a service to demonstrate injection (not always needed)\n *     $provide.value('greet', function(name){\n *       return 'Hello ' + name + '!';\n *     });\n *\n *     // register a filter factory which uses the\n *     // greet service to demonstrate DI.\n *     $filterProvider.register('greet', function(greet){\n *       // return the filter function which uses the greet service\n *       // to generate salutation\n *       return function(text) {\n *         // filters need to be forgiving so check input validity\n *         return text && greet(text) || text;\n *       };\n *     });\n *   }\n * ```\n *\n * The filter function is registered with the `$injector` under the filter name suffix with\n * `Filter`.\n *\n * ```js\n *   it('should be the same instance', inject(\n *     function($filterProvider) {\n *       $filterProvider.register('reverse', function(){\n *         return ...;\n *       });\n *     },\n *     function($filter, reverseFilter) {\n *       expect($filter('reverse')).toBe(reverseFilter);\n *     });\n * ```\n *\n *\n * For more information about how angular filters work, and how to create your own filters, see\n * {@link guide/filter Filters} in the Angular Developer Guide.\n */\n\n/**\n * @ngdoc service\n * @name $filter\n * @kind function\n * @description\n * Filters are used for formatting data displayed to the user.\n *\n * They can be used in view templates, controllers or services.Angular comes\n * with a collection of [built-in filters](api/ng/filter), but it is easy to\n * define your own as well.\n *\n * The general syntax in templates is as follows:\n *\n * ```html\n * {{ expression [| filter_name[:parameter_value] ... ] }}\n * ```\n *\n * @param {String} name Name of the filter function to retrieve\n * @return {Function} the filter function\n * @example\n   <example name=\"$filter\" module=\"filterExample\">\n     <file name=\"index.html\">\n       <div ng-controller=\"MainCtrl\">\n        <h3>{{ originalText }}</h3>\n        <h3>{{ filteredText }}</h3>\n       </div>\n     </file>\n\n     <file name=\"script.js\">\n      angular.module('filterExample', [])\n      .controller('MainCtrl', function($scope, $filter) {\n        $scope.originalText = 'hello';\n        $scope.filteredText = $filter('uppercase')($scope.originalText);\n      });\n     </file>\n   </example>\n  */\n$FilterProvider.$inject = ['$provide'];\n/** @this */\nfunction $FilterProvider($provide) {\n  var suffix = 'Filter';\n\n  /**\n   * @ngdoc method\n   * @name $filterProvider#register\n   * @param {string|Object} name Name of the filter function, or an object map of filters where\n   *    the keys are the filter names and the values are the filter factories.\n   *\n   *    <div class=\"alert alert-warning\">\n   *    **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.\n   *    Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace\n   *    your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores\n   *    (`myapp_subsection_filterx`).\n   *    </div>\n    * @param {Function} factory If the first argument was a string, a factory function for the filter to be registered.\n   * @returns {Object} Registered filter instance, or if a map of filters was provided then a map\n   *    of the registered filter instances.\n   */\n  function register(name, factory) {\n    if (isObject(name)) {\n      var filters = {};\n      forEach(name, function(filter, key) {\n        filters[key] = register(key, filter);\n      });\n      return filters;\n    } else {\n      return $provide.factory(name + suffix, factory);\n    }\n  }\n  this.register = register;\n\n  this.$get = ['$injector', function($injector) {\n    return function(name) {\n      return $injector.get(name + suffix);\n    };\n  }];\n\n  ////////////////////////////////////////\n\n  /* global\n    currencyFilter: false,\n    dateFilter: false,\n    filterFilter: false,\n    jsonFilter: false,\n    limitToFilter: false,\n    lowercaseFilter: false,\n    numberFilter: false,\n    orderByFilter: false,\n    uppercaseFilter: false\n  */\n\n  register('currency', currencyFilter);\n  register('date', dateFilter);\n  register('filter', filterFilter);\n  register('json', jsonFilter);\n  register('limitTo', limitToFilter);\n  register('lowercase', lowercaseFilter);\n  register('number', numberFilter);\n  register('orderBy', orderByFilter);\n  register('uppercase', uppercaseFilter);\n}\n\n/**\n * @ngdoc filter\n * @name filter\n * @kind function\n *\n * @description\n * Selects a subset of items from `array` and returns it as a new array.\n *\n * @param {Array} array The source array.\n * <div class=\"alert alert-info\">\n *   **Note**: If the array contains objects that reference themselves, filtering is not possible.\n * </div>\n * @param {string|Object|function()} expression The predicate to be used for selecting items from\n *   `array`.\n *\n *   Can be one of:\n *\n *   - `string`: The string is used for matching against the contents of the `array`. All strings or\n *     objects with string properties in `array` that match this string will be returned. This also\n *     applies to nested object properties.\n *     The predicate can be negated by prefixing the string with `!`.\n *\n *   - `Object`: A pattern object can be used to filter specific properties on objects contained\n *     by `array`. For example `{name:\"M\", phone:\"1\"}` predicate will return an array of items\n *     which have property `name` containing \"M\" and property `phone` containing \"1\". A special\n *     property name (`$` by default) can be used (e.g. as in `{$: \"text\"}`) to accept a match\n *     against any property of the object or its nested object properties. That's equivalent to the\n *     simple substring match with a `string` as described above. The special property name can be\n *     overwritten, using the `anyPropertyKey` parameter.\n *     The predicate can be negated by prefixing the string with `!`.\n *     For example `{name: \"!M\"}` predicate will return an array of items which have property `name`\n *     not containing \"M\".\n *\n *     Note that a named property will match properties on the same level only, while the special\n *     `$` property will match properties on the same level or deeper. E.g. an array item like\n *     `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but\n *     **will** be matched by `{$: 'John'}`.\n *\n *   - `function(value, index, array)`: A predicate function can be used to write arbitrary filters.\n *     The function is called for each element of the array, with the element, its index, and\n *     the entire array itself as arguments.\n *\n *     The final result is an array of those elements that the predicate returned true for.\n *\n * @param {function(actual, expected)|true|false} [comparator] Comparator which is used in\n *     determining if the expected value (from the filter expression) and actual value (from\n *     the object in the array) should be considered a match.\n *\n *   Can be one of:\n *\n *   - `function(actual, expected)`:\n *     The function will be given the object value and the predicate value to compare and\n *     should return true if both values should be considered equal.\n *\n *   - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected)}`.\n *     This is essentially strict comparison of expected and actual.\n *\n *   - `false`: A short hand for a function which will look for a substring match in a case\n *     insensitive way. Primitive values are converted to strings. Objects are not compared against\n *     primitives, unless they have a custom `toString` method (e.g. `Date` objects).\n *\n *\n *   Defaults to `false`.\n *\n * @param {string} [anyPropertyKey] The special property name that matches against any property.\n *     By default `$`.\n *\n * @example\n   <example name=\"filter-filter\">\n     <file name=\"index.html\">\n       <div ng-init=\"friends = [{name:'John', phone:'555-1276'},\n                                {name:'Mary', phone:'800-BIG-MARY'},\n                                {name:'Mike', phone:'555-4321'},\n                                {name:'Adam', phone:'555-5678'},\n                                {name:'Julie', phone:'555-8765'},\n                                {name:'Juliette', phone:'555-5678'}]\"></div>\n\n       <label>Search: <input ng-model=\"searchText\"></label>\n       <table id=\"searchTextResults\">\n         <tr><th>Name</th><th>Phone</th></tr>\n         <tr ng-repeat=\"friend in friends | filter:searchText\">\n           <td>{{friend.name}}</td>\n           <td>{{friend.phone}}</td>\n         </tr>\n       </table>\n       <hr>\n       <label>Any: <input ng-model=\"search.$\"></label> <br>\n       <label>Name only <input ng-model=\"search.name\"></label><br>\n       <label>Phone only <input ng-model=\"search.phone\"></label><br>\n       <label>Equality <input type=\"checkbox\" ng-model=\"strict\"></label><br>\n       <table id=\"searchObjResults\">\n         <tr><th>Name</th><th>Phone</th></tr>\n         <tr ng-repeat=\"friendObj in friends | filter:search:strict\">\n           <td>{{friendObj.name}}</td>\n           <td>{{friendObj.phone}}</td>\n         </tr>\n       </table>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       var expectFriendNames = function(expectedNames, key) {\n         element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {\n           arr.forEach(function(wd, i) {\n             expect(wd.getText()).toMatch(expectedNames[i]);\n           });\n         });\n       };\n\n       it('should search across all fields when filtering with a string', function() {\n         var searchText = element(by.model('searchText'));\n         searchText.clear();\n         searchText.sendKeys('m');\n         expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');\n\n         searchText.clear();\n         searchText.sendKeys('76');\n         expectFriendNames(['John', 'Julie'], 'friend');\n       });\n\n       it('should search in specific fields when filtering with a predicate object', function() {\n         var searchAny = element(by.model('search.$'));\n         searchAny.clear();\n         searchAny.sendKeys('i');\n         expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');\n       });\n       it('should use a equal comparison when comparator is true', function() {\n         var searchName = element(by.model('search.name'));\n         var strict = element(by.model('strict'));\n         searchName.clear();\n         searchName.sendKeys('Julie');\n         strict.click();\n         expectFriendNames(['Julie'], 'friendObj');\n       });\n     </file>\n   </example>\n */\n\nfunction filterFilter() {\n  return function(array, expression, comparator, anyPropertyKey) {\n    if (!isArrayLike(array)) {\n      if (array == null) {\n        return array;\n      } else {\n        throw minErr('filter')('notarray', 'Expected array but received: {0}', array);\n      }\n    }\n\n    anyPropertyKey = anyPropertyKey || '$';\n    var expressionType = getTypeForFilter(expression);\n    var predicateFn;\n    var matchAgainstAnyProp;\n\n    switch (expressionType) {\n      case 'function':\n        predicateFn = expression;\n        break;\n      case 'boolean':\n      case 'null':\n      case 'number':\n      case 'string':\n        matchAgainstAnyProp = true;\n        // falls through\n      case 'object':\n        predicateFn = createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp);\n        break;\n      default:\n        return array;\n    }\n\n    return Array.prototype.filter.call(array, predicateFn);\n  };\n}\n\n// Helper functions for `filterFilter`\nfunction createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp) {\n  var shouldMatchPrimitives = isObject(expression) && (anyPropertyKey in expression);\n  var predicateFn;\n\n  if (comparator === true) {\n    comparator = equals;\n  } else if (!isFunction(comparator)) {\n    comparator = function(actual, expected) {\n      if (isUndefined(actual)) {\n        // No substring matching against `undefined`\n        return false;\n      }\n      if ((actual === null) || (expected === null)) {\n        // No substring matching against `null`; only match against `null`\n        return actual === expected;\n      }\n      if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual))) {\n        // Should not compare primitives against objects, unless they have custom `toString` method\n        return false;\n      }\n\n      actual = lowercase('' + actual);\n      expected = lowercase('' + expected);\n      return actual.indexOf(expected) !== -1;\n    };\n  }\n\n  predicateFn = function(item) {\n    if (shouldMatchPrimitives && !isObject(item)) {\n      return deepCompare(item, expression[anyPropertyKey], comparator, anyPropertyKey, false);\n    }\n    return deepCompare(item, expression, comparator, anyPropertyKey, matchAgainstAnyProp);\n  };\n\n  return predicateFn;\n}\n\nfunction deepCompare(actual, expected, comparator, anyPropertyKey, matchAgainstAnyProp, dontMatchWholeObject) {\n  var actualType = getTypeForFilter(actual);\n  var expectedType = getTypeForFilter(expected);\n\n  if ((expectedType === 'string') && (expected.charAt(0) === '!')) {\n    return !deepCompare(actual, expected.substring(1), comparator, anyPropertyKey, matchAgainstAnyProp);\n  } else if (isArray(actual)) {\n    // In case `actual` is an array, consider it a match\n    // if ANY of it's items matches `expected`\n    return actual.some(function(item) {\n      return deepCompare(item, expected, comparator, anyPropertyKey, matchAgainstAnyProp);\n    });\n  }\n\n  switch (actualType) {\n    case 'object':\n      var key;\n      if (matchAgainstAnyProp) {\n        for (key in actual) {\n          // Under certain, rare, circumstances, key may not be a string and `charAt` will be undefined\n          // See: https://github.com/angular/angular.js/issues/15644\n          if (key.charAt && (key.charAt(0) !== '$') &&\n              deepCompare(actual[key], expected, comparator, anyPropertyKey, true)) {\n            return true;\n          }\n        }\n        return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, anyPropertyKey, false);\n      } else if (expectedType === 'object') {\n        for (key in expected) {\n          var expectedVal = expected[key];\n          if (isFunction(expectedVal) || isUndefined(expectedVal)) {\n            continue;\n          }\n\n          var matchAnyProperty = key === anyPropertyKey;\n          var actualVal = matchAnyProperty ? actual : actual[key];\n          if (!deepCompare(actualVal, expectedVal, comparator, anyPropertyKey, matchAnyProperty, matchAnyProperty)) {\n            return false;\n          }\n        }\n        return true;\n      } else {\n        return comparator(actual, expected);\n      }\n    case 'function':\n      return false;\n    default:\n      return comparator(actual, expected);\n  }\n}\n\n// Used for easily differentiating between `null` and actual `object`\nfunction getTypeForFilter(val) {\n  return (val === null) ? 'null' : typeof val;\n}\n\nvar MAX_DIGITS = 22;\nvar DECIMAL_SEP = '.';\nvar ZERO_CHAR = '0';\n\n/**\n * @ngdoc filter\n * @name currency\n * @kind function\n *\n * @description\n * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default\n * symbol for current locale is used.\n *\n * @param {number} amount Input to filter.\n * @param {string=} symbol Currency symbol or identifier to be displayed.\n * @param {number=} fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale\n * @returns {string} Formatted number.\n *\n *\n * @example\n   <example module=\"currencyExample\" name=\"currency-filter\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('currencyExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.amount = 1234.56;\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <input type=\"number\" ng-model=\"amount\" aria-label=\"amount\"> <br>\n         default currency symbol ($): <span id=\"currency-default\">{{amount | currency}}</span><br>\n         custom currency identifier (USD$): <span id=\"currency-custom\">{{amount | currency:\"USD$\"}}</span><br>\n         no fractions (0): <span id=\"currency-no-fractions\">{{amount | currency:\"USD$\":0}}</span>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should init with 1234.56', function() {\n         expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');\n         expect(element(by.id('currency-custom')).getText()).toBe('USD$1,234.56');\n         expect(element(by.id('currency-no-fractions')).getText()).toBe('USD$1,235');\n       });\n       it('should update', function() {\n         if (browser.params.browser === 'safari') {\n           // Safari does not understand the minus key. See\n           // https://github.com/angular/protractor/issues/481\n           return;\n         }\n         element(by.model('amount')).clear();\n         element(by.model('amount')).sendKeys('-1234');\n         expect(element(by.id('currency-default')).getText()).toBe('-$1,234.00');\n         expect(element(by.id('currency-custom')).getText()).toBe('-USD$1,234.00');\n         expect(element(by.id('currency-no-fractions')).getText()).toBe('-USD$1,234');\n       });\n     </file>\n   </example>\n */\ncurrencyFilter.$inject = ['$locale'];\nfunction currencyFilter($locale) {\n  var formats = $locale.NUMBER_FORMATS;\n  return function(amount, currencySymbol, fractionSize) {\n    if (isUndefined(currencySymbol)) {\n      currencySymbol = formats.CURRENCY_SYM;\n    }\n\n    if (isUndefined(fractionSize)) {\n      fractionSize = formats.PATTERNS[1].maxFrac;\n    }\n\n    // if null or undefined pass it through\n    return (amount == null)\n        ? amount\n        : formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize).\n            replace(/\\u00A4/g, currencySymbol);\n  };\n}\n\n/**\n * @ngdoc filter\n * @name number\n * @kind function\n *\n * @description\n * Formats a number as text.\n *\n * If the input is null or undefined, it will just be returned.\n * If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively.\n * If the input is not a number an empty string is returned.\n *\n *\n * @param {number|string} number Number to format.\n * @param {(number|string)=} fractionSize Number of decimal places to round the number to.\n * If this is not provided then the fraction size is computed from the current locale's number\n * formatting pattern. In the case of the default locale, it will be 3.\n * @returns {string} Number rounded to `fractionSize` appropriately formatted based on the current\n *                   locale (e.g., in the en_US locale it will have \".\" as the decimal separator and\n *                   include \",\" group separators after each third digit).\n *\n * @example\n   <example module=\"numberFilterExample\" name=\"number-filter\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('numberFilterExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.val = 1234.56789;\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <label>Enter number: <input ng-model='val'></label><br>\n         Default formatting: <span id='number-default'>{{val | number}}</span><br>\n         No fractions: <span>{{val | number:0}}</span><br>\n         Negative number: <span>{{-val | number:4}}</span>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should format numbers', function() {\n         expect(element(by.id('number-default')).getText()).toBe('1,234.568');\n         expect(element(by.binding('val | number:0')).getText()).toBe('1,235');\n         expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');\n       });\n\n       it('should update', function() {\n         element(by.model('val')).clear();\n         element(by.model('val')).sendKeys('3374.333');\n         expect(element(by.id('number-default')).getText()).toBe('3,374.333');\n         expect(element(by.binding('val | number:0')).getText()).toBe('3,374');\n         expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');\n      });\n     </file>\n   </example>\n */\nnumberFilter.$inject = ['$locale'];\nfunction numberFilter($locale) {\n  var formats = $locale.NUMBER_FORMATS;\n  return function(number, fractionSize) {\n\n    // if null or undefined pass it through\n    return (number == null)\n        ? number\n        : formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP,\n                       fractionSize);\n  };\n}\n\n/**\n * Parse a number (as a string) into three components that can be used\n * for formatting the number.\n *\n * (Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/)\n *\n * @param  {string} numStr The number to parse\n * @return {object} An object describing this number, containing the following keys:\n *  - d : an array of digits containing leading zeros as necessary\n *  - i : the number of the digits in `d` that are to the left of the decimal point\n *  - e : the exponent for numbers that would need more than `MAX_DIGITS` digits in `d`\n *\n */\nfunction parse(numStr) {\n  var exponent = 0, digits, numberOfIntegerDigits;\n  var i, j, zeros;\n\n  // Decimal point?\n  if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) {\n    numStr = numStr.replace(DECIMAL_SEP, '');\n  }\n\n  // Exponential form?\n  if ((i = numStr.search(/e/i)) > 0) {\n    // Work out the exponent.\n    if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i;\n    numberOfIntegerDigits += +numStr.slice(i + 1);\n    numStr = numStr.substring(0, i);\n  } else if (numberOfIntegerDigits < 0) {\n    // There was no decimal point or exponent so it is an integer.\n    numberOfIntegerDigits = numStr.length;\n  }\n\n  // Count the number of leading zeros.\n  for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) { /* empty */ }\n\n  if (i === (zeros = numStr.length)) {\n    // The digits are all zero.\n    digits = [0];\n    numberOfIntegerDigits = 1;\n  } else {\n    // Count the number of trailing zeros\n    zeros--;\n    while (numStr.charAt(zeros) === ZERO_CHAR) zeros--;\n\n    // Trailing zeros are insignificant so ignore them\n    numberOfIntegerDigits -= i;\n    digits = [];\n    // Convert string to array of digits without leading/trailing zeros.\n    for (j = 0; i <= zeros; i++, j++) {\n      digits[j] = +numStr.charAt(i);\n    }\n  }\n\n  // If the number overflows the maximum allowed digits then use an exponent.\n  if (numberOfIntegerDigits > MAX_DIGITS) {\n    digits = digits.splice(0, MAX_DIGITS - 1);\n    exponent = numberOfIntegerDigits - 1;\n    numberOfIntegerDigits = 1;\n  }\n\n  return { d: digits, e: exponent, i: numberOfIntegerDigits };\n}\n\n/**\n * Round the parsed number to the specified number of decimal places\n * This function changed the parsedNumber in-place\n */\nfunction roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {\n    var digits = parsedNumber.d;\n    var fractionLen = digits.length - parsedNumber.i;\n\n    // determine fractionSize if it is not specified; `+fractionSize` converts it to a number\n    fractionSize = (isUndefined(fractionSize)) ? Math.min(Math.max(minFrac, fractionLen), maxFrac) : +fractionSize;\n\n    // The index of the digit to where rounding is to occur\n    var roundAt = fractionSize + parsedNumber.i;\n    var digit = digits[roundAt];\n\n    if (roundAt > 0) {\n      // Drop fractional digits beyond `roundAt`\n      digits.splice(Math.max(parsedNumber.i, roundAt));\n\n      // Set non-fractional digits beyond `roundAt` to 0\n      for (var j = roundAt; j < digits.length; j++) {\n        digits[j] = 0;\n      }\n    } else {\n      // We rounded to zero so reset the parsedNumber\n      fractionLen = Math.max(0, fractionLen);\n      parsedNumber.i = 1;\n      digits.length = Math.max(1, roundAt = fractionSize + 1);\n      digits[0] = 0;\n      for (var i = 1; i < roundAt; i++) digits[i] = 0;\n    }\n\n    if (digit >= 5) {\n      if (roundAt - 1 < 0) {\n        for (var k = 0; k > roundAt; k--) {\n          digits.unshift(0);\n          parsedNumber.i++;\n        }\n        digits.unshift(1);\n        parsedNumber.i++;\n      } else {\n        digits[roundAt - 1]++;\n      }\n    }\n\n    // Pad out with zeros to get the required fraction length\n    for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);\n\n\n    // Do any carrying, e.g. a digit was rounded up to 10\n    var carry = digits.reduceRight(function(carry, d, i, digits) {\n      d = d + carry;\n      digits[i] = d % 10;\n      return Math.floor(d / 10);\n    }, 0);\n    if (carry) {\n      digits.unshift(carry);\n      parsedNumber.i++;\n    }\n}\n\n/**\n * Format a number into a string\n * @param  {number} number       The number to format\n * @param  {{\n *           minFrac, // the minimum number of digits required in the fraction part of the number\n *           maxFrac, // the maximum number of digits required in the fraction part of the number\n *           gSize,   // number of digits in each group of separated digits\n *           lgSize,  // number of digits in the last group of digits before the decimal separator\n *           negPre,  // the string to go in front of a negative number (e.g. `-` or `(`))\n *           posPre,  // the string to go in front of a positive number\n *           negSuf,  // the string to go after a negative number (e.g. `)`)\n *           posSuf   // the string to go after a positive number\n *         }} pattern\n * @param  {string} groupSep     The string to separate groups of number (e.g. `,`)\n * @param  {string} decimalSep   The string to act as the decimal separator (e.g. `.`)\n * @param  {[type]} fractionSize The size of the fractional part of the number\n * @return {string}              The number formatted as a string\n */\nfunction formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {\n\n  if (!(isString(number) || isNumber(number)) || isNaN(number)) return '';\n\n  var isInfinity = !isFinite(number);\n  var isZero = false;\n  var numStr = Math.abs(number) + '',\n      formattedText = '',\n      parsedNumber;\n\n  if (isInfinity) {\n    formattedText = '\\u221e';\n  } else {\n    parsedNumber = parse(numStr);\n\n    roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac);\n\n    var digits = parsedNumber.d;\n    var integerLen = parsedNumber.i;\n    var exponent = parsedNumber.e;\n    var decimals = [];\n    isZero = digits.reduce(function(isZero, d) { return isZero && !d; }, true);\n\n    // pad zeros for small numbers\n    while (integerLen < 0) {\n      digits.unshift(0);\n      integerLen++;\n    }\n\n    // extract decimals digits\n    if (integerLen > 0) {\n      decimals = digits.splice(integerLen, digits.length);\n    } else {\n      decimals = digits;\n      digits = [0];\n    }\n\n    // format the integer digits with grouping separators\n    var groups = [];\n    if (digits.length >= pattern.lgSize) {\n      groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(''));\n    }\n    while (digits.length > pattern.gSize) {\n      groups.unshift(digits.splice(-pattern.gSize, digits.length).join(''));\n    }\n    if (digits.length) {\n      groups.unshift(digits.join(''));\n    }\n    formattedText = groups.join(groupSep);\n\n    // append the decimal digits\n    if (decimals.length) {\n      formattedText += decimalSep + decimals.join('');\n    }\n\n    if (exponent) {\n      formattedText += 'e+' + exponent;\n    }\n  }\n  if (number < 0 && !isZero) {\n    return pattern.negPre + formattedText + pattern.negSuf;\n  } else {\n    return pattern.posPre + formattedText + pattern.posSuf;\n  }\n}\n\nfunction padNumber(num, digits, trim, negWrap) {\n  var neg = '';\n  if (num < 0 || (negWrap && num <= 0)) {\n    if (negWrap) {\n      num = -num + 1;\n    } else {\n      num = -num;\n      neg = '-';\n    }\n  }\n  num = '' + num;\n  while (num.length < digits) num = ZERO_CHAR + num;\n  if (trim) {\n    num = num.substr(num.length - digits);\n  }\n  return neg + num;\n}\n\n\nfunction dateGetter(name, size, offset, trim, negWrap) {\n  offset = offset || 0;\n  return function(date) {\n    var value = date['get' + name]();\n    if (offset > 0 || value > -offset) {\n      value += offset;\n    }\n    if (value === 0 && offset === -12) value = 12;\n    return padNumber(value, size, trim, negWrap);\n  };\n}\n\nfunction dateStrGetter(name, shortForm, standAlone) {\n  return function(date, formats) {\n    var value = date['get' + name]();\n    var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');\n    var get = uppercase(propPrefix + name);\n\n    return formats[get][value];\n  };\n}\n\nfunction timeZoneGetter(date, formats, offset) {\n  var zone = -1 * offset;\n  var paddedZone = (zone >= 0) ? '+' : '';\n\n  paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +\n                padNumber(Math.abs(zone % 60), 2);\n\n  return paddedZone;\n}\n\nfunction getFirstThursdayOfYear(year) {\n    // 0 = index of January\n    var dayOfWeekOnFirst = (new Date(year, 0, 1)).getDay();\n    // 4 = index of Thursday (+1 to account for 1st = 5)\n    // 11 = index of *next* Thursday (+1 account for 1st = 12)\n    return new Date(year, 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst);\n}\n\nfunction getThursdayThisWeek(datetime) {\n    return new Date(datetime.getFullYear(), datetime.getMonth(),\n      // 4 = index of Thursday\n      datetime.getDate() + (4 - datetime.getDay()));\n}\n\nfunction weekGetter(size) {\n   return function(date) {\n      var firstThurs = getFirstThursdayOfYear(date.getFullYear()),\n         thisThurs = getThursdayThisWeek(date);\n\n      var diff = +thisThurs - +firstThurs,\n         result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week\n\n      return padNumber(result, size);\n   };\n}\n\nfunction ampmGetter(date, formats) {\n  return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];\n}\n\nfunction eraGetter(date, formats) {\n  return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1];\n}\n\nfunction longEraGetter(date, formats) {\n  return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1];\n}\n\nvar DATE_FORMATS = {\n  yyyy: dateGetter('FullYear', 4, 0, false, true),\n    yy: dateGetter('FullYear', 2, 0, true, true),\n     y: dateGetter('FullYear', 1, 0, false, true),\n  MMMM: dateStrGetter('Month'),\n   MMM: dateStrGetter('Month', true),\n    MM: dateGetter('Month', 2, 1),\n     M: dateGetter('Month', 1, 1),\n  LLLL: dateStrGetter('Month', false, true),\n    dd: dateGetter('Date', 2),\n     d: dateGetter('Date', 1),\n    HH: dateGetter('Hours', 2),\n     H: dateGetter('Hours', 1),\n    hh: dateGetter('Hours', 2, -12),\n     h: dateGetter('Hours', 1, -12),\n    mm: dateGetter('Minutes', 2),\n     m: dateGetter('Minutes', 1),\n    ss: dateGetter('Seconds', 2),\n     s: dateGetter('Seconds', 1),\n     // while ISO 8601 requires fractions to be prefixed with `.` or `,`\n     // we can be just safely rely on using `sss` since we currently don't support single or two digit fractions\n   sss: dateGetter('Milliseconds', 3),\n  EEEE: dateStrGetter('Day'),\n   EEE: dateStrGetter('Day', true),\n     a: ampmGetter,\n     Z: timeZoneGetter,\n    ww: weekGetter(2),\n     w: weekGetter(1),\n     G: eraGetter,\n     GG: eraGetter,\n     GGG: eraGetter,\n     GGGG: longEraGetter\n};\n\nvar DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,\n    NUMBER_STRING = /^-?\\d+$/;\n\n/**\n * @ngdoc filter\n * @name date\n * @kind function\n *\n * @description\n *   Formats `date` to a string based on the requested `format`.\n *\n *   `format` string can be composed of the following elements:\n *\n *   * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010)\n *   * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)\n *   * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199)\n *   * `'MMMM'`: Month in year (January-December)\n *   * `'MMM'`: Month in year (Jan-Dec)\n *   * `'MM'`: Month in year, padded (01-12)\n *   * `'M'`: Month in year (1-12)\n *   * `'LLLL'`: Stand-alone month in year (January-December)\n *   * `'dd'`: Day in month, padded (01-31)\n *   * `'d'`: Day in month (1-31)\n *   * `'EEEE'`: Day in Week,(Sunday-Saturday)\n *   * `'EEE'`: Day in Week, (Sun-Sat)\n *   * `'HH'`: Hour in day, padded (00-23)\n *   * `'H'`: Hour in day (0-23)\n *   * `'hh'`: Hour in AM/PM, padded (01-12)\n *   * `'h'`: Hour in AM/PM, (1-12)\n *   * `'mm'`: Minute in hour, padded (00-59)\n *   * `'m'`: Minute in hour (0-59)\n *   * `'ss'`: Second in minute, padded (00-59)\n *   * `'s'`: Second in minute (0-59)\n *   * `'sss'`: Millisecond in second, padded (000-999)\n *   * `'a'`: AM/PM marker\n *   * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)\n *   * `'ww'`: Week of year, padded (00-53). Week 01 is the week with the first Thursday of the year\n *   * `'w'`: Week of year (0-53). Week 1 is the week with the first Thursday of the year\n *   * `'G'`, `'GG'`, `'GGG'`: The abbreviated form of the era string (e.g. 'AD')\n *   * `'GGGG'`: The long form of the era string (e.g. 'Anno Domini')\n *\n *   `format` string can also be one of the following predefined\n *   {@link guide/i18n localizable formats}:\n *\n *   * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale\n *     (e.g. Sep 3, 2010 12:05:08 PM)\n *   * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US  locale (e.g. 9/3/10 12:05 PM)\n *   * `'fullDate'`: equivalent to `'EEEE, MMMM d, y'` for en_US  locale\n *     (e.g. Friday, September 3, 2010)\n *   * `'longDate'`: equivalent to `'MMMM d, y'` for en_US  locale (e.g. September 3, 2010)\n *   * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US  locale (e.g. Sep 3, 2010)\n *   * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)\n *   * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 PM)\n *   * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 PM)\n *\n *   `format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g.\n *   `\"h 'in the morning'\"`). In order to output a single quote, escape it - i.e., two single quotes in a sequence\n *   (e.g. `\"h 'o''clock'\"`).\n *\n * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or\n *    number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its\n *    shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is\n *    specified in the string input, the time is considered to be in the local timezone.\n * @param {string=} format Formatting rules (see Description). If not specified,\n *    `mediumDate` is used.\n * @param {string=} timezone Timezone to be used for formatting. It understands UTC/GMT and the\n *    continental US time zone abbreviations, but for general use, use a time zone offset, for\n *    example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)\n *    If not specified, the timezone of the browser will be used.\n * @returns {string} Formatted string or the input if input is not recognized as date/millis.\n *\n * @example\n   <example name=\"filter-date\">\n     <file name=\"index.html\">\n       <span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:\n           <span>{{1288323623006 | date:'medium'}}</span><br>\n       <span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:\n          <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>\n       <span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:\n          <span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>\n       <span ng-non-bindable>{{1288323623006 | date:\"MM/dd/yyyy 'at' h:mma\"}}</span>:\n          <span>{{'1288323623006' | date:\"MM/dd/yyyy 'at' h:mma\"}}</span><br>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should format date', function() {\n         expect(element(by.binding(\"1288323623006 | date:'medium'\")).getText()).\n            toMatch(/Oct 2\\d, 2010 \\d{1,2}:\\d{2}:\\d{2} (AM|PM)/);\n         expect(element(by.binding(\"1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'\")).getText()).\n            toMatch(/2010-10-2\\d \\d{2}:\\d{2}:\\d{2} (-|\\+)?\\d{4}/);\n         expect(element(by.binding(\"'1288323623006' | date:'MM/dd/yyyy @ h:mma'\")).getText()).\n            toMatch(/10\\/2\\d\\/2010 @ \\d{1,2}:\\d{2}(AM|PM)/);\n         expect(element(by.binding(\"'1288323623006' | date:\\\"MM/dd/yyyy 'at' h:mma\\\"\")).getText()).\n            toMatch(/10\\/2\\d\\/2010 at \\d{1,2}:\\d{2}(AM|PM)/);\n       });\n     </file>\n   </example>\n */\ndateFilter.$inject = ['$locale'];\nfunction dateFilter($locale) {\n\n\n  var R_ISO8601_STR = /^(\\d{4})-?(\\d\\d)-?(\\d\\d)(?:T(\\d\\d)(?::?(\\d\\d)(?::?(\\d\\d)(?:\\.(\\d+))?)?)?(Z|([+-])(\\d\\d):?(\\d\\d))?)?$/;\n                     // 1        2       3         4          5          6          7          8  9     10      11\n  function jsonStringToDate(string) {\n    var match;\n    if ((match = string.match(R_ISO8601_STR))) {\n      var date = new Date(0),\n          tzHour = 0,\n          tzMin  = 0,\n          dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,\n          timeSetter = match[8] ? date.setUTCHours : date.setHours;\n\n      if (match[9]) {\n        tzHour = toInt(match[9] + match[10]);\n        tzMin = toInt(match[9] + match[11]);\n      }\n      dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));\n      var h = toInt(match[4] || 0) - tzHour;\n      var m = toInt(match[5] || 0) - tzMin;\n      var s = toInt(match[6] || 0);\n      var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);\n      timeSetter.call(date, h, m, s, ms);\n      return date;\n    }\n    return string;\n  }\n\n\n  return function(date, format, timezone) {\n    var text = '',\n        parts = [],\n        fn, match;\n\n    format = format || 'mediumDate';\n    format = $locale.DATETIME_FORMATS[format] || format;\n    if (isString(date)) {\n      date = NUMBER_STRING.test(date) ? toInt(date) : jsonStringToDate(date);\n    }\n\n    if (isNumber(date)) {\n      date = new Date(date);\n    }\n\n    if (!isDate(date) || !isFinite(date.getTime())) {\n      return date;\n    }\n\n    while (format) {\n      match = DATE_FORMATS_SPLIT.exec(format);\n      if (match) {\n        parts = concat(parts, match, 1);\n        format = parts.pop();\n      } else {\n        parts.push(format);\n        format = null;\n      }\n    }\n\n    var dateTimezoneOffset = date.getTimezoneOffset();\n    if (timezone) {\n      dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);\n      date = convertTimezoneToLocal(date, timezone, true);\n    }\n    forEach(parts, function(value) {\n      fn = DATE_FORMATS[value];\n      text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset)\n                 : value === '\\'\\'' ? '\\'' : value.replace(/(^'|'$)/g, '').replace(/''/g, '\\'');\n    });\n\n    return text;\n  };\n}\n\n\n/**\n * @ngdoc filter\n * @name json\n * @kind function\n *\n * @description\n *   Allows you to convert a JavaScript object into JSON string.\n *\n *   This filter is mostly useful for debugging. When using the double curly {{value}} notation\n *   the binding is automatically converted to JSON.\n *\n * @param {*} object Any JavaScript object (including arrays and primitive types) to filter.\n * @param {number=} spacing The number of spaces to use per indentation, defaults to 2.\n * @returns {string} JSON string.\n *\n *\n * @example\n   <example name=\"filter-json\">\n     <file name=\"index.html\">\n       <pre id=\"default-spacing\">{{ {'name':'value'} | json }}</pre>\n       <pre id=\"custom-spacing\">{{ {'name':'value'} | json:4 }}</pre>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should jsonify filtered objects', function() {\n         expect(element(by.id('default-spacing')).getText()).toMatch(/\\{\\n {2}\"name\": ?\"value\"\\n}/);\n         expect(element(by.id('custom-spacing')).getText()).toMatch(/\\{\\n {4}\"name\": ?\"value\"\\n}/);\n       });\n     </file>\n   </example>\n *\n */\nfunction jsonFilter() {\n  return function(object, spacing) {\n    if (isUndefined(spacing)) {\n        spacing = 2;\n    }\n    return toJson(object, spacing);\n  };\n}\n\n\n/**\n * @ngdoc filter\n * @name lowercase\n * @kind function\n * @description\n * Converts string to lowercase.\n * @see angular.lowercase\n */\nvar lowercaseFilter = valueFn(lowercase);\n\n\n/**\n * @ngdoc filter\n * @name uppercase\n * @kind function\n * @description\n * Converts string to uppercase.\n * @see angular.uppercase\n */\nvar uppercaseFilter = valueFn(uppercase);\n\n/**\n * @ngdoc filter\n * @name limitTo\n * @kind function\n *\n * @description\n * Creates a new array or string containing only a specified number of elements. The elements are\n * taken from either the beginning or the end of the source array, string or number, as specified by\n * the value and sign (positive or negative) of `limit`. Other array-like objects are also supported\n * (e.g. array subclasses, NodeLists, jqLite/jQuery collections etc). If a number is used as input,\n * it is converted to a string.\n *\n * @param {Array|ArrayLike|string|number} input - Array/array-like, string or number to be limited.\n * @param {string|number} limit - The length of the returned array or string. If the `limit` number\n *     is positive, `limit` number of items from the beginning of the source array/string are copied.\n *     If the number is negative, `limit` number  of items from the end of the source array/string\n *     are copied. The `limit` will be trimmed if it exceeds `array.length`. If `limit` is undefined,\n *     the input will be returned unchanged.\n * @param {(string|number)=} begin - Index at which to begin limitation. As a negative index,\n *     `begin` indicates an offset from the end of `input`. Defaults to `0`.\n * @returns {Array|string} A new sub-array or substring of length `limit` or less if the input had\n *     less than `limit` elements.\n *\n * @example\n   <example module=\"limitToExample\" name=\"limit-to-filter\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('limitToExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.numbers = [1,2,3,4,5,6,7,8,9];\n             $scope.letters = \"abcdefghi\";\n             $scope.longNumber = 2345432342;\n             $scope.numLimit = 3;\n             $scope.letterLimit = 3;\n             $scope.longNumberLimit = 3;\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <label>\n            Limit {{numbers}} to:\n            <input type=\"number\" step=\"1\" ng-model=\"numLimit\">\n         </label>\n         <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>\n         <label>\n            Limit {{letters}} to:\n            <input type=\"number\" step=\"1\" ng-model=\"letterLimit\">\n         </label>\n         <p>Output letters: {{ letters | limitTo:letterLimit }}</p>\n         <label>\n            Limit {{longNumber}} to:\n            <input type=\"number\" step=\"1\" ng-model=\"longNumberLimit\">\n         </label>\n         <p>Output long number: {{ longNumber | limitTo:longNumberLimit }}</p>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       var numLimitInput = element(by.model('numLimit'));\n       var letterLimitInput = element(by.model('letterLimit'));\n       var longNumberLimitInput = element(by.model('longNumberLimit'));\n       var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));\n       var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));\n       var limitedLongNumber = element(by.binding('longNumber | limitTo:longNumberLimit'));\n\n       it('should limit the number array to first three items', function() {\n         expect(numLimitInput.getAttribute('value')).toBe('3');\n         expect(letterLimitInput.getAttribute('value')).toBe('3');\n         expect(longNumberLimitInput.getAttribute('value')).toBe('3');\n         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');\n         expect(limitedLetters.getText()).toEqual('Output letters: abc');\n         expect(limitedLongNumber.getText()).toEqual('Output long number: 234');\n       });\n\n       // There is a bug in safari and protractor that doesn't like the minus key\n       // it('should update the output when -3 is entered', function() {\n       //   numLimitInput.clear();\n       //   numLimitInput.sendKeys('-3');\n       //   letterLimitInput.clear();\n       //   letterLimitInput.sendKeys('-3');\n       //   longNumberLimitInput.clear();\n       //   longNumberLimitInput.sendKeys('-3');\n       //   expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');\n       //   expect(limitedLetters.getText()).toEqual('Output letters: ghi');\n       //   expect(limitedLongNumber.getText()).toEqual('Output long number: 342');\n       // });\n\n       it('should not exceed the maximum size of input array', function() {\n         numLimitInput.clear();\n         numLimitInput.sendKeys('100');\n         letterLimitInput.clear();\n         letterLimitInput.sendKeys('100');\n         longNumberLimitInput.clear();\n         longNumberLimitInput.sendKeys('100');\n         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');\n         expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');\n         expect(limitedLongNumber.getText()).toEqual('Output long number: 2345432342');\n       });\n     </file>\n   </example>\n*/\nfunction limitToFilter() {\n  return function(input, limit, begin) {\n    if (Math.abs(Number(limit)) === Infinity) {\n      limit = Number(limit);\n    } else {\n      limit = toInt(limit);\n    }\n    if (isNumberNaN(limit)) return input;\n\n    if (isNumber(input)) input = input.toString();\n    if (!isArrayLike(input)) return input;\n\n    begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);\n    begin = (begin < 0) ? Math.max(0, input.length + begin) : begin;\n\n    if (limit >= 0) {\n      return sliceFn(input, begin, begin + limit);\n    } else {\n      if (begin === 0) {\n        return sliceFn(input, limit, input.length);\n      } else {\n        return sliceFn(input, Math.max(0, begin + limit), begin);\n      }\n    }\n  };\n}\n\nfunction sliceFn(input, begin, end) {\n  if (isString(input)) return input.slice(begin, end);\n\n  return slice.call(input, begin, end);\n}\n\n/**\n * @ngdoc filter\n * @name orderBy\n * @kind function\n *\n * @description\n * Returns an array containing the items from the specified `collection`, ordered by a `comparator`\n * function based on the values computed using the `expression` predicate.\n *\n * For example, `[{id: 'foo'}, {id: 'bar'}] | orderBy:'id'` would result in\n * `[{id: 'bar'}, {id: 'foo'}]`.\n *\n * The `collection` can be an Array or array-like object (e.g. NodeList, jQuery object, TypedArray,\n * String, etc).\n *\n * The `expression` can be a single predicate, or a list of predicates each serving as a tie-breaker\n * for the preceding one. The `expression` is evaluated against each item and the output is used\n * for comparing with other items.\n *\n * You can change the sorting order by setting `reverse` to `true`. By default, items are sorted in\n * ascending order.\n *\n * The comparison is done using the `comparator` function. If none is specified, a default, built-in\n * comparator is used (see below for details - in a nutshell, it compares numbers numerically and\n * strings alphabetically).\n *\n * ### Under the hood\n *\n * Ordering the specified `collection` happens in two phases:\n *\n * 1. All items are passed through the predicate (or predicates), and the returned values are saved\n *    along with their type (`string`, `number` etc). For example, an item `{label: 'foo'}`, passed\n *    through a predicate that extracts the value of the `label` property, would be transformed to:\n *    ```\n *    {\n *      value: 'foo',\n *      type: 'string',\n *      index: ...\n *    }\n *    ```\n * 2. The comparator function is used to sort the items, based on the derived values, types and\n *    indices.\n *\n * If you use a custom comparator, it will be called with pairs of objects of the form\n * `{value: ..., type: '...', index: ...}` and is expected to return `0` if the objects are equal\n * (as far as the comparator is concerned), `-1` if the 1st one should be ranked higher than the\n * second, or `1` otherwise.\n *\n * In order to ensure that the sorting will be deterministic across platforms, if none of the\n * specified predicates can distinguish between two items, `orderBy` will automatically introduce a\n * dummy predicate that returns the item's index as `value`.\n * (If you are using a custom comparator, make sure it can handle this predicate as well.)\n *\n * Finally, in an attempt to simplify things, if a predicate returns an object as the extracted\n * value for an item, `orderBy` will try to convert that object to a primitive value, before passing\n * it to the comparator. The following rules govern the conversion:\n *\n * 1. If the object has a `valueOf()` method that returns a primitive, its return value will be\n *    used instead.<br />\n *    (If the object has a `valueOf()` method that returns another object, then the returned object\n *    will be used in subsequent steps.)\n * 2. If the object has a custom `toString()` method (i.e. not the one inherited from `Object`) that\n *    returns a primitive, its return value will be used instead.<br />\n *    (If the object has a `toString()` method that returns another object, then the returned object\n *    will be used in subsequent steps.)\n * 3. No conversion; the object itself is used.\n *\n * ### The default comparator\n *\n * The default, built-in comparator should be sufficient for most usecases. In short, it compares\n * numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to\n * using their index in the original collection, and sorts values of different types by type.\n *\n * More specifically, it follows these steps to determine the relative order of items:\n *\n * 1. If the compared values are of different types, compare the types themselves alphabetically.\n * 2. If both values are of type `string`, compare them alphabetically in a case- and\n *    locale-insensitive way.\n * 3. If both values are objects, compare their indices instead.\n * 4. Otherwise, return:\n *    -  `0`, if the values are equal (by strict equality comparison, i.e. using `===`).\n *    - `-1`, if the 1st value is \"less than\" the 2nd value (compared using the `<` operator).\n *    -  `1`, otherwise.\n *\n * **Note:** If you notice numbers not being sorted as expected, make sure they are actually being\n *           saved as numbers and not strings.\n * **Note:** For the purpose of sorting, `null` values are treated as the string `'null'` (i.e.\n *           `type: 'string'`, `value: 'null'`). This may cause unexpected sort order relative to\n *           other values.\n *\n * @param {Array|ArrayLike} collection - The collection (array or array-like object) to sort.\n * @param {(Function|string|Array.<Function|string>)=} expression - A predicate (or list of\n *    predicates) to be used by the comparator to determine the order of elements.\n *\n *    Can be one of:\n *\n *    - `Function`: A getter function. This function will be called with each item as argument and\n *      the return value will be used for sorting.\n *    - `string`: An Angular expression. This expression will be evaluated against each item and the\n *      result will be used for sorting. For example, use `'label'` to sort by a property called\n *      `label` or `'label.substring(0, 3)'` to sort by the first 3 characters of the `label`\n *      property.<br />\n *      (The result of a constant expression is interpreted as a property name to be used for\n *      comparison. For example, use `'\"special name\"'` (note the extra pair of quotes) to sort by a\n *      property called `special name`.)<br />\n *      An expression can be optionally prefixed with `+` or `-` to control the sorting direction,\n *      ascending or descending. For example, `'+label'` or `'-label'`. If no property is provided,\n *      (e.g. `'+'` or `'-'`), the collection element itself is used in comparisons.\n *    - `Array`: An array of function and/or string predicates. If a predicate cannot determine the\n *      relative order of two items, the next predicate is used as a tie-breaker.\n *\n * **Note:** If the predicate is missing or empty then it defaults to `'+'`.\n *\n * @param {boolean=} reverse - If `true`, reverse the sorting order.\n * @param {(Function)=} comparator - The comparator function used to determine the relative order of\n *    value pairs. If omitted, the built-in comparator will be used.\n *\n * @returns {Array} - The sorted array.\n *\n *\n * @example\n * ### Ordering a table with `ngRepeat`\n *\n * The example below demonstrates a simple {@link ngRepeat ngRepeat}, where the data is sorted by\n * age in descending order (expression is set to `'-age'`). The `comparator` is not set, which means\n * it defaults to the built-in comparator.\n *\n   <example name=\"orderBy-static\" module=\"orderByExample1\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <table class=\"friends\">\n           <tr>\n             <th>Name</th>\n             <th>Phone Number</th>\n             <th>Age</th>\n           </tr>\n           <tr ng-repeat=\"friend in friends | orderBy:'-age'\">\n             <td>{{friend.name}}</td>\n             <td>{{friend.phone}}</td>\n             <td>{{friend.age}}</td>\n           </tr>\n         </table>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('orderByExample1', [])\n         .controller('ExampleController', ['$scope', function($scope) {\n           $scope.friends = [\n             {name: 'John',   phone: '555-1212',  age: 10},\n             {name: 'Mary',   phone: '555-9876',  age: 19},\n             {name: 'Mike',   phone: '555-4321',  age: 21},\n             {name: 'Adam',   phone: '555-5678',  age: 35},\n             {name: 'Julie',  phone: '555-8765',  age: 29}\n           ];\n         }]);\n     </file>\n     <file name=\"style.css\">\n       .friends {\n         border-collapse: collapse;\n       }\n\n       .friends th {\n         border-bottom: 1px solid;\n       }\n       .friends td, .friends th {\n         border-left: 1px solid;\n         padding: 5px 10px;\n       }\n       .friends td:first-child, .friends th:first-child {\n         border-left: none;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       // Element locators\n       var names = element.all(by.repeater('friends').column('friend.name'));\n\n       it('should sort friends by age in reverse order', function() {\n         expect(names.get(0).getText()).toBe('Adam');\n         expect(names.get(1).getText()).toBe('Julie');\n         expect(names.get(2).getText()).toBe('Mike');\n         expect(names.get(3).getText()).toBe('Mary');\n         expect(names.get(4).getText()).toBe('John');\n       });\n     </file>\n   </example>\n * <hr />\n *\n * @example\n * ### Changing parameters dynamically\n *\n * All parameters can be changed dynamically. The next example shows how you can make the columns of\n * a table sortable, by binding the `expression` and `reverse` parameters to scope properties.\n *\n   <example name=\"orderBy-dynamic\" module=\"orderByExample2\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <pre>Sort by = {{propertyName}}; reverse = {{reverse}}</pre>\n         <hr/>\n         <button ng-click=\"propertyName = null; reverse = false\">Set to unsorted</button>\n         <hr/>\n         <table class=\"friends\">\n           <tr>\n             <th>\n               <button ng-click=\"sortBy('name')\">Name</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'name'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n             <th>\n               <button ng-click=\"sortBy('phone')\">Phone Number</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'phone'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n             <th>\n               <button ng-click=\"sortBy('age')\">Age</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'age'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n           </tr>\n           <tr ng-repeat=\"friend in friends | orderBy:propertyName:reverse\">\n             <td>{{friend.name}}</td>\n             <td>{{friend.phone}}</td>\n             <td>{{friend.age}}</td>\n           </tr>\n         </table>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('orderByExample2', [])\n         .controller('ExampleController', ['$scope', function($scope) {\n           var friends = [\n             {name: 'John',   phone: '555-1212',  age: 10},\n             {name: 'Mary',   phone: '555-9876',  age: 19},\n             {name: 'Mike',   phone: '555-4321',  age: 21},\n             {name: 'Adam',   phone: '555-5678',  age: 35},\n             {name: 'Julie',  phone: '555-8765',  age: 29}\n           ];\n\n           $scope.propertyName = 'age';\n           $scope.reverse = true;\n           $scope.friends = friends;\n\n           $scope.sortBy = function(propertyName) {\n             $scope.reverse = ($scope.propertyName === propertyName) ? !$scope.reverse : false;\n             $scope.propertyName = propertyName;\n           };\n         }]);\n     </file>\n     <file name=\"style.css\">\n       .friends {\n         border-collapse: collapse;\n       }\n\n       .friends th {\n         border-bottom: 1px solid;\n       }\n       .friends td, .friends th {\n         border-left: 1px solid;\n         padding: 5px 10px;\n       }\n       .friends td:first-child, .friends th:first-child {\n         border-left: none;\n       }\n\n       .sortorder:after {\n         content: '\\25b2';   // BLACK UP-POINTING TRIANGLE\n       }\n       .sortorder.reverse:after {\n         content: '\\25bc';   // BLACK DOWN-POINTING TRIANGLE\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       // Element locators\n       var unsortButton = element(by.partialButtonText('unsorted'));\n       var nameHeader = element(by.partialButtonText('Name'));\n       var phoneHeader = element(by.partialButtonText('Phone'));\n       var ageHeader = element(by.partialButtonText('Age'));\n       var firstName = element(by.repeater('friends').column('friend.name').row(0));\n       var lastName = element(by.repeater('friends').column('friend.name').row(4));\n\n       it('should sort friends by some property, when clicking on the column header', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         phoneHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Mary');\n\n         nameHeader.click();\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('Mike');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Adam');\n       });\n\n       it('should sort friends in reverse order, when clicking on the same column', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Adam');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n       });\n\n       it('should restore the original order, when clicking \"Set to unsorted\"', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         unsortButton.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Julie');\n       });\n     </file>\n   </example>\n * <hr />\n *\n * @example\n * ### Using `orderBy` inside a controller\n *\n * It is also possible to call the `orderBy` filter manually, by injecting `orderByFilter`, and\n * calling it with the desired parameters. (Alternatively, you could inject the `$filter` factory\n * and retrieve the `orderBy` filter with `$filter('orderBy')`.)\n *\n   <example name=\"orderBy-call-manually\" module=\"orderByExample3\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <pre>Sort by = {{propertyName}}; reverse = {{reverse}}</pre>\n         <hr/>\n         <button ng-click=\"sortBy(null)\">Set to unsorted</button>\n         <hr/>\n         <table class=\"friends\">\n           <tr>\n             <th>\n               <button ng-click=\"sortBy('name')\">Name</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'name'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n             <th>\n               <button ng-click=\"sortBy('phone')\">Phone Number</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'phone'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n             <th>\n               <button ng-click=\"sortBy('age')\">Age</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'age'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n           </tr>\n           <tr ng-repeat=\"friend in friends\">\n             <td>{{friend.name}}</td>\n             <td>{{friend.phone}}</td>\n             <td>{{friend.age}}</td>\n           </tr>\n         </table>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('orderByExample3', [])\n         .controller('ExampleController', ['$scope', 'orderByFilter', function($scope, orderBy) {\n           var friends = [\n             {name: 'John',   phone: '555-1212',  age: 10},\n             {name: 'Mary',   phone: '555-9876',  age: 19},\n             {name: 'Mike',   phone: '555-4321',  age: 21},\n             {name: 'Adam',   phone: '555-5678',  age: 35},\n             {name: 'Julie',  phone: '555-8765',  age: 29}\n           ];\n\n           $scope.propertyName = 'age';\n           $scope.reverse = true;\n           $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse);\n\n           $scope.sortBy = function(propertyName) {\n             $scope.reverse = (propertyName !== null && $scope.propertyName === propertyName)\n                 ? !$scope.reverse : false;\n             $scope.propertyName = propertyName;\n             $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse);\n           };\n         }]);\n     </file>\n     <file name=\"style.css\">\n       .friends {\n         border-collapse: collapse;\n       }\n\n       .friends th {\n         border-bottom: 1px solid;\n       }\n       .friends td, .friends th {\n         border-left: 1px solid;\n         padding: 5px 10px;\n       }\n       .friends td:first-child, .friends th:first-child {\n         border-left: none;\n       }\n\n       .sortorder:after {\n         content: '\\25b2';   // BLACK UP-POINTING TRIANGLE\n       }\n       .sortorder.reverse:after {\n         content: '\\25bc';   // BLACK DOWN-POINTING TRIANGLE\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       // Element locators\n       var unsortButton = element(by.partialButtonText('unsorted'));\n       var nameHeader = element(by.partialButtonText('Name'));\n       var phoneHeader = element(by.partialButtonText('Phone'));\n       var ageHeader = element(by.partialButtonText('Age'));\n       var firstName = element(by.repeater('friends').column('friend.name').row(0));\n       var lastName = element(by.repeater('friends').column('friend.name').row(4));\n\n       it('should sort friends by some property, when clicking on the column header', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         phoneHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Mary');\n\n         nameHeader.click();\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('Mike');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Adam');\n       });\n\n       it('should sort friends in reverse order, when clicking on the same column', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Adam');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n       });\n\n       it('should restore the original order, when clicking \"Set to unsorted\"', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         unsortButton.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Julie');\n       });\n     </file>\n   </example>\n * <hr />\n *\n * @example\n * ### Using a custom comparator\n *\n * If you have very specific requirements about the way items are sorted, you can pass your own\n * comparator function. For example, you might need to compare some strings in a locale-sensitive\n * way. (When specifying a custom comparator, you also need to pass a value for the `reverse`\n * argument - passing `false` retains the default sorting order, i.e. ascending.)\n *\n   <example name=\"orderBy-custom-comparator\" module=\"orderByExample4\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <div class=\"friends-container custom-comparator\">\n           <h3>Locale-sensitive Comparator</h3>\n           <table class=\"friends\">\n             <tr>\n               <th>Name</th>\n               <th>Favorite Letter</th>\n             </tr>\n             <tr ng-repeat=\"friend in friends | orderBy:'favoriteLetter':false:localeSensitiveComparator\">\n               <td>{{friend.name}}</td>\n               <td>{{friend.favoriteLetter}}</td>\n             </tr>\n           </table>\n         </div>\n         <div class=\"friends-container default-comparator\">\n           <h3>Default Comparator</h3>\n           <table class=\"friends\">\n             <tr>\n               <th>Name</th>\n               <th>Favorite Letter</th>\n             </tr>\n             <tr ng-repeat=\"friend in friends | orderBy:'favoriteLetter'\">\n               <td>{{friend.name}}</td>\n               <td>{{friend.favoriteLetter}}</td>\n             </tr>\n           </table>\n         </div>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('orderByExample4', [])\n         .controller('ExampleController', ['$scope', function($scope) {\n           $scope.friends = [\n             {name: 'John',   favoriteLetter: 'Ä'},\n             {name: 'Mary',   favoriteLetter: 'Ü'},\n             {name: 'Mike',   favoriteLetter: 'Ö'},\n             {name: 'Adam',   favoriteLetter: 'H'},\n             {name: 'Julie',  favoriteLetter: 'Z'}\n           ];\n\n           $scope.localeSensitiveComparator = function(v1, v2) {\n             // If we don't get strings, just compare by index\n             if (v1.type !== 'string' || v2.type !== 'string') {\n               return (v1.index < v2.index) ? -1 : 1;\n             }\n\n             // Compare strings alphabetically, taking locale into account\n             return v1.value.localeCompare(v2.value);\n           };\n         }]);\n     </file>\n     <file name=\"style.css\">\n       .friends-container {\n         display: inline-block;\n         margin: 0 30px;\n       }\n\n       .friends {\n         border-collapse: collapse;\n       }\n\n       .friends th {\n         border-bottom: 1px solid;\n       }\n       .friends td, .friends th {\n         border-left: 1px solid;\n         padding: 5px 10px;\n       }\n       .friends td:first-child, .friends th:first-child {\n         border-left: none;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       // Element locators\n       var container = element(by.css('.custom-comparator'));\n       var names = container.all(by.repeater('friends').column('friend.name'));\n\n       it('should sort friends by favorite letter (in correct alphabetical order)', function() {\n         expect(names.get(0).getText()).toBe('John');\n         expect(names.get(1).getText()).toBe('Adam');\n         expect(names.get(2).getText()).toBe('Mike');\n         expect(names.get(3).getText()).toBe('Mary');\n         expect(names.get(4).getText()).toBe('Julie');\n       });\n     </file>\n   </example>\n *\n */\norderByFilter.$inject = ['$parse'];\nfunction orderByFilter($parse) {\n  return function(array, sortPredicate, reverseOrder, compareFn) {\n\n    if (array == null) return array;\n    if (!isArrayLike(array)) {\n      throw minErr('orderBy')('notarray', 'Expected array but received: {0}', array);\n    }\n\n    if (!isArray(sortPredicate)) { sortPredicate = [sortPredicate]; }\n    if (sortPredicate.length === 0) { sortPredicate = ['+']; }\n\n    var predicates = processPredicates(sortPredicate);\n\n    var descending = reverseOrder ? -1 : 1;\n\n    // Define the `compare()` function. Use a default comparator if none is specified.\n    var compare = isFunction(compareFn) ? compareFn : defaultCompare;\n\n    // The next three lines are a version of a Swartzian Transform idiom from Perl\n    // (sometimes called the Decorate-Sort-Undecorate idiom)\n    // See https://en.wikipedia.org/wiki/Schwartzian_transform\n    var compareValues = Array.prototype.map.call(array, getComparisonObject);\n    compareValues.sort(doComparison);\n    array = compareValues.map(function(item) { return item.value; });\n\n    return array;\n\n    function getComparisonObject(value, index) {\n      // NOTE: We are adding an extra `tieBreaker` value based on the element's index.\n      // This will be used to keep the sort stable when none of the input predicates can\n      // distinguish between two elements.\n      return {\n        value: value,\n        tieBreaker: {value: index, type: 'number', index: index},\n        predicateValues: predicates.map(function(predicate) {\n          return getPredicateValue(predicate.get(value), index);\n        })\n      };\n    }\n\n    function doComparison(v1, v2) {\n      for (var i = 0, ii = predicates.length; i < ii; i++) {\n        var result = compare(v1.predicateValues[i], v2.predicateValues[i]);\n        if (result) {\n          return result * predicates[i].descending * descending;\n        }\n      }\n\n      return compare(v1.tieBreaker, v2.tieBreaker) * descending;\n    }\n  };\n\n  function processPredicates(sortPredicates) {\n    return sortPredicates.map(function(predicate) {\n      var descending = 1, get = identity;\n\n      if (isFunction(predicate)) {\n        get = predicate;\n      } else if (isString(predicate)) {\n        if ((predicate.charAt(0) === '+' || predicate.charAt(0) === '-')) {\n          descending = predicate.charAt(0) === '-' ? -1 : 1;\n          predicate = predicate.substring(1);\n        }\n        if (predicate !== '') {\n          get = $parse(predicate);\n          if (get.constant) {\n            var key = get();\n            get = function(value) { return value[key]; };\n          }\n        }\n      }\n      return {get: get, descending: descending};\n    });\n  }\n\n  function isPrimitive(value) {\n    switch (typeof value) {\n      case 'number': /* falls through */\n      case 'boolean': /* falls through */\n      case 'string':\n        return true;\n      default:\n        return false;\n    }\n  }\n\n  function objectValue(value) {\n    // If `valueOf` is a valid function use that\n    if (isFunction(value.valueOf)) {\n      value = value.valueOf();\n      if (isPrimitive(value)) return value;\n    }\n    // If `toString` is a valid function and not the one from `Object.prototype` use that\n    if (hasCustomToString(value)) {\n      value = value.toString();\n      if (isPrimitive(value)) return value;\n    }\n\n    return value;\n  }\n\n  function getPredicateValue(value, index) {\n    var type = typeof value;\n    if (value === null) {\n      type = 'string';\n      value = 'null';\n    } else if (type === 'object') {\n      value = objectValue(value);\n    }\n    return {value: value, type: type, index: index};\n  }\n\n  function defaultCompare(v1, v2) {\n    var result = 0;\n    var type1 = v1.type;\n    var type2 = v2.type;\n\n    if (type1 === type2) {\n      var value1 = v1.value;\n      var value2 = v2.value;\n\n      if (type1 === 'string') {\n        // Compare strings case-insensitively\n        value1 = value1.toLowerCase();\n        value2 = value2.toLowerCase();\n      } else if (type1 === 'object') {\n        // For basic objects, use the position of the object\n        // in the collection instead of the value\n        if (isObject(value1)) value1 = v1.index;\n        if (isObject(value2)) value2 = v2.index;\n      }\n\n      if (value1 !== value2) {\n        result = value1 < value2 ? -1 : 1;\n      }\n    } else {\n      result = type1 < type2 ? -1 : 1;\n    }\n\n    return result;\n  }\n}\n\nfunction ngDirective(directive) {\n  if (isFunction(directive)) {\n    directive = {\n      link: directive\n    };\n  }\n  directive.restrict = directive.restrict || 'AC';\n  return valueFn(directive);\n}\n\n/**\n * @ngdoc directive\n * @name a\n * @restrict E\n *\n * @description\n * Modifies the default behavior of the html a tag so that the default action is prevented when\n * the href attribute is empty.\n *\n * For dynamically creating `href` attributes for a tags, see the {@link ng.ngHref `ngHref`} directive.\n */\nvar htmlAnchorDirective = valueFn({\n  restrict: 'E',\n  compile: function(element, attr) {\n    if (!attr.href && !attr.xlinkHref) {\n      return function(scope, element) {\n        // If the linked element is not an anchor tag anymore, do nothing\n        if (element[0].nodeName.toLowerCase() !== 'a') return;\n\n        // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.\n        var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?\n                   'xlink:href' : 'href';\n        element.on('click', function(event) {\n          // if we have no href url, then don't navigate anywhere.\n          if (!element.attr(href)) {\n            event.preventDefault();\n          }\n        });\n      };\n    }\n  }\n});\n\n/**\n * @ngdoc directive\n * @name ngHref\n * @restrict A\n * @priority 99\n *\n * @description\n * Using Angular markup like `{{hash}}` in an href attribute will\n * make the link go to the wrong URL if the user clicks it before\n * Angular has a chance to replace the `{{hash}}` markup with its\n * value. Until Angular replaces the markup the link will be broken\n * and will most likely return a 404 error. The `ngHref` directive\n * solves this problem.\n *\n * The wrong way to write it:\n * ```html\n * <a href=\"http://www.gravatar.com/avatar/{{hash}}\">link1</a>\n * ```\n *\n * The correct way to write it:\n * ```html\n * <a ng-href=\"http://www.gravatar.com/avatar/{{hash}}\">link1</a>\n * ```\n *\n * @element A\n * @param {template} ngHref any string which can contain `{{}}` markup.\n *\n * @example\n * This example shows various combinations of `href`, `ng-href` and `ng-click` attributes\n * in links and their different behaviors:\n    <example name=\"ng-href\">\n      <file name=\"index.html\">\n        <input ng-model=\"value\" /><br />\n        <a id=\"link-1\" href ng-click=\"value = 1\">link 1</a> (link, don't reload)<br />\n        <a id=\"link-2\" href=\"\" ng-click=\"value = 2\">link 2</a> (link, don't reload)<br />\n        <a id=\"link-3\" ng-href=\"/{{'123'}}\">link 3</a> (link, reload!)<br />\n        <a id=\"link-4\" href=\"\" name=\"xx\" ng-click=\"value = 4\">anchor</a> (link, don't reload)<br />\n        <a id=\"link-5\" name=\"xxx\" ng-click=\"value = 5\">anchor</a> (no link)<br />\n        <a id=\"link-6\" ng-href=\"{{value}}\">link</a> (link, change location)\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should execute ng-click but not reload when href without value', function() {\n          element(by.id('link-1')).click();\n          expect(element(by.model('value')).getAttribute('value')).toEqual('1');\n          expect(element(by.id('link-1')).getAttribute('href')).toBe('');\n        });\n\n        it('should execute ng-click but not reload when href empty string', function() {\n          element(by.id('link-2')).click();\n          expect(element(by.model('value')).getAttribute('value')).toEqual('2');\n          expect(element(by.id('link-2')).getAttribute('href')).toBe('');\n        });\n\n        it('should execute ng-click and change url when ng-href specified', function() {\n          expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\\/123$/);\n\n          element(by.id('link-3')).click();\n\n          // At this point, we navigate away from an Angular page, so we need\n          // to use browser.driver to get the base webdriver.\n\n          browser.wait(function() {\n            return browser.driver.getCurrentUrl().then(function(url) {\n              return url.match(/\\/123$/);\n            });\n          }, 5000, 'page should navigate to /123');\n        });\n\n        it('should execute ng-click but not reload when href empty string and name specified', function() {\n          element(by.id('link-4')).click();\n          expect(element(by.model('value')).getAttribute('value')).toEqual('4');\n          expect(element(by.id('link-4')).getAttribute('href')).toBe('');\n        });\n\n        it('should execute ng-click but not reload when no href but name specified', function() {\n          element(by.id('link-5')).click();\n          expect(element(by.model('value')).getAttribute('value')).toEqual('5');\n          expect(element(by.id('link-5')).getAttribute('href')).toBe(null);\n        });\n\n        it('should only change url when only ng-href', function() {\n          element(by.model('value')).clear();\n          element(by.model('value')).sendKeys('6');\n          expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\\/6$/);\n\n          element(by.id('link-6')).click();\n\n          // At this point, we navigate away from an Angular page, so we need\n          // to use browser.driver to get the base webdriver.\n          browser.wait(function() {\n            return browser.driver.getCurrentUrl().then(function(url) {\n              return url.match(/\\/6$/);\n            });\n          }, 5000, 'page should navigate to /6');\n        });\n      </file>\n    </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngSrc\n * @restrict A\n * @priority 99\n *\n * @description\n * Using Angular markup like `{{hash}}` in a `src` attribute doesn't\n * work right: The browser will fetch from the URL with the literal\n * text `{{hash}}` until Angular replaces the expression inside\n * `{{hash}}`. The `ngSrc` directive solves this problem.\n *\n * The buggy way to write it:\n * ```html\n * <img src=\"http://www.gravatar.com/avatar/{{hash}}\" alt=\"Description\"/>\n * ```\n *\n * The correct way to write it:\n * ```html\n * <img ng-src=\"http://www.gravatar.com/avatar/{{hash}}\" alt=\"Description\" />\n * ```\n *\n * @element IMG\n * @param {template} ngSrc any string which can contain `{{}}` markup.\n */\n\n/**\n * @ngdoc directive\n * @name ngSrcset\n * @restrict A\n * @priority 99\n *\n * @description\n * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't\n * work right: The browser will fetch from the URL with the literal\n * text `{{hash}}` until Angular replaces the expression inside\n * `{{hash}}`. The `ngSrcset` directive solves this problem.\n *\n * The buggy way to write it:\n * ```html\n * <img srcset=\"http://www.gravatar.com/avatar/{{hash}} 2x\" alt=\"Description\"/>\n * ```\n *\n * The correct way to write it:\n * ```html\n * <img ng-srcset=\"http://www.gravatar.com/avatar/{{hash}} 2x\" alt=\"Description\" />\n * ```\n *\n * @element IMG\n * @param {template} ngSrcset any string which can contain `{{}}` markup.\n */\n\n/**\n * @ngdoc directive\n * @name ngDisabled\n * @restrict A\n * @priority 100\n *\n * @description\n *\n * This directive sets the `disabled` attribute on the element (typically a form control,\n * e.g. `input`, `button`, `select` etc.) if the\n * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.\n *\n * A special directive is necessary because we cannot use interpolation inside the `disabled`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * @example\n    <example name=\"ng-disabled\">\n      <file name=\"index.html\">\n        <label>Click me to toggle: <input type=\"checkbox\" ng-model=\"checked\"></label><br/>\n        <button ng-model=\"button\" ng-disabled=\"checked\">Button</button>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should toggle button', function() {\n          expect(element(by.css('button')).getAttribute('disabled')).toBeFalsy();\n          element(by.model('checked')).click();\n          expect(element(by.css('button')).getAttribute('disabled')).toBeTruthy();\n        });\n      </file>\n    </example>\n *\n * @element INPUT\n * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,\n *     then the `disabled` attribute will be set on the element\n */\n\n\n/**\n * @ngdoc directive\n * @name ngChecked\n * @restrict A\n * @priority 100\n *\n * @description\n * Sets the `checked` attribute on the element, if the expression inside `ngChecked` is truthy.\n *\n * Note that this directive should not be used together with {@link ngModel `ngModel`},\n * as this can lead to unexpected behavior.\n *\n * A special directive is necessary because we cannot use interpolation inside the `checked`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * @example\n    <example name=\"ng-checked\">\n      <file name=\"index.html\">\n        <label>Check me to check both: <input type=\"checkbox\" ng-model=\"master\"></label><br/>\n        <input id=\"checkSlave\" type=\"checkbox\" ng-checked=\"master\" aria-label=\"Slave input\">\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should check both checkBoxes', function() {\n          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();\n          element(by.model('master')).click();\n          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();\n        });\n      </file>\n    </example>\n *\n * @element INPUT\n * @param {expression} ngChecked If the {@link guide/expression expression} is truthy,\n *     then the `checked` attribute will be set on the element\n */\n\n\n/**\n * @ngdoc directive\n * @name ngReadonly\n * @restrict A\n * @priority 100\n *\n * @description\n *\n * Sets the `readonly` attribute on the element, if the expression inside `ngReadonly` is truthy.\n * Note that `readonly` applies only to `input` elements with specific types. [See the input docs on\n * MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-readonly) for more information.\n *\n * A special directive is necessary because we cannot use interpolation inside the `readonly`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * @example\n    <example name=\"ng-readonly\">\n      <file name=\"index.html\">\n        <label>Check me to make text readonly: <input type=\"checkbox\" ng-model=\"checked\"></label><br/>\n        <input type=\"text\" ng-readonly=\"checked\" value=\"I'm Angular\" aria-label=\"Readonly field\" />\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should toggle readonly attr', function() {\n          expect(element(by.css('[type=\"text\"]')).getAttribute('readonly')).toBeFalsy();\n          element(by.model('checked')).click();\n          expect(element(by.css('[type=\"text\"]')).getAttribute('readonly')).toBeTruthy();\n        });\n      </file>\n    </example>\n *\n * @element INPUT\n * @param {expression} ngReadonly If the {@link guide/expression expression} is truthy,\n *     then special attribute \"readonly\" will be set on the element\n */\n\n\n/**\n * @ngdoc directive\n * @name ngSelected\n * @restrict A\n * @priority 100\n *\n * @description\n *\n * Sets the `selected` attribute on the element, if the expression inside `ngSelected` is truthy.\n *\n * A special directive is necessary because we cannot use interpolation inside the `selected`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * <div class=\"alert alert-warning\">\n *   **Note:** `ngSelected` does not interact with the `select` and `ngModel` directives, it only\n *   sets the `selected` attribute on the element. If you are using `ngModel` on the select, you\n *   should not use `ngSelected` on the options, as `ngModel` will set the select value and\n *   selected options.\n * </div>\n *\n * @example\n    <example name=\"ng-selected\">\n      <file name=\"index.html\">\n        <label>Check me to select: <input type=\"checkbox\" ng-model=\"selected\"></label><br/>\n        <select aria-label=\"ngSelected demo\">\n          <option>Hello!</option>\n          <option id=\"greet\" ng-selected=\"selected\">Greetings!</option>\n        </select>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should select Greetings!', function() {\n          expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();\n          element(by.model('selected')).click();\n          expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();\n        });\n      </file>\n    </example>\n *\n * @element OPTION\n * @param {expression} ngSelected If the {@link guide/expression expression} is truthy,\n *     then special attribute \"selected\" will be set on the element\n */\n\n/**\n * @ngdoc directive\n * @name ngOpen\n * @restrict A\n * @priority 100\n *\n * @description\n *\n * Sets the `open` attribute on the element, if the expression inside `ngOpen` is truthy.\n *\n * A special directive is necessary because we cannot use interpolation inside the `open`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * ## A note about browser compatibility\n *\n * Edge, Firefox, and Internet Explorer do not support the `details` element, it is\n * recommended to use {@link ng.ngShow} and {@link ng.ngHide} instead.\n *\n * @example\n     <example name=\"ng-open\">\n       <file name=\"index.html\">\n         <label>Check me check multiple: <input type=\"checkbox\" ng-model=\"open\"></label><br/>\n         <details id=\"details\" ng-open=\"open\">\n            <summary>Show/Hide me</summary>\n         </details>\n       </file>\n       <file name=\"protractor.js\" type=\"protractor\">\n         it('should toggle open', function() {\n           expect(element(by.id('details')).getAttribute('open')).toBeFalsy();\n           element(by.model('open')).click();\n           expect(element(by.id('details')).getAttribute('open')).toBeTruthy();\n         });\n       </file>\n     </example>\n *\n * @element DETAILS\n * @param {expression} ngOpen If the {@link guide/expression expression} is truthy,\n *     then special attribute \"open\" will be set on the element\n */\n\nvar ngAttributeAliasDirectives = {};\n\n// boolean attrs are evaluated\nforEach(BOOLEAN_ATTR, function(propName, attrName) {\n  // binding to multiple is not supported\n  if (propName === 'multiple') return;\n\n  function defaultLinkFn(scope, element, attr) {\n    scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {\n      attr.$set(attrName, !!value);\n    });\n  }\n\n  var normalized = directiveNormalize('ng-' + attrName);\n  var linkFn = defaultLinkFn;\n\n  if (propName === 'checked') {\n    linkFn = function(scope, element, attr) {\n      // ensuring ngChecked doesn't interfere with ngModel when both are set on the same input\n      if (attr.ngModel !== attr[normalized]) {\n        defaultLinkFn(scope, element, attr);\n      }\n    };\n  }\n\n  ngAttributeAliasDirectives[normalized] = function() {\n    return {\n      restrict: 'A',\n      priority: 100,\n      link: linkFn\n    };\n  };\n});\n\n// aliased input attrs are evaluated\nforEach(ALIASED_ATTR, function(htmlAttr, ngAttr) {\n  ngAttributeAliasDirectives[ngAttr] = function() {\n    return {\n      priority: 100,\n      link: function(scope, element, attr) {\n        //special case ngPattern when a literal regular expression value\n        //is used as the expression (this way we don't have to watch anything).\n        if (ngAttr === 'ngPattern' && attr.ngPattern.charAt(0) === '/') {\n          var match = attr.ngPattern.match(REGEX_STRING_REGEXP);\n          if (match) {\n            attr.$set('ngPattern', new RegExp(match[1], match[2]));\n            return;\n          }\n        }\n\n        scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {\n          attr.$set(ngAttr, value);\n        });\n      }\n    };\n  };\n});\n\n// ng-src, ng-srcset, ng-href are interpolated\nforEach(['src', 'srcset', 'href'], function(attrName) {\n  var normalized = directiveNormalize('ng-' + attrName);\n  ngAttributeAliasDirectives[normalized] = function() {\n    return {\n      priority: 99, // it needs to run after the attributes are interpolated\n      link: function(scope, element, attr) {\n        var propName = attrName,\n            name = attrName;\n\n        if (attrName === 'href' &&\n            toString.call(element.prop('href')) === '[object SVGAnimatedString]') {\n          name = 'xlinkHref';\n          attr.$attr[name] = 'xlink:href';\n          propName = null;\n        }\n\n        attr.$observe(normalized, function(value) {\n          if (!value) {\n            if (attrName === 'href') {\n              attr.$set(name, null);\n            }\n            return;\n          }\n\n          attr.$set(name, value);\n\n          // Support: IE 9-11 only\n          // On IE, if \"ng:src\" directive declaration is used and \"src\" attribute doesn't exist\n          // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need\n          // to set the property as well to achieve the desired effect.\n          // We use attr[attrName] value since $set can sanitize the url.\n          if (msie && propName) element.prop(propName, attr[name]);\n        });\n      }\n    };\n  };\n});\n\n/* global -nullFormCtrl, -PENDING_CLASS, -SUBMITTED_CLASS\n */\nvar nullFormCtrl = {\n  $addControl: noop,\n  $$renameControl: nullFormRenameControl,\n  $removeControl: noop,\n  $setValidity: noop,\n  $setDirty: noop,\n  $setPristine: noop,\n  $setSubmitted: noop\n},\nPENDING_CLASS = 'ng-pending',\nSUBMITTED_CLASS = 'ng-submitted';\n\nfunction nullFormRenameControl(control, name) {\n  control.$name = name;\n}\n\n/**\n * @ngdoc type\n * @name form.FormController\n *\n * @property {boolean} $pristine True if user has not interacted with the form yet.\n * @property {boolean} $dirty True if user has already interacted with the form.\n * @property {boolean} $valid True if all of the containing forms and controls are valid.\n * @property {boolean} $invalid True if at least one containing control or form is invalid.\n * @property {boolean} $pending True if at least one containing control or form is pending.\n * @property {boolean} $submitted True if user has submitted the form even if its invalid.\n *\n * @property {Object} $error Is an object hash, containing references to controls or\n *  forms with failing validators, where:\n *\n *  - keys are validation tokens (error names),\n *  - values are arrays of controls or forms that have a failing validator for given error name.\n *\n *  Built-in validation tokens:\n *\n *  - `email`\n *  - `max`\n *  - `maxlength`\n *  - `min`\n *  - `minlength`\n *  - `number`\n *  - `pattern`\n *  - `required`\n *  - `url`\n *  - `date`\n *  - `datetimelocal`\n *  - `time`\n *  - `week`\n *  - `month`\n *\n * @description\n * `FormController` keeps track of all its controls and nested forms as well as the state of them,\n * such as being valid/invalid or dirty/pristine.\n *\n * Each {@link ng.directive:form form} directive creates an instance\n * of `FormController`.\n *\n */\n//asks for $scope to fool the BC controller module\nFormController.$inject = ['$element', '$attrs', '$scope', '$animate', '$interpolate'];\nfunction FormController($element, $attrs, $scope, $animate, $interpolate) {\n  this.$$controls = [];\n\n  // init state\n  this.$error = {};\n  this.$$success = {};\n  this.$pending = undefined;\n  this.$name = $interpolate($attrs.name || $attrs.ngForm || '')($scope);\n  this.$dirty = false;\n  this.$pristine = true;\n  this.$valid = true;\n  this.$invalid = false;\n  this.$submitted = false;\n  this.$$parentForm = nullFormCtrl;\n\n  this.$$element = $element;\n  this.$$animate = $animate;\n\n  setupValidity(this);\n}\n\nFormController.prototype = {\n  /**\n   * @ngdoc method\n   * @name form.FormController#$rollbackViewValue\n   *\n   * @description\n   * Rollback all form controls pending updates to the `$modelValue`.\n   *\n   * Updates may be pending by a debounced event or because the input is waiting for a some future\n   * event defined in `ng-model-options`. This method is typically needed by the reset button of\n   * a form that uses `ng-model-options` to pend updates.\n   */\n  $rollbackViewValue: function() {\n    forEach(this.$$controls, function(control) {\n      control.$rollbackViewValue();\n    });\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$commitViewValue\n   *\n   * @description\n   * Commit all form controls pending updates to the `$modelValue`.\n   *\n   * Updates may be pending by a debounced event or because the input is waiting for a some future\n   * event defined in `ng-model-options`. This method is rarely needed as `NgModelController`\n   * usually handles calling this in response to input events.\n   */\n  $commitViewValue: function() {\n    forEach(this.$$controls, function(control) {\n      control.$commitViewValue();\n    });\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$addControl\n   * @param {object} control control object, either a {@link form.FormController} or an\n   * {@link ngModel.NgModelController}\n   *\n   * @description\n   * Register a control with the form. Input elements using ngModelController do this automatically\n   * when they are linked.\n   *\n   * Note that the current state of the control will not be reflected on the new parent form. This\n   * is not an issue with normal use, as freshly compiled and linked controls are in a `$pristine`\n   * state.\n   *\n   * However, if the method is used programmatically, for example by adding dynamically created controls,\n   * or controls that have been previously removed without destroying their corresponding DOM element,\n   * it's the developers responsibility to make sure the current state propagates to the parent form.\n   *\n   * For example, if an input control is added that is already `$dirty` and has `$error` properties,\n   * calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form.\n   */\n  $addControl: function(control) {\n    // Breaking change - before, inputs whose name was \"hasOwnProperty\" were quietly ignored\n    // and not added to the scope.  Now we throw an error.\n    assertNotHasOwnProperty(control.$name, 'input');\n    this.$$controls.push(control);\n\n    if (control.$name) {\n      this[control.$name] = control;\n    }\n\n    control.$$parentForm = this;\n  },\n\n  // Private API: rename a form control\n  $$renameControl: function(control, newName) {\n    var oldName = control.$name;\n\n    if (this[oldName] === control) {\n      delete this[oldName];\n    }\n    this[newName] = control;\n    control.$name = newName;\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$removeControl\n   * @param {object} control control object, either a {@link form.FormController} or an\n   * {@link ngModel.NgModelController}\n   *\n   * @description\n   * Deregister a control from the form.\n   *\n   * Input elements using ngModelController do this automatically when they are destroyed.\n   *\n   * Note that only the removed control's validation state (`$errors`etc.) will be removed from the\n   * form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be\n   * different from case to case. For example, removing the only `$dirty` control from a form may or\n   * may not mean that the form is still `$dirty`.\n   */\n  $removeControl: function(control) {\n    if (control.$name && this[control.$name] === control) {\n      delete this[control.$name];\n    }\n    forEach(this.$pending, function(value, name) {\n      // eslint-disable-next-line no-invalid-this\n      this.$setValidity(name, null, control);\n    }, this);\n    forEach(this.$error, function(value, name) {\n      // eslint-disable-next-line no-invalid-this\n      this.$setValidity(name, null, control);\n    }, this);\n    forEach(this.$$success, function(value, name) {\n      // eslint-disable-next-line no-invalid-this\n      this.$setValidity(name, null, control);\n    }, this);\n\n    arrayRemove(this.$$controls, control);\n    control.$$parentForm = nullFormCtrl;\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$setDirty\n   *\n   * @description\n   * Sets the form to a dirty state.\n   *\n   * This method can be called to add the 'ng-dirty' class and set the form to a dirty\n   * state (ng-dirty class). This method will also propagate to parent forms.\n   */\n  $setDirty: function() {\n    this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);\n    this.$$animate.addClass(this.$$element, DIRTY_CLASS);\n    this.$dirty = true;\n    this.$pristine = false;\n    this.$$parentForm.$setDirty();\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$setPristine\n   *\n   * @description\n   * Sets the form to its pristine state.\n   *\n   * This method sets the form's `$pristine` state to true, the `$dirty` state to false, removes\n   * the `ng-dirty` class and adds the `ng-pristine` class. Additionally, it sets the `$submitted`\n   * state to false.\n   *\n   * This method will also propagate to all the controls contained in this form.\n   *\n   * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after\n   * saving or resetting it.\n   */\n  $setPristine: function() {\n    this.$$animate.setClass(this.$$element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);\n    this.$dirty = false;\n    this.$pristine = true;\n    this.$submitted = false;\n    forEach(this.$$controls, function(control) {\n      control.$setPristine();\n    });\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$setUntouched\n   *\n   * @description\n   * Sets the form to its untouched state.\n   *\n   * This method can be called to remove the 'ng-touched' class and set the form controls to their\n   * untouched state (ng-untouched class).\n   *\n   * Setting a form controls back to their untouched state is often useful when setting the form\n   * back to its pristine state.\n   */\n  $setUntouched: function() {\n    forEach(this.$$controls, function(control) {\n      control.$setUntouched();\n    });\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$setSubmitted\n   *\n   * @description\n   * Sets the form to its submitted state.\n   */\n  $setSubmitted: function() {\n    this.$$animate.addClass(this.$$element, SUBMITTED_CLASS);\n    this.$submitted = true;\n    this.$$parentForm.$setSubmitted();\n  }\n};\n\n/**\n * @ngdoc method\n * @name form.FormController#$setValidity\n *\n * @description\n * Sets the validity of a form control.\n *\n * This method will also propagate to parent forms.\n */\naddSetValidityMethod({\n  clazz: FormController,\n  set: function(object, property, controller) {\n    var list = object[property];\n    if (!list) {\n      object[property] = [controller];\n    } else {\n      var index = list.indexOf(controller);\n      if (index === -1) {\n        list.push(controller);\n      }\n    }\n  },\n  unset: function(object, property, controller) {\n    var list = object[property];\n    if (!list) {\n      return;\n    }\n    arrayRemove(list, controller);\n    if (list.length === 0) {\n      delete object[property];\n    }\n  }\n});\n\n/**\n * @ngdoc directive\n * @name ngForm\n * @restrict EAC\n *\n * @description\n * Nestable alias of {@link ng.directive:form `form`} directive. HTML\n * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a\n * sub-group of controls needs to be determined.\n *\n * Note: the purpose of `ngForm` is to group controls,\n * but not to be a replacement for the `<form>` tag with all of its capabilities\n * (e.g. posting to the server, ...).\n *\n * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into\n *                       related scope, under this name.\n *\n */\n\n /**\n * @ngdoc directive\n * @name form\n * @restrict E\n *\n * @description\n * Directive that instantiates\n * {@link form.FormController FormController}.\n *\n * If the `name` attribute is specified, the form controller is published onto the current scope under\n * this name.\n *\n * # Alias: {@link ng.directive:ngForm `ngForm`}\n *\n * In Angular, forms can be nested. This means that the outer form is valid when all of the child\n * forms are valid as well. However, browsers do not allow nesting of `<form>` elements, so\n * Angular provides the {@link ng.directive:ngForm `ngForm`} directive, which behaves identically to\n * `form` but can be nested. Nested forms can be useful, for example, if the validity of a sub-group\n * of controls needs to be determined.\n *\n * # CSS classes\n *  - `ng-valid` is set if the form is valid.\n *  - `ng-invalid` is set if the form is invalid.\n *  - `ng-pending` is set if the form is pending.\n *  - `ng-pristine` is set if the form is pristine.\n *  - `ng-dirty` is set if the form is dirty.\n *  - `ng-submitted` is set if the form was submitted.\n *\n * Keep in mind that ngAnimate can detect each of these classes when added and removed.\n *\n *\n * # Submitting a form and preventing the default action\n *\n * Since the role of forms in client-side Angular applications is different than in classical\n * roundtrip apps, it is desirable for the browser not to translate the form submission into a full\n * page reload that sends the data to the server. Instead some javascript logic should be triggered\n * to handle the form submission in an application-specific way.\n *\n * For this reason, Angular prevents the default action (form submission to the server) unless the\n * `<form>` element has an `action` attribute specified.\n *\n * You can use one of the following two ways to specify what javascript method should be called when\n * a form is submitted:\n *\n * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element\n * - {@link ng.directive:ngClick ngClick} directive on the first\n  *  button or input field of type submit (input[type=submit])\n *\n * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit}\n * or {@link ng.directive:ngClick ngClick} directives.\n * This is because of the following form submission rules in the HTML specification:\n *\n * - If a form has only one input field then hitting enter in this field triggers form submit\n * (`ngSubmit`)\n * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter\n * doesn't trigger submit\n * - if a form has one or more input fields and one or more buttons or input[type=submit] then\n * hitting enter in any of the input fields will trigger the click handler on the *first* button or\n * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`)\n *\n * Any pending `ngModelOptions` changes will take place immediately when an enclosing form is\n * submitted. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`\n * to have access to the updated model.\n *\n * ## Animation Hooks\n *\n * Animations in ngForm are triggered when any of the associated CSS classes are added and removed.\n * These classes are: `.ng-pristine`, `.ng-dirty`, `.ng-invalid` and `.ng-valid` as well as any\n * other validations that are performed within the form. Animations in ngForm are similar to how\n * they work in ngClass and animations can be hooked into using CSS transitions, keyframes as well\n * as JS animations.\n *\n * The following example shows a simple way to utilize CSS transitions to style a form element\n * that has been rendered as invalid after it has been validated:\n *\n * <pre>\n * //be sure to include ngAnimate as a module to hook into more\n * //advanced animations\n * .my-form {\n *   transition:0.5s linear all;\n *   background: white;\n * }\n * .my-form.ng-invalid {\n *   background: red;\n *   color:white;\n * }\n * </pre>\n *\n * @example\n    <example name=\"ng-form\" deps=\"angular-animate.js\" animations=\"true\" fixBase=\"true\" module=\"formExample\">\n      <file name=\"index.html\">\n       <script>\n         angular.module('formExample', [])\n           .controller('FormController', ['$scope', function($scope) {\n             $scope.userType = 'guest';\n           }]);\n       </script>\n       <style>\n        .my-form {\n          transition:all linear 0.5s;\n          background: transparent;\n        }\n        .my-form.ng-invalid {\n          background: red;\n        }\n       </style>\n       <form name=\"myForm\" ng-controller=\"FormController\" class=\"my-form\">\n         userType: <input name=\"input\" ng-model=\"userType\" required>\n         <span class=\"error\" ng-show=\"myForm.input.$error.required\">Required!</span><br>\n         <code>userType = {{userType}}</code><br>\n         <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br>\n         <code>myForm.input.$error = {{myForm.input.$error}}</code><br>\n         <code>myForm.$valid = {{myForm.$valid}}</code><br>\n         <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br>\n        </form>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should initialize to model', function() {\n          var userType = element(by.binding('userType'));\n          var valid = element(by.binding('myForm.input.$valid'));\n\n          expect(userType.getText()).toContain('guest');\n          expect(valid.getText()).toContain('true');\n        });\n\n        it('should be invalid if empty', function() {\n          var userType = element(by.binding('userType'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var userInput = element(by.model('userType'));\n\n          userInput.clear();\n          userInput.sendKeys('');\n\n          expect(userType.getText()).toEqual('userType =');\n          expect(valid.getText()).toContain('false');\n        });\n      </file>\n    </example>\n *\n * @param {string=} name Name of the form. If specified, the form controller will be published into\n *                       related scope, under this name.\n */\nvar formDirectiveFactory = function(isNgForm) {\n  return ['$timeout', '$parse', function($timeout, $parse) {\n    var formDirective = {\n      name: 'form',\n      restrict: isNgForm ? 'EAC' : 'E',\n      require: ['form', '^^?form'], //first is the form's own ctrl, second is an optional parent form\n      controller: FormController,\n      compile: function ngFormCompile(formElement, attr) {\n        // Setup initial state of the control\n        formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS);\n\n        var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false);\n\n        return {\n          pre: function ngFormPreLink(scope, formElement, attr, ctrls) {\n            var controller = ctrls[0];\n\n            // if `action` attr is not present on the form, prevent the default action (submission)\n            if (!('action' in attr)) {\n              // we can't use jq events because if a form is destroyed during submission the default\n              // action is not prevented. see #1238\n              //\n              // IE 9 is not affected because it doesn't fire a submit event and try to do a full\n              // page reload if the form was destroyed by submission of the form via a click handler\n              // on a button in the form. Looks like an IE9 specific bug.\n              var handleFormSubmission = function(event) {\n                scope.$apply(function() {\n                  controller.$commitViewValue();\n                  controller.$setSubmitted();\n                });\n\n                event.preventDefault();\n              };\n\n              formElement[0].addEventListener('submit', handleFormSubmission);\n\n              // unregister the preventDefault listener so that we don't not leak memory but in a\n              // way that will achieve the prevention of the default action.\n              formElement.on('$destroy', function() {\n                $timeout(function() {\n                  formElement[0].removeEventListener('submit', handleFormSubmission);\n                }, 0, false);\n              });\n            }\n\n            var parentFormCtrl = ctrls[1] || controller.$$parentForm;\n            parentFormCtrl.$addControl(controller);\n\n            var setter = nameAttr ? getSetter(controller.$name) : noop;\n\n            if (nameAttr) {\n              setter(scope, controller);\n              attr.$observe(nameAttr, function(newValue) {\n                if (controller.$name === newValue) return;\n                setter(scope, undefined);\n                controller.$$parentForm.$$renameControl(controller, newValue);\n                setter = getSetter(controller.$name);\n                setter(scope, controller);\n              });\n            }\n            formElement.on('$destroy', function() {\n              controller.$$parentForm.$removeControl(controller);\n              setter(scope, undefined);\n              extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards\n            });\n          }\n        };\n      }\n    };\n\n    return formDirective;\n\n    function getSetter(expression) {\n      if (expression === '') {\n        //create an assignable expression, so forms with an empty name can be renamed later\n        return $parse('this[\"\"]').assign;\n      }\n      return $parse(expression).assign || noop;\n    }\n  }];\n};\n\nvar formDirective = formDirectiveFactory();\nvar ngFormDirective = formDirectiveFactory(true);\n\n\n\n// helper methods\nfunction setupValidity(instance) {\n  instance.$$classCache = {};\n  instance.$$classCache[INVALID_CLASS] = !(instance.$$classCache[VALID_CLASS] = instance.$$element.hasClass(VALID_CLASS));\n}\nfunction addSetValidityMethod(context) {\n  var clazz = context.clazz,\n      set = context.set,\n      unset = context.unset;\n\n  clazz.prototype.$setValidity = function(validationErrorKey, state, controller) {\n    if (isUndefined(state)) {\n      createAndSet(this, '$pending', validationErrorKey, controller);\n    } else {\n      unsetAndCleanup(this, '$pending', validationErrorKey, controller);\n    }\n    if (!isBoolean(state)) {\n      unset(this.$error, validationErrorKey, controller);\n      unset(this.$$success, validationErrorKey, controller);\n    } else {\n      if (state) {\n        unset(this.$error, validationErrorKey, controller);\n        set(this.$$success, validationErrorKey, controller);\n      } else {\n        set(this.$error, validationErrorKey, controller);\n        unset(this.$$success, validationErrorKey, controller);\n      }\n    }\n    if (this.$pending) {\n      cachedToggleClass(this, PENDING_CLASS, true);\n      this.$valid = this.$invalid = undefined;\n      toggleValidationCss(this, '', null);\n    } else {\n      cachedToggleClass(this, PENDING_CLASS, false);\n      this.$valid = isObjectEmpty(this.$error);\n      this.$invalid = !this.$valid;\n      toggleValidationCss(this, '', this.$valid);\n    }\n\n    // re-read the state as the set/unset methods could have\n    // combined state in this.$error[validationError] (used for forms),\n    // where setting/unsetting only increments/decrements the value,\n    // and does not replace it.\n    var combinedState;\n    if (this.$pending && this.$pending[validationErrorKey]) {\n      combinedState = undefined;\n    } else if (this.$error[validationErrorKey]) {\n      combinedState = false;\n    } else if (this.$$success[validationErrorKey]) {\n      combinedState = true;\n    } else {\n      combinedState = null;\n    }\n\n    toggleValidationCss(this, validationErrorKey, combinedState);\n    this.$$parentForm.$setValidity(validationErrorKey, combinedState, this);\n  };\n\n  function createAndSet(ctrl, name, value, controller) {\n    if (!ctrl[name]) {\n      ctrl[name] = {};\n    }\n    set(ctrl[name], value, controller);\n  }\n\n  function unsetAndCleanup(ctrl, name, value, controller) {\n    if (ctrl[name]) {\n      unset(ctrl[name], value, controller);\n    }\n    if (isObjectEmpty(ctrl[name])) {\n      ctrl[name] = undefined;\n    }\n  }\n\n  function cachedToggleClass(ctrl, className, switchValue) {\n    if (switchValue && !ctrl.$$classCache[className]) {\n      ctrl.$$animate.addClass(ctrl.$$element, className);\n      ctrl.$$classCache[className] = true;\n    } else if (!switchValue && ctrl.$$classCache[className]) {\n      ctrl.$$animate.removeClass(ctrl.$$element, className);\n      ctrl.$$classCache[className] = false;\n    }\n  }\n\n  function toggleValidationCss(ctrl, validationErrorKey, isValid) {\n    validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';\n\n    cachedToggleClass(ctrl, VALID_CLASS + validationErrorKey, isValid === true);\n    cachedToggleClass(ctrl, INVALID_CLASS + validationErrorKey, isValid === false);\n  }\n}\n\nfunction isObjectEmpty(obj) {\n  if (obj) {\n    for (var prop in obj) {\n      if (obj.hasOwnProperty(prop)) {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\n/* global\n  VALID_CLASS: false,\n  INVALID_CLASS: false,\n  PRISTINE_CLASS: false,\n  DIRTY_CLASS: false,\n  ngModelMinErr: false\n*/\n\n// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231\nvar ISO_DATE_REGEXP = /^\\d{4,}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+(?:[+-][0-2]\\d:[0-5]\\d|Z)$/;\n// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)\n// Note: We are being more lenient, because browsers are too.\n//   1. Scheme\n//   2. Slashes\n//   3. Username\n//   4. Password\n//   5. Hostname\n//   6. Port\n//   7. Path\n//   8. Query\n//   9. Fragment\n//                 1111111111111111 222   333333    44444        55555555555555555555555     666     77777777     8888888     999\nvar URL_REGEXP = /^[a-z][a-z\\d.+-]*:\\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\\s:/?#]+|\\[[a-f\\d:]+])(?::\\d+)?(?:\\/[^?#]*)?(?:\\?[^#]*)?(?:#.*)?$/i;\n// eslint-disable-next-line max-len\nvar EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;\nvar NUMBER_REGEXP = /^\\s*(-|\\+)?(\\d+|(\\d*(\\.\\d*)))([eE][+-]?\\d+)?\\s*$/;\nvar DATE_REGEXP = /^(\\d{4,})-(\\d{2})-(\\d{2})$/;\nvar DATETIMELOCAL_REGEXP = /^(\\d{4,})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d)(?::(\\d\\d)(\\.\\d{1,3})?)?$/;\nvar WEEK_REGEXP = /^(\\d{4,})-W(\\d\\d)$/;\nvar MONTH_REGEXP = /^(\\d{4,})-(\\d\\d)$/;\nvar TIME_REGEXP = /^(\\d\\d):(\\d\\d)(?::(\\d\\d)(\\.\\d{1,3})?)?$/;\n\nvar PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown';\nvar PARTIAL_VALIDATION_TYPES = createMap();\nforEach('date,datetime-local,month,time,week'.split(','), function(type) {\n  PARTIAL_VALIDATION_TYPES[type] = true;\n});\n\nvar inputType = {\n\n  /**\n   * @ngdoc input\n   * @name input[text]\n   *\n   * @description\n   * Standard HTML text input with angular data binding, inherited by most of the `input` elements.\n   *\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} required Adds `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n   *    minlength.\n   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of\n   *    any length.\n   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string\n   *    that contains the regular expression body that will be converted to a regular expression\n   *    as in the ngPattern directive.\n   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n   *    If the expression evaluates to a RegExp object, then this is used directly.\n   *    If the expression evaluates to a string, then it will be converted to a RegExp\n   *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n   *    `new RegExp('^abc$')`.<br />\n   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n   *    start at the index of the last search's match, thus not taking the whole input value into\n   *    account.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.\n   *    This parameter is ignored for input[type=password] controls, which will never trim the\n   *    input.\n   *\n   * @example\n      <example name=\"text-input-directive\" module=\"textInputExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('textInputExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.example = {\n                 text: 'guest',\n                 word: /^\\s*\\w*\\s*$/\n               };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>Single word:\n             <input type=\"text\" name=\"input\" ng-model=\"example.text\"\n                    ng-pattern=\"example.word\" required ng-trim=\"false\">\n           </label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n               Required!</span>\n             <span class=\"error\" ng-show=\"myForm.input.$error.pattern\">\n               Single word only!</span>\n           </div>\n           <code>text = {{example.text}}</code><br/>\n           <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br/>\n           <code>myForm.input.$error = {{myForm.input.$error}}</code><br/>\n           <code>myForm.$valid = {{myForm.$valid}}</code><br/>\n           <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br/>\n          </form>\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var text = element(by.binding('example.text'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var input = element(by.model('example.text'));\n\n          it('should initialize to model', function() {\n            expect(text.getText()).toContain('guest');\n            expect(valid.getText()).toContain('true');\n          });\n\n          it('should be invalid if empty', function() {\n            input.clear();\n            input.sendKeys('');\n\n            expect(text.getText()).toEqual('text =');\n            expect(valid.getText()).toContain('false');\n          });\n\n          it('should be invalid if multi word', function() {\n            input.clear();\n            input.sendKeys('hello world');\n\n            expect(valid.getText()).toContain('false');\n          });\n        </file>\n      </example>\n   */\n  'text': textInputType,\n\n    /**\n     * @ngdoc input\n     * @name input[date]\n     *\n     * @description\n     * Input with date validation and transformation. In browsers that do not yet support\n     * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601\n     * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many\n     * modern browsers do not yet support this input type, it is important to provide cues to users on the\n     * expected input format via a placeholder or label.\n     *\n     * The model must always be a Date object, otherwise Angular will throw an error.\n     * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n     *\n     * The timezone to be used to read/write the `Date` instance in the model can be defined using\n     * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n     *\n     * @param {string} ngModel Assignable angular expression to data-bind to.\n     * @param {string=} name Property name of the form under which the control is published.\n     * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a\n     *   valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute\n     *   (e.g. `min=\"{{minDate | date:'yyyy-MM-dd'}}\"`). Note that `min` will also add native HTML5\n     *   constraint validation.\n     * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be\n     *   a valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute\n     *   (e.g. `max=\"{{maxDate | date:'yyyy-MM-dd'}}\"`). Note that `max` will also add native HTML5\n     *   constraint validation.\n     * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO date string\n     *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n     * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO date string\n     *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n     * @param {string=} required Sets `required` validation error key if the value is not entered.\n     * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n     *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n     *    `required` when you want to data-bind to the `required` attribute.\n     * @param {string=} ngChange Angular expression to be executed when input changes due to user\n     *    interaction with the input element.\n     *\n     * @example\n     <example name=\"date-input-directive\" module=\"dateInputExample\">\n     <file name=\"index.html\">\n       <script>\n          angular.module('dateInputExample', [])\n            .controller('DateController', ['$scope', function($scope) {\n              $scope.example = {\n                value: new Date(2013, 9, 22)\n              };\n            }]);\n       </script>\n       <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n          <label for=\"exampleInput\">Pick a date in 2013:</label>\n          <input type=\"date\" id=\"exampleInput\" name=\"input\" ng-model=\"example.value\"\n              placeholder=\"yyyy-MM-dd\" min=\"2013-01-01\" max=\"2013-12-31\" required />\n          <div role=\"alert\">\n            <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n                Required!</span>\n            <span class=\"error\" ng-show=\"myForm.input.$error.date\">\n                Not a valid date!</span>\n           </div>\n           <tt>value = {{example.value | date: \"yyyy-MM-dd\"}}</tt><br/>\n           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n       </form>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n        var value = element(by.binding('example.value | date: \"yyyy-MM-dd\"'));\n        var valid = element(by.binding('myForm.input.$valid'));\n\n        // currently protractor/webdriver does not support\n        // sending keys to all known HTML5 input controls\n        // for various browsers (see https://github.com/angular/protractor/issues/562).\n        function setInput(val) {\n          // set the value of the element and force validation.\n          var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n          \"ipt.value = '\" + val + \"';\" +\n          \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n          browser.executeScript(scr);\n        }\n\n        it('should initialize to model', function() {\n          expect(value.getText()).toContain('2013-10-22');\n          expect(valid.getText()).toContain('myForm.input.$valid = true');\n        });\n\n        it('should be invalid if empty', function() {\n          setInput('');\n          expect(value.getText()).toEqual('value =');\n          expect(valid.getText()).toContain('myForm.input.$valid = false');\n        });\n\n        it('should be invalid if over max', function() {\n          setInput('2015-01-01');\n          expect(value.getText()).toContain('');\n          expect(valid.getText()).toContain('myForm.input.$valid = false');\n        });\n     </file>\n     </example>\n     */\n  'date': createDateInputType('date', DATE_REGEXP,\n         createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']),\n         'yyyy-MM-dd'),\n\n   /**\n    * @ngdoc input\n    * @name input[datetime-local]\n    *\n    * @description\n    * Input with datetime validation and transformation. In browsers that do not yet support\n    * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601\n    * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`.\n    *\n    * The model must always be a Date object, otherwise Angular will throw an error.\n    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n    *\n    * The timezone to be used to read/write the `Date` instance in the model can be defined using\n    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n    *\n    * @param {string} ngModel Assignable angular expression to data-bind to.\n    * @param {string=} name Property name of the form under which the control is published.\n    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n    *   This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation\n    *   inside this attribute (e.g. `min=\"{{minDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}\"`).\n    *   Note that `min` will also add native HTML5 constraint validation.\n    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n    *   This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation\n    *   inside this attribute (e.g. `max=\"{{maxDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}\"`).\n    *   Note that `max` will also add native HTML5 constraint validation.\n    * @param {(date|string)=} ngMin Sets the `min` validation error key to the Date / ISO datetime string\n    *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n    * @param {(date|string)=} ngMax Sets the `max` validation error key to the Date / ISO datetime string\n    *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n    * @param {string=} required Sets `required` validation error key if the value is not entered.\n    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n    *    `required` when you want to data-bind to the `required` attribute.\n    * @param {string=} ngChange Angular expression to be executed when input changes due to user\n    *    interaction with the input element.\n    *\n    * @example\n    <example name=\"datetimelocal-input-directive\" module=\"dateExample\">\n    <file name=\"index.html\">\n      <script>\n        angular.module('dateExample', [])\n          .controller('DateController', ['$scope', function($scope) {\n            $scope.example = {\n              value: new Date(2010, 11, 28, 14, 57)\n            };\n          }]);\n      </script>\n      <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n        <label for=\"exampleInput\">Pick a date between in 2013:</label>\n        <input type=\"datetime-local\" id=\"exampleInput\" name=\"input\" ng-model=\"example.value\"\n            placeholder=\"yyyy-MM-ddTHH:mm:ss\" min=\"2001-01-01T00:00:00\" max=\"2013-12-31T00:00:00\" required />\n        <div role=\"alert\">\n          <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n              Required!</span>\n          <span class=\"error\" ng-show=\"myForm.input.$error.datetimelocal\">\n              Not a valid date!</span>\n        </div>\n        <tt>value = {{example.value | date: \"yyyy-MM-ddTHH:mm:ss\"}}</tt><br/>\n        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n      </form>\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var value = element(by.binding('example.value | date: \"yyyy-MM-ddTHH:mm:ss\"'));\n      var valid = element(by.binding('myForm.input.$valid'));\n\n      // currently protractor/webdriver does not support\n      // sending keys to all known HTML5 input controls\n      // for various browsers (https://github.com/angular/protractor/issues/562).\n      function setInput(val) {\n        // set the value of the element and force validation.\n        var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n        \"ipt.value = '\" + val + \"';\" +\n        \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n        browser.executeScript(scr);\n      }\n\n      it('should initialize to model', function() {\n        expect(value.getText()).toContain('2010-12-28T14:57:00');\n        expect(valid.getText()).toContain('myForm.input.$valid = true');\n      });\n\n      it('should be invalid if empty', function() {\n        setInput('');\n        expect(value.getText()).toEqual('value =');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n\n      it('should be invalid if over max', function() {\n        setInput('2015-01-01T23:59:00');\n        expect(value.getText()).toContain('');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n    </file>\n    </example>\n    */\n  'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP,\n      createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']),\n      'yyyy-MM-ddTHH:mm:ss.sss'),\n\n  /**\n   * @ngdoc input\n   * @name input[time]\n   *\n   * @description\n   * Input with time validation and transformation. In browsers that do not yet support\n   * the HTML5 time input, a text element will be used. In that case, the text must be entered in a valid ISO-8601\n   * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a\n   * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`.\n   *\n   * The model must always be a Date object, otherwise Angular will throw an error.\n   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n   *\n   * The timezone to be used to read/write the `Date` instance in the model can be defined using\n   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n   *   This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this\n   *   attribute (e.g. `min=\"{{minTime | date:'HH:mm:ss'}}\"`). Note that `min` will also add\n   *   native HTML5 constraint validation.\n   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n   *   This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this\n   *   attribute (e.g. `max=\"{{maxTime | date:'HH:mm:ss'}}\"`). Note that `max` will also add\n   *   native HTML5 constraint validation.\n   * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO time string the\n   *   `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n   * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO time string the\n   *   `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n   <example name=\"time-input-directive\" module=\"timeExample\">\n   <file name=\"index.html\">\n     <script>\n      angular.module('timeExample', [])\n        .controller('DateController', ['$scope', function($scope) {\n          $scope.example = {\n            value: new Date(1970, 0, 1, 14, 57, 0)\n          };\n        }]);\n     </script>\n     <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n        <label for=\"exampleInput\">Pick a time between 8am and 5pm:</label>\n        <input type=\"time\" id=\"exampleInput\" name=\"input\" ng-model=\"example.value\"\n            placeholder=\"HH:mm:ss\" min=\"08:00:00\" max=\"17:00:00\" required />\n        <div role=\"alert\">\n          <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n              Required!</span>\n          <span class=\"error\" ng-show=\"myForm.input.$error.time\">\n              Not a valid date!</span>\n        </div>\n        <tt>value = {{example.value | date: \"HH:mm:ss\"}}</tt><br/>\n        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n     </form>\n   </file>\n   <file name=\"protractor.js\" type=\"protractor\">\n      var value = element(by.binding('example.value | date: \"HH:mm:ss\"'));\n      var valid = element(by.binding('myForm.input.$valid'));\n\n      // currently protractor/webdriver does not support\n      // sending keys to all known HTML5 input controls\n      // for various browsers (https://github.com/angular/protractor/issues/562).\n      function setInput(val) {\n        // set the value of the element and force validation.\n        var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n        \"ipt.value = '\" + val + \"';\" +\n        \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n        browser.executeScript(scr);\n      }\n\n      it('should initialize to model', function() {\n        expect(value.getText()).toContain('14:57:00');\n        expect(valid.getText()).toContain('myForm.input.$valid = true');\n      });\n\n      it('should be invalid if empty', function() {\n        setInput('');\n        expect(value.getText()).toEqual('value =');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n\n      it('should be invalid if over max', function() {\n        setInput('23:59:00');\n        expect(value.getText()).toContain('');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n   </file>\n   </example>\n   */\n  'time': createDateInputType('time', TIME_REGEXP,\n      createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']),\n     'HH:mm:ss.sss'),\n\n   /**\n    * @ngdoc input\n    * @name input[week]\n    *\n    * @description\n    * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support\n    * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601\n    * week format (yyyy-W##), for example: `2013-W02`.\n    *\n    * The model must always be a Date object, otherwise Angular will throw an error.\n    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n    *\n    * The timezone to be used to read/write the `Date` instance in the model can be defined using\n    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n    *\n    * @param {string} ngModel Assignable angular expression to data-bind to.\n    * @param {string=} name Property name of the form under which the control is published.\n    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n    *   This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this\n    *   attribute (e.g. `min=\"{{minWeek | date:'yyyy-Www'}}\"`). Note that `min` will also add\n    *   native HTML5 constraint validation.\n    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n    *   This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this\n    *   attribute (e.g. `max=\"{{maxWeek | date:'yyyy-Www'}}\"`). Note that `max` will also add\n    *   native HTML5 constraint validation.\n    * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string\n    *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n    * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string\n    *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n    * @param {string=} required Sets `required` validation error key if the value is not entered.\n    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n    *    `required` when you want to data-bind to the `required` attribute.\n    * @param {string=} ngChange Angular expression to be executed when input changes due to user\n    *    interaction with the input element.\n    *\n    * @example\n    <example name=\"week-input-directive\" module=\"weekExample\">\n    <file name=\"index.html\">\n      <script>\n      angular.module('weekExample', [])\n        .controller('DateController', ['$scope', function($scope) {\n          $scope.example = {\n            value: new Date(2013, 0, 3)\n          };\n        }]);\n      </script>\n      <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n        <label>Pick a date between in 2013:\n          <input id=\"exampleInput\" type=\"week\" name=\"input\" ng-model=\"example.value\"\n                 placeholder=\"YYYY-W##\" min=\"2012-W32\"\n                 max=\"2013-W52\" required />\n        </label>\n        <div role=\"alert\">\n          <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n              Required!</span>\n          <span class=\"error\" ng-show=\"myForm.input.$error.week\">\n              Not a valid date!</span>\n        </div>\n        <tt>value = {{example.value | date: \"yyyy-Www\"}}</tt><br/>\n        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n      </form>\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var value = element(by.binding('example.value | date: \"yyyy-Www\"'));\n      var valid = element(by.binding('myForm.input.$valid'));\n\n      // currently protractor/webdriver does not support\n      // sending keys to all known HTML5 input controls\n      // for various browsers (https://github.com/angular/protractor/issues/562).\n      function setInput(val) {\n        // set the value of the element and force validation.\n        var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n        \"ipt.value = '\" + val + \"';\" +\n        \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n        browser.executeScript(scr);\n      }\n\n      it('should initialize to model', function() {\n        expect(value.getText()).toContain('2013-W01');\n        expect(valid.getText()).toContain('myForm.input.$valid = true');\n      });\n\n      it('should be invalid if empty', function() {\n        setInput('');\n        expect(value.getText()).toEqual('value =');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n\n      it('should be invalid if over max', function() {\n        setInput('2015-W01');\n        expect(value.getText()).toContain('');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n    </file>\n    </example>\n    */\n  'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'),\n\n  /**\n   * @ngdoc input\n   * @name input[month]\n   *\n   * @description\n   * Input with month validation and transformation. In browsers that do not yet support\n   * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601\n   * month format (yyyy-MM), for example: `2009-01`.\n   *\n   * The model must always be a Date object, otherwise Angular will throw an error.\n   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n   * If the model is not set to the first of the month, the next view to model update will set it\n   * to the first of the month.\n   *\n   * The timezone to be used to read/write the `Date` instance in the model can be defined using\n   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n   *   This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this\n   *   attribute (e.g. `min=\"{{minMonth | date:'yyyy-MM'}}\"`). Note that `min` will also add\n   *   native HTML5 constraint validation.\n   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n   *   This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this\n   *   attribute (e.g. `max=\"{{maxMonth | date:'yyyy-MM'}}\"`). Note that `max` will also add\n   *   native HTML5 constraint validation.\n   * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string\n   *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n   * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string\n   *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n   <example name=\"month-input-directive\" module=\"monthExample\">\n   <file name=\"index.html\">\n     <script>\n      angular.module('monthExample', [])\n        .controller('DateController', ['$scope', function($scope) {\n          $scope.example = {\n            value: new Date(2013, 9, 1)\n          };\n        }]);\n     </script>\n     <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n       <label for=\"exampleInput\">Pick a month in 2013:</label>\n       <input id=\"exampleInput\" type=\"month\" name=\"input\" ng-model=\"example.value\"\n          placeholder=\"yyyy-MM\" min=\"2013-01\" max=\"2013-12\" required />\n       <div role=\"alert\">\n         <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n            Required!</span>\n         <span class=\"error\" ng-show=\"myForm.input.$error.month\">\n            Not a valid month!</span>\n       </div>\n       <tt>value = {{example.value | date: \"yyyy-MM\"}}</tt><br/>\n       <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n       <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n       <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n       <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n     </form>\n   </file>\n   <file name=\"protractor.js\" type=\"protractor\">\n      var value = element(by.binding('example.value | date: \"yyyy-MM\"'));\n      var valid = element(by.binding('myForm.input.$valid'));\n\n      // currently protractor/webdriver does not support\n      // sending keys to all known HTML5 input controls\n      // for various browsers (https://github.com/angular/protractor/issues/562).\n      function setInput(val) {\n        // set the value of the element and force validation.\n        var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n        \"ipt.value = '\" + val + \"';\" +\n        \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n        browser.executeScript(scr);\n      }\n\n      it('should initialize to model', function() {\n        expect(value.getText()).toContain('2013-10');\n        expect(valid.getText()).toContain('myForm.input.$valid = true');\n      });\n\n      it('should be invalid if empty', function() {\n        setInput('');\n        expect(value.getText()).toEqual('value =');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n\n      it('should be invalid if over max', function() {\n        setInput('2015-01');\n        expect(value.getText()).toContain('');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n   </file>\n   </example>\n   */\n  'month': createDateInputType('month', MONTH_REGEXP,\n     createDateParser(MONTH_REGEXP, ['yyyy', 'MM']),\n     'yyyy-MM'),\n\n  /**\n   * @ngdoc input\n   * @name input[number]\n   *\n   * @description\n   * Text input with number validation and transformation. Sets the `number` validation\n   * error if not a valid number.\n   *\n   * <div class=\"alert alert-warning\">\n   * The model must always be of type `number` otherwise Angular will throw an error.\n   * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt}\n   * error docs for more information and an example of how to convert your model if necessary.\n   * </div>\n   *\n   * ## Issues with HTML5 constraint validation\n   *\n   * In browsers that follow the\n   * [HTML5 specification](https://html.spec.whatwg.org/multipage/forms.html#number-state-%28type=number%29),\n   * `input[number]` does not work as expected with {@link ngModelOptions `ngModelOptions.allowInvalid`}.\n   * If a non-number is entered in the input, the browser will report the value as an empty string,\n   * which means the view / model values in `ngModel` and subsequently the scope value\n   * will also be an empty string.\n   *\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n   *    Can be interpolated.\n   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n   *    Can be interpolated.\n   * @param {string=} ngMin Like `min`, sets the `min` validation error key if the value entered is less than `ngMin`,\n   *    but does not trigger HTML5 native validation. Takes an expression.\n   * @param {string=} ngMax Like `max`, sets the `max` validation error key if the value entered is greater than `ngMax`,\n   *    but does not trigger HTML5 native validation. Takes an expression.\n   * @param {string=} step Sets the `step` validation error key if the value entered does not fit the `step` constraint.\n   *    Can be interpolated.\n   * @param {string=} ngStep Like `step`, sets the `step` validation error key if the value entered does not fit the `ngStep` constraint,\n   *    but does not trigger HTML5 native validation. Takes an expression.\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n   *    minlength.\n   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of\n   *    any length.\n   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string\n   *    that contains the regular expression body that will be converted to a regular expression\n   *    as in the ngPattern directive.\n   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n   *    If the expression evaluates to a RegExp object, then this is used directly.\n   *    If the expression evaluates to a string, then it will be converted to a RegExp\n   *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n   *    `new RegExp('^abc$')`.<br />\n   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n   *    start at the index of the last search's match, thus not taking the whole input value into\n   *    account.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n      <example name=\"number-input-directive\" module=\"numberExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('numberExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.example = {\n                 value: 12\n               };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>Number:\n             <input type=\"number\" name=\"input\" ng-model=\"example.value\"\n                    min=\"0\" max=\"99\" required>\n          </label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n               Required!</span>\n             <span class=\"error\" ng-show=\"myForm.input.$error.number\">\n               Not valid number!</span>\n           </div>\n           <tt>value = {{example.value}}</tt><br/>\n           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n          </form>\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var value = element(by.binding('example.value'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var input = element(by.model('example.value'));\n\n          it('should initialize to model', function() {\n            expect(value.getText()).toContain('12');\n            expect(valid.getText()).toContain('true');\n          });\n\n          it('should be invalid if empty', function() {\n            input.clear();\n            input.sendKeys('');\n            expect(value.getText()).toEqual('value =');\n            expect(valid.getText()).toContain('false');\n          });\n\n          it('should be invalid if over max', function() {\n            input.clear();\n            input.sendKeys('123');\n            expect(value.getText()).toEqual('value =');\n            expect(valid.getText()).toContain('false');\n          });\n        </file>\n      </example>\n   */\n  'number': numberInputType,\n\n\n  /**\n   * @ngdoc input\n   * @name input[url]\n   *\n   * @description\n   * Text input with URL validation. Sets the `url` validation error key if the content is not a\n   * valid URL.\n   *\n   * <div class=\"alert alert-warning\">\n   * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex\n   * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify\n   * the built-in validators (see the {@link guide/forms Forms guide})\n   * </div>\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n   *    minlength.\n   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of\n   *    any length.\n   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string\n   *    that contains the regular expression body that will be converted to a regular expression\n   *    as in the ngPattern directive.\n   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n   *    If the expression evaluates to a RegExp object, then this is used directly.\n   *    If the expression evaluates to a string, then it will be converted to a RegExp\n   *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n   *    `new RegExp('^abc$')`.<br />\n   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n   *    start at the index of the last search's match, thus not taking the whole input value into\n   *    account.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n      <example name=\"url-input-directive\" module=\"urlExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('urlExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.url = {\n                 text: 'http://google.com'\n               };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>URL:\n             <input type=\"url\" name=\"input\" ng-model=\"url.text\" required>\n           <label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n               Required!</span>\n             <span class=\"error\" ng-show=\"myForm.input.$error.url\">\n               Not valid url!</span>\n           </div>\n           <tt>text = {{url.text}}</tt><br/>\n           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n           <tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>\n          </form>\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var text = element(by.binding('url.text'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var input = element(by.model('url.text'));\n\n          it('should initialize to model', function() {\n            expect(text.getText()).toContain('http://google.com');\n            expect(valid.getText()).toContain('true');\n          });\n\n          it('should be invalid if empty', function() {\n            input.clear();\n            input.sendKeys('');\n\n            expect(text.getText()).toEqual('text =');\n            expect(valid.getText()).toContain('false');\n          });\n\n          it('should be invalid if not url', function() {\n            input.clear();\n            input.sendKeys('box');\n\n            expect(valid.getText()).toContain('false');\n          });\n        </file>\n      </example>\n   */\n  'url': urlInputType,\n\n\n  /**\n   * @ngdoc input\n   * @name input[email]\n   *\n   * @description\n   * Text input with email validation. Sets the `email` validation error key if not a valid email\n   * address.\n   *\n   * <div class=\"alert alert-warning\">\n   * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex\n   * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can\n   * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide})\n   * </div>\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n   *    minlength.\n   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of\n   *    any length.\n   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string\n   *    that contains the regular expression body that will be converted to a regular expression\n   *    as in the ngPattern directive.\n   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n   *    If the expression evaluates to a RegExp object, then this is used directly.\n   *    If the expression evaluates to a string, then it will be converted to a RegExp\n   *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n   *    `new RegExp('^abc$')`.<br />\n   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n   *    start at the index of the last search's match, thus not taking the whole input value into\n   *    account.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n      <example name=\"email-input-directive\" module=\"emailExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('emailExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.email = {\n                 text: 'me@example.com'\n               };\n             }]);\n         </script>\n           <form name=\"myForm\" ng-controller=\"ExampleController\">\n             <label>Email:\n               <input type=\"email\" name=\"input\" ng-model=\"email.text\" required>\n             </label>\n             <div role=\"alert\">\n               <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n                 Required!</span>\n               <span class=\"error\" ng-show=\"myForm.input.$error.email\">\n                 Not valid email!</span>\n             </div>\n             <tt>text = {{email.text}}</tt><br/>\n             <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n             <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n             <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n             <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n             <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>\n           </form>\n         </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var text = element(by.binding('email.text'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var input = element(by.model('email.text'));\n\n          it('should initialize to model', function() {\n            expect(text.getText()).toContain('me@example.com');\n            expect(valid.getText()).toContain('true');\n          });\n\n          it('should be invalid if empty', function() {\n            input.clear();\n            input.sendKeys('');\n            expect(text.getText()).toEqual('text =');\n            expect(valid.getText()).toContain('false');\n          });\n\n          it('should be invalid if not email', function() {\n            input.clear();\n            input.sendKeys('xxx');\n\n            expect(valid.getText()).toContain('false');\n          });\n        </file>\n      </example>\n   */\n  'email': emailInputType,\n\n\n  /**\n   * @ngdoc input\n   * @name input[radio]\n   *\n   * @description\n   * HTML radio button.\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string} value The value to which the `ngModel` expression should be set when selected.\n   *    Note that `value` only supports `string` values, i.e. the scope model needs to be a string,\n   *    too. Use `ngValue` if you need complex models (`number`, `object`, ...).\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   * @param {string} ngValue Angular expression to which `ngModel` will be be set when the radio\n   *    is selected. Should be used instead of the `value` attribute if you need\n   *    a non-string `ngModel` (`boolean`, `array`, ...).\n   *\n   * @example\n      <example name=\"radio-input-directive\" module=\"radioExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('radioExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.color = {\n                 name: 'blue'\n               };\n               $scope.specialValue = {\n                 \"id\": \"12345\",\n                 \"value\": \"green\"\n               };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>\n             <input type=\"radio\" ng-model=\"color.name\" value=\"red\">\n             Red\n           </label><br/>\n           <label>\n             <input type=\"radio\" ng-model=\"color.name\" ng-value=\"specialValue\">\n             Green\n           </label><br/>\n           <label>\n             <input type=\"radio\" ng-model=\"color.name\" value=\"blue\">\n             Blue\n           </label><br/>\n           <tt>color = {{color.name | json}}</tt><br/>\n          </form>\n          Note that `ng-value=\"specialValue\"` sets radio item's value to be the value of `$scope.specialValue`.\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          it('should change state', function() {\n            var inputs = element.all(by.model('color.name'));\n            var color = element(by.binding('color.name'));\n\n            expect(color.getText()).toContain('blue');\n\n            inputs.get(0).click();\n            expect(color.getText()).toContain('red');\n\n            inputs.get(1).click();\n            expect(color.getText()).toContain('green');\n          });\n        </file>\n      </example>\n   */\n  'radio': radioInputType,\n\n  /**\n   * @ngdoc input\n   * @name input[range]\n   *\n   * @description\n   * Native range input with validation and transformation.\n   *\n   * The model for the range input must always be a `Number`.\n   *\n   * IE9 and other browsers that do not support the `range` type fall back\n   * to a text input without any default values for `min`, `max` and `step`. Model binding,\n   * validation and number parsing are nevertheless supported.\n   *\n   * Browsers that support range (latest Chrome, Safari, Firefox, Edge) treat `input[range]`\n   * in a way that never allows the input to hold an invalid value. That means:\n   * - any non-numerical value is set to `(max + min) / 2`.\n   * - any numerical value that is less than the current min val, or greater than the current max val\n   * is set to the min / max val respectively.\n   * - additionally, the current `step` is respected, so the nearest value that satisfies a step\n   * is used.\n   *\n   * See the [HTML Spec on input[type=range]](https://www.w3.org/TR/html5/forms.html#range-state-(type=range))\n   * for more info.\n   *\n   * This has the following consequences for Angular:\n   *\n   * Since the element value should always reflect the current model value, a range input\n   * will set the bound ngModel expression to the value that the browser has set for the\n   * input element. For example, in the following input `<input type=\"range\" ng-model=\"model.value\">`,\n   * if the application sets `model.value = null`, the browser will set the input to `'50'`.\n   * Angular will then set the model to `50`, to prevent input and model value being out of sync.\n   *\n   * That means the model for range will immediately be set to `50` after `ngModel` has been\n   * initialized. It also means a range input can never have the required error.\n   *\n   * This does not only affect changes to the model value, but also to the values of the `min`,\n   * `max`, and `step` attributes. When these change in a way that will cause the browser to modify\n   * the input value, Angular will also update the model value.\n   *\n   * Automatic value adjustment also means that a range input element can never have the `required`,\n   * `min`, or `max` errors.\n   *\n   * However, `step` is currently only fully implemented by Firefox. Other browsers have problems\n   * when the step value changes dynamically - they do not adjust the element value correctly, but\n   * instead may set the `stepMismatch` error. If that's the case, the Angular will set the `step`\n   * error on the input, and set the model to `undefined`.\n   *\n   * Note that `input[range]` is not compatible with`ngMax`, `ngMin`, and `ngStep`, because they do\n   * not set the `min` and `max` attributes, which means that the browser won't automatically adjust\n   * the input value based on their values, and will always assume min = 0, max = 100, and step = 1.\n   *\n   * @param {string}  ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} min Sets the `min` validation to ensure that the value entered is greater\n   *                  than `min`. Can be interpolated.\n   * @param {string=} max Sets the `max` validation to ensure that the value entered is less than `max`.\n   *                  Can be interpolated.\n   * @param {string=} step Sets the `step` validation to ensure that the value entered matches the `step`\n   *                  Can be interpolated.\n   * @param {string=} ngChange Angular expression to be executed when the ngModel value changes due\n   *                  to user interaction with the input element.\n   * @param {expression=} ngChecked If the expression is truthy, then the `checked` attribute will be set on the\n   *                      element. **Note** : `ngChecked` should not be used alongside `ngModel`.\n   *                      Checkout {@link ng.directive:ngChecked ngChecked} for usage.\n   *\n   * @example\n      <example name=\"range-input-directive\" module=\"rangeExample\">\n        <file name=\"index.html\">\n          <script>\n            angular.module('rangeExample', [])\n              .controller('ExampleController', ['$scope', function($scope) {\n                $scope.value = 75;\n                $scope.min = 10;\n                $scope.max = 90;\n              }]);\n          </script>\n          <form name=\"myForm\" ng-controller=\"ExampleController\">\n\n            Model as range: <input type=\"range\" name=\"range\" ng-model=\"value\" min=\"{{min}}\"  max=\"{{max}}\">\n            <hr>\n            Model as number: <input type=\"number\" ng-model=\"value\"><br>\n            Min: <input type=\"number\" ng-model=\"min\"><br>\n            Max: <input type=\"number\" ng-model=\"max\"><br>\n            value = <code>{{value}}</code><br/>\n            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>\n            myForm.range.$error = <code>{{myForm.range.$error}}</code>\n          </form>\n        </file>\n      </example>\n\n   * ## Range Input with ngMin & ngMax attributes\n\n   * @example\n      <example name=\"range-input-directive-ng\" module=\"rangeExample\">\n        <file name=\"index.html\">\n          <script>\n            angular.module('rangeExample', [])\n              .controller('ExampleController', ['$scope', function($scope) {\n                $scope.value = 75;\n                $scope.min = 10;\n                $scope.max = 90;\n              }]);\n          </script>\n          <form name=\"myForm\" ng-controller=\"ExampleController\">\n            Model as range: <input type=\"range\" name=\"range\" ng-model=\"value\" ng-min=\"min\" ng-max=\"max\">\n            <hr>\n            Model as number: <input type=\"number\" ng-model=\"value\"><br>\n            Min: <input type=\"number\" ng-model=\"min\"><br>\n            Max: <input type=\"number\" ng-model=\"max\"><br>\n            value = <code>{{value}}</code><br/>\n            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>\n            myForm.range.$error = <code>{{myForm.range.$error}}</code>\n          </form>\n        </file>\n      </example>\n\n   */\n  'range': rangeInputType,\n\n  /**\n   * @ngdoc input\n   * @name input[checkbox]\n   *\n   * @description\n   * HTML checkbox.\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {expression=} ngTrueValue The value to which the expression should be set when selected.\n   * @param {expression=} ngFalseValue The value to which the expression should be set when not selected.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n      <example name=\"checkbox-input-directive\" module=\"checkboxExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('checkboxExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.checkboxModel = {\n                value1 : true,\n                value2 : 'YES'\n              };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>Value1:\n             <input type=\"checkbox\" ng-model=\"checkboxModel.value1\">\n           </label><br/>\n           <label>Value2:\n             <input type=\"checkbox\" ng-model=\"checkboxModel.value2\"\n                    ng-true-value=\"'YES'\" ng-false-value=\"'NO'\">\n            </label><br/>\n           <tt>value1 = {{checkboxModel.value1}}</tt><br/>\n           <tt>value2 = {{checkboxModel.value2}}</tt><br/>\n          </form>\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          it('should change state', function() {\n            var value1 = element(by.binding('checkboxModel.value1'));\n            var value2 = element(by.binding('checkboxModel.value2'));\n\n            expect(value1.getText()).toContain('true');\n            expect(value2.getText()).toContain('YES');\n\n            element(by.model('checkboxModel.value1')).click();\n            element(by.model('checkboxModel.value2')).click();\n\n            expect(value1.getText()).toContain('false');\n            expect(value2.getText()).toContain('NO');\n          });\n        </file>\n      </example>\n   */\n  'checkbox': checkboxInputType,\n\n  'hidden': noop,\n  'button': noop,\n  'submit': noop,\n  'reset': noop,\n  'file': noop\n};\n\nfunction stringBasedInputType(ctrl) {\n  ctrl.$formatters.push(function(value) {\n    return ctrl.$isEmpty(value) ? value : value.toString();\n  });\n}\n\nfunction textInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n  stringBasedInputType(ctrl);\n}\n\nfunction baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  var type = lowercase(element[0].type);\n\n  // In composition mode, users are still inputting intermediate text buffer,\n  // hold the listener until composition is done.\n  // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent\n  if (!$sniffer.android) {\n    var composing = false;\n\n    element.on('compositionstart', function() {\n      composing = true;\n    });\n\n    element.on('compositionend', function() {\n      composing = false;\n      listener();\n    });\n  }\n\n  var timeout;\n\n  var listener = function(ev) {\n    if (timeout) {\n      $browser.defer.cancel(timeout);\n      timeout = null;\n    }\n    if (composing) return;\n    var value = element.val(),\n        event = ev && ev.type;\n\n    // By default we will trim the value\n    // If the attribute ng-trim exists we will avoid trimming\n    // If input type is 'password', the value is never trimmed\n    if (type !== 'password' && (!attr.ngTrim || attr.ngTrim !== 'false')) {\n      value = trim(value);\n    }\n\n    // If a control is suffering from bad input (due to native validators), browsers discard its\n    // value, so it may be necessary to revalidate (by calling $setViewValue again) even if the\n    // control's value is the same empty value twice in a row.\n    if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {\n      ctrl.$setViewValue(value, event);\n    }\n  };\n\n  // if the browser does support \"input\" event, we are fine - except on IE9 which doesn't fire the\n  // input event on backspace, delete or cut\n  if ($sniffer.hasEvent('input')) {\n    element.on('input', listener);\n  } else {\n    var deferListener = function(ev, input, origValue) {\n      if (!timeout) {\n        timeout = $browser.defer(function() {\n          timeout = null;\n          if (!input || input.value !== origValue) {\n            listener(ev);\n          }\n        });\n      }\n    };\n\n    element.on('keydown', /** @this */ function(event) {\n      var key = event.keyCode;\n\n      // ignore\n      //    command            modifiers                   arrows\n      if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;\n\n      deferListener(event, this, this.value);\n    });\n\n    // if user modifies input value using context menu in IE, we need \"paste\" and \"cut\" events to catch it\n    if ($sniffer.hasEvent('paste')) {\n      element.on('paste cut', deferListener);\n    }\n  }\n\n  // if user paste into input using mouse on older browser\n  // or form autocomplete on newer browser, we need \"change\" event to catch it\n  element.on('change', listener);\n\n  // Some native input types (date-family) have the ability to change validity without\n  // firing any input/change events.\n  // For these event types, when native validators are present and the browser supports the type,\n  // check for validity changes on various DOM events.\n  if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) {\n    element.on(PARTIAL_VALIDATION_EVENTS, /** @this */ function(ev) {\n      if (!timeout) {\n        var validity = this[VALIDITY_STATE_PROPERTY];\n        var origBadInput = validity.badInput;\n        var origTypeMismatch = validity.typeMismatch;\n        timeout = $browser.defer(function() {\n          timeout = null;\n          if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) {\n            listener(ev);\n          }\n        });\n      }\n    });\n  }\n\n  ctrl.$render = function() {\n    // Workaround for Firefox validation #12102.\n    var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue;\n    if (element.val() !== value) {\n      element.val(value);\n    }\n  };\n}\n\nfunction weekParser(isoWeek, existingDate) {\n  if (isDate(isoWeek)) {\n    return isoWeek;\n  }\n\n  if (isString(isoWeek)) {\n    WEEK_REGEXP.lastIndex = 0;\n    var parts = WEEK_REGEXP.exec(isoWeek);\n    if (parts) {\n      var year = +parts[1],\n          week = +parts[2],\n          hours = 0,\n          minutes = 0,\n          seconds = 0,\n          milliseconds = 0,\n          firstThurs = getFirstThursdayOfYear(year),\n          addDays = (week - 1) * 7;\n\n      if (existingDate) {\n        hours = existingDate.getHours();\n        minutes = existingDate.getMinutes();\n        seconds = existingDate.getSeconds();\n        milliseconds = existingDate.getMilliseconds();\n      }\n\n      return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds);\n    }\n  }\n\n  return NaN;\n}\n\nfunction createDateParser(regexp, mapping) {\n  return function(iso, date) {\n    var parts, map;\n\n    if (isDate(iso)) {\n      return iso;\n    }\n\n    if (isString(iso)) {\n      // When a date is JSON'ified to wraps itself inside of an extra\n      // set of double quotes. This makes the date parsing code unable\n      // to match the date string and parse it as a date.\n      if (iso.charAt(0) === '\"' && iso.charAt(iso.length - 1) === '\"') {\n        iso = iso.substring(1, iso.length - 1);\n      }\n      if (ISO_DATE_REGEXP.test(iso)) {\n        return new Date(iso);\n      }\n      regexp.lastIndex = 0;\n      parts = regexp.exec(iso);\n\n      if (parts) {\n        parts.shift();\n        if (date) {\n          map = {\n            yyyy: date.getFullYear(),\n            MM: date.getMonth() + 1,\n            dd: date.getDate(),\n            HH: date.getHours(),\n            mm: date.getMinutes(),\n            ss: date.getSeconds(),\n            sss: date.getMilliseconds() / 1000\n          };\n        } else {\n          map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 };\n        }\n\n        forEach(parts, function(part, index) {\n          if (index < mapping.length) {\n            map[mapping[index]] = +part;\n          }\n        });\n        return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0);\n      }\n    }\n\n    return NaN;\n  };\n}\n\nfunction createDateInputType(type, regexp, parseDate, format) {\n  return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {\n    badInputChecker(scope, element, attr, ctrl);\n    baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n    var timezone = ctrl && ctrl.$options.getOption('timezone');\n    var previousDate;\n\n    ctrl.$$parserName = type;\n    ctrl.$parsers.push(function(value) {\n      if (ctrl.$isEmpty(value)) return null;\n      if (regexp.test(value)) {\n        // Note: We cannot read ctrl.$modelValue, as there might be a different\n        // parser/formatter in the processing chain so that the model\n        // contains some different data format!\n        var parsedDate = parseDate(value, previousDate);\n        if (timezone) {\n          parsedDate = convertTimezoneToLocal(parsedDate, timezone);\n        }\n        return parsedDate;\n      }\n      return undefined;\n    });\n\n    ctrl.$formatters.push(function(value) {\n      if (value && !isDate(value)) {\n        throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);\n      }\n      if (isValidDate(value)) {\n        previousDate = value;\n        if (previousDate && timezone) {\n          previousDate = convertTimezoneToLocal(previousDate, timezone, true);\n        }\n        return $filter('date')(value, format, timezone);\n      } else {\n        previousDate = null;\n        return '';\n      }\n    });\n\n    if (isDefined(attr.min) || attr.ngMin) {\n      var minVal;\n      ctrl.$validators.min = function(value) {\n        return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal;\n      };\n      attr.$observe('min', function(val) {\n        minVal = parseObservedDateValue(val);\n        ctrl.$validate();\n      });\n    }\n\n    if (isDefined(attr.max) || attr.ngMax) {\n      var maxVal;\n      ctrl.$validators.max = function(value) {\n        return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;\n      };\n      attr.$observe('max', function(val) {\n        maxVal = parseObservedDateValue(val);\n        ctrl.$validate();\n      });\n    }\n\n    function isValidDate(value) {\n      // Invalid Date: getTime() returns NaN\n      return value && !(value.getTime && value.getTime() !== value.getTime());\n    }\n\n    function parseObservedDateValue(val) {\n      return isDefined(val) && !isDate(val) ? parseDate(val) || undefined : val;\n    }\n  };\n}\n\nfunction badInputChecker(scope, element, attr, ctrl) {\n  var node = element[0];\n  var nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity);\n  if (nativeValidation) {\n    ctrl.$parsers.push(function(value) {\n      var validity = element.prop(VALIDITY_STATE_PROPERTY) || {};\n      return validity.badInput || validity.typeMismatch ? undefined : value;\n    });\n  }\n}\n\nfunction numberFormatterParser(ctrl) {\n  ctrl.$$parserName = 'number';\n  ctrl.$parsers.push(function(value) {\n    if (ctrl.$isEmpty(value))      return null;\n    if (NUMBER_REGEXP.test(value)) return parseFloat(value);\n    return undefined;\n  });\n\n  ctrl.$formatters.push(function(value) {\n    if (!ctrl.$isEmpty(value)) {\n      if (!isNumber(value)) {\n        throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value);\n      }\n      value = value.toString();\n    }\n    return value;\n  });\n}\n\nfunction parseNumberAttrVal(val) {\n  if (isDefined(val) && !isNumber(val)) {\n    val = parseFloat(val);\n  }\n  return !isNumberNaN(val) ? val : undefined;\n}\n\nfunction isNumberInteger(num) {\n  // See http://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript#14794066\n  // (minus the assumption that `num` is a number)\n\n  // eslint-disable-next-line no-bitwise\n  return (num | 0) === num;\n}\n\nfunction countDecimals(num) {\n  var numString = num.toString();\n  var decimalSymbolIndex = numString.indexOf('.');\n\n  if (decimalSymbolIndex === -1) {\n    if (-1 < num && num < 1) {\n      // It may be in the exponential notation format (`1e-X`)\n      var match = /e-(\\d+)$/.exec(numString);\n\n      if (match) {\n        return Number(match[1]);\n      }\n    }\n\n    return 0;\n  }\n\n  return numString.length - decimalSymbolIndex - 1;\n}\n\nfunction isValidForStep(viewValue, stepBase, step) {\n  // At this point `stepBase` and `step` are expected to be non-NaN values\n  // and `viewValue` is expected to be a valid stringified number.\n  var value = Number(viewValue);\n\n  var isNonIntegerValue = !isNumberInteger(value);\n  var isNonIntegerStepBase = !isNumberInteger(stepBase);\n  var isNonIntegerStep = !isNumberInteger(step);\n\n  // Due to limitations in Floating Point Arithmetic (e.g. `0.3 - 0.2 !== 0.1` or\n  // `0.5 % 0.1 !== 0`), we need to convert all numbers to integers.\n  if (isNonIntegerValue || isNonIntegerStepBase || isNonIntegerStep) {\n    var valueDecimals = isNonIntegerValue ? countDecimals(value) : 0;\n    var stepBaseDecimals = isNonIntegerStepBase ? countDecimals(stepBase) : 0;\n    var stepDecimals = isNonIntegerStep ? countDecimals(step) : 0;\n\n    var decimalCount = Math.max(valueDecimals, stepBaseDecimals, stepDecimals);\n    var multiplier = Math.pow(10, decimalCount);\n\n    value = value * multiplier;\n    stepBase = stepBase * multiplier;\n    step = step * multiplier;\n\n    if (isNonIntegerValue) value = Math.round(value);\n    if (isNonIntegerStepBase) stepBase = Math.round(stepBase);\n    if (isNonIntegerStep) step = Math.round(step);\n  }\n\n  return (value - stepBase) % step === 0;\n}\n\nfunction numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  badInputChecker(scope, element, attr, ctrl);\n  numberFormatterParser(ctrl);\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n\n  var minVal;\n  var maxVal;\n\n  if (isDefined(attr.min) || attr.ngMin) {\n    ctrl.$validators.min = function(value) {\n      return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;\n    };\n\n    attr.$observe('min', function(val) {\n      minVal = parseNumberAttrVal(val);\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    });\n  }\n\n  if (isDefined(attr.max) || attr.ngMax) {\n    ctrl.$validators.max = function(value) {\n      return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;\n    };\n\n    attr.$observe('max', function(val) {\n      maxVal = parseNumberAttrVal(val);\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    });\n  }\n\n  if (isDefined(attr.step) || attr.ngStep) {\n    var stepVal;\n    ctrl.$validators.step = function(modelValue, viewValue) {\n      return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) ||\n             isValidForStep(viewValue, minVal || 0, stepVal);\n    };\n\n    attr.$observe('step', function(val) {\n      stepVal = parseNumberAttrVal(val);\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    });\n  }\n}\n\nfunction rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  badInputChecker(scope, element, attr, ctrl);\n  numberFormatterParser(ctrl);\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n\n  var supportsRange = ctrl.$$hasNativeValidators && element[0].type === 'range',\n      minVal = supportsRange ? 0 : undefined,\n      maxVal = supportsRange ? 100 : undefined,\n      stepVal = supportsRange ? 1 : undefined,\n      validity = element[0].validity,\n      hasMinAttr = isDefined(attr.min),\n      hasMaxAttr = isDefined(attr.max),\n      hasStepAttr = isDefined(attr.step);\n\n  var originalRender = ctrl.$render;\n\n  ctrl.$render = supportsRange && isDefined(validity.rangeUnderflow) && isDefined(validity.rangeOverflow) ?\n    //Browsers that implement range will set these values automatically, but reading the adjusted values after\n    //$render would cause the min / max validators to be applied with the wrong value\n    function rangeRender() {\n      originalRender();\n      ctrl.$setViewValue(element.val());\n    } :\n    originalRender;\n\n  if (hasMinAttr) {\n    ctrl.$validators.min = supportsRange ?\n      // Since all browsers set the input to a valid value, we don't need to check validity\n      function noopMinValidator() { return true; } :\n      // non-support browsers validate the min val\n      function minValidator(modelValue, viewValue) {\n        return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal;\n      };\n\n    setInitialValueAndObserver('min', minChange);\n  }\n\n  if (hasMaxAttr) {\n    ctrl.$validators.max = supportsRange ?\n      // Since all browsers set the input to a valid value, we don't need to check validity\n      function noopMaxValidator() { return true; } :\n      // non-support browsers validate the max val\n      function maxValidator(modelValue, viewValue) {\n        return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal;\n      };\n\n    setInitialValueAndObserver('max', maxChange);\n  }\n\n  if (hasStepAttr) {\n    ctrl.$validators.step = supportsRange ?\n      function nativeStepValidator() {\n        // Currently, only FF implements the spec on step change correctly (i.e. adjusting the\n        // input element value to a valid value). It's possible that other browsers set the stepMismatch\n        // validity error instead, so we can at least report an error in that case.\n        return !validity.stepMismatch;\n      } :\n      // ngStep doesn't set the setp attr, so the browser doesn't adjust the input value as setting step would\n      function stepValidator(modelValue, viewValue) {\n        return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) ||\n               isValidForStep(viewValue, minVal || 0, stepVal);\n      };\n\n    setInitialValueAndObserver('step', stepChange);\n  }\n\n  function setInitialValueAndObserver(htmlAttrName, changeFn) {\n    // interpolated attributes set the attribute value only after a digest, but we need the\n    // attribute value when the input is first rendered, so that the browser can adjust the\n    // input value based on the min/max value\n    element.attr(htmlAttrName, attr[htmlAttrName]);\n    attr.$observe(htmlAttrName, changeFn);\n  }\n\n  function minChange(val) {\n    minVal = parseNumberAttrVal(val);\n    // ignore changes before model is initialized\n    if (isNumberNaN(ctrl.$modelValue)) {\n      return;\n    }\n\n    if (supportsRange) {\n      var elVal = element.val();\n      // IE11 doesn't set the el val correctly if the minVal is greater than the element value\n      if (minVal > elVal) {\n        elVal = minVal;\n        element.val(elVal);\n      }\n      ctrl.$setViewValue(elVal);\n    } else {\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    }\n  }\n\n  function maxChange(val) {\n    maxVal = parseNumberAttrVal(val);\n    // ignore changes before model is initialized\n    if (isNumberNaN(ctrl.$modelValue)) {\n      return;\n    }\n\n    if (supportsRange) {\n      var elVal = element.val();\n      // IE11 doesn't set the el val correctly if the maxVal is less than the element value\n      if (maxVal < elVal) {\n        element.val(maxVal);\n        // IE11 and Chrome don't set the value to the minVal when max < min\n        elVal = maxVal < minVal ? minVal : maxVal;\n      }\n      ctrl.$setViewValue(elVal);\n    } else {\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    }\n  }\n\n  function stepChange(val) {\n    stepVal = parseNumberAttrVal(val);\n    // ignore changes before model is initialized\n    if (isNumberNaN(ctrl.$modelValue)) {\n      return;\n    }\n\n    // Some browsers don't adjust the input value correctly, but set the stepMismatch error\n    if (supportsRange && ctrl.$viewValue !== element.val()) {\n      ctrl.$setViewValue(element.val());\n    } else {\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    }\n  }\n}\n\nfunction urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  // Note: no badInputChecker here by purpose as `url` is only a validation\n  // in browsers, i.e. we can always read out input.value even if it is not valid!\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n  stringBasedInputType(ctrl);\n\n  ctrl.$$parserName = 'url';\n  ctrl.$validators.url = function(modelValue, viewValue) {\n    var value = modelValue || viewValue;\n    return ctrl.$isEmpty(value) || URL_REGEXP.test(value);\n  };\n}\n\nfunction emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  // Note: no badInputChecker here by purpose as `url` is only a validation\n  // in browsers, i.e. we can always read out input.value even if it is not valid!\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n  stringBasedInputType(ctrl);\n\n  ctrl.$$parserName = 'email';\n  ctrl.$validators.email = function(modelValue, viewValue) {\n    var value = modelValue || viewValue;\n    return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);\n  };\n}\n\nfunction radioInputType(scope, element, attr, ctrl) {\n  var doTrim = !attr.ngTrim || trim(attr.ngTrim) !== 'false';\n  // make the name unique, if not defined\n  if (isUndefined(attr.name)) {\n    element.attr('name', nextUid());\n  }\n\n  var listener = function(ev) {\n    var value;\n    if (element[0].checked) {\n      value = attr.value;\n      if (doTrim) {\n        value = trim(value);\n      }\n      ctrl.$setViewValue(value, ev && ev.type);\n    }\n  };\n\n  element.on('click', listener);\n\n  ctrl.$render = function() {\n    var value = attr.value;\n    if (doTrim) {\n      value = trim(value);\n    }\n    element[0].checked = (value === ctrl.$viewValue);\n  };\n\n  attr.$observe('value', ctrl.$render);\n}\n\nfunction parseConstantExpr($parse, context, name, expression, fallback) {\n  var parseFn;\n  if (isDefined(expression)) {\n    parseFn = $parse(expression);\n    if (!parseFn.constant) {\n      throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' +\n                                   '`{1}`.', name, expression);\n    }\n    return parseFn(context);\n  }\n  return fallback;\n}\n\nfunction checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {\n  var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true);\n  var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);\n\n  var listener = function(ev) {\n    ctrl.$setViewValue(element[0].checked, ev && ev.type);\n  };\n\n  element.on('click', listener);\n\n  ctrl.$render = function() {\n    element[0].checked = ctrl.$viewValue;\n  };\n\n  // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false`\n  // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert\n  // it to a boolean.\n  ctrl.$isEmpty = function(value) {\n    return value === false;\n  };\n\n  ctrl.$formatters.push(function(value) {\n    return equals(value, trueValue);\n  });\n\n  ctrl.$parsers.push(function(value) {\n    return value ? trueValue : falseValue;\n  });\n}\n\n\n/**\n * @ngdoc directive\n * @name textarea\n * @restrict E\n *\n * @description\n * HTML textarea element control with angular data-binding. The data-binding and validation\n * properties of this element are exactly the same as those of the\n * {@link ng.directive:input input element}.\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} name Property name of the form under which the control is published.\n * @param {string=} required Sets `required` validation error key if the value is not entered.\n * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n *    `required` when you want to data-bind to the `required` attribute.\n * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n *    minlength.\n * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any\n *    length.\n * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n *    If the expression evaluates to a RegExp object, then this is used directly.\n *    If the expression evaluates to a string, then it will be converted to a RegExp\n *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n *    `new RegExp('^abc$')`.<br />\n *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n *    start at the index of the last search's match, thus not taking the whole input value into\n *    account.\n * @param {string=} ngChange Angular expression to be executed when input changes due to user\n *    interaction with the input element.\n * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.\n *\n * @knownIssue\n *\n * When specifying the `placeholder` attribute of `<textarea>`, Internet Explorer will temporarily\n * insert the placeholder value as the textarea's content. If the placeholder value contains\n * interpolation (`{{ ... }}`), an error will be logged in the console when Angular tries to update\n * the value of the by-then-removed text node. This doesn't affect the functionality of the\n * textarea, but can be undesirable.\n *\n * You can work around this Internet Explorer issue by using `ng-attr-placeholder` instead of\n * `placeholder` on textareas, whenever you need interpolation in the placeholder value. You can\n * find more details on `ngAttr` in the\n * [Interpolation](guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes) section of the\n * Developer Guide.\n */\n\n\n/**\n * @ngdoc directive\n * @name input\n * @restrict E\n *\n * @description\n * HTML input element control. When used together with {@link ngModel `ngModel`}, it provides data-binding,\n * input state control, and validation.\n * Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Not every feature offered is available for all input types.\n * Specifically, data binding and event handling via `ng-model` is unsupported for `input[file]`.\n * </div>\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} name Property name of the form under which the control is published.\n * @param {string=} required Sets `required` validation error key if the value is not entered.\n * @param {boolean=} ngRequired Sets `required` attribute if set to true\n * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n *    minlength.\n * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any\n *    length.\n * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n *    value does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n *    If the expression evaluates to a RegExp object, then this is used directly.\n *    If the expression evaluates to a string, then it will be converted to a RegExp\n *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n *    `new RegExp('^abc$')`.<br />\n *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n *    start at the index of the last search's match, thus not taking the whole input value into\n *    account.\n * @param {string=} ngChange Angular expression to be executed when input changes due to user\n *    interaction with the input element.\n * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.\n *    This parameter is ignored for input[type=password] controls, which will never trim the\n *    input.\n *\n * @example\n    <example name=\"input-directive\" module=\"inputExample\">\n      <file name=\"index.html\">\n       <script>\n          angular.module('inputExample', [])\n            .controller('ExampleController', ['$scope', function($scope) {\n              $scope.user = {name: 'guest', last: 'visitor'};\n            }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <form name=\"myForm\">\n           <label>\n              User name:\n              <input type=\"text\" name=\"userName\" ng-model=\"user.name\" required>\n           </label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.userName.$error.required\">\n              Required!</span>\n           </div>\n           <label>\n              Last name:\n              <input type=\"text\" name=\"lastName\" ng-model=\"user.last\"\n              ng-minlength=\"3\" ng-maxlength=\"10\">\n           </label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.lastName.$error.minlength\">\n               Too short!</span>\n             <span class=\"error\" ng-show=\"myForm.lastName.$error.maxlength\">\n               Too long!</span>\n           </div>\n         </form>\n         <hr>\n         <tt>user = {{user}}</tt><br/>\n         <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br/>\n         <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br/>\n         <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br/>\n         <tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br/>\n         <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n         <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n         <tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br/>\n         <tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br/>\n       </div>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        var user = element(by.exactBinding('user'));\n        var userNameValid = element(by.binding('myForm.userName.$valid'));\n        var lastNameValid = element(by.binding('myForm.lastName.$valid'));\n        var lastNameError = element(by.binding('myForm.lastName.$error'));\n        var formValid = element(by.binding('myForm.$valid'));\n        var userNameInput = element(by.model('user.name'));\n        var userLastInput = element(by.model('user.last'));\n\n        it('should initialize to model', function() {\n          expect(user.getText()).toContain('{\"name\":\"guest\",\"last\":\"visitor\"}');\n          expect(userNameValid.getText()).toContain('true');\n          expect(formValid.getText()).toContain('true');\n        });\n\n        it('should be invalid if empty when required', function() {\n          userNameInput.clear();\n          userNameInput.sendKeys('');\n\n          expect(user.getText()).toContain('{\"last\":\"visitor\"}');\n          expect(userNameValid.getText()).toContain('false');\n          expect(formValid.getText()).toContain('false');\n        });\n\n        it('should be valid if empty when min length is set', function() {\n          userLastInput.clear();\n          userLastInput.sendKeys('');\n\n          expect(user.getText()).toContain('{\"name\":\"guest\",\"last\":\"\"}');\n          expect(lastNameValid.getText()).toContain('true');\n          expect(formValid.getText()).toContain('true');\n        });\n\n        it('should be invalid if less than required min length', function() {\n          userLastInput.clear();\n          userLastInput.sendKeys('xx');\n\n          expect(user.getText()).toContain('{\"name\":\"guest\"}');\n          expect(lastNameValid.getText()).toContain('false');\n          expect(lastNameError.getText()).toContain('minlength');\n          expect(formValid.getText()).toContain('false');\n        });\n\n        it('should be invalid if longer than max length', function() {\n          userLastInput.clear();\n          userLastInput.sendKeys('some ridiculously long name');\n\n          expect(user.getText()).toContain('{\"name\":\"guest\"}');\n          expect(lastNameValid.getText()).toContain('false');\n          expect(lastNameError.getText()).toContain('maxlength');\n          expect(formValid.getText()).toContain('false');\n        });\n      </file>\n    </example>\n */\nvar inputDirective = ['$browser', '$sniffer', '$filter', '$parse',\n    function($browser, $sniffer, $filter, $parse) {\n  return {\n    restrict: 'E',\n    require: ['?ngModel'],\n    link: {\n      pre: function(scope, element, attr, ctrls) {\n        if (ctrls[0]) {\n          (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer,\n                                                              $browser, $filter, $parse);\n        }\n      }\n    }\n  };\n}];\n\n\n\nvar CONSTANT_VALUE_REGEXP = /^(true|false|\\d+)$/;\n/**\n * @ngdoc directive\n * @name ngValue\n *\n * @description\n * Binds the given expression to the value of the element.\n *\n * It is mainly used on {@link input[radio] `input[radio]`} and option elements,\n * so that when the element is selected, the {@link ngModel `ngModel`} of that element (or its\n * {@link select `select`} parent element) is set to the bound value. It is especially useful\n * for dynamically generated lists using {@link ngRepeat `ngRepeat`}, as shown below.\n *\n * It can also be used to achieve one-way binding of a given expression to an input element\n * such as an `input[text]` or a `textarea`, when that element does not use ngModel.\n *\n * @element input\n * @param {string=} ngValue angular expression, whose value will be bound to the `value` attribute\n * and `value` property of the element.\n *\n * @example\n    <example name=\"ngValue-directive\" module=\"valueExample\">\n      <file name=\"index.html\">\n       <script>\n          angular.module('valueExample', [])\n            .controller('ExampleController', ['$scope', function($scope) {\n              $scope.names = ['pizza', 'unicorns', 'robots'];\n              $scope.my = { favorite: 'unicorns' };\n            }]);\n       </script>\n        <form ng-controller=\"ExampleController\">\n          <h2>Which is your favorite?</h2>\n            <label ng-repeat=\"name in names\" for=\"{{name}}\">\n              {{name}}\n              <input type=\"radio\"\n                     ng-model=\"my.favorite\"\n                     ng-value=\"name\"\n                     id=\"{{name}}\"\n                     name=\"favorite\">\n            </label>\n          <div>You chose {{my.favorite}}</div>\n        </form>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        var favorite = element(by.binding('my.favorite'));\n\n        it('should initialize to model', function() {\n          expect(favorite.getText()).toContain('unicorns');\n        });\n        it('should bind the values to the inputs', function() {\n          element.all(by.model('my.favorite')).get(0).click();\n          expect(favorite.getText()).toContain('pizza');\n        });\n      </file>\n    </example>\n */\nvar ngValueDirective = function() {\n  /**\n   *  inputs use the value attribute as their default value if the value property is not set.\n   *  Once the value property has been set (by adding input), it will not react to changes to\n   *  the value attribute anymore. Setting both attribute and property fixes this behavior, and\n   *  makes it possible to use ngValue as a sort of one-way bind.\n   */\n  function updateElementValue(element, attr, value) {\n    // Support: IE9 only\n    // In IE9 values are converted to string (e.g. `input.value = null` results in `input.value === 'null'`).\n    var propValue = isDefined(value) ? value : (msie === 9) ? '' : null;\n    element.prop('value', propValue);\n    attr.$set('value', value);\n  }\n\n  return {\n    restrict: 'A',\n    priority: 100,\n    compile: function(tpl, tplAttr) {\n      if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {\n        return function ngValueConstantLink(scope, elm, attr) {\n          var value = scope.$eval(attr.ngValue);\n          updateElementValue(elm, attr, value);\n        };\n      } else {\n        return function ngValueLink(scope, elm, attr) {\n          scope.$watch(attr.ngValue, function valueWatchAction(value) {\n            updateElementValue(elm, attr, value);\n          });\n        };\n      }\n    }\n  };\n};\n\n/**\n * @ngdoc directive\n * @name ngBind\n * @restrict AC\n *\n * @description\n * The `ngBind` attribute tells Angular to replace the text content of the specified HTML element\n * with the value of a given expression, and to update the text content when the value of that\n * expression changes.\n *\n * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like\n * `{{ expression }}` which is similar but less verbose.\n *\n * It is preferable to use `ngBind` instead of `{{ expression }}` if a template is momentarily\n * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an\n * element attribute, it makes the bindings invisible to the user while the page is loading.\n *\n * An alternative solution to this problem would be using the\n * {@link ng.directive:ngCloak ngCloak} directive.\n *\n *\n * @element ANY\n * @param {expression} ngBind {@link guide/expression Expression} to evaluate.\n *\n * @example\n * Enter a name in the Live Preview text box; the greeting below the text box changes instantly.\n   <example module=\"bindExample\" name=\"ng-bind\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('bindExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.name = 'Whirled';\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <label>Enter name: <input type=\"text\" ng-model=\"name\"></label><br>\n         Hello <span ng-bind=\"name\"></span>!\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-bind', function() {\n         var nameInput = element(by.model('name'));\n\n         expect(element(by.binding('name')).getText()).toBe('Whirled');\n         nameInput.clear();\n         nameInput.sendKeys('world');\n         expect(element(by.binding('name')).getText()).toBe('world');\n       });\n     </file>\n   </example>\n */\nvar ngBindDirective = ['$compile', function($compile) {\n  return {\n    restrict: 'AC',\n    compile: function ngBindCompile(templateElement) {\n      $compile.$$addBindingClass(templateElement);\n      return function ngBindLink(scope, element, attr) {\n        $compile.$$addBindingInfo(element, attr.ngBind);\n        element = element[0];\n        scope.$watch(attr.ngBind, function ngBindWatchAction(value) {\n          element.textContent = stringify(value);\n        });\n      };\n    }\n  };\n}];\n\n\n/**\n * @ngdoc directive\n * @name ngBindTemplate\n *\n * @description\n * The `ngBindTemplate` directive specifies that the element\n * text content should be replaced with the interpolation of the template\n * in the `ngBindTemplate` attribute.\n * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`\n * expressions. This directive is needed since some HTML elements\n * (such as TITLE and OPTION) cannot contain SPAN elements.\n *\n * @element ANY\n * @param {string} ngBindTemplate template of form\n *   <tt>{{</tt> <tt>expression</tt> <tt>}}</tt> to eval.\n *\n * @example\n * Try it here: enter text in text box and watch the greeting change.\n   <example module=\"bindExample\" name=\"ng-bind-template\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('bindExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.salutation = 'Hello';\n             $scope.name = 'World';\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n        <label>Salutation: <input type=\"text\" ng-model=\"salutation\"></label><br>\n        <label>Name: <input type=\"text\" ng-model=\"name\"></label><br>\n        <pre ng-bind-template=\"{{salutation}} {{name}}!\"></pre>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-bind', function() {\n         var salutationElem = element(by.binding('salutation'));\n         var salutationInput = element(by.model('salutation'));\n         var nameInput = element(by.model('name'));\n\n         expect(salutationElem.getText()).toBe('Hello World!');\n\n         salutationInput.clear();\n         salutationInput.sendKeys('Greetings');\n         nameInput.clear();\n         nameInput.sendKeys('user');\n\n         expect(salutationElem.getText()).toBe('Greetings user!');\n       });\n     </file>\n   </example>\n */\nvar ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate, $compile) {\n  return {\n    compile: function ngBindTemplateCompile(templateElement) {\n      $compile.$$addBindingClass(templateElement);\n      return function ngBindTemplateLink(scope, element, attr) {\n        var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate));\n        $compile.$$addBindingInfo(element, interpolateFn.expressions);\n        element = element[0];\n        attr.$observe('ngBindTemplate', function(value) {\n          element.textContent = isUndefined(value) ? '' : value;\n        });\n      };\n    }\n  };\n}];\n\n\n/**\n * @ngdoc directive\n * @name ngBindHtml\n *\n * @description\n * Evaluates the expression and inserts the resulting HTML into the element in a secure way. By default,\n * the resulting HTML content will be sanitized using the {@link ngSanitize.$sanitize $sanitize} service.\n * To utilize this functionality, ensure that `$sanitize` is available, for example, by including {@link\n * ngSanitize} in your module's dependencies (not in core Angular). In order to use {@link ngSanitize}\n * in your module's dependencies, you need to include \"angular-sanitize.js\" in your application.\n *\n * You may also bypass sanitization for values you know are safe. To do so, bind to\n * an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}.  See the example\n * under {@link ng.$sce#show-me-an-example-using-sce- Strict Contextual Escaping (SCE)}.\n *\n * Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you\n * will have an exception (instead of an exploit.)\n *\n * @element ANY\n * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.\n *\n * @example\n\n   <example module=\"bindHtmlExample\" deps=\"angular-sanitize.js\" name=\"ng-bind-html\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n        <p ng-bind-html=\"myHTML\"></p>\n       </div>\n     </file>\n\n     <file name=\"script.js\">\n       angular.module('bindHtmlExample', ['ngSanitize'])\n         .controller('ExampleController', ['$scope', function($scope) {\n           $scope.myHTML =\n              'I am an <code>HTML</code>string with ' +\n              '<a href=\"#\">links!</a> and other <em>stuff</em>';\n         }]);\n     </file>\n\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-bind-html', function() {\n         expect(element(by.binding('myHTML')).getText()).toBe(\n             'I am an HTMLstring with links! and other stuff');\n       });\n     </file>\n   </example>\n */\nvar ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {\n  return {\n    restrict: 'A',\n    compile: function ngBindHtmlCompile(tElement, tAttrs) {\n      var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);\n      var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function sceValueOf(val) {\n        // Unwrap the value to compare the actual inner safe value, not the wrapper object.\n        return $sce.valueOf(val);\n      });\n      $compile.$$addBindingClass(tElement);\n\n      return function ngBindHtmlLink(scope, element, attr) {\n        $compile.$$addBindingInfo(element, attr.ngBindHtml);\n\n        scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {\n          // The watched value is the unwrapped value. To avoid re-escaping, use the direct getter.\n          var value = ngBindHtmlGetter(scope);\n          element.html($sce.getTrustedHtml(value) || '');\n        });\n      };\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngChange\n *\n * @description\n * Evaluate the given expression when the user changes the input.\n * The expression is evaluated immediately, unlike the JavaScript onchange event\n * which only triggers at the end of a change (usually, when the user leaves the\n * form element or presses the return key).\n *\n * The `ngChange` expression is only evaluated when a change in the input value causes\n * a new value to be committed to the model.\n *\n * It will not be evaluated:\n * * if the value returned from the `$parsers` transformation pipeline has not changed\n * * if the input has continued to be invalid since the model will stay `null`\n * * if the model is changed programmatically and not by a change to the input value\n *\n *\n * Note, this directive requires `ngModel` to be present.\n *\n * @element input\n * @param {expression} ngChange {@link guide/expression Expression} to evaluate upon change\n * in input value.\n *\n * @example\n * <example name=\"ngChange-directive\" module=\"changeExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('changeExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.counter = 0;\n *           $scope.change = function() {\n *             $scope.counter++;\n *           };\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <input type=\"checkbox\" ng-model=\"confirmed\" ng-change=\"change()\" id=\"ng-change-example1\" />\n *       <input type=\"checkbox\" ng-model=\"confirmed\" id=\"ng-change-example2\" />\n *       <label for=\"ng-change-example2\">Confirmed</label><br />\n *       <tt>debug = {{confirmed}}</tt><br/>\n *       <tt>counter = {{counter}}</tt><br/>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     var counter = element(by.binding('counter'));\n *     var debug = element(by.binding('confirmed'));\n *\n *     it('should evaluate the expression if changing from view', function() {\n *       expect(counter.getText()).toContain('0');\n *\n *       element(by.id('ng-change-example1')).click();\n *\n *       expect(counter.getText()).toContain('1');\n *       expect(debug.getText()).toContain('true');\n *     });\n *\n *     it('should not evaluate the expression if changing from model', function() {\n *       element(by.id('ng-change-example2')).click();\n\n *       expect(counter.getText()).toContain('0');\n *       expect(debug.getText()).toContain('true');\n *     });\n *   </file>\n * </example>\n */\nvar ngChangeDirective = valueFn({\n  restrict: 'A',\n  require: 'ngModel',\n  link: function(scope, element, attr, ctrl) {\n    ctrl.$viewChangeListeners.push(function() {\n      scope.$eval(attr.ngChange);\n    });\n  }\n});\n\n/* exported\n  ngClassDirective,\n  ngClassEvenDirective,\n  ngClassOddDirective\n*/\n\nfunction classDirective(name, selector) {\n  name = 'ngClass' + name;\n  var indexWatchExpression;\n\n  return ['$parse', function($parse) {\n    return {\n      restrict: 'AC',\n      link: function(scope, element, attr) {\n        var expression = attr[name].trim();\n        var isOneTime = (expression.charAt(0) === ':') && (expression.charAt(1) === ':');\n\n        var watchInterceptor = isOneTime ? toFlatValue : toClassString;\n        var watchExpression = $parse(expression, watchInterceptor);\n        var watchAction = isOneTime ? ngClassOneTimeWatchAction : ngClassWatchAction;\n\n        var classCounts = element.data('$classCounts');\n        var oldModulo = true;\n        var oldClassString;\n\n        if (!classCounts) {\n          // Use createMap() to prevent class assumptions involving property\n          // names in Object.prototype\n          classCounts = createMap();\n          element.data('$classCounts', classCounts);\n        }\n\n        if (name !== 'ngClass') {\n          if (!indexWatchExpression) {\n            indexWatchExpression = $parse('$index', function moduloTwo($index) {\n              // eslint-disable-next-line no-bitwise\n              return $index & 1;\n            });\n          }\n\n          scope.$watch(indexWatchExpression, ngClassIndexWatchAction);\n        }\n\n        scope.$watch(watchExpression, watchAction, isOneTime);\n\n        function addClasses(classString) {\n          classString = digestClassCounts(split(classString), 1);\n          attr.$addClass(classString);\n        }\n\n        function removeClasses(classString) {\n          classString = digestClassCounts(split(classString), -1);\n          attr.$removeClass(classString);\n        }\n\n        function updateClasses(oldClassString, newClassString) {\n          var oldClassArray = split(oldClassString);\n          var newClassArray = split(newClassString);\n\n          var toRemoveArray = arrayDifference(oldClassArray, newClassArray);\n          var toAddArray = arrayDifference(newClassArray, oldClassArray);\n\n          var toRemoveString = digestClassCounts(toRemoveArray, -1);\n          var toAddString = digestClassCounts(toAddArray, 1);\n\n          attr.$addClass(toAddString);\n          attr.$removeClass(toRemoveString);\n        }\n\n        function digestClassCounts(classArray, count) {\n          var classesToUpdate = [];\n\n          forEach(classArray, function(className) {\n            if (count > 0 || classCounts[className]) {\n              classCounts[className] = (classCounts[className] || 0) + count;\n              if (classCounts[className] === +(count > 0)) {\n                classesToUpdate.push(className);\n              }\n            }\n          });\n\n          return classesToUpdate.join(' ');\n        }\n\n        function ngClassIndexWatchAction(newModulo) {\n          // This watch-action should run before the `ngClass[OneTime]WatchAction()`, thus it\n          // adds/removes `oldClassString`. If the `ngClass` expression has changed as well, the\n          // `ngClass[OneTime]WatchAction()` will update the classes.\n          if (newModulo === selector) {\n            addClasses(oldClassString);\n          } else {\n            removeClasses(oldClassString);\n          }\n\n          oldModulo = newModulo;\n        }\n\n        function ngClassOneTimeWatchAction(newClassValue) {\n          var newClassString = toClassString(newClassValue);\n\n          if (newClassString !== oldClassString) {\n            ngClassWatchAction(newClassString);\n          }\n        }\n\n        function ngClassWatchAction(newClassString) {\n          if (oldModulo === selector) {\n            updateClasses(oldClassString, newClassString);\n          }\n\n          oldClassString = newClassString;\n        }\n      }\n    };\n  }];\n\n  // Helpers\n  function arrayDifference(tokens1, tokens2) {\n    if (!tokens1 || !tokens1.length) return [];\n    if (!tokens2 || !tokens2.length) return tokens1;\n\n    var values = [];\n\n    outer:\n    for (var i = 0; i < tokens1.length; i++) {\n      var token = tokens1[i];\n      for (var j = 0; j < tokens2.length; j++) {\n        if (token === tokens2[j]) continue outer;\n      }\n      values.push(token);\n    }\n\n    return values;\n  }\n\n  function split(classString) {\n    return classString && classString.split(' ');\n  }\n\n  function toClassString(classValue) {\n    var classString = classValue;\n\n    if (isArray(classValue)) {\n      classString = classValue.map(toClassString).join(' ');\n    } else if (isObject(classValue)) {\n      classString = Object.keys(classValue).\n        filter(function(key) { return classValue[key]; }).\n        join(' ');\n    }\n\n    return classString;\n  }\n\n  function toFlatValue(classValue) {\n    var flatValue = classValue;\n\n    if (isArray(classValue)) {\n      flatValue = classValue.map(toFlatValue);\n    } else if (isObject(classValue)) {\n      var hasUndefined = false;\n\n      flatValue = Object.keys(classValue).filter(function(key) {\n        var value = classValue[key];\n\n        if (!hasUndefined && isUndefined(value)) {\n          hasUndefined = true;\n        }\n\n        return value;\n      });\n\n      if (hasUndefined) {\n        // Prevent the `oneTimeLiteralWatchInterceptor` from unregistering\n        // the watcher, by including at least one `undefined` value.\n        flatValue.push(undefined);\n      }\n    }\n\n    return flatValue;\n  }\n}\n\n/**\n * @ngdoc directive\n * @name ngClass\n * @restrict AC\n *\n * @description\n * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding\n * an expression that represents all classes to be added.\n *\n * The directive operates in three different ways, depending on which of three types the expression\n * evaluates to:\n *\n * 1. If the expression evaluates to a string, the string should be one or more space-delimited class\n * names.\n *\n * 2. If the expression evaluates to an object, then for each key-value pair of the\n * object with a truthy value the corresponding key is used as a class name.\n *\n * 3. If the expression evaluates to an array, each element of the array should either be a string as in\n * type 1 or an object as in type 2. This means that you can mix strings and objects together in an array\n * to give you more control over what CSS classes appear. See the code below for an example of this.\n *\n *\n * The directive won't add duplicate classes if a particular class was already set.\n *\n * When the expression changes, the previously added classes are removed and only then are the\n * new classes added.\n *\n * @knownIssue\n * You should not use {@link guide/interpolation interpolation} in the value of the `class`\n * attribute, when using the `ngClass` directive on the same element.\n * See {@link guide/interpolation#known-issues here} for more info.\n *\n * @animations\n * | Animation                        | Occurs                              |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#addClass addClass}       | just before the class is applied to the element   |\n * | {@link ng.$animate#removeClass removeClass} | just before the class is removed from the element |\n *\n * @element ANY\n * @param {expression} ngClass {@link guide/expression Expression} to eval. The result\n *   of the evaluation can be a string representing space delimited class\n *   names, an array, or a map of class names to boolean values. In the case of a map, the\n *   names of the properties whose values are truthy will be added as css classes to the\n *   element.\n *\n * @example Example that demonstrates basic bindings via ngClass directive.\n   <example name=\"ng-class\">\n     <file name=\"index.html\">\n       <p ng-class=\"{strike: deleted, bold: important, 'has-error': error}\">Map Syntax Example</p>\n       <label>\n          <input type=\"checkbox\" ng-model=\"deleted\">\n          deleted (apply \"strike\" class)\n       </label><br>\n       <label>\n          <input type=\"checkbox\" ng-model=\"important\">\n          important (apply \"bold\" class)\n       </label><br>\n       <label>\n          <input type=\"checkbox\" ng-model=\"error\">\n          error (apply \"has-error\" class)\n       </label>\n       <hr>\n       <p ng-class=\"style\">Using String Syntax</p>\n       <input type=\"text\" ng-model=\"style\"\n              placeholder=\"Type: bold strike red\" aria-label=\"Type: bold strike red\">\n       <hr>\n       <p ng-class=\"[style1, style2, style3]\">Using Array Syntax</p>\n       <input ng-model=\"style1\"\n              placeholder=\"Type: bold, strike or red\" aria-label=\"Type: bold, strike or red\"><br>\n       <input ng-model=\"style2\"\n              placeholder=\"Type: bold, strike or red\" aria-label=\"Type: bold, strike or red 2\"><br>\n       <input ng-model=\"style3\"\n              placeholder=\"Type: bold, strike or red\" aria-label=\"Type: bold, strike or red 3\"><br>\n       <hr>\n       <p ng-class=\"[style4, {orange: warning}]\">Using Array and Map Syntax</p>\n       <input ng-model=\"style4\" placeholder=\"Type: bold, strike\" aria-label=\"Type: bold, strike\"><br>\n       <label><input type=\"checkbox\" ng-model=\"warning\"> warning (apply \"orange\" class)</label>\n     </file>\n     <file name=\"style.css\">\n       .strike {\n           text-decoration: line-through;\n       }\n       .bold {\n           font-weight: bold;\n       }\n       .red {\n           color: red;\n       }\n       .has-error {\n           color: red;\n           background-color: yellow;\n       }\n       .orange {\n           color: orange;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       var ps = element.all(by.css('p'));\n\n       it('should let you toggle the class', function() {\n\n         expect(ps.first().getAttribute('class')).not.toMatch(/bold/);\n         expect(ps.first().getAttribute('class')).not.toMatch(/has-error/);\n\n         element(by.model('important')).click();\n         expect(ps.first().getAttribute('class')).toMatch(/bold/);\n\n         element(by.model('error')).click();\n         expect(ps.first().getAttribute('class')).toMatch(/has-error/);\n       });\n\n       it('should let you toggle string example', function() {\n         expect(ps.get(1).getAttribute('class')).toBe('');\n         element(by.model('style')).clear();\n         element(by.model('style')).sendKeys('red');\n         expect(ps.get(1).getAttribute('class')).toBe('red');\n       });\n\n       it('array example should have 3 classes', function() {\n         expect(ps.get(2).getAttribute('class')).toBe('');\n         element(by.model('style1')).sendKeys('bold');\n         element(by.model('style2')).sendKeys('strike');\n         element(by.model('style3')).sendKeys('red');\n         expect(ps.get(2).getAttribute('class')).toBe('bold strike red');\n       });\n\n       it('array with map example should have 2 classes', function() {\n         expect(ps.last().getAttribute('class')).toBe('');\n         element(by.model('style4')).sendKeys('bold');\n         element(by.model('warning')).click();\n         expect(ps.last().getAttribute('class')).toBe('bold orange');\n       });\n     </file>\n   </example>\n\n   ## Animations\n\n   The example below demonstrates how to perform animations using ngClass.\n\n   <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-class\">\n     <file name=\"index.html\">\n      <input id=\"setbtn\" type=\"button\" value=\"set\" ng-click=\"myVar='my-class'\">\n      <input id=\"clearbtn\" type=\"button\" value=\"clear\" ng-click=\"myVar=''\">\n      <br>\n      <span class=\"base-class\" ng-class=\"myVar\">Sample Text</span>\n     </file>\n     <file name=\"style.css\">\n       .base-class {\n         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;\n       }\n\n       .base-class.my-class {\n         color: red;\n         font-size:3em;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-class', function() {\n         expect(element(by.css('.base-class')).getAttribute('class')).not.\n           toMatch(/my-class/);\n\n         element(by.id('setbtn')).click();\n\n         expect(element(by.css('.base-class')).getAttribute('class')).\n           toMatch(/my-class/);\n\n         element(by.id('clearbtn')).click();\n\n         expect(element(by.css('.base-class')).getAttribute('class')).not.\n           toMatch(/my-class/);\n       });\n     </file>\n   </example>\n\n\n   ## ngClass and pre-existing CSS3 Transitions/Animations\n   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.\n   Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder\n   any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure\n   to view the step by step details of {@link $animate#addClass $animate.addClass} and\n   {@link $animate#removeClass $animate.removeClass}.\n */\nvar ngClassDirective = classDirective('', true);\n\n/**\n * @ngdoc directive\n * @name ngClassOdd\n * @restrict AC\n *\n * @description\n * The `ngClassOdd` and `ngClassEven` directives work exactly as\n * {@link ng.directive:ngClass ngClass}, except they work in\n * conjunction with `ngRepeat` and take effect only on odd (even) rows.\n *\n * This directive can be applied only within the scope of an\n * {@link ng.directive:ngRepeat ngRepeat}.\n *\n * @element ANY\n * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result\n *   of the evaluation can be a string representing space delimited class names or an array.\n *\n * @example\n   <example name=\"ng-class-odd\">\n     <file name=\"index.html\">\n        <ol ng-init=\"names=['John', 'Mary', 'Cate', 'Suz']\">\n          <li ng-repeat=\"name in names\">\n           <span ng-class-odd=\"'odd'\" ng-class-even=\"'even'\">\n             {{name}}\n           </span>\n          </li>\n        </ol>\n     </file>\n     <file name=\"style.css\">\n       .odd {\n         color: red;\n       }\n       .even {\n         color: blue;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-class-odd and ng-class-even', function() {\n         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).\n           toMatch(/odd/);\n         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).\n           toMatch(/even/);\n       });\n     </file>\n   </example>\n */\nvar ngClassOddDirective = classDirective('Odd', 0);\n\n/**\n * @ngdoc directive\n * @name ngClassEven\n * @restrict AC\n *\n * @description\n * The `ngClassOdd` and `ngClassEven` directives work exactly as\n * {@link ng.directive:ngClass ngClass}, except they work in\n * conjunction with `ngRepeat` and take effect only on odd (even) rows.\n *\n * This directive can be applied only within the scope of an\n * {@link ng.directive:ngRepeat ngRepeat}.\n *\n * @element ANY\n * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The\n *   result of the evaluation can be a string representing space delimited class names or an array.\n *\n * @example\n   <example name=\"ng-class-even\">\n     <file name=\"index.html\">\n        <ol ng-init=\"names=['John', 'Mary', 'Cate', 'Suz']\">\n          <li ng-repeat=\"name in names\">\n           <span ng-class-odd=\"'odd'\" ng-class-even=\"'even'\">\n             {{name}} &nbsp; &nbsp; &nbsp;\n           </span>\n          </li>\n        </ol>\n     </file>\n     <file name=\"style.css\">\n       .odd {\n         color: red;\n       }\n       .even {\n         color: blue;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-class-odd and ng-class-even', function() {\n         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).\n           toMatch(/odd/);\n         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).\n           toMatch(/even/);\n       });\n     </file>\n   </example>\n */\nvar ngClassEvenDirective = classDirective('Even', 1);\n\n/**\n * @ngdoc directive\n * @name ngCloak\n * @restrict AC\n *\n * @description\n * The `ngCloak` directive is used to prevent the Angular html template from being briefly\n * displayed by the browser in its raw (uncompiled) form while your application is loading. Use this\n * directive to avoid the undesirable flicker effect caused by the html template display.\n *\n * The directive can be applied to the `<body>` element, but the preferred usage is to apply\n * multiple `ngCloak` directives to small portions of the page to permit progressive rendering\n * of the browser view.\n *\n * `ngCloak` works in cooperation with the following css rule embedded within `angular.js` and\n * `angular.min.js`.\n * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).\n *\n * ```css\n * [ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {\n *   display: none !important;\n * }\n * ```\n *\n * When this css rule is loaded by the browser, all html elements (including their children) that\n * are tagged with the `ngCloak` directive are hidden. When Angular encounters this directive\n * during the compilation of the template it deletes the `ngCloak` element attribute, making\n * the compiled element visible.\n *\n * For the best result, the `angular.js` script must be loaded in the head section of the html\n * document; alternatively, the css rule above must be included in the external stylesheet of the\n * application.\n *\n * @element ANY\n *\n * @example\n   <example name=\"ng-cloak\">\n     <file name=\"index.html\">\n        <div id=\"template1\" ng-cloak>{{ 'hello' }}</div>\n        <div id=\"template2\" class=\"ng-cloak\">{{ 'world' }}</div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should remove the template directive and css class', function() {\n         expect($('#template1').getAttribute('ng-cloak')).\n           toBeNull();\n         expect($('#template2').getAttribute('ng-cloak')).\n           toBeNull();\n       });\n     </file>\n   </example>\n *\n */\nvar ngCloakDirective = ngDirective({\n  compile: function(element, attr) {\n    attr.$set('ngCloak', undefined);\n    element.removeClass('ng-cloak');\n  }\n});\n\n/**\n * @ngdoc directive\n * @name ngController\n *\n * @description\n * The `ngController` directive attaches a controller class to the view. This is a key aspect of how angular\n * supports the principles behind the Model-View-Controller design pattern.\n *\n * MVC components in angular:\n *\n * * Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties\n *   are accessed through bindings.\n * * View — The template (HTML with data bindings) that is rendered into the View.\n * * Controller — The `ngController` directive specifies a Controller class; the class contains business\n *   logic behind the application to decorate the scope with functions and values\n *\n * Note that you can also attach controllers to the DOM by declaring it in a route definition\n * via the {@link ngRoute.$route $route} service. A common mistake is to declare the controller\n * again using `ng-controller` in the template itself.  This will cause the controller to be attached\n * and executed twice.\n *\n * @element ANY\n * @scope\n * @priority 500\n * @param {expression} ngController Name of a constructor function registered with the current\n * {@link ng.$controllerProvider $controllerProvider} or an {@link guide/expression expression}\n * that on the current scope evaluates to a constructor function.\n *\n * The controller instance can be published into a scope property by specifying\n * `ng-controller=\"as propertyName\"`.\n *\n * If the current `$controllerProvider` is configured to use globals (via\n * {@link ng.$controllerProvider#allowGlobals `$controllerProvider.allowGlobals()` }), this may\n * also be the name of a globally accessible constructor function (deprecated, not recommended).\n *\n * @example\n * Here is a simple form for editing user contact information. Adding, removing, clearing, and\n * greeting are methods declared on the controller (see source tab). These methods can\n * easily be called from the angular markup. Any changes to the data are automatically reflected\n * in the View without the need for a manual update.\n *\n * Two different declaration styles are included below:\n *\n * * one binds methods and properties directly onto the controller using `this`:\n * `ng-controller=\"SettingsController1 as settings\"`\n * * one injects `$scope` into the controller:\n * `ng-controller=\"SettingsController2\"`\n *\n * The second option is more common in the Angular community, and is generally used in boilerplates\n * and in this guide. However, there are advantages to binding properties directly to the controller\n * and avoiding scope.\n *\n * * Using `controller as` makes it obvious which controller you are accessing in the template when\n * multiple controllers apply to an element.\n * * If you are writing your controllers as classes you have easier access to the properties and\n * methods, which will appear on the scope, from inside the controller code.\n * * Since there is always a `.` in the bindings, you don't have to worry about prototypal\n * inheritance masking primitives.\n *\n * This example demonstrates the `controller as` syntax.\n *\n * <example name=\"ngControllerAs\" module=\"controllerAsExample\">\n *   <file name=\"index.html\">\n *    <div id=\"ctrl-as-exmpl\" ng-controller=\"SettingsController1 as settings\">\n *      <label>Name: <input type=\"text\" ng-model=\"settings.name\"/></label>\n *      <button ng-click=\"settings.greet()\">greet</button><br/>\n *      Contact:\n *      <ul>\n *        <li ng-repeat=\"contact in settings.contacts\">\n *          <select ng-model=\"contact.type\" aria-label=\"Contact method\" id=\"select_{{$index}}\">\n *             <option>phone</option>\n *             <option>email</option>\n *          </select>\n *          <input type=\"text\" ng-model=\"contact.value\" aria-labelledby=\"select_{{$index}}\" />\n *          <button ng-click=\"settings.clearContact(contact)\">clear</button>\n *          <button ng-click=\"settings.removeContact(contact)\" aria-label=\"Remove\">X</button>\n *        </li>\n *        <li><button ng-click=\"settings.addContact()\">add</button></li>\n *     </ul>\n *    </div>\n *   </file>\n *   <file name=\"app.js\">\n *    angular.module('controllerAsExample', [])\n *      .controller('SettingsController1', SettingsController1);\n *\n *    function SettingsController1() {\n *      this.name = 'John Smith';\n *      this.contacts = [\n *        {type: 'phone', value: '408 555 1212'},\n *        {type: 'email', value: 'john.smith@example.org'}\n *      ];\n *    }\n *\n *    SettingsController1.prototype.greet = function() {\n *      alert(this.name);\n *    };\n *\n *    SettingsController1.prototype.addContact = function() {\n *      this.contacts.push({type: 'email', value: 'yourname@example.org'});\n *    };\n *\n *    SettingsController1.prototype.removeContact = function(contactToRemove) {\n *     var index = this.contacts.indexOf(contactToRemove);\n *      this.contacts.splice(index, 1);\n *    };\n *\n *    SettingsController1.prototype.clearContact = function(contact) {\n *      contact.type = 'phone';\n *      contact.value = '';\n *    };\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     it('should check controller as', function() {\n *       var container = element(by.id('ctrl-as-exmpl'));\n *         expect(container.element(by.model('settings.name'))\n *           .getAttribute('value')).toBe('John Smith');\n *\n *       var firstRepeat =\n *           container.element(by.repeater('contact in settings.contacts').row(0));\n *       var secondRepeat =\n *           container.element(by.repeater('contact in settings.contacts').row(1));\n *\n *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))\n *           .toBe('408 555 1212');\n *\n *       expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))\n *           .toBe('john.smith@example.org');\n *\n *       firstRepeat.element(by.buttonText('clear')).click();\n *\n *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))\n *           .toBe('');\n *\n *       container.element(by.buttonText('add')).click();\n *\n *       expect(container.element(by.repeater('contact in settings.contacts').row(2))\n *           .element(by.model('contact.value'))\n *           .getAttribute('value'))\n *           .toBe('yourname@example.org');\n *     });\n *   </file>\n * </example>\n *\n * This example demonstrates the \"attach to `$scope`\" style of controller.\n *\n * <example name=\"ngController\" module=\"controllerExample\">\n *  <file name=\"index.html\">\n *   <div id=\"ctrl-exmpl\" ng-controller=\"SettingsController2\">\n *     <label>Name: <input type=\"text\" ng-model=\"name\"/></label>\n *     <button ng-click=\"greet()\">greet</button><br/>\n *     Contact:\n *     <ul>\n *       <li ng-repeat=\"contact in contacts\">\n *         <select ng-model=\"contact.type\" id=\"select_{{$index}}\">\n *            <option>phone</option>\n *            <option>email</option>\n *         </select>\n *         <input type=\"text\" ng-model=\"contact.value\" aria-labelledby=\"select_{{$index}}\" />\n *         <button ng-click=\"clearContact(contact)\">clear</button>\n *         <button ng-click=\"removeContact(contact)\">X</button>\n *       </li>\n *       <li>[ <button ng-click=\"addContact()\">add</button> ]</li>\n *    </ul>\n *   </div>\n *  </file>\n *  <file name=\"app.js\">\n *   angular.module('controllerExample', [])\n *     .controller('SettingsController2', ['$scope', SettingsController2]);\n *\n *   function SettingsController2($scope) {\n *     $scope.name = 'John Smith';\n *     $scope.contacts = [\n *       {type:'phone', value:'408 555 1212'},\n *       {type:'email', value:'john.smith@example.org'}\n *     ];\n *\n *     $scope.greet = function() {\n *       alert($scope.name);\n *     };\n *\n *     $scope.addContact = function() {\n *       $scope.contacts.push({type:'email', value:'yourname@example.org'});\n *     };\n *\n *     $scope.removeContact = function(contactToRemove) {\n *       var index = $scope.contacts.indexOf(contactToRemove);\n *       $scope.contacts.splice(index, 1);\n *     };\n *\n *     $scope.clearContact = function(contact) {\n *       contact.type = 'phone';\n *       contact.value = '';\n *     };\n *   }\n *  </file>\n *  <file name=\"protractor.js\" type=\"protractor\">\n *    it('should check controller', function() {\n *      var container = element(by.id('ctrl-exmpl'));\n *\n *      expect(container.element(by.model('name'))\n *          .getAttribute('value')).toBe('John Smith');\n *\n *      var firstRepeat =\n *          container.element(by.repeater('contact in contacts').row(0));\n *      var secondRepeat =\n *          container.element(by.repeater('contact in contacts').row(1));\n *\n *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))\n *          .toBe('408 555 1212');\n *      expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))\n *          .toBe('john.smith@example.org');\n *\n *      firstRepeat.element(by.buttonText('clear')).click();\n *\n *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))\n *          .toBe('');\n *\n *      container.element(by.buttonText('add')).click();\n *\n *      expect(container.element(by.repeater('contact in contacts').row(2))\n *          .element(by.model('contact.value'))\n *          .getAttribute('value'))\n *          .toBe('yourname@example.org');\n *    });\n *  </file>\n *</example>\n\n */\nvar ngControllerDirective = [function() {\n  return {\n    restrict: 'A',\n    scope: true,\n    controller: '@',\n    priority: 500\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngCsp\n *\n * @restrict A\n * @element ANY\n * @description\n *\n * Angular has some features that can conflict with certain restrictions that are applied when using\n * [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) rules.\n *\n * If you intend to implement CSP with these rules then you must tell Angular not to use these\n * features.\n *\n * This is necessary when developing things like Google Chrome Extensions or Universal Windows Apps.\n *\n *\n * The following default rules in CSP affect Angular:\n *\n * * The use of `eval()`, `Function(string)` and similar functions to dynamically create and execute\n * code from strings is forbidden. Angular makes use of this in the {@link $parse} service to\n * provide a 30% increase in the speed of evaluating Angular expressions. (This CSP rule can be\n * disabled with the CSP keyword `unsafe-eval`, but it is generally not recommended as it would\n * weaken the protections offered by CSP.)\n *\n * * The use of inline resources, such as inline `<script>` and `<style>` elements, are forbidden.\n * This prevents apps from injecting custom styles directly into the document. Angular makes use of\n * this to include some CSS rules (e.g. {@link ngCloak} and {@link ngHide}). To make these\n * directives work when a CSP rule is blocking inline styles, you must link to the `angular-csp.css`\n * in your HTML manually. (This CSP rule can be disabled with the CSP keyword `unsafe-inline`, but\n * it is generally not recommended as it would weaken the protections offered by CSP.)\n *\n * If you do not provide `ngCsp` then Angular tries to autodetect if CSP is blocking dynamic code\n * creation from strings (e.g., `unsafe-eval` not specified in CSP header) and automatically\n * deactivates this feature in the {@link $parse} service. This autodetection, however, triggers a\n * CSP error to be logged in the console:\n *\n * ```\n * Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of\n * script in the following Content Security Policy directive: \"default-src 'self'\". Note that\n * 'script-src' was not explicitly set, so 'default-src' is used as a fallback.\n * ```\n *\n * This error is harmless but annoying. To prevent the error from showing up, put the `ngCsp`\n * directive on an element of the HTML document that appears before the `<script>` tag that loads\n * the `angular.js` file.\n *\n * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.*\n *\n * You can specify which of the CSP related Angular features should be deactivated by providing\n * a value for the `ng-csp` attribute. The options are as follows:\n *\n * * no-inline-style: this stops Angular from injecting CSS styles into the DOM\n *\n * * no-unsafe-eval: this stops Angular from optimizing $parse with unsafe eval of strings\n *\n * You can use these values in the following combinations:\n *\n *\n * * No declaration means that Angular will assume that you can do inline styles, but it will do\n * a runtime check for unsafe-eval. E.g. `<body>`. This is backwardly compatible with previous\n * versions of Angular.\n *\n * * A simple `ng-csp` (or `data-ng-csp`) attribute will tell Angular to deactivate both inline\n * styles and unsafe eval. E.g. `<body ng-csp>`. This is backwardly compatible with previous\n * versions of Angular.\n *\n * * Specifying only `no-unsafe-eval` tells Angular that we must not use eval, but that we can\n * inject inline styles. E.g. `<body ng-csp=\"no-unsafe-eval\">`.\n *\n * * Specifying only `no-inline-style` tells Angular that we must not inject styles, but that we can\n * run eval - no automatic check for unsafe eval will occur. E.g. `<body ng-csp=\"no-inline-style\">`\n *\n * * Specifying both `no-unsafe-eval` and `no-inline-style` tells Angular that we must not inject\n * styles nor use eval, which is the same as an empty: ng-csp.\n * E.g.`<body ng-csp=\"no-inline-style;no-unsafe-eval\">`\n *\n * @example\n * This example shows how to apply the `ngCsp` directive to the `html` tag.\n   ```html\n     <!doctype html>\n     <html ng-app ng-csp>\n     ...\n     ...\n     </html>\n   ```\n  * @example\n      <!-- Note: the `.csp` suffix in the example name triggers CSP mode in our http server! -->\n      <example name=\"example.csp\" module=\"cspExample\" ng-csp=\"true\">\n        <file name=\"index.html\">\n          <div ng-controller=\"MainController as ctrl\">\n            <div>\n              <button ng-click=\"ctrl.inc()\" id=\"inc\">Increment</button>\n              <span id=\"counter\">\n                {{ctrl.counter}}\n              </span>\n            </div>\n\n            <div>\n              <button ng-click=\"ctrl.evil()\" id=\"evil\">Evil</button>\n              <span id=\"evilError\">\n                {{ctrl.evilError}}\n              </span>\n            </div>\n          </div>\n        </file>\n        <file name=\"script.js\">\n           angular.module('cspExample', [])\n             .controller('MainController', function MainController() {\n                this.counter = 0;\n                this.inc = function() {\n                  this.counter++;\n                };\n                this.evil = function() {\n                  try {\n                    eval('1+2'); // eslint-disable-line no-eval\n                  } catch (e) {\n                    this.evilError = e.message;\n                  }\n                };\n              });\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var util, webdriver;\n\n          var incBtn = element(by.id('inc'));\n          var counter = element(by.id('counter'));\n          var evilBtn = element(by.id('evil'));\n          var evilError = element(by.id('evilError'));\n\n          function getAndClearSevereErrors() {\n            return browser.manage().logs().get('browser').then(function(browserLog) {\n              return browserLog.filter(function(logEntry) {\n                return logEntry.level.value > webdriver.logging.Level.WARNING.value;\n              });\n            });\n          }\n\n          function clearErrors() {\n            getAndClearSevereErrors();\n          }\n\n          function expectNoErrors() {\n            getAndClearSevereErrors().then(function(filteredLog) {\n              expect(filteredLog.length).toEqual(0);\n              if (filteredLog.length) {\n                console.log('browser console errors: ' + util.inspect(filteredLog));\n              }\n            });\n          }\n\n          function expectError(regex) {\n            getAndClearSevereErrors().then(function(filteredLog) {\n              var found = false;\n              filteredLog.forEach(function(log) {\n                if (log.message.match(regex)) {\n                  found = true;\n                }\n              });\n              if (!found) {\n                throw new Error('expected an error that matches ' + regex);\n              }\n            });\n          }\n\n          beforeEach(function() {\n            util = require('util');\n            webdriver = require('selenium-webdriver');\n          });\n\n          // For now, we only test on Chrome,\n          // as Safari does not load the page with Protractor's injected scripts,\n          // and Firefox webdriver always disables content security policy (#6358)\n          if (browser.params.browser !== 'chrome') {\n            return;\n          }\n\n          it('should not report errors when the page is loaded', function() {\n            // clear errors so we are not dependent on previous tests\n            clearErrors();\n            // Need to reload the page as the page is already loaded when\n            // we come here\n            browser.driver.getCurrentUrl().then(function(url) {\n              browser.get(url);\n            });\n            expectNoErrors();\n          });\n\n          it('should evaluate expressions', function() {\n            expect(counter.getText()).toEqual('0');\n            incBtn.click();\n            expect(counter.getText()).toEqual('1');\n            expectNoErrors();\n          });\n\n          it('should throw and report an error when using \"eval\"', function() {\n            evilBtn.click();\n            expect(evilError.getText()).toMatch(/Content Security Policy/);\n            expectError(/Content Security Policy/);\n          });\n        </file>\n      </example>\n  */\n\n// `ngCsp` is not implemented as a proper directive any more, because we need it be processed while\n// we bootstrap the app (before `$parse` is instantiated). For this reason, we just have the `csp()`\n// fn that looks for the `ng-csp` attribute anywhere in the current doc.\n\n/**\n * @ngdoc directive\n * @name ngClick\n *\n * @description\n * The ngClick directive allows you to specify custom behavior when\n * an element is clicked.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon\n * click. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-click\">\n     <file name=\"index.html\">\n      <button ng-click=\"count = count + 1\" ng-init=\"count=0\">\n        Increment\n      </button>\n      <span>\n        count: {{count}}\n      </span>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-click', function() {\n         expect(element(by.binding('count')).getText()).toMatch('0');\n         element(by.css('button')).click();\n         expect(element(by.binding('count')).getText()).toMatch('1');\n       });\n     </file>\n   </example>\n */\n/*\n * A collection of directives that allows creation of custom event handlers that are defined as\n * angular expressions and are compiled and executed within the current scope.\n */\nvar ngEventDirectives = {};\n\n// For events that might fire synchronously during DOM manipulation\n// we need to execute their event handlers asynchronously using $evalAsync,\n// so that they are not executed in an inconsistent state.\nvar forceAsyncEvents = {\n  'blur': true,\n  'focus': true\n};\nforEach(\n  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),\n  function(eventName) {\n    var directiveName = directiveNormalize('ng-' + eventName);\n    ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {\n      return {\n        restrict: 'A',\n        compile: function($element, attr) {\n          // NOTE:\n          // We expose the powerful `$event` object on the scope that provides access to the Window,\n          // etc. This is OK, because expressions are not sandboxed any more (and the expression\n          // sandbox was never meant to be a security feature anyway).\n          var fn = $parse(attr[directiveName]);\n          return function ngEventHandler(scope, element) {\n            element.on(eventName, function(event) {\n              var callback = function() {\n                fn(scope, {$event: event});\n              };\n              if (forceAsyncEvents[eventName] && $rootScope.$$phase) {\n                scope.$evalAsync(callback);\n              } else {\n                scope.$apply(callback);\n              }\n            });\n          };\n        }\n      };\n    }];\n  }\n);\n\n/**\n * @ngdoc directive\n * @name ngDblclick\n *\n * @description\n * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon\n * a dblclick. (The Event object is available as `$event`)\n *\n * @example\n   <example name=\"ng-dblclick\">\n     <file name=\"index.html\">\n      <button ng-dblclick=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (on double click)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMousedown\n *\n * @description\n * The ngMousedown directive allows you to specify custom behavior on mousedown event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon\n * mousedown. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mousedown\">\n     <file name=\"index.html\">\n      <button ng-mousedown=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (on mouse down)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMouseup\n *\n * @description\n * Specify custom behavior on mouseup event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon\n * mouseup. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mouseup\">\n     <file name=\"index.html\">\n      <button ng-mouseup=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (on mouse up)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngMouseover\n *\n * @description\n * Specify custom behavior on mouseover event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon\n * mouseover. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mouseover\">\n     <file name=\"index.html\">\n      <button ng-mouseover=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (when mouse is over)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMouseenter\n *\n * @description\n * Specify custom behavior on mouseenter event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon\n * mouseenter. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mouseenter\">\n     <file name=\"index.html\">\n      <button ng-mouseenter=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (when mouse enters)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMouseleave\n *\n * @description\n * Specify custom behavior on mouseleave event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon\n * mouseleave. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mouseleave\">\n     <file name=\"index.html\">\n      <button ng-mouseleave=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (when mouse leaves)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMousemove\n *\n * @description\n * Specify custom behavior on mousemove event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon\n * mousemove. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mousemove\">\n     <file name=\"index.html\">\n      <button ng-mousemove=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (when mouse moves)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngKeydown\n *\n * @description\n * Specify custom behavior on keydown event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon\n * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)\n *\n * @example\n   <example name=\"ng-keydown\">\n     <file name=\"index.html\">\n      <input ng-keydown=\"count = count + 1\" ng-init=\"count=0\">\n      key down count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngKeyup\n *\n * @description\n * Specify custom behavior on keyup event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon\n * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)\n *\n * @example\n   <example name=\"ng-keyup\">\n     <file name=\"index.html\">\n       <p>Typing in the input box below updates the key count</p>\n       <input ng-keyup=\"count = count + 1\" ng-init=\"count=0\"> key up count: {{count}}\n\n       <p>Typing in the input box below updates the keycode</p>\n       <input ng-keyup=\"event=$event\">\n       <p>event keyCode: {{ event.keyCode }}</p>\n       <p>event altKey: {{ event.altKey }}</p>\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngKeypress\n *\n * @description\n * Specify custom behavior on keypress event.\n *\n * @element ANY\n * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon\n * keypress. ({@link guide/expression#-event- Event object is available as `$event`}\n * and can be interrogated for keyCode, altKey, etc.)\n *\n * @example\n   <example name=\"ng-keypress\">\n     <file name=\"index.html\">\n      <input ng-keypress=\"count = count + 1\" ng-init=\"count=0\">\n      key press count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngSubmit\n *\n * @description\n * Enables binding angular expressions to onsubmit events.\n *\n * Additionally it prevents the default action (which for form means sending the request to the\n * server and reloading the current page), but only if the form does not contain `action`,\n * `data-action`, or `x-action` attributes.\n *\n * <div class=\"alert alert-warning\">\n * **Warning:** Be careful not to cause \"double-submission\" by using both the `ngClick` and\n * `ngSubmit` handlers together. See the\n * {@link form#submitting-a-form-and-preventing-the-default-action `form` directive documentation}\n * for a detailed discussion of when `ngSubmit` may be triggered.\n * </div>\n *\n * @element form\n * @priority 0\n * @param {expression} ngSubmit {@link guide/expression Expression} to eval.\n * ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example module=\"submitExample\" name=\"ng-submit\">\n     <file name=\"index.html\">\n      <script>\n        angular.module('submitExample', [])\n          .controller('ExampleController', ['$scope', function($scope) {\n            $scope.list = [];\n            $scope.text = 'hello';\n            $scope.submit = function() {\n              if ($scope.text) {\n                $scope.list.push(this.text);\n                $scope.text = '';\n              }\n            };\n          }]);\n      </script>\n      <form ng-submit=\"submit()\" ng-controller=\"ExampleController\">\n        Enter text and hit enter:\n        <input type=\"text\" ng-model=\"text\" name=\"text\" />\n        <input type=\"submit\" id=\"submit\" value=\"Submit\" />\n        <pre>list={{list}}</pre>\n      </form>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-submit', function() {\n         expect(element(by.binding('list')).getText()).toBe('list=[]');\n         element(by.css('#submit')).click();\n         expect(element(by.binding('list')).getText()).toContain('hello');\n         expect(element(by.model('text')).getAttribute('value')).toBe('');\n       });\n       it('should ignore empty strings', function() {\n         expect(element(by.binding('list')).getText()).toBe('list=[]');\n         element(by.css('#submit')).click();\n         element(by.css('#submit')).click();\n         expect(element(by.binding('list')).getText()).toContain('hello');\n        });\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngFocus\n *\n * @description\n * Specify custom behavior on focus event.\n *\n * Note: As the `focus` event is executed synchronously when calling `input.focus()`\n * AngularJS executes the expression using `scope.$evalAsync` if the event is fired\n * during an `$apply` to ensure a consistent state.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon\n * focus. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n * See {@link ng.directive:ngClick ngClick}\n */\n\n/**\n * @ngdoc directive\n * @name ngBlur\n *\n * @description\n * Specify custom behavior on blur event.\n *\n * A [blur event](https://developer.mozilla.org/en-US/docs/Web/Events/blur) fires when\n * an element has lost focus.\n *\n * Note: As the `blur` event is executed synchronously also during DOM manipulations\n * (e.g. removing a focussed input),\n * AngularJS executes the expression using `scope.$evalAsync` if the event is fired\n * during an `$apply` to ensure a consistent state.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon\n * blur. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n * See {@link ng.directive:ngClick ngClick}\n */\n\n/**\n * @ngdoc directive\n * @name ngCopy\n *\n * @description\n * Specify custom behavior on copy event.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon\n * copy. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-copy\">\n     <file name=\"index.html\">\n      <input ng-copy=\"copied=true\" ng-init=\"copied=false; value='copy me'\" ng-model=\"value\">\n      copied: {{copied}}\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngCut\n *\n * @description\n * Specify custom behavior on cut event.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon\n * cut. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-cut\">\n     <file name=\"index.html\">\n      <input ng-cut=\"cut=true\" ng-init=\"cut=false; value='cut me'\" ng-model=\"value\">\n      cut: {{cut}}\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngPaste\n *\n * @description\n * Specify custom behavior on paste event.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon\n * paste. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-paste\">\n     <file name=\"index.html\">\n      <input ng-paste=\"paste=true\" ng-init=\"paste=false\" placeholder='paste here'>\n      pasted: {{paste}}\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngIf\n * @restrict A\n * @multiElement\n *\n * @description\n * The `ngIf` directive removes or recreates a portion of the DOM tree based on an\n * {expression}. If the expression assigned to `ngIf` evaluates to a false\n * value then the element is removed from the DOM, otherwise a clone of the\n * element is reinserted into the DOM.\n *\n * `ngIf` differs from `ngShow` and `ngHide` in that `ngIf` completely removes and recreates the\n * element in the DOM rather than changing its visibility via the `display` css property.  A common\n * case when this difference is significant is when using css selectors that rely on an element's\n * position within the DOM, such as the `:first-child` or `:last-child` pseudo-classes.\n *\n * Note that when an element is removed using `ngIf` its scope is destroyed and a new scope\n * is created when the element is restored.  The scope created within `ngIf` inherits from\n * its parent scope using\n * [prototypal inheritance](https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance).\n * An important implication of this is if `ngModel` is used within `ngIf` to bind to\n * a javascript primitive defined in the parent scope. In this case any modifications made to the\n * variable within the child scope will override (hide) the value in the parent scope.\n *\n * Also, `ngIf` recreates elements using their compiled state. An example of this behavior\n * is if an element's class attribute is directly modified after it's compiled, using something like\n * jQuery's `.addClass()` method, and the element is later removed. When `ngIf` recreates the element\n * the added class will be lost because the original compiled state is used to regenerate the element.\n *\n * Additionally, you can provide animations via the `ngAnimate` module to animate the `enter`\n * and `leave` effects.\n *\n * @animations\n * | Animation                        | Occurs                               |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#enter enter}  | just after the `ngIf` contents change and a new DOM element is created and injected into the `ngIf` container |\n * | {@link ng.$animate#leave leave}  | just before the `ngIf` contents are removed from the DOM |\n *\n * @element ANY\n * @scope\n * @priority 600\n * @param {expression} ngIf If the {@link guide/expression expression} is falsy then\n *     the element is removed from the DOM tree. If it is truthy a copy of the compiled\n *     element is added to the DOM tree.\n *\n * @example\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-if\">\n    <file name=\"index.html\">\n      <label>Click me: <input type=\"checkbox\" ng-model=\"checked\" ng-init=\"checked=true\" /></label><br/>\n      Show when checked:\n      <span ng-if=\"checked\" class=\"animate-if\">\n        This is removed when the checkbox is unchecked.\n      </span>\n    </file>\n    <file name=\"animations.css\">\n      .animate-if {\n        background:white;\n        border:1px solid black;\n        padding:10px;\n      }\n\n      .animate-if.ng-enter, .animate-if.ng-leave {\n        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;\n      }\n\n      .animate-if.ng-enter,\n      .animate-if.ng-leave.ng-leave-active {\n        opacity:0;\n      }\n\n      .animate-if.ng-leave,\n      .animate-if.ng-enter.ng-enter-active {\n        opacity:1;\n      }\n    </file>\n  </example>\n */\nvar ngIfDirective = ['$animate', '$compile', function($animate, $compile) {\n  return {\n    multiElement: true,\n    transclude: 'element',\n    priority: 600,\n    terminal: true,\n    restrict: 'A',\n    $$tlb: true,\n    link: function($scope, $element, $attr, ctrl, $transclude) {\n        var block, childScope, previousElements;\n        $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {\n\n          if (value) {\n            if (!childScope) {\n              $transclude(function(clone, newScope) {\n                childScope = newScope;\n                clone[clone.length++] = $compile.$$createComment('end ngIf', $attr.ngIf);\n                // Note: We only need the first/last node of the cloned nodes.\n                // However, we need to keep the reference to the jqlite wrapper as it might be changed later\n                // by a directive with templateUrl when its template arrives.\n                block = {\n                  clone: clone\n                };\n                $animate.enter(clone, $element.parent(), $element);\n              });\n            }\n          } else {\n            if (previousElements) {\n              previousElements.remove();\n              previousElements = null;\n            }\n            if (childScope) {\n              childScope.$destroy();\n              childScope = null;\n            }\n            if (block) {\n              previousElements = getBlockNodes(block.clone);\n              $animate.leave(previousElements).done(function(response) {\n                if (response !== false) previousElements = null;\n              });\n              block = null;\n            }\n          }\n        });\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngInclude\n * @restrict ECA\n *\n * @description\n * Fetches, compiles and includes an external HTML fragment.\n *\n * By default, the template URL is restricted to the same domain and protocol as the\n * application document. This is done by calling {@link $sce#getTrustedResourceUrl\n * $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols\n * you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or\n * {@link $sce#trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link\n * ng.$sce Strict Contextual Escaping}.\n *\n * In addition, the browser's\n * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)\n * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)\n * policy may further restrict whether the template is successfully loaded.\n * For example, `ngInclude` won't work for cross-domain requests on all browsers and for `file://`\n * access on some browsers.\n *\n * @animations\n * | Animation                        | Occurs                              |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#enter enter}  | when the expression changes, on the new include |\n * | {@link ng.$animate#leave leave}  | when the expression changes, on the old include |\n *\n * The enter and leave animation occur concurrently.\n *\n * @scope\n * @priority 400\n *\n * @param {string} ngInclude|src angular expression evaluating to URL. If the source is a string constant,\n *                 make sure you wrap it in **single** quotes, e.g. `src=\"'myPartialTemplate.html'\"`.\n * @param {string=} onload Expression to evaluate when a new partial is loaded.\n *                  <div class=\"alert alert-warning\">\n *                  **Note:** When using onload on SVG elements in IE11, the browser will try to call\n *                  a function with the name on the window element, which will usually throw a\n *                  \"function is undefined\" error. To fix this, you can instead use `data-onload` or a\n *                  different form that {@link guide/directive#normalization matches} `onload`.\n *                  </div>\n   *\n * @param {string=} autoscroll Whether `ngInclude` should call {@link ng.$anchorScroll\n *                  $anchorScroll} to scroll the viewport after the content is loaded.\n *\n *                  - If the attribute is not set, disable scrolling.\n *                  - If the attribute is set without value, enable scrolling.\n *                  - Otherwise enable scrolling only if the expression evaluates to truthy value.\n *\n * @example\n  <example module=\"includeExample\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-include\">\n    <file name=\"index.html\">\n     <div ng-controller=\"ExampleController\">\n       <select ng-model=\"template\" ng-options=\"t.name for t in templates\">\n        <option value=\"\">(blank)</option>\n       </select>\n       url of the template: <code>{{template.url}}</code>\n       <hr/>\n       <div class=\"slide-animate-container\">\n         <div class=\"slide-animate\" ng-include=\"template.url\"></div>\n       </div>\n     </div>\n    </file>\n    <file name=\"script.js\">\n      angular.module('includeExample', ['ngAnimate'])\n        .controller('ExampleController', ['$scope', function($scope) {\n          $scope.templates =\n            [{ name: 'template1.html', url: 'template1.html'},\n             { name: 'template2.html', url: 'template2.html'}];\n          $scope.template = $scope.templates[0];\n        }]);\n     </file>\n    <file name=\"template1.html\">\n      Content of template1.html\n    </file>\n    <file name=\"template2.html\">\n      Content of template2.html\n    </file>\n    <file name=\"animations.css\">\n      .slide-animate-container {\n        position:relative;\n        background:white;\n        border:1px solid black;\n        height:40px;\n        overflow:hidden;\n      }\n\n      .slide-animate {\n        padding:10px;\n      }\n\n      .slide-animate.ng-enter, .slide-animate.ng-leave {\n        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;\n\n        position:absolute;\n        top:0;\n        left:0;\n        right:0;\n        bottom:0;\n        display:block;\n        padding:10px;\n      }\n\n      .slide-animate.ng-enter {\n        top:-50px;\n      }\n      .slide-animate.ng-enter.ng-enter-active {\n        top:0;\n      }\n\n      .slide-animate.ng-leave {\n        top:0;\n      }\n      .slide-animate.ng-leave.ng-leave-active {\n        top:50px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var templateSelect = element(by.model('template'));\n      var includeElem = element(by.css('[ng-include]'));\n\n      it('should load template1.html', function() {\n        expect(includeElem.getText()).toMatch(/Content of template1.html/);\n      });\n\n      it('should load template2.html', function() {\n        if (browser.params.browser === 'firefox') {\n          // Firefox can't handle using selects\n          // See https://github.com/angular/protractor/issues/480\n          return;\n        }\n        templateSelect.click();\n        templateSelect.all(by.css('option')).get(2).click();\n        expect(includeElem.getText()).toMatch(/Content of template2.html/);\n      });\n\n      it('should change to blank', function() {\n        if (browser.params.browser === 'firefox') {\n          // Firefox can't handle using selects\n          return;\n        }\n        templateSelect.click();\n        templateSelect.all(by.css('option')).get(0).click();\n        expect(includeElem.isPresent()).toBe(false);\n      });\n    </file>\n  </example>\n */\n\n\n/**\n * @ngdoc event\n * @name ngInclude#$includeContentRequested\n * @eventType emit on the scope ngInclude was declared in\n * @description\n * Emitted every time the ngInclude content is requested.\n *\n * @param {Object} angularEvent Synthetic event object.\n * @param {String} src URL of content to load.\n */\n\n\n/**\n * @ngdoc event\n * @name ngInclude#$includeContentLoaded\n * @eventType emit on the current ngInclude scope\n * @description\n * Emitted every time the ngInclude content is reloaded.\n *\n * @param {Object} angularEvent Synthetic event object.\n * @param {String} src URL of content to load.\n */\n\n\n/**\n * @ngdoc event\n * @name ngInclude#$includeContentError\n * @eventType emit on the scope ngInclude was declared in\n * @description\n * Emitted when a template HTTP request yields an erroneous response (status < 200 || status > 299)\n *\n * @param {Object} angularEvent Synthetic event object.\n * @param {String} src URL of content to load.\n */\nvar ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate',\n                  function($templateRequest,   $anchorScroll,   $animate) {\n  return {\n    restrict: 'ECA',\n    priority: 400,\n    terminal: true,\n    transclude: 'element',\n    controller: angular.noop,\n    compile: function(element, attr) {\n      var srcExp = attr.ngInclude || attr.src,\n          onloadExp = attr.onload || '',\n          autoScrollExp = attr.autoscroll;\n\n      return function(scope, $element, $attr, ctrl, $transclude) {\n        var changeCounter = 0,\n            currentScope,\n            previousElement,\n            currentElement;\n\n        var cleanupLastIncludeContent = function() {\n          if (previousElement) {\n            previousElement.remove();\n            previousElement = null;\n          }\n          if (currentScope) {\n            currentScope.$destroy();\n            currentScope = null;\n          }\n          if (currentElement) {\n            $animate.leave(currentElement).done(function(response) {\n              if (response !== false) previousElement = null;\n            });\n            previousElement = currentElement;\n            currentElement = null;\n          }\n        };\n\n        scope.$watch(srcExp, function ngIncludeWatchAction(src) {\n          var afterAnimation = function(response) {\n            if (response !== false && isDefined(autoScrollExp) &&\n              (!autoScrollExp || scope.$eval(autoScrollExp))) {\n                $anchorScroll();\n            }\n          };\n          var thisChangeId = ++changeCounter;\n\n          if (src) {\n            //set the 2nd param to true to ignore the template request error so that the inner\n            //contents and scope can be cleaned up.\n            $templateRequest(src, true).then(function(response) {\n              if (scope.$$destroyed) return;\n\n              if (thisChangeId !== changeCounter) return;\n              var newScope = scope.$new();\n              ctrl.template = response;\n\n              // Note: This will also link all children of ng-include that were contained in the original\n              // html. If that content contains controllers, ... they could pollute/change the scope.\n              // However, using ng-include on an element with additional content does not make sense...\n              // Note: We can't remove them in the cloneAttchFn of $transclude as that\n              // function is called before linking the content, which would apply child\n              // directives to non existing elements.\n              var clone = $transclude(newScope, function(clone) {\n                cleanupLastIncludeContent();\n                $animate.enter(clone, null, $element).done(afterAnimation);\n              });\n\n              currentScope = newScope;\n              currentElement = clone;\n\n              currentScope.$emit('$includeContentLoaded', src);\n              scope.$eval(onloadExp);\n            }, function() {\n              if (scope.$$destroyed) return;\n\n              if (thisChangeId === changeCounter) {\n                cleanupLastIncludeContent();\n                scope.$emit('$includeContentError', src);\n              }\n            });\n            scope.$emit('$includeContentRequested', src);\n          } else {\n            cleanupLastIncludeContent();\n            ctrl.template = null;\n          }\n        });\n      };\n    }\n  };\n}];\n\n// This directive is called during the $transclude call of the first `ngInclude` directive.\n// It will replace and compile the content of the element with the loaded template.\n// We need this directive so that the element content is already filled when\n// the link function of another directive on the same element as ngInclude\n// is called.\nvar ngIncludeFillContentDirective = ['$compile',\n  function($compile) {\n    return {\n      restrict: 'ECA',\n      priority: -400,\n      require: 'ngInclude',\n      link: function(scope, $element, $attr, ctrl) {\n        if (toString.call($element[0]).match(/SVG/)) {\n          // WebKit: https://bugs.webkit.org/show_bug.cgi?id=135698 --- SVG elements do not\n          // support innerHTML, so detect this here and try to generate the contents\n          // specially.\n          $element.empty();\n          $compile(jqLiteBuildFragment(ctrl.template, window.document).childNodes)(scope,\n              function namespaceAdaptedClone(clone) {\n            $element.append(clone);\n          }, {futureParentElement: $element});\n          return;\n        }\n\n        $element.html(ctrl.template);\n        $compile($element.contents())(scope);\n      }\n    };\n  }];\n\n/**\n * @ngdoc directive\n * @name ngInit\n * @restrict AC\n *\n * @description\n * The `ngInit` directive allows you to evaluate an expression in the\n * current scope.\n *\n * <div class=\"alert alert-danger\">\n * This directive can be abused to add unnecessary amounts of logic into your templates.\n * There are only a few appropriate uses of `ngInit`, such as for aliasing special properties of\n * {@link ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below; and for injecting data via\n * server side scripting. Besides these few cases, you should use {@link guide/controller controllers}\n * rather than `ngInit` to initialize values on a scope.\n * </div>\n *\n * <div class=\"alert alert-warning\">\n * **Note**: If you have assignment in `ngInit` along with a {@link ng.$filter `filter`}, make\n * sure you have parentheses to ensure correct operator precedence:\n * <pre class=\"prettyprint\">\n * `<div ng-init=\"test1 = ($index | toString)\"></div>`\n * </pre>\n * </div>\n *\n * @priority 450\n *\n * @element ANY\n * @param {expression} ngInit {@link guide/expression Expression} to eval.\n *\n * @example\n   <example module=\"initExample\" name=\"ng-init\">\n     <file name=\"index.html\">\n   <script>\n     angular.module('initExample', [])\n       .controller('ExampleController', ['$scope', function($scope) {\n         $scope.list = [['a', 'b'], ['c', 'd']];\n       }]);\n   </script>\n   <div ng-controller=\"ExampleController\">\n     <div ng-repeat=\"innerList in list\" ng-init=\"outerIndex = $index\">\n       <div ng-repeat=\"value in innerList\" ng-init=\"innerIndex = $index\">\n          <span class=\"example-init\">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>\n       </div>\n     </div>\n   </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should alias index positions', function() {\n         var elements = element.all(by.css('.example-init'));\n         expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');\n         expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');\n         expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');\n         expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');\n       });\n     </file>\n   </example>\n */\nvar ngInitDirective = ngDirective({\n  priority: 450,\n  compile: function() {\n    return {\n      pre: function(scope, element, attrs) {\n        scope.$eval(attrs.ngInit);\n      }\n    };\n  }\n});\n\n/**\n * @ngdoc directive\n * @name ngList\n *\n * @description\n * Text input that converts between a delimited string and an array of strings. The default\n * delimiter is a comma followed by a space - equivalent to `ng-list=\", \"`. You can specify a custom\n * delimiter as the value of the `ngList` attribute - for example, `ng-list=\" | \"`.\n *\n * The behaviour of the directive is affected by the use of the `ngTrim` attribute.\n * * If `ngTrim` is set to `\"false\"` then whitespace around both the separator and each\n *   list item is respected. This implies that the user of the directive is responsible for\n *   dealing with whitespace but also allows you to use whitespace as a delimiter, such as a\n *   tab or newline character.\n * * Otherwise whitespace around the delimiter is ignored when splitting (although it is respected\n *   when joining the list items back together) and whitespace around each list item is stripped\n *   before it is added to the model.\n *\n * ### Example with Validation\n *\n * <example name=\"ngList-directive\" module=\"listExample\">\n *   <file name=\"app.js\">\n *      angular.module('listExample', [])\n *        .controller('ExampleController', ['$scope', function($scope) {\n *          $scope.names = ['morpheus', 'neo', 'trinity'];\n *        }]);\n *   </file>\n *   <file name=\"index.html\">\n *    <form name=\"myForm\" ng-controller=\"ExampleController\">\n *      <label>List: <input name=\"namesInput\" ng-model=\"names\" ng-list required></label>\n *      <span role=\"alert\">\n *        <span class=\"error\" ng-show=\"myForm.namesInput.$error.required\">\n *        Required!</span>\n *      </span>\n *      <br>\n *      <tt>names = {{names}}</tt><br/>\n *      <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>\n *      <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>\n *      <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n *      <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n *     </form>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     var listInput = element(by.model('names'));\n *     var names = element(by.exactBinding('names'));\n *     var valid = element(by.binding('myForm.namesInput.$valid'));\n *     var error = element(by.css('span.error'));\n *\n *     it('should initialize to model', function() {\n *       expect(names.getText()).toContain('[\"morpheus\",\"neo\",\"trinity\"]');\n *       expect(valid.getText()).toContain('true');\n *       expect(error.getCssValue('display')).toBe('none');\n *     });\n *\n *     it('should be invalid if empty', function() {\n *       listInput.clear();\n *       listInput.sendKeys('');\n *\n *       expect(names.getText()).toContain('');\n *       expect(valid.getText()).toContain('false');\n *       expect(error.getCssValue('display')).not.toBe('none');\n *     });\n *   </file>\n * </example>\n *\n * ### Example - splitting on newline\n * <example name=\"ngList-directive-newlines\">\n *   <file name=\"index.html\">\n *    <textarea ng-model=\"list\" ng-list=\"&#10;\" ng-trim=\"false\"></textarea>\n *    <pre>{{ list | json }}</pre>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     it(\"should split the text by newlines\", function() {\n *       var listInput = element(by.model('list'));\n *       var output = element(by.binding('list | json'));\n *       listInput.sendKeys('abc\\ndef\\nghi');\n *       expect(output.getText()).toContain('[\\n  \"abc\",\\n  \"def\",\\n  \"ghi\"\\n]');\n *     });\n *   </file>\n * </example>\n *\n * @element input\n * @param {string=} ngList optional delimiter that should be used to split the value.\n */\nvar ngListDirective = function() {\n  return {\n    restrict: 'A',\n    priority: 100,\n    require: 'ngModel',\n    link: function(scope, element, attr, ctrl) {\n      var ngList = attr.ngList || ', ';\n      var trimValues = attr.ngTrim !== 'false';\n      var separator = trimValues ? trim(ngList) : ngList;\n\n      var parse = function(viewValue) {\n        // If the viewValue is invalid (say required but empty) it will be `undefined`\n        if (isUndefined(viewValue)) return;\n\n        var list = [];\n\n        if (viewValue) {\n          forEach(viewValue.split(separator), function(value) {\n            if (value) list.push(trimValues ? trim(value) : value);\n          });\n        }\n\n        return list;\n      };\n\n      ctrl.$parsers.push(parse);\n      ctrl.$formatters.push(function(value) {\n        if (isArray(value)) {\n          return value.join(ngList);\n        }\n\n        return undefined;\n      });\n\n      // Override the standard $isEmpty because an empty array means the input is empty.\n      ctrl.$isEmpty = function(value) {\n        return !value || !value.length;\n      };\n    }\n  };\n};\n\n/* global VALID_CLASS: true,\n  INVALID_CLASS: true,\n  PRISTINE_CLASS: true,\n  DIRTY_CLASS: true,\n  UNTOUCHED_CLASS: true,\n  TOUCHED_CLASS: true,\n  PENDING_CLASS: true,\n  addSetValidityMethod: true,\n  setupValidity: true,\n  defaultModelOptions: false\n*/\n\n\nvar VALID_CLASS = 'ng-valid',\n    INVALID_CLASS = 'ng-invalid',\n    PRISTINE_CLASS = 'ng-pristine',\n    DIRTY_CLASS = 'ng-dirty',\n    UNTOUCHED_CLASS = 'ng-untouched',\n    TOUCHED_CLASS = 'ng-touched',\n    EMPTY_CLASS = 'ng-empty',\n    NOT_EMPTY_CLASS = 'ng-not-empty';\n\nvar ngModelMinErr = minErr('ngModel');\n\n/**\n * @ngdoc type\n * @name ngModel.NgModelController\n *\n * @property {*} $viewValue The actual value from the control's view. For `input` elements, this is a\n * String. See {@link ngModel.NgModelController#$setViewValue} for information about when the $viewValue\n * is set.\n *\n * @property {*} $modelValue The value in the model that the control is bound to.\n *\n * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever\n *  the control updates the ngModelController with a new {@link ngModel.NgModelController#$viewValue\n    `$viewValue`} from the DOM, usually via user input.\n    See {@link ngModel.NgModelController#$setViewValue `$setViewValue()`} for a detailed lifecycle explanation.\n    Note that the `$parsers` are not called when the bound ngModel expression changes programmatically.\n\n  The functions are called in array order, each passing\n    its return value through to the next. The last return value is forwarded to the\n    {@link ngModel.NgModelController#$validators `$validators`} collection.\n\n  Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue\n    `$viewValue`}.\n\n  Returning `undefined` from a parser means a parse error occurred. In that case,\n    no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel`\n    will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`}\n    is set to `true`. The parse error is stored in `ngModel.$error.parse`.\n\n  This simple example shows a parser that would convert text input value to lowercase:\n * ```js\n * function parse(value) {\n *   if (value) {\n *     return value.toLowerCase();\n *   }\n * }\n * ngModelController.$parsers.push(parse);\n * ```\n\n *\n * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever\n    the bound ngModel expression changes programmatically. The `$formatters` are not called when the\n    value of the control is changed by user interaction.\n\n  Formatters are used to format / convert the {@link ngModel.NgModelController#$modelValue\n    `$modelValue`} for display in the control.\n\n  The functions are called in reverse array order, each passing the value through to the\n    next. The last return value is used as the actual DOM value.\n\n  This simple example shows a formatter that would convert the model value to uppercase:\n\n * ```js\n * function format(value) {\n *   if (value) {\n *     return value.toUpperCase();\n *   }\n * }\n * ngModel.$formatters.push(format);\n * ```\n *\n * @property {Object.<string, function>} $validators A collection of validators that are applied\n *      whenever the model value changes. The key value within the object refers to the name of the\n *      validator while the function refers to the validation operation. The validation operation is\n *      provided with the model value as an argument and must return a true or false value depending\n *      on the response of that validation.\n *\n * ```js\n * ngModel.$validators.validCharacters = function(modelValue, viewValue) {\n *   var value = modelValue || viewValue;\n *   return /[0-9]+/.test(value) &&\n *          /[a-z]+/.test(value) &&\n *          /[A-Z]+/.test(value) &&\n *          /\\W+/.test(value);\n * };\n * ```\n *\n * @property {Object.<string, function>} $asyncValidators A collection of validations that are expected to\n *      perform an asynchronous validation (e.g. a HTTP request). The validation function that is provided\n *      is expected to return a promise when it is run during the model validation process. Once the promise\n *      is delivered then the validation status will be set to true when fulfilled and false when rejected.\n *      When the asynchronous validators are triggered, each of the validators will run in parallel and the model\n *      value will only be updated once all validators have been fulfilled. As long as an asynchronous validator\n *      is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators\n *      will only run once all synchronous validators have passed.\n *\n * Please note that if $http is used then it is important that the server returns a success HTTP response code\n * in order to fulfill the validation and a status level of `4xx` in order to reject the validation.\n *\n * ```js\n * ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {\n *   var value = modelValue || viewValue;\n *\n *   // Lookup user by username\n *   return $http.get('/api/users/' + value).\n *      then(function resolved() {\n *        //username exists, this means validation fails\n *        return $q.reject('exists');\n *      }, function rejected() {\n *        //username does not exist, therefore this validation passes\n *        return true;\n *      });\n * };\n * ```\n *\n * @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the\n *     view value has changed. It is called with no arguments, and its return value is ignored.\n *     This can be used in place of additional $watches against the model value.\n *\n * @property {Object} $error An object hash with all failing validator ids as keys.\n * @property {Object} $pending An object hash with all pending validator ids as keys.\n *\n * @property {boolean} $untouched True if control has not lost focus yet.\n * @property {boolean} $touched True if control has lost focus.\n * @property {boolean} $pristine True if user has not interacted with the control yet.\n * @property {boolean} $dirty True if user has already interacted with the control.\n * @property {boolean} $valid True if there is no error.\n * @property {boolean} $invalid True if at least one error on the control.\n * @property {string} $name The name attribute of the control.\n *\n * @description\n *\n * `NgModelController` provides API for the {@link ngModel `ngModel`} directive.\n * The controller contains services for data-binding, validation, CSS updates, and value formatting\n * and parsing. It purposefully does not contain any logic which deals with DOM rendering or\n * listening to DOM events.\n * Such DOM related logic should be provided by other directives which make use of\n * `NgModelController` for data-binding to control elements.\n * Angular provides this DOM logic for most {@link input `input`} elements.\n * At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example\n * custom control example} that uses `ngModelController` to bind to `contenteditable` elements.\n *\n * @example\n * ### Custom Control Example\n * This example shows how to use `NgModelController` with a custom control to achieve\n * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)\n * collaborate together to achieve the desired result.\n *\n * `contenteditable` is an HTML5 attribute, which tells the browser to let the element\n * contents be edited in place by the user.\n *\n * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}\n * module to automatically remove \"bad\" content like inline event listener (e.g. `<span onclick=\"...\">`).\n * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks\n * that content using the `$sce` service.\n *\n * <example name=\"NgModelController\" module=\"customControl\" deps=\"angular-sanitize.js\">\n    <file name=\"style.css\">\n      [contenteditable] {\n        border: 1px solid black;\n        background-color: white;\n        min-height: 20px;\n      }\n\n      .ng-invalid {\n        border: 1px solid red;\n      }\n\n    </file>\n    <file name=\"script.js\">\n      angular.module('customControl', ['ngSanitize']).\n        directive('contenteditable', ['$sce', function($sce) {\n          return {\n            restrict: 'A', // only activate on element attribute\n            require: '?ngModel', // get a hold of NgModelController\n            link: function(scope, element, attrs, ngModel) {\n              if (!ngModel) return; // do nothing if no ng-model\n\n              // Specify how UI should be updated\n              ngModel.$render = function() {\n                element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));\n              };\n\n              // Listen for change events to enable binding\n              element.on('blur keyup change', function() {\n                scope.$evalAsync(read);\n              });\n              read(); // initialize\n\n              // Write data to the model\n              function read() {\n                var html = element.html();\n                // When we clear the content editable the browser leaves a <br> behind\n                // If strip-br attribute is provided then we strip this out\n                if (attrs.stripBr && html === '<br>') {\n                  html = '';\n                }\n                ngModel.$setViewValue(html);\n              }\n            }\n          };\n        }]);\n    </file>\n    <file name=\"index.html\">\n      <form name=\"myForm\">\n       <div contenteditable\n            name=\"myWidget\" ng-model=\"userContent\"\n            strip-br=\"true\"\n            required>Change me!</div>\n        <span ng-show=\"myForm.myWidget.$error.required\">Required!</span>\n       <hr>\n       <textarea ng-model=\"userContent\" aria-label=\"Dynamic textarea\"></textarea>\n      </form>\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n    it('should data-bind and become invalid', function() {\n      if (browser.params.browser === 'safari' || browser.params.browser === 'firefox') {\n        // SafariDriver can't handle contenteditable\n        // and Firefox driver can't clear contenteditables very well\n        return;\n      }\n      var contentEditable = element(by.css('[contenteditable]'));\n      var content = 'Change me!';\n\n      expect(contentEditable.getText()).toEqual(content);\n\n      contentEditable.clear();\n      contentEditable.sendKeys(protractor.Key.BACK_SPACE);\n      expect(contentEditable.getText()).toEqual('');\n      expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);\n    });\n    </file>\n * </example>\n *\n *\n */\nNgModelController.$inject = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$q', '$interpolate'];\nfunction NgModelController($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $q, $interpolate) {\n  this.$viewValue = Number.NaN;\n  this.$modelValue = Number.NaN;\n  this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.\n  this.$validators = {};\n  this.$asyncValidators = {};\n  this.$parsers = [];\n  this.$formatters = [];\n  this.$viewChangeListeners = [];\n  this.$untouched = true;\n  this.$touched = false;\n  this.$pristine = true;\n  this.$dirty = false;\n  this.$valid = true;\n  this.$invalid = false;\n  this.$error = {}; // keep invalid keys here\n  this.$$success = {}; // keep valid keys here\n  this.$pending = undefined; // keep pending keys here\n  this.$name = $interpolate($attr.name || '', false)($scope);\n  this.$$parentForm = nullFormCtrl;\n  this.$options = defaultModelOptions;\n\n  this.$$parsedNgModel = $parse($attr.ngModel);\n  this.$$parsedNgModelAssign = this.$$parsedNgModel.assign;\n  this.$$ngModelGet = this.$$parsedNgModel;\n  this.$$ngModelSet = this.$$parsedNgModelAssign;\n  this.$$pendingDebounce = null;\n  this.$$parserValid = undefined;\n\n  this.$$currentValidationRunId = 0;\n\n  this.$$scope = $scope;\n  this.$$attr = $attr;\n  this.$$element = $element;\n  this.$$animate = $animate;\n  this.$$timeout = $timeout;\n  this.$$parse = $parse;\n  this.$$q = $q;\n  this.$$exceptionHandler = $exceptionHandler;\n\n  setupValidity(this);\n  setupModelWatcher(this);\n}\n\nNgModelController.prototype = {\n  $$initGetterSetters: function() {\n    if (this.$options.getOption('getterSetter')) {\n      var invokeModelGetter = this.$$parse(this.$$attr.ngModel + '()'),\n          invokeModelSetter = this.$$parse(this.$$attr.ngModel + '($$$p)');\n\n      this.$$ngModelGet = function($scope) {\n        var modelValue = this.$$parsedNgModel($scope);\n        if (isFunction(modelValue)) {\n          modelValue = invokeModelGetter($scope);\n        }\n        return modelValue;\n      };\n      this.$$ngModelSet = function($scope, newValue) {\n        if (isFunction(this.$$parsedNgModel($scope))) {\n          invokeModelSetter($scope, {$$$p: newValue});\n        } else {\n          this.$$parsedNgModelAssign($scope, newValue);\n        }\n      };\n    } else if (!this.$$parsedNgModel.assign) {\n      throw ngModelMinErr('nonassign', 'Expression \\'{0}\\' is non-assignable. Element: {1}',\n          this.$$attr.ngModel, startingTag(this.$$element));\n    }\n  },\n\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$render\n   *\n   * @description\n   * Called when the view needs to be updated. It is expected that the user of the ng-model\n   * directive will implement this method.\n   *\n   * The `$render()` method is invoked in the following situations:\n   *\n   * * `$rollbackViewValue()` is called.  If we are rolling back the view value to the last\n   *   committed value then `$render()` is called to update the input control.\n   * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and\n   *   the `$viewValue` are different from last time.\n   *\n   * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of\n   * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue`\n   * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be\n   * invoked if you only change a property on the objects.\n   */\n  $render: noop,\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$isEmpty\n   *\n   * @description\n   * This is called when we need to determine if the value of an input is empty.\n   *\n   * For instance, the required directive does this to work out if the input has data or not.\n   *\n   * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`.\n   *\n   * You can override this for input directives whose concept of being empty is different from the\n   * default. The `checkboxInputType` directive does this because in its case a value of `false`\n   * implies empty.\n   *\n   * @param {*} value The value of the input to check for emptiness.\n   * @returns {boolean} True if `value` is \"empty\".\n   */\n  $isEmpty: function(value) {\n    // eslint-disable-next-line no-self-compare\n    return isUndefined(value) || value === '' || value === null || value !== value;\n  },\n\n  $$updateEmptyClasses: function(value) {\n    if (this.$isEmpty(value)) {\n      this.$$animate.removeClass(this.$$element, NOT_EMPTY_CLASS);\n      this.$$animate.addClass(this.$$element, EMPTY_CLASS);\n    } else {\n      this.$$animate.removeClass(this.$$element, EMPTY_CLASS);\n      this.$$animate.addClass(this.$$element, NOT_EMPTY_CLASS);\n    }\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setPristine\n   *\n   * @description\n   * Sets the control to its pristine state.\n   *\n   * This method can be called to remove the `ng-dirty` class and set the control to its pristine\n   * state (`ng-pristine` class). A model is considered to be pristine when the control\n   * has not been changed from when first compiled.\n   */\n  $setPristine: function() {\n    this.$dirty = false;\n    this.$pristine = true;\n    this.$$animate.removeClass(this.$$element, DIRTY_CLASS);\n    this.$$animate.addClass(this.$$element, PRISTINE_CLASS);\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setDirty\n   *\n   * @description\n   * Sets the control to its dirty state.\n   *\n   * This method can be called to remove the `ng-pristine` class and set the control to its dirty\n   * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed\n   * from when first compiled.\n   */\n  $setDirty: function() {\n    this.$dirty = true;\n    this.$pristine = false;\n    this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);\n    this.$$animate.addClass(this.$$element, DIRTY_CLASS);\n    this.$$parentForm.$setDirty();\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setUntouched\n   *\n   * @description\n   * Sets the control to its untouched state.\n   *\n   * This method can be called to remove the `ng-touched` class and set the control to its\n   * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched\n   * by default, however this function can be used to restore that state if the model has\n   * already been touched by the user.\n   */\n  $setUntouched: function() {\n    this.$touched = false;\n    this.$untouched = true;\n    this.$$animate.setClass(this.$$element, UNTOUCHED_CLASS, TOUCHED_CLASS);\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setTouched\n   *\n   * @description\n   * Sets the control to its touched state.\n   *\n   * This method can be called to remove the `ng-untouched` class and set the control to its\n   * touched state (`ng-touched` class). A model is considered to be touched when the user has\n   * first focused the control element and then shifted focus away from the control (blur event).\n   */\n  $setTouched: function() {\n    this.$touched = true;\n    this.$untouched = false;\n    this.$$animate.setClass(this.$$element, TOUCHED_CLASS, UNTOUCHED_CLASS);\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$rollbackViewValue\n   *\n   * @description\n   * Cancel an update and reset the input element's value to prevent an update to the `$modelValue`,\n   * which may be caused by a pending debounced event or because the input is waiting for some\n   * future event.\n   *\n   * If you have an input that uses `ng-model-options` to set up debounced updates or updates that\n   * depend on special events such as `blur`, there can be a period when the `$viewValue` is out of\n   * sync with the ngModel's `$modelValue`.\n   *\n   * In this case, you can use `$rollbackViewValue()` to manually cancel the debounced / future update\n   * and reset the input to the last committed view value.\n   *\n   * It is also possible that you run into difficulties if you try to update the ngModel's `$modelValue`\n   * programmatically before these debounced/future events have resolved/occurred, because Angular's\n   * dirty checking mechanism is not able to tell whether the model has actually changed or not.\n   *\n   * The `$rollbackViewValue()` method should be called before programmatically changing the model of an\n   * input which may have such events pending. This is important in order to make sure that the\n   * input field will be updated with the new model value and any pending operations are cancelled.\n   *\n   * <example name=\"ng-model-cancel-update\" module=\"cancel-update-example\">\n   *   <file name=\"app.js\">\n   *     angular.module('cancel-update-example', [])\n   *\n   *     .controller('CancelUpdateController', ['$scope', function($scope) {\n   *       $scope.model = {value1: '', value2: ''};\n   *\n   *       $scope.setEmpty = function(e, value, rollback) {\n   *         if (e.keyCode === 27) {\n   *           e.preventDefault();\n   *           if (rollback) {\n   *             $scope.myForm[value].$rollbackViewValue();\n   *           }\n   *           $scope.model[value] = '';\n   *         }\n   *       };\n   *     }]);\n   *   </file>\n   *   <file name=\"index.html\">\n   *     <div ng-controller=\"CancelUpdateController\">\n   *       <p>Both of these inputs are only updated if they are blurred. Hitting escape should\n   *       empty them. Follow these steps and observe the difference:</p>\n   *       <ol>\n   *         <li>Type something in the input. You will see that the model is not yet updated</li>\n   *         <li>Press the Escape key.\n   *           <ol>\n   *             <li> In the first example, nothing happens, because the model is already '', and no\n   *             update is detected. If you blur the input, the model will be set to the current view.\n   *             </li>\n   *             <li> In the second example, the pending update is cancelled, and the input is set back\n   *             to the last committed view value (''). Blurring the input does nothing.\n   *             </li>\n   *           </ol>\n   *         </li>\n   *       </ol>\n   *\n   *       <form name=\"myForm\" ng-model-options=\"{ updateOn: 'blur' }\">\n   *         <div>\n   *           <p id=\"inputDescription1\">Without $rollbackViewValue():</p>\n   *           <input name=\"value1\" aria-describedby=\"inputDescription1\" ng-model=\"model.value1\"\n   *                  ng-keydown=\"setEmpty($event, 'value1')\">\n   *           value1: \"{{ model.value1 }}\"\n   *         </div>\n   *\n   *         <div>\n   *           <p id=\"inputDescription2\">With $rollbackViewValue():</p>\n   *           <input name=\"value2\" aria-describedby=\"inputDescription2\" ng-model=\"model.value2\"\n   *                  ng-keydown=\"setEmpty($event, 'value2', true)\">\n   *           value2: \"{{ model.value2 }}\"\n   *         </div>\n   *       </form>\n   *     </div>\n   *   </file>\n       <file name=\"style.css\">\n          div {\n            display: table-cell;\n          }\n          div:nth-child(1) {\n            padding-right: 30px;\n          }\n\n        </file>\n   * </example>\n   */\n  $rollbackViewValue: function() {\n    this.$$timeout.cancel(this.$$pendingDebounce);\n    this.$viewValue = this.$$lastCommittedViewValue;\n    this.$render();\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$validate\n   *\n   * @description\n   * Runs each of the registered validators (first synchronous validators and then\n   * asynchronous validators).\n   * If the validity changes to invalid, the model will be set to `undefined`,\n   * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.\n   * If the validity changes to valid, it will set the model to the last available valid\n   * `$modelValue`, i.e. either the last parsed value or the last value set from the scope.\n   */\n  $validate: function() {\n    // ignore $validate before model is initialized\n    if (isNumberNaN(this.$modelValue)) {\n      return;\n    }\n\n    var viewValue = this.$$lastCommittedViewValue;\n    // Note: we use the $$rawModelValue as $modelValue might have been\n    // set to undefined during a view -> model update that found validation\n    // errors. We can't parse the view here, since that could change\n    // the model although neither viewValue nor the model on the scope changed\n    var modelValue = this.$$rawModelValue;\n\n    var prevValid = this.$valid;\n    var prevModelValue = this.$modelValue;\n\n    var allowInvalid = this.$options.getOption('allowInvalid');\n\n    var that = this;\n    this.$$runValidators(modelValue, viewValue, function(allValid) {\n      // If there was no change in validity, don't update the model\n      // This prevents changing an invalid modelValue to undefined\n      if (!allowInvalid && prevValid !== allValid) {\n        // Note: Don't check this.$valid here, as we could have\n        // external validators (e.g. calculated on the server),\n        // that just call $setValidity and need the model value\n        // to calculate their validity.\n        that.$modelValue = allValid ? modelValue : undefined;\n\n        if (that.$modelValue !== prevModelValue) {\n          that.$$writeModelToScope();\n        }\n      }\n    });\n  },\n\n  $$runValidators: function(modelValue, viewValue, doneCallback) {\n    this.$$currentValidationRunId++;\n    var localValidationRunId = this.$$currentValidationRunId;\n    var that = this;\n\n    // check parser error\n    if (!processParseErrors()) {\n      validationDone(false);\n      return;\n    }\n    if (!processSyncValidators()) {\n      validationDone(false);\n      return;\n    }\n    processAsyncValidators();\n\n    function processParseErrors() {\n      var errorKey = that.$$parserName || 'parse';\n      if (isUndefined(that.$$parserValid)) {\n        setValidity(errorKey, null);\n      } else {\n        if (!that.$$parserValid) {\n          forEach(that.$validators, function(v, name) {\n            setValidity(name, null);\n          });\n          forEach(that.$asyncValidators, function(v, name) {\n            setValidity(name, null);\n          });\n        }\n        // Set the parse error last, to prevent unsetting it, should a $validators key == parserName\n        setValidity(errorKey, that.$$parserValid);\n        return that.$$parserValid;\n      }\n      return true;\n    }\n\n    function processSyncValidators() {\n      var syncValidatorsValid = true;\n      forEach(that.$validators, function(validator, name) {\n        var result = Boolean(validator(modelValue, viewValue));\n        syncValidatorsValid = syncValidatorsValid && result;\n        setValidity(name, result);\n      });\n      if (!syncValidatorsValid) {\n        forEach(that.$asyncValidators, function(v, name) {\n          setValidity(name, null);\n        });\n        return false;\n      }\n      return true;\n    }\n\n    function processAsyncValidators() {\n      var validatorPromises = [];\n      var allValid = true;\n      forEach(that.$asyncValidators, function(validator, name) {\n        var promise = validator(modelValue, viewValue);\n        if (!isPromiseLike(promise)) {\n          throw ngModelMinErr('nopromise',\n            'Expected asynchronous validator to return a promise but got \\'{0}\\' instead.', promise);\n        }\n        setValidity(name, undefined);\n        validatorPromises.push(promise.then(function() {\n          setValidity(name, true);\n        }, function() {\n          allValid = false;\n          setValidity(name, false);\n        }));\n      });\n      if (!validatorPromises.length) {\n        validationDone(true);\n      } else {\n        that.$$q.all(validatorPromises).then(function() {\n          validationDone(allValid);\n        }, noop);\n      }\n    }\n\n    function setValidity(name, isValid) {\n      if (localValidationRunId === that.$$currentValidationRunId) {\n        that.$setValidity(name, isValid);\n      }\n    }\n\n    function validationDone(allValid) {\n      if (localValidationRunId === that.$$currentValidationRunId) {\n\n        doneCallback(allValid);\n      }\n    }\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$commitViewValue\n   *\n   * @description\n   * Commit a pending update to the `$modelValue`.\n   *\n   * Updates may be pending by a debounced event or because the input is waiting for a some future\n   * event defined in `ng-model-options`. this method is rarely needed as `NgModelController`\n   * usually handles calling this in response to input events.\n   */\n  $commitViewValue: function() {\n    var viewValue = this.$viewValue;\n\n    this.$$timeout.cancel(this.$$pendingDebounce);\n\n    // If the view value has not changed then we should just exit, except in the case where there is\n    // a native validator on the element. In this case the validation state may have changed even though\n    // the viewValue has stayed empty.\n    if (this.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !this.$$hasNativeValidators)) {\n      return;\n    }\n    this.$$updateEmptyClasses(viewValue);\n    this.$$lastCommittedViewValue = viewValue;\n\n    // change to dirty\n    if (this.$pristine) {\n      this.$setDirty();\n    }\n    this.$$parseAndValidate();\n  },\n\n  $$parseAndValidate: function() {\n    var viewValue = this.$$lastCommittedViewValue;\n    var modelValue = viewValue;\n    var that = this;\n\n    this.$$parserValid = isUndefined(modelValue) ? undefined : true;\n\n    if (this.$$parserValid) {\n      for (var i = 0; i < this.$parsers.length; i++) {\n        modelValue = this.$parsers[i](modelValue);\n        if (isUndefined(modelValue)) {\n          this.$$parserValid = false;\n          break;\n        }\n      }\n    }\n    if (isNumberNaN(this.$modelValue)) {\n      // this.$modelValue has not been touched yet...\n      this.$modelValue = this.$$ngModelGet(this.$$scope);\n    }\n    var prevModelValue = this.$modelValue;\n    var allowInvalid = this.$options.getOption('allowInvalid');\n    this.$$rawModelValue = modelValue;\n\n    if (allowInvalid) {\n      this.$modelValue = modelValue;\n      writeToModelIfNeeded();\n    }\n\n    // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.\n    // This can happen if e.g. $setViewValue is called from inside a parser\n    this.$$runValidators(modelValue, this.$$lastCommittedViewValue, function(allValid) {\n      if (!allowInvalid) {\n        // Note: Don't check this.$valid here, as we could have\n        // external validators (e.g. calculated on the server),\n        // that just call $setValidity and need the model value\n        // to calculate their validity.\n        that.$modelValue = allValid ? modelValue : undefined;\n        writeToModelIfNeeded();\n      }\n    });\n\n    function writeToModelIfNeeded() {\n      if (that.$modelValue !== prevModelValue) {\n        that.$$writeModelToScope();\n      }\n    }\n  },\n\n  $$writeModelToScope: function() {\n    this.$$ngModelSet(this.$$scope, this.$modelValue);\n    forEach(this.$viewChangeListeners, function(listener) {\n      try {\n        listener();\n      } catch (e) {\n        // eslint-disable-next-line no-invalid-this\n        this.$$exceptionHandler(e);\n      }\n    }, this);\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setViewValue\n   *\n   * @description\n   * Update the view value.\n   *\n   * This method should be called when a control wants to change the view value; typically,\n   * this is done from within a DOM event handler. For example, the {@link ng.directive:input input}\n   * directive calls it when the value of the input changes and {@link ng.directive:select select}\n   * calls it when an option is selected.\n   *\n   * When `$setViewValue` is called, the new `value` will be staged for committing through the `$parsers`\n   * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged\n   * value is sent directly for processing through the `$parsers` pipeline. After this, the `$validators` and\n   * `$asyncValidators` are called and the value is applied to `$modelValue`.\n   * Finally, the value is set to the **expression** specified in the `ng-model` attribute and\n   * all the registered change listeners, in the `$viewChangeListeners` list are called.\n   *\n   * In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn`\n   * and the `default` trigger is not listed, all those actions will remain pending until one of the\n   * `updateOn` events is triggered on the DOM element.\n   * All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions}\n   * directive is used with a custom debounce for this particular event.\n   * Note that a `$digest` is only triggered once the `updateOn` events are fired, or if `debounce`\n   * is specified, once the timer runs out.\n   *\n   * When used with standard inputs, the view value will always be a string (which is in some cases\n   * parsed into another type, such as a `Date` object for `input[date]`.)\n   * However, custom controls might also pass objects to this method. In this case, we should make\n   * a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not\n   * perform a deep watch of objects, it only looks for a change of identity. If you only change\n   * the property of the object then ngModel will not realize that the object has changed and\n   * will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should\n   * not change properties of the copy once it has been passed to `$setViewValue`.\n   * Otherwise you may cause the model value on the scope to change incorrectly.\n   *\n   * <div class=\"alert alert-info\">\n   * In any case, the value passed to the method should always reflect the current value\n   * of the control. For example, if you are calling `$setViewValue` for an input element,\n   * you should pass the input DOM value. Otherwise, the control and the scope model become\n   * out of sync. It's also important to note that `$setViewValue` does not call `$render` or change\n   * the control's DOM value in any way. If we want to change the control's DOM value\n   * programmatically, we should update the `ngModel` scope expression. Its new value will be\n   * picked up by the model controller, which will run it through the `$formatters`, `$render` it\n   * to update the DOM, and finally call `$validate` on it.\n   * </div>\n   *\n   * @param {*} value value from the view.\n   * @param {string} trigger Event that triggered the update.\n   */\n  $setViewValue: function(value, trigger) {\n    this.$viewValue = value;\n    if (this.$options.getOption('updateOnDefault')) {\n      this.$$debounceViewValueCommit(trigger);\n    }\n  },\n\n  $$debounceViewValueCommit: function(trigger) {\n    var debounceDelay = this.$options.getOption('debounce');\n\n    if (isNumber(debounceDelay[trigger])) {\n      debounceDelay = debounceDelay[trigger];\n    } else if (isNumber(debounceDelay['default'])) {\n      debounceDelay = debounceDelay['default'];\n    }\n\n    this.$$timeout.cancel(this.$$pendingDebounce);\n    var that = this;\n    if (debounceDelay > 0) { // this fails if debounceDelay is an object\n      this.$$pendingDebounce = this.$$timeout(function() {\n        that.$commitViewValue();\n      }, debounceDelay);\n    } else if (this.$$scope.$root.$$phase) {\n      this.$commitViewValue();\n    } else {\n      this.$$scope.$apply(function() {\n        that.$commitViewValue();\n      });\n    }\n  },\n\n  /**\n   * @ngdoc method\n   *\n   * @name ngModel.NgModelController#$overrideModelOptions\n   *\n   * @description\n   *\n   * Override the current model options settings programmatically.\n   *\n   * The previous `ModelOptions` value will not be modified. Instead, a\n   * new `ModelOptions` object will inherit from the previous one overriding\n   * or inheriting settings that are defined in the given parameter.\n   *\n   * See {@link ngModelOptions} for information about what options can be specified\n   * and how model option inheritance works.\n   *\n   * @param {Object} options a hash of settings to override the previous options\n   *\n   */\n  $overrideModelOptions: function(options) {\n    this.$options = this.$options.createChild(options);\n  }\n};\n\nfunction setupModelWatcher(ctrl) {\n  // model -> value\n  // Note: we cannot use a normal scope.$watch as we want to detect the following:\n  // 1. scope value is 'a'\n  // 2. user enters 'b'\n  // 3. ng-change kicks in and reverts scope value to 'a'\n  //    -> scope value did not change since the last digest as\n  //       ng-change executes in apply phase\n  // 4. view should be changed back to 'a'\n  ctrl.$$scope.$watch(function ngModelWatch() {\n    var modelValue = ctrl.$$ngModelGet(ctrl.$$scope);\n\n    // if scope model value and ngModel value are out of sync\n    // TODO(perf): why not move this to the action fn?\n    if (modelValue !== ctrl.$modelValue &&\n       // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator\n        // eslint-disable-next-line no-self-compare\n       (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)\n    ) {\n      ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;\n      ctrl.$$parserValid = undefined;\n\n      var formatters = ctrl.$formatters,\n          idx = formatters.length;\n\n      var viewValue = modelValue;\n      while (idx--) {\n        viewValue = formatters[idx](viewValue);\n      }\n      if (ctrl.$viewValue !== viewValue) {\n        ctrl.$$updateEmptyClasses(viewValue);\n        ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;\n        ctrl.$render();\n\n        // It is possible that model and view value have been updated during render\n        ctrl.$$runValidators(ctrl.$modelValue, ctrl.$viewValue, noop);\n      }\n    }\n\n    return modelValue;\n  });\n}\n\n/**\n * @ngdoc method\n * @name ngModel.NgModelController#$setValidity\n *\n * @description\n * Change the validity state, and notify the form.\n *\n * This method can be called within $parsers/$formatters or a custom validation implementation.\n * However, in most cases it should be sufficient to use the `ngModel.$validators` and\n * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically.\n *\n * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned\n *        to either `$error[validationErrorKey]` or `$pending[validationErrorKey]`\n *        (for unfulfilled `$asyncValidators`), so that it is available for data-binding.\n *        The `validationErrorKey` should be in camelCase and will get converted into dash-case\n *        for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`\n *        class and can be bound to as  `{{someForm.someControl.$error.myError}}` .\n * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined),\n *                          or skipped (null). Pending is used for unfulfilled `$asyncValidators`.\n *                          Skipped is used by Angular when validators do not run because of parse errors and\n *                          when `$asyncValidators` do not run because any of the `$validators` failed.\n */\naddSetValidityMethod({\n  clazz: NgModelController,\n  set: function(object, property) {\n    object[property] = true;\n  },\n  unset: function(object, property) {\n    delete object[property];\n  }\n});\n\n\n/**\n * @ngdoc directive\n * @name ngModel\n *\n * @element input\n * @priority 1\n *\n * @description\n * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a\n * property on the scope using {@link ngModel.NgModelController NgModelController},\n * which is created and exposed by this directive.\n *\n * `ngModel` is responsible for:\n *\n * - Binding the view into the model, which other directives such as `input`, `textarea` or `select`\n *   require.\n * - Providing validation behavior (i.e. required, number, email, url).\n * - Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).\n * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`,\n *   `ng-untouched`, `ng-empty`, `ng-not-empty`) including animations.\n * - Registering the control with its parent {@link ng.directive:form form}.\n *\n * Note: `ngModel` will try to bind to the property given by evaluating the expression on the\n * current scope. If the property doesn't already exist on this scope, it will be created\n * implicitly and added to the scope.\n *\n * For best practices on using `ngModel`, see:\n *\n *  - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes)\n *\n * For basic examples, how to use `ngModel`, see:\n *\n *  - {@link ng.directive:input input}\n *    - {@link input[text] text}\n *    - {@link input[checkbox] checkbox}\n *    - {@link input[radio] radio}\n *    - {@link input[number] number}\n *    - {@link input[email] email}\n *    - {@link input[url] url}\n *    - {@link input[date] date}\n *    - {@link input[datetime-local] datetime-local}\n *    - {@link input[time] time}\n *    - {@link input[month] month}\n *    - {@link input[week] week}\n *  - {@link ng.directive:select select}\n *  - {@link ng.directive:textarea textarea}\n *\n * # Complex Models (objects or collections)\n *\n * By default, `ngModel` watches the model by reference, not value. This is important to know when\n * binding inputs to models that are objects (e.g. `Date`) or collections (e.g. arrays). If only properties of the\n * object or collection change, `ngModel` will not be notified and so the input will not be  re-rendered.\n *\n * The model must be assigned an entirely new object or collection before a re-rendering will occur.\n *\n * Some directives have options that will cause them to use a custom `$watchCollection` on the model expression\n * - for example, `ngOptions` will do so when a `track by` clause is included in the comprehension expression or\n * if the select is given the `multiple` attribute.\n *\n * The `$watchCollection()` method only does a shallow comparison, meaning that changing properties deeper than the\n * first level of the object (or only changing the properties of an item in the collection if it's an array) will still\n * not trigger a re-rendering of the model.\n *\n * # CSS classes\n * The following CSS classes are added and removed on the associated input/select/textarea element\n * depending on the validity of the model.\n *\n *  - `ng-valid`: the model is valid\n *  - `ng-invalid`: the model is invalid\n *  - `ng-valid-[key]`: for each valid key added by `$setValidity`\n *  - `ng-invalid-[key]`: for each invalid key added by `$setValidity`\n *  - `ng-pristine`: the control hasn't been interacted with yet\n *  - `ng-dirty`: the control has been interacted with\n *  - `ng-touched`: the control has been blurred\n *  - `ng-untouched`: the control hasn't been blurred\n *  - `ng-pending`: any `$asyncValidators` are unfulfilled\n *  - `ng-empty`: the view does not contain a value or the value is deemed \"empty\", as defined\n *     by the {@link ngModel.NgModelController#$isEmpty} method\n *  - `ng-not-empty`: the view contains a non-empty value\n *\n * Keep in mind that ngAnimate can detect each of these classes when added and removed.\n *\n * ## Animation Hooks\n *\n * Animations within models are triggered when any of the associated CSS classes are added and removed\n * on the input element which is attached to the model. These classes include: `.ng-pristine`, `.ng-dirty`,\n * `.ng-invalid` and `.ng-valid` as well as any other validations that are performed on the model itself.\n * The animations that are triggered within ngModel are similar to how they work in ngClass and\n * animations can be hooked into using CSS transitions, keyframes as well as JS animations.\n *\n * The following example shows a simple way to utilize CSS transitions to style an input element\n * that has been rendered as invalid after it has been validated:\n *\n * <pre>\n * //be sure to include ngAnimate as a module to hook into more\n * //advanced animations\n * .my-input {\n *   transition:0.5s linear all;\n *   background: white;\n * }\n * .my-input.ng-invalid {\n *   background: red;\n *   color:white;\n * }\n * </pre>\n *\n * @example\n * <example deps=\"angular-animate.js\" animations=\"true\" fixBase=\"true\" module=\"inputExample\" name=\"ng-model\">\n     <file name=\"index.html\">\n       <script>\n        angular.module('inputExample', [])\n          .controller('ExampleController', ['$scope', function($scope) {\n            $scope.val = '1';\n          }]);\n       </script>\n       <style>\n         .my-input {\n           transition:all linear 0.5s;\n           background: transparent;\n         }\n         .my-input.ng-invalid {\n           color:white;\n           background: red;\n         }\n       </style>\n       <p id=\"inputDescription\">\n        Update input to see transitions when valid/invalid.\n        Integer is a valid value.\n       </p>\n       <form name=\"testForm\" ng-controller=\"ExampleController\">\n         <input ng-model=\"val\" ng-pattern=\"/^\\d+$/\" name=\"anim\" class=\"my-input\"\n                aria-describedby=\"inputDescription\" />\n       </form>\n     </file>\n * </example>\n *\n * ## Binding to a getter/setter\n *\n * Sometimes it's helpful to bind `ngModel` to a getter/setter function.  A getter/setter is a\n * function that returns a representation of the model when called with zero arguments, and sets\n * the internal state of a model when called with an argument. It's sometimes useful to use this\n * for models that have an internal representation that's different from what the model exposes\n * to the view.\n *\n * <div class=\"alert alert-success\">\n * **Best Practice:** It's best to keep getters fast because Angular is likely to call them more\n * frequently than other parts of your code.\n * </div>\n *\n * You use this behavior by adding `ng-model-options=\"{ getterSetter: true }\"` to an element that\n * has `ng-model` attached to it. You can also add `ng-model-options=\"{ getterSetter: true }\"` to\n * a `<form>`, which will enable this behavior for all `<input>`s within it. See\n * {@link ng.directive:ngModelOptions `ngModelOptions`} for more.\n *\n * The following example shows how to use `ngModel` with a getter/setter:\n *\n * @example\n * <example name=\"ngModel-getter-setter\" module=\"getterSetterExample\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <form name=\"userForm\">\n           <label>Name:\n             <input type=\"text\" name=\"userName\"\n                    ng-model=\"user.name\"\n                    ng-model-options=\"{ getterSetter: true }\" />\n           </label>\n         </form>\n         <pre>user.name = <span ng-bind=\"user.name()\"></span></pre>\n       </div>\n     </file>\n     <file name=\"app.js\">\n       angular.module('getterSetterExample', [])\n         .controller('ExampleController', ['$scope', function($scope) {\n           var _name = 'Brian';\n           $scope.user = {\n             name: function(newName) {\n              // Note that newName can be undefined for two reasons:\n              // 1. Because it is called as a getter and thus called with no arguments\n              // 2. Because the property should actually be set to undefined. This happens e.g. if the\n              //    input is invalid\n              return arguments.length ? (_name = newName) : _name;\n             }\n           };\n         }]);\n     </file>\n * </example>\n */\nvar ngModelDirective = ['$rootScope', function($rootScope) {\n  return {\n    restrict: 'A',\n    require: ['ngModel', '^?form', '^?ngModelOptions'],\n    controller: NgModelController,\n    // Prelink needs to run before any input directive\n    // so that we can set the NgModelOptions in NgModelController\n    // before anyone else uses it.\n    priority: 1,\n    compile: function ngModelCompile(element) {\n      // Setup initial state of the control\n      element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS);\n\n      return {\n        pre: function ngModelPreLink(scope, element, attr, ctrls) {\n          var modelCtrl = ctrls[0],\n              formCtrl = ctrls[1] || modelCtrl.$$parentForm,\n              optionsCtrl = ctrls[2];\n\n          if (optionsCtrl) {\n            modelCtrl.$options = optionsCtrl.$options;\n          }\n\n          modelCtrl.$$initGetterSetters();\n\n          // notify others, especially parent forms\n          formCtrl.$addControl(modelCtrl);\n\n          attr.$observe('name', function(newValue) {\n            if (modelCtrl.$name !== newValue) {\n              modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);\n            }\n          });\n\n          scope.$on('$destroy', function() {\n            modelCtrl.$$parentForm.$removeControl(modelCtrl);\n          });\n        },\n        post: function ngModelPostLink(scope, element, attr, ctrls) {\n          var modelCtrl = ctrls[0];\n          if (modelCtrl.$options.getOption('updateOn')) {\n            element.on(modelCtrl.$options.getOption('updateOn'), function(ev) {\n              modelCtrl.$$debounceViewValueCommit(ev && ev.type);\n            });\n          }\n\n          function setTouched() {\n            modelCtrl.$setTouched();\n          }\n\n          element.on('blur', function() {\n            if (modelCtrl.$touched) return;\n\n            if ($rootScope.$$phase) {\n              scope.$evalAsync(setTouched);\n            } else {\n              scope.$apply(setTouched);\n            }\n          });\n        }\n      };\n    }\n  };\n}];\n\n/* exported defaultModelOptions */\nvar defaultModelOptions;\nvar DEFAULT_REGEXP = /(\\s+|^)default(\\s+|$)/;\n\n/**\n * @ngdoc type\n * @name ModelOptions\n * @description\n * A container for the options set by the {@link ngModelOptions} directive\n */\nfunction ModelOptions(options) {\n  this.$$options = options;\n}\n\nModelOptions.prototype = {\n\n  /**\n   * @ngdoc method\n   * @name ModelOptions#getOption\n   * @param {string} name the name of the option to retrieve\n   * @returns {*} the value of the option\n   * @description\n   * Returns the value of the given option\n   */\n  getOption: function(name) {\n    return this.$$options[name];\n  },\n\n  /**\n   * @ngdoc method\n   * @name ModelOptions#createChild\n   * @param {Object} options a hash of options for the new child that will override the parent's options\n   * @return {ModelOptions} a new `ModelOptions` object initialized with the given options.\n   */\n  createChild: function(options) {\n    var inheritAll = false;\n\n    // make a shallow copy\n    options = extend({}, options);\n\n    // Inherit options from the parent if specified by the value `\"$inherit\"`\n    forEach(options, /* @this */ function(option, key) {\n      if (option === '$inherit') {\n        if (key === '*') {\n          inheritAll = true;\n        } else {\n          options[key] = this.$$options[key];\n          // `updateOn` is special so we must also inherit the `updateOnDefault` option\n          if (key === 'updateOn') {\n            options.updateOnDefault = this.$$options.updateOnDefault;\n          }\n        }\n      } else {\n        if (key === 'updateOn') {\n          // If the `updateOn` property contains the `default` event then we have to remove\n          // it from the event list and set the `updateOnDefault` flag.\n          options.updateOnDefault = false;\n          options[key] = trim(option.replace(DEFAULT_REGEXP, function() {\n            options.updateOnDefault = true;\n            return ' ';\n          }));\n        }\n      }\n    }, this);\n\n    if (inheritAll) {\n      // We have a property of the form: `\"*\": \"$inherit\"`\n      delete options['*'];\n      defaults(options, this.$$options);\n    }\n\n    // Finally add in any missing defaults\n    defaults(options, defaultModelOptions.$$options);\n\n    return new ModelOptions(options);\n  }\n};\n\n\ndefaultModelOptions = new ModelOptions({\n  updateOn: '',\n  updateOnDefault: true,\n  debounce: 0,\n  getterSetter: false,\n  allowInvalid: false,\n  timezone: null\n});\n\n\n/**\n * @ngdoc directive\n * @name ngModelOptions\n *\n * @description\n * This directive allows you to modify the behaviour of {@link ngModel} directives within your\n * application. You can specify an `ngModelOptions` directive on any element. All {@link ngModel}\n * directives will use the options of their nearest `ngModelOptions` ancestor.\n *\n * The `ngModelOptions` settings are found by evaluating the value of the attribute directive as\n * an Angular expression. This expression should evaluate to an object, whose properties contain\n * the settings. For example: `<div \"ng-model-options\"=\"{ debounce: 100 }\"`.\n *\n * ## Inheriting Options\n *\n * You can specify that an `ngModelOptions` setting should be inherited from a parent `ngModelOptions`\n * directive by giving it the value of `\"$inherit\"`.\n * Then it will inherit that setting from the first `ngModelOptions` directive found by traversing up the\n * DOM tree. If there is no ancestor element containing an `ngModelOptions` directive then default settings\n * will be used.\n *\n * For example given the following fragment of HTML\n *\n *\n * ```html\n * <div ng-model-options=\"{ allowInvalid: true, debounce: 200 }\">\n *   <form ng-model-options=\"{ updateOn: 'blur', allowInvalid: '$inherit' }\">\n *     <input ng-model-options=\"{ updateOn: 'default', allowInvalid: '$inherit' }\" />\n *   </form>\n * </div>\n * ```\n *\n * the `input` element will have the following settings\n *\n * ```js\n * { allowInvalid: true, updateOn: 'default', debounce: 0 }\n * ```\n *\n * Notice that the `debounce` setting was not inherited and used the default value instead.\n *\n * You can specify that all undefined settings are automatically inherited from an ancestor by\n * including a property with key of `\"*\"` and value of `\"$inherit\"`.\n *\n * For example given the following fragment of HTML\n *\n *\n * ```html\n * <div ng-model-options=\"{ allowInvalid: true, debounce: 200 }\">\n *   <form ng-model-options=\"{ updateOn: 'blur', \"*\": '$inherit' }\">\n *     <input ng-model-options=\"{ updateOn: 'default', \"*\": '$inherit' }\" />\n *   </form>\n * </div>\n * ```\n *\n * the `input` element will have the following settings\n *\n * ```js\n * { allowInvalid: true, updateOn: 'default', debounce: 200 }\n * ```\n *\n * Notice that the `debounce` setting now inherits the value from the outer `<div>` element.\n *\n * If you are creating a reusable component then you should be careful when using `\"*\": \"$inherit\"`\n * since you may inadvertently inherit a setting in the future that changes the behavior of your component.\n *\n *\n * ## Triggering and debouncing model updates\n *\n * The `updateOn` and `debounce` properties allow you to specify a custom list of events that will\n * trigger a model update and/or a debouncing delay so that the actual update only takes place when\n * a timer expires; this timer will be reset after another change takes place.\n *\n * Given the nature of `ngModelOptions`, the value displayed inside input fields in the view might\n * be different from the value in the actual model. This means that if you update the model you\n * should also invoke {@link ngModel.NgModelController#$rollbackViewValue} on the relevant input field in\n * order to make sure it is synchronized with the model and that any debounced action is canceled.\n *\n * The easiest way to reference the control's {@link ngModel.NgModelController#$rollbackViewValue}\n * method is by making sure the input is placed inside a form that has a `name` attribute. This is\n * important because `form` controllers are published to the related scope under the name in their\n * `name` attribute.\n *\n * Any pending changes will take place immediately when an enclosing form is submitted via the\n * `submit` event. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`\n * to have access to the updated model.\n *\n * The following example shows how to override immediate updates. Changes on the inputs within the\n * form will update the model only when the control loses focus (blur event). If `escape` key is\n * pressed while the input field is focused, the value is reset to the value in the current model.\n *\n * <example name=\"ngModelOptions-directive-blur\" module=\"optionsExample\">\n *   <file name=\"index.html\">\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"userForm\">\n *         <label>\n *           Name:\n *           <input type=\"text\" name=\"userName\"\n *                  ng-model=\"user.name\"\n *                  ng-model-options=\"{ updateOn: 'blur' }\"\n *                  ng-keyup=\"cancel($event)\" />\n *         </label><br />\n *         <label>\n *           Other data:\n *           <input type=\"text\" ng-model=\"user.data\" />\n *         </label><br />\n *       </form>\n *       <pre>user.name = <span ng-bind=\"user.name\"></span></pre>\n *     </div>\n *   </file>\n *   <file name=\"app.js\">\n *     angular.module('optionsExample', [])\n *       .controller('ExampleController', ['$scope', function($scope) {\n *         $scope.user = { name: 'say', data: '' };\n *\n *         $scope.cancel = function(e) {\n *           if (e.keyCode === 27) {\n *             $scope.userForm.userName.$rollbackViewValue();\n *           }\n *         };\n *       }]);\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     var model = element(by.binding('user.name'));\n *     var input = element(by.model('user.name'));\n *     var other = element(by.model('user.data'));\n *\n *     it('should allow custom events', function() {\n *       input.sendKeys(' hello');\n *       input.click();\n *       expect(model.getText()).toEqual('say');\n *       other.click();\n *       expect(model.getText()).toEqual('say hello');\n *     });\n *\n *     it('should $rollbackViewValue when model changes', function() {\n *       input.sendKeys(' hello');\n *       expect(input.getAttribute('value')).toEqual('say hello');\n *       input.sendKeys(protractor.Key.ESCAPE);\n *       expect(input.getAttribute('value')).toEqual('say');\n *       other.click();\n *       expect(model.getText()).toEqual('say');\n *     });\n *   </file>\n * </example>\n *\n * The next example shows how to debounce model changes. Model will be updated only 1 sec after last change.\n * If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty.\n *\n * <example name=\"ngModelOptions-directive-debounce\" module=\"optionsExample\">\n *   <file name=\"index.html\">\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"userForm\">\n *         Name:\n *         <input type=\"text\" name=\"userName\"\n *                ng-model=\"user.name\"\n *                ng-model-options=\"{ debounce: 1000 }\" />\n *         <button ng-click=\"userForm.userName.$rollbackViewValue(); user.name=''\">Clear</button><br />\n *       </form>\n *       <pre>user.name = <span ng-bind=\"user.name\"></span></pre>\n *     </div>\n *   </file>\n *   <file name=\"app.js\">\n *     angular.module('optionsExample', [])\n *       .controller('ExampleController', ['$scope', function($scope) {\n *         $scope.user = { name: 'say' };\n *       }]);\n *   </file>\n * </example>\n *\n * ## Model updates and validation\n *\n * The default behaviour in `ngModel` is that the model value is set to `undefined` when the\n * validation determines that the value is invalid. By setting the `allowInvalid` property to true,\n * the model will still be updated even if the value is invalid.\n *\n *\n * ## Connecting to the scope\n *\n * By setting the `getterSetter` property to true you are telling ngModel that the `ngModel` expression\n * on the scope refers to a \"getter/setter\" function rather than the value itself.\n *\n * The following example shows how to bind to getter/setters:\n *\n * <example name=\"ngModelOptions-directive-getter-setter\" module=\"getterSetterExample\">\n *   <file name=\"index.html\">\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"userForm\">\n *         <label>\n *           Name:\n *           <input type=\"text\" name=\"userName\"\n *                  ng-model=\"user.name\"\n *                  ng-model-options=\"{ getterSetter: true }\" />\n *         </label>\n *       </form>\n *       <pre>user.name = <span ng-bind=\"user.name()\"></span></pre>\n *     </div>\n *   </file>\n *   <file name=\"app.js\">\n *     angular.module('getterSetterExample', [])\n *       .controller('ExampleController', ['$scope', function($scope) {\n *         var _name = 'Brian';\n *         $scope.user = {\n *           name: function(newName) {\n *             return angular.isDefined(newName) ? (_name = newName) : _name;\n *           }\n *         };\n *       }]);\n *   </file>\n * </example>\n *\n *\n * ## Specifying timezones\n *\n * You can specify the timezone that date/time input directives expect by providing its name in the\n * `timezone` property.\n *\n * @param {Object} ngModelOptions options to apply to {@link ngModel} directives on this element and\n *   and its descendents. Valid keys are:\n *   - `updateOn`: string specifying which event should the input be bound to. You can set several\n *     events using an space delimited list. There is a special event called `default` that\n *     matches the default events belonging to the control.\n *   - `debounce`: integer value which contains the debounce model update value in milliseconds. A\n *     value of 0 triggers an immediate update. If an object is supplied instead, you can specify a\n *     custom value for each event. For example:\n *     ```\n *     ng-model-options=\"{\n *       updateOn: 'default blur',\n *       debounce: { 'default': 500, 'blur': 0 }\n *     }\"\n *     ```\n *   - `allowInvalid`: boolean value which indicates that the model can be set with values that did\n *     not validate correctly instead of the default behavior of setting the model to undefined.\n *   - `getterSetter`: boolean value which determines whether or not to treat functions bound to\n *     `ngModel` as getters/setters.\n *   - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for\n *     `<input type=\"date\" />`, `<input type=\"time\" />`, ... . It understands UTC/GMT and the\n *     continental US time zone abbreviations, but for general use, use a time zone offset, for\n *     example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)\n *     If not specified, the timezone of the browser will be used.\n *\n */\nvar ngModelOptionsDirective = function() {\n  NgModelOptionsController.$inject = ['$attrs', '$scope'];\n  function NgModelOptionsController($attrs, $scope) {\n    this.$$attrs = $attrs;\n    this.$$scope = $scope;\n  }\n  NgModelOptionsController.prototype = {\n    $onInit: function() {\n      var parentOptions = this.parentCtrl ? this.parentCtrl.$options : defaultModelOptions;\n      var modelOptionsDefinition = this.$$scope.$eval(this.$$attrs.ngModelOptions);\n\n      this.$options = parentOptions.createChild(modelOptionsDefinition);\n    }\n  };\n\n  return {\n    restrict: 'A',\n    // ngModelOptions needs to run before ngModel and input directives\n    priority: 10,\n    require: {parentCtrl: '?^^ngModelOptions'},\n    bindToController: true,\n    controller: NgModelOptionsController\n  };\n};\n\n\n// shallow copy over values from `src` that are not already specified on `dst`\nfunction defaults(dst, src) {\n  forEach(src, function(value, key) {\n    if (!isDefined(dst[key])) {\n      dst[key] = value;\n    }\n  });\n}\n\n/**\n * @ngdoc directive\n * @name ngNonBindable\n * @restrict AC\n * @priority 1000\n *\n * @description\n * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current\n * DOM element. This is useful if the element contains what appears to be Angular directives and\n * bindings but which should be ignored by Angular. This could be the case if you have a site that\n * displays snippets of code, for instance.\n *\n * @element ANY\n *\n * @example\n * In this example there are two locations where a simple interpolation binding (`{{}}`) is present,\n * but the one wrapped in `ngNonBindable` is left alone.\n *\n * @example\n    <example name=\"ng-non-bindable\">\n      <file name=\"index.html\">\n        <div>Normal: {{1 + 2}}</div>\n        <div ng-non-bindable>Ignored: {{1 + 2}}</div>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-non-bindable', function() {\n         expect(element(by.binding('1 + 2')).getText()).toContain('3');\n         expect(element.all(by.css('div')).last().getText()).toMatch(/1 \\+ 2/);\n       });\n      </file>\n    </example>\n */\nvar ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });\n\n/* exported ngOptionsDirective */\n\n/* global jqLiteRemove */\n\nvar ngOptionsMinErr = minErr('ngOptions');\n\n/**\n * @ngdoc directive\n * @name ngOptions\n * @restrict A\n *\n * @description\n *\n * The `ngOptions` attribute can be used to dynamically generate a list of `<option>`\n * elements for the `<select>` element using the array or object obtained by evaluating the\n * `ngOptions` comprehension expression.\n *\n * In many cases, {@link ng.directive:ngRepeat ngRepeat} can be used on `<option>` elements instead of\n * `ngOptions` to achieve a similar result. However, `ngOptions` provides some benefits:\n * - more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the\n * comprehension expression\n * - reduced memory consumption by not creating a new scope for each repeated instance\n * - increased render speed by creating the options in a documentFragment instead of individually\n *\n * When an item in the `<select>` menu is selected, the array element or object property\n * represented by the selected option will be bound to the model identified by the `ngModel`\n * directive.\n *\n * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can\n * be nested into the `<select>` element. This element will then represent the `null` or \"not selected\"\n * option. See example below for demonstration.\n *\n * ## Complex Models (objects or collections)\n *\n * By default, `ngModel` watches the model by reference, not value. This is important to know when\n * binding the select to a model that is an object or a collection.\n *\n * One issue occurs if you want to preselect an option. For example, if you set\n * the model to an object that is equal to an object in your collection, `ngOptions` won't be able to set the selection,\n * because the objects are not identical. So by default, you should always reference the item in your collection\n * for preselections, e.g.: `$scope.selected = $scope.collection[3]`.\n *\n * Another solution is to use a `track by` clause, because then `ngOptions` will track the identity\n * of the item not by reference, but by the result of the `track by` expression. For example, if your\n * collection items have an id property, you would `track by item.id`.\n *\n * A different issue with objects or collections is that ngModel won't detect if an object property or\n * a collection item changes. For that reason, `ngOptions` additionally watches the model using\n * `$watchCollection`, when the expression contains a `track by` clause or the the select has the `multiple` attribute.\n * This allows ngOptions to trigger a re-rendering of the options even if the actual object/collection\n * has not changed identity, but only a property on the object or an item in the collection changes.\n *\n * Note that `$watchCollection` does a shallow comparison of the properties of the object (or the items in the collection\n * if the model is an array). This means that changing a property deeper than the first level inside the\n * object/collection will not trigger a re-rendering.\n *\n * ## `select` **`as`**\n *\n * Using `select` **`as`** will bind the result of the `select` expression to the model, but\n * the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)\n * or property name (for object data sources) of the value within the collection. If a **`track by`** expression\n * is used, the result of that expression will be set as the value of the `option` and `select` elements.\n *\n *\n * ### `select` **`as`** and **`track by`**\n *\n * <div class=\"alert alert-warning\">\n * Be careful when using `select` **`as`** and **`track by`** in the same expression.\n * </div>\n *\n * Given this array of items on the $scope:\n *\n * ```js\n * $scope.items = [{\n *   id: 1,\n *   label: 'aLabel',\n *   subItem: { name: 'aSubItem' }\n * }, {\n *   id: 2,\n *   label: 'bLabel',\n *   subItem: { name: 'bSubItem' }\n * }];\n * ```\n *\n * This will work:\n *\n * ```html\n * <select ng-options=\"item as item.label for item in items track by item.id\" ng-model=\"selected\"></select>\n * ```\n * ```js\n * $scope.selected = $scope.items[0];\n * ```\n *\n * but this will not work:\n *\n * ```html\n * <select ng-options=\"item.subItem as item.label for item in items track by item.id\" ng-model=\"selected\"></select>\n * ```\n * ```js\n * $scope.selected = $scope.items[0].subItem;\n * ```\n *\n * In both examples, the **`track by`** expression is applied successfully to each `item` in the\n * `items` array. Because the selected option has been set programmatically in the controller, the\n * **`track by`** expression is also applied to the `ngModel` value. In the first example, the\n * `ngModel` value is `items[0]` and the **`track by`** expression evaluates to `items[0].id` with\n * no issue. In the second example, the `ngModel` value is `items[0].subItem` and the **`track by`**\n * expression evaluates to `items[0].subItem.id` (which is undefined). As a result, the model value\n * is not matched against any `<option>` and the `<select>` appears as having no selected value.\n *\n *\n * @param {string} ngModel Assignable AngularJS expression to data-bind to.\n * @param {comprehension_expression} ngOptions in one of the following forms:\n *\n *   * for array data sources:\n *     * `label` **`for`** `value` **`in`** `array`\n *     * `select` **`as`** `label` **`for`** `value` **`in`** `array`\n *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array`\n *     * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array`\n *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`\n *     * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`\n *     * `label` **`for`** `value` **`in`** `array` | orderBy:`orderexpr` **`track by`** `trackexpr`\n *        (for including a filter with `track by`)\n *   * for object data sources:\n *     * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`\n *     * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`\n *     * `label` **`group by`** `group` **`for (`**`key`**`,`** `value`**`) in`** `object`\n *     * `label` **`disable when`** `disable` **`for (`**`key`**`,`** `value`**`) in`** `object`\n *     * `select` **`as`** `label` **`group by`** `group`\n *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`\n *     * `select` **`as`** `label` **`disable when`** `disable`\n *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`\n *\n * Where:\n *\n *   * `array` / `object`: an expression which evaluates to an array / object to iterate over.\n *   * `value`: local variable which will refer to each item in the `array` or each property value\n *      of `object` during iteration.\n *   * `key`: local variable which will refer to a property name in `object` during iteration.\n *   * `label`: The result of this expression will be the label for `<option>` element. The\n *     `expression` will most likely refer to the `value` variable (e.g. `value.propertyName`).\n *   * `select`: The result of this expression will be bound to the model of the parent `<select>`\n *      element. If not specified, `select` expression will default to `value`.\n *   * `group`: The result of this expression will be used to group options using the `<optgroup>`\n *      DOM element.\n *   * `disable`: The result of this expression will be used to disable the rendered `<option>`\n *      element. Return `true` to disable.\n *   * `trackexpr`: Used when working with an array of objects. The result of this expression will be\n *      used to identify the objects in the array. The `trackexpr` will most likely refer to the\n *     `value` variable (e.g. `value.propertyName`). With this the selection is preserved\n *      even when the options are recreated (e.g. reloaded from the server).\n * @param {string=} name Property name of the form under which the control is published.\n * @param {string=} required The control is considered valid only if value is entered.\n * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n *    `required` when you want to data-bind to the `required` attribute.\n * @param {string=} ngAttrSize sets the size of the select element dynamically. Uses the\n * {@link guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes ngAttr} directive.\n *\n * @example\n    <example module=\"selectExample\" name=\"select\">\n      <file name=\"index.html\">\n        <script>\n        angular.module('selectExample', [])\n          .controller('ExampleController', ['$scope', function($scope) {\n            $scope.colors = [\n              {name:'black', shade:'dark'},\n              {name:'white', shade:'light', notAnOption: true},\n              {name:'red', shade:'dark'},\n              {name:'blue', shade:'dark', notAnOption: true},\n              {name:'yellow', shade:'light', notAnOption: false}\n            ];\n            $scope.myColor = $scope.colors[2]; // red\n          }]);\n        </script>\n        <div ng-controller=\"ExampleController\">\n          <ul>\n            <li ng-repeat=\"color in colors\">\n              <label>Name: <input ng-model=\"color.name\"></label>\n              <label><input type=\"checkbox\" ng-model=\"color.notAnOption\"> Disabled?</label>\n              <button ng-click=\"colors.splice($index, 1)\" aria-label=\"Remove\">X</button>\n            </li>\n            <li>\n              <button ng-click=\"colors.push({})\">add</button>\n            </li>\n          </ul>\n          <hr/>\n          <label>Color (null not allowed):\n            <select ng-model=\"myColor\" ng-options=\"color.name for color in colors\"></select>\n          </label><br/>\n          <label>Color (null allowed):\n          <span  class=\"nullable\">\n            <select ng-model=\"myColor\" ng-options=\"color.name for color in colors\">\n              <option value=\"\">-- choose color --</option>\n            </select>\n          </span></label><br/>\n\n          <label>Color grouped by shade:\n            <select ng-model=\"myColor\" ng-options=\"color.name group by color.shade for color in colors\">\n            </select>\n          </label><br/>\n\n          <label>Color grouped by shade, with some disabled:\n            <select ng-model=\"myColor\"\n                  ng-options=\"color.name group by color.shade disable when color.notAnOption for color in colors\">\n            </select>\n          </label><br/>\n\n\n\n          Select <button ng-click=\"myColor = { name:'not in list', shade: 'other' }\">bogus</button>.\n          <br/>\n          <hr/>\n          Currently selected: {{ {selected_color:myColor} }}\n          <div style=\"border:solid 1px black; height:20px\"\n               ng-style=\"{'background-color':myColor.name}\">\n          </div>\n        </div>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n         it('should check ng-options', function() {\n           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red');\n           element.all(by.model('myColor')).first().click();\n           element.all(by.css('select[ng-model=\"myColor\"] option')).first().click();\n           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black');\n           element(by.css('.nullable select[ng-model=\"myColor\"]')).click();\n           element.all(by.css('.nullable select[ng-model=\"myColor\"] option')).first().click();\n           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('null');\n         });\n      </file>\n    </example>\n */\n\n/* eslint-disable max-len */\n//                     //00001111111111000000000002222222222000000000000000000000333333333300000000000000000000000004444444444400000000000005555555555555000000000666666666666600000007777777777777000000000000000888888888800000000000000000009999999999\nvar NG_OPTIONS_REGEXP = /^\\s*([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?(?:\\s+group\\s+by\\s+([\\s\\S]+?))?(?:\\s+disable\\s+when\\s+([\\s\\S]+?))?\\s+for\\s+(?:([$\\w][$\\w]*)|(?:\\(\\s*([$\\w][$\\w]*)\\s*,\\s*([$\\w][$\\w]*)\\s*\\)))\\s+in\\s+([\\s\\S]+?)(?:\\s+track\\s+by\\s+([\\s\\S]+?))?$/;\n                        // 1: value expression (valueFn)\n                        // 2: label expression (displayFn)\n                        // 3: group by expression (groupByFn)\n                        // 4: disable when expression (disableWhenFn)\n                        // 5: array item variable name\n                        // 6: object item key variable name\n                        // 7: object item value variable name\n                        // 8: collection expression\n                        // 9: track by expression\n/* eslint-enable */\n\n\nvar ngOptionsDirective = ['$compile', '$document', '$parse', function($compile, $document, $parse) {\n\n  function parseOptionsExpression(optionsExp, selectElement, scope) {\n\n    var match = optionsExp.match(NG_OPTIONS_REGEXP);\n    if (!(match)) {\n      throw ngOptionsMinErr('iexp',\n        'Expected expression in form of ' +\n        '\\'_select_ (as _label_)? for (_key_,)?_value_ in _collection_\\'' +\n        ' but got \\'{0}\\'. Element: {1}',\n        optionsExp, startingTag(selectElement));\n    }\n\n    // Extract the parts from the ngOptions expression\n\n    // The variable name for the value of the item in the collection\n    var valueName = match[5] || match[7];\n    // The variable name for the key of the item in the collection\n    var keyName = match[6];\n\n    // An expression that generates the viewValue for an option if there is a label expression\n    var selectAs = / as /.test(match[0]) && match[1];\n    // An expression that is used to track the id of each object in the options collection\n    var trackBy = match[9];\n    // An expression that generates the viewValue for an option if there is no label expression\n    var valueFn = $parse(match[2] ? match[1] : valueName);\n    var selectAsFn = selectAs && $parse(selectAs);\n    var viewValueFn = selectAsFn || valueFn;\n    var trackByFn = trackBy && $parse(trackBy);\n\n    // Get the value by which we are going to track the option\n    // if we have a trackFn then use that (passing scope and locals)\n    // otherwise just hash the given viewValue\n    var getTrackByValueFn = trackBy ?\n                              function(value, locals) { return trackByFn(scope, locals); } :\n                              function getHashOfValue(value) { return hashKey(value); };\n    var getTrackByValue = function(value, key) {\n      return getTrackByValueFn(value, getLocals(value, key));\n    };\n\n    var displayFn = $parse(match[2] || match[1]);\n    var groupByFn = $parse(match[3] || '');\n    var disableWhenFn = $parse(match[4] || '');\n    var valuesFn = $parse(match[8]);\n\n    var locals = {};\n    var getLocals = keyName ? function(value, key) {\n      locals[keyName] = key;\n      locals[valueName] = value;\n      return locals;\n    } : function(value) {\n      locals[valueName] = value;\n      return locals;\n    };\n\n\n    function Option(selectValue, viewValue, label, group, disabled) {\n      this.selectValue = selectValue;\n      this.viewValue = viewValue;\n      this.label = label;\n      this.group = group;\n      this.disabled = disabled;\n    }\n\n    function getOptionValuesKeys(optionValues) {\n      var optionValuesKeys;\n\n      if (!keyName && isArrayLike(optionValues)) {\n        optionValuesKeys = optionValues;\n      } else {\n        // if object, extract keys, in enumeration order, unsorted\n        optionValuesKeys = [];\n        for (var itemKey in optionValues) {\n          if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') {\n            optionValuesKeys.push(itemKey);\n          }\n        }\n      }\n      return optionValuesKeys;\n    }\n\n    return {\n      trackBy: trackBy,\n      getTrackByValue: getTrackByValue,\n      getWatchables: $parse(valuesFn, function(optionValues) {\n        // Create a collection of things that we would like to watch (watchedArray)\n        // so that they can all be watched using a single $watchCollection\n        // that only runs the handler once if anything changes\n        var watchedArray = [];\n        optionValues = optionValues || [];\n\n        var optionValuesKeys = getOptionValuesKeys(optionValues);\n        var optionValuesLength = optionValuesKeys.length;\n        for (var index = 0; index < optionValuesLength; index++) {\n          var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];\n          var value = optionValues[key];\n\n          var locals = getLocals(value, key);\n          var selectValue = getTrackByValueFn(value, locals);\n          watchedArray.push(selectValue);\n\n          // Only need to watch the displayFn if there is a specific label expression\n          if (match[2] || match[1]) {\n            var label = displayFn(scope, locals);\n            watchedArray.push(label);\n          }\n\n          // Only need to watch the disableWhenFn if there is a specific disable expression\n          if (match[4]) {\n            var disableWhen = disableWhenFn(scope, locals);\n            watchedArray.push(disableWhen);\n          }\n        }\n        return watchedArray;\n      }),\n\n      getOptions: function() {\n\n        var optionItems = [];\n        var selectValueMap = {};\n\n        // The option values were already computed in the `getWatchables` fn,\n        // which must have been called to trigger `getOptions`\n        var optionValues = valuesFn(scope) || [];\n        var optionValuesKeys = getOptionValuesKeys(optionValues);\n        var optionValuesLength = optionValuesKeys.length;\n\n        for (var index = 0; index < optionValuesLength; index++) {\n          var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];\n          var value = optionValues[key];\n          var locals = getLocals(value, key);\n          var viewValue = viewValueFn(scope, locals);\n          var selectValue = getTrackByValueFn(viewValue, locals);\n          var label = displayFn(scope, locals);\n          var group = groupByFn(scope, locals);\n          var disabled = disableWhenFn(scope, locals);\n          var optionItem = new Option(selectValue, viewValue, label, group, disabled);\n\n          optionItems.push(optionItem);\n          selectValueMap[selectValue] = optionItem;\n        }\n\n        return {\n          items: optionItems,\n          selectValueMap: selectValueMap,\n          getOptionFromViewValue: function(value) {\n            return selectValueMap[getTrackByValue(value)];\n          },\n          getViewValueFromOption: function(option) {\n            // If the viewValue could be an object that may be mutated by the application,\n            // we need to make a copy and not return the reference to the value on the option.\n            return trackBy ? copy(option.viewValue) : option.viewValue;\n          }\n        };\n      }\n    };\n  }\n\n\n  // we can't just jqLite('<option>') since jqLite is not smart enough\n  // to create it in <select> and IE barfs otherwise.\n  var optionTemplate = window.document.createElement('option'),\n      optGroupTemplate = window.document.createElement('optgroup');\n\n    function ngOptionsPostLink(scope, selectElement, attr, ctrls) {\n\n      var selectCtrl = ctrls[0];\n      var ngModelCtrl = ctrls[1];\n      var multiple = attr.multiple;\n\n      // The emptyOption allows the application developer to provide their own custom \"empty\"\n      // option when the viewValue does not match any of the option values.\n      for (var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) {\n        if (children[i].value === '') {\n          selectCtrl.hasEmptyOption = true;\n          selectCtrl.emptyOption = children.eq(i);\n          break;\n        }\n      }\n\n      var providedEmptyOption = !!selectCtrl.emptyOption;\n\n      var unknownOption = jqLite(optionTemplate.cloneNode(false));\n      unknownOption.val('?');\n\n      var options;\n      var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope);\n      // This stores the newly created options before they are appended to the select.\n      // Since the contents are removed from the fragment when it is appended,\n      // we only need to create it once.\n      var listFragment = $document[0].createDocumentFragment();\n\n      // Overwrite the implementation. ngOptions doesn't use hashes\n      selectCtrl.generateUnknownOptionValue = function(val) {\n        return '?';\n      };\n\n      // Update the controller methods for multiple selectable options\n      if (!multiple) {\n\n        selectCtrl.writeValue = function writeNgOptionsValue(value) {\n          var selectedOption = options.selectValueMap[selectElement.val()];\n          var option = options.getOptionFromViewValue(value);\n\n          // Make sure to remove the selected attribute from the previously selected option\n          // Otherwise, screen readers might get confused\n          if (selectedOption) selectedOption.element.removeAttribute('selected');\n\n          if (option) {\n            // Don't update the option when it is already selected.\n            // For example, the browser will select the first option by default. In that case,\n            // most properties are set automatically - except the `selected` attribute, which we\n            // set always\n\n            if (selectElement[0].value !== option.selectValue) {\n              selectCtrl.removeUnknownOption();\n              selectCtrl.unselectEmptyOption();\n\n              selectElement[0].value = option.selectValue;\n              option.element.selected = true;\n            }\n\n            option.element.setAttribute('selected', 'selected');\n          } else {\n\n            if (providedEmptyOption) {\n              selectCtrl.selectEmptyOption();\n            } else if (selectCtrl.unknownOption.parent().length) {\n              selectCtrl.updateUnknownOption(value);\n            } else {\n              selectCtrl.renderUnknownOption(value);\n            }\n          }\n        };\n\n        selectCtrl.readValue = function readNgOptionsValue() {\n\n          var selectedOption = options.selectValueMap[selectElement.val()];\n\n          if (selectedOption && !selectedOption.disabled) {\n            selectCtrl.unselectEmptyOption();\n            selectCtrl.removeUnknownOption();\n            return options.getViewValueFromOption(selectedOption);\n          }\n          return null;\n        };\n\n        // If we are using `track by` then we must watch the tracked value on the model\n        // since ngModel only watches for object identity change\n        // FIXME: When a user selects an option, this watch will fire needlessly\n        if (ngOptions.trackBy) {\n          scope.$watch(\n            function() { return ngOptions.getTrackByValue(ngModelCtrl.$viewValue); },\n            function() { ngModelCtrl.$render(); }\n          );\n        }\n\n      } else {\n\n        selectCtrl.writeValue = function writeNgOptionsMultiple(values) {\n          // Only set `<option>.selected` if necessary, in order to prevent some browsers from\n          // scrolling to `<option>` elements that are outside the `<select>` element's viewport.\n\n          var selectedOptions = values && values.map(getAndUpdateSelectedOption) || [];\n\n          options.items.forEach(function(option) {\n            if (option.element.selected && !includes(selectedOptions, option)) {\n              option.element.selected = false;\n            }\n          });\n        };\n\n\n        selectCtrl.readValue = function readNgOptionsMultiple() {\n          var selectedValues = selectElement.val() || [],\n              selections = [];\n\n          forEach(selectedValues, function(value) {\n            var option = options.selectValueMap[value];\n            if (option && !option.disabled) selections.push(options.getViewValueFromOption(option));\n          });\n\n          return selections;\n        };\n\n        // If we are using `track by` then we must watch these tracked values on the model\n        // since ngModel only watches for object identity change\n        if (ngOptions.trackBy) {\n\n          scope.$watchCollection(function() {\n            if (isArray(ngModelCtrl.$viewValue)) {\n              return ngModelCtrl.$viewValue.map(function(value) {\n                return ngOptions.getTrackByValue(value);\n              });\n            }\n          }, function() {\n            ngModelCtrl.$render();\n          });\n\n        }\n      }\n\n      if (providedEmptyOption) {\n\n        // we need to remove it before calling selectElement.empty() because otherwise IE will\n        // remove the label from the element. wtf?\n        selectCtrl.emptyOption.remove();\n\n        // compile the element since there might be bindings in it\n        $compile(selectCtrl.emptyOption)(scope);\n\n        if (selectCtrl.emptyOption[0].nodeType === NODE_TYPE_COMMENT) {\n          // This means the empty option has currently no actual DOM node, probably because\n          // it has been modified by a transclusion directive.\n          selectCtrl.hasEmptyOption = false;\n\n          // Redefine the registerOption function, which will catch\n          // options that are added by ngIf etc. (rendering of the node is async because of\n          // lazy transclusion)\n          selectCtrl.registerOption = function(optionScope, optionEl) {\n            if (optionEl.val() === '') {\n              selectCtrl.hasEmptyOption = true;\n              selectCtrl.emptyOption = optionEl;\n              selectCtrl.emptyOption.removeClass('ng-scope');\n              // This ensures the new empty option is selected if previously no option was selected\n              ngModelCtrl.$render();\n\n              optionEl.on('$destroy', function() {\n                selectCtrl.hasEmptyOption = false;\n                selectCtrl.emptyOption = undefined;\n              });\n            }\n          };\n\n        } else {\n          // remove the class, which is added automatically because we recompile the element and it\n          // becomes the compilation root\n          selectCtrl.emptyOption.removeClass('ng-scope');\n        }\n\n      }\n\n      selectElement.empty();\n\n      // We need to do this here to ensure that the options object is defined\n      // when we first hit it in writeNgOptionsValue\n      updateOptions();\n\n      // We will re-render the option elements if the option values or labels change\n      scope.$watchCollection(ngOptions.getWatchables, updateOptions);\n\n      // ------------------------------------------------------------------ //\n\n      function addOptionElement(option, parent) {\n        var optionElement = optionTemplate.cloneNode(false);\n        parent.appendChild(optionElement);\n        updateOptionElement(option, optionElement);\n      }\n\n      function getAndUpdateSelectedOption(viewValue) {\n        var option = options.getOptionFromViewValue(viewValue);\n        var element = option && option.element;\n\n        if (element && !element.selected) element.selected = true;\n\n        return option;\n      }\n\n      function updateOptionElement(option, element) {\n        option.element = element;\n        element.disabled = option.disabled;\n        // NOTE: The label must be set before the value, otherwise IE10/11/EDGE create unresponsive\n        // selects in certain circumstances when multiple selects are next to each other and display\n        // the option list in listbox style, i.e. the select is [multiple], or specifies a [size].\n        // See https://github.com/angular/angular.js/issues/11314 for more info.\n        // This is unfortunately untestable with unit / e2e tests\n        if (option.label !== element.label) {\n          element.label = option.label;\n          element.textContent = option.label;\n        }\n        element.value = option.selectValue;\n      }\n\n      function updateOptions() {\n        var previousValue = options && selectCtrl.readValue();\n\n        // We must remove all current options, but cannot simply set innerHTML = null\n        // since the providedEmptyOption might have an ngIf on it that inserts comments which we\n        // must preserve.\n        // Instead, iterate over the current option elements and remove them or their optgroup\n        // parents\n        if (options) {\n\n          for (var i = options.items.length - 1; i >= 0; i--) {\n            var option = options.items[i];\n            if (isDefined(option.group)) {\n              jqLiteRemove(option.element.parentNode);\n            } else {\n              jqLiteRemove(option.element);\n            }\n          }\n        }\n\n        options = ngOptions.getOptions();\n\n        var groupElementMap = {};\n\n        // Ensure that the empty option is always there if it was explicitly provided\n        if (providedEmptyOption) {\n          selectElement.prepend(selectCtrl.emptyOption);\n        }\n\n        options.items.forEach(function addOption(option) {\n          var groupElement;\n\n          if (isDefined(option.group)) {\n\n            // This option is to live in a group\n            // See if we have already created this group\n            groupElement = groupElementMap[option.group];\n\n            if (!groupElement) {\n\n              groupElement = optGroupTemplate.cloneNode(false);\n              listFragment.appendChild(groupElement);\n\n              // Update the label on the group element\n              // \"null\" is special cased because of Safari\n              groupElement.label = option.group === null ? 'null' : option.group;\n\n              // Store it for use later\n              groupElementMap[option.group] = groupElement;\n            }\n\n            addOptionElement(option, groupElement);\n\n          } else {\n\n            // This option is not in a group\n            addOptionElement(option, listFragment);\n          }\n        });\n\n        selectElement[0].appendChild(listFragment);\n\n        ngModelCtrl.$render();\n\n        // Check to see if the value has changed due to the update to the options\n        if (!ngModelCtrl.$isEmpty(previousValue)) {\n          var nextValue = selectCtrl.readValue();\n          var isNotPrimitive = ngOptions.trackBy || multiple;\n          if (isNotPrimitive ? !equals(previousValue, nextValue) : previousValue !== nextValue) {\n            ngModelCtrl.$setViewValue(nextValue);\n            ngModelCtrl.$render();\n          }\n        }\n\n      }\n  }\n\n  return {\n    restrict: 'A',\n    terminal: true,\n    require: ['select', 'ngModel'],\n    link: {\n      pre: function ngOptionsPreLink(scope, selectElement, attr, ctrls) {\n        // Deactivate the SelectController.register method to prevent\n        // option directives from accidentally registering themselves\n        // (and unwanted $destroy handlers etc.)\n        ctrls[0].registerOption = noop;\n      },\n      post: ngOptionsPostLink\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngPluralize\n * @restrict EA\n *\n * @description\n * `ngPluralize` is a directive that displays messages according to en-US localization rules.\n * These rules are bundled with angular.js, but can be overridden\n * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive\n * by specifying the mappings between\n * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)\n * and the strings to be displayed.\n *\n * # Plural categories and explicit number rules\n * There are two\n * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)\n * in Angular's default en-US locale: \"one\" and \"other\".\n *\n * While a plural category may match many numbers (for example, in en-US locale, \"other\" can match\n * any number that is not 1), an explicit number rule can only match one number. For example, the\n * explicit number rule for \"3\" matches the number 3. There are examples of plural categories\n * and explicit number rules throughout the rest of this documentation.\n *\n * # Configuring ngPluralize\n * You configure ngPluralize by providing 2 attributes: `count` and `when`.\n * You can also provide an optional attribute, `offset`.\n *\n * The value of the `count` attribute can be either a string or an {@link guide/expression\n * Angular expression}; these are evaluated on the current scope for its bound value.\n *\n * The `when` attribute specifies the mappings between plural categories and the actual\n * string to be displayed. The value of the attribute should be a JSON object.\n *\n * The following example shows how to configure ngPluralize:\n *\n * ```html\n * <ng-pluralize count=\"personCount\"\n                 when=\"{'0': 'Nobody is viewing.',\n *                      'one': '1 person is viewing.',\n *                      'other': '{} people are viewing.'}\">\n * </ng-pluralize>\n *```\n *\n * In the example, `\"0: Nobody is viewing.\"` is an explicit number rule. If you did not\n * specify this rule, 0 would be matched to the \"other\" category and \"0 people are viewing\"\n * would be shown instead of \"Nobody is viewing\". You can specify an explicit number rule for\n * other numbers, for example 12, so that instead of showing \"12 people are viewing\", you can\n * show \"a dozen people are viewing\".\n *\n * You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted\n * into pluralized strings. In the previous example, Angular will replace `{}` with\n * <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder\n * for <span ng-non-bindable>{{numberExpression}}</span>.\n *\n * If no rule is defined for a category, then an empty string is displayed and a warning is generated.\n * Note that some locales define more categories than `one` and `other`. For example, fr-fr defines `few` and `many`.\n *\n * # Configuring ngPluralize with offset\n * The `offset` attribute allows further customization of pluralized text, which can result in\n * a better user experience. For example, instead of the message \"4 people are viewing this document\",\n * you might display \"John, Kate and 2 others are viewing this document\".\n * The offset attribute allows you to offset a number by any desired value.\n * Let's take a look at an example:\n *\n * ```html\n * <ng-pluralize count=\"personCount\" offset=2\n *               when=\"{'0': 'Nobody is viewing.',\n *                      '1': '{{person1}} is viewing.',\n *                      '2': '{{person1}} and {{person2}} are viewing.',\n *                      'one': '{{person1}}, {{person2}} and one other person are viewing.',\n *                      'other': '{{person1}}, {{person2}} and {} other people are viewing.'}\">\n * </ng-pluralize>\n * ```\n *\n * Notice that we are still using two plural categories(one, other), but we added\n * three explicit number rules 0, 1 and 2.\n * When one person, perhaps John, views the document, \"John is viewing\" will be shown.\n * When three people view the document, no explicit number rule is found, so\n * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.\n * In this case, plural category 'one' is matched and \"John, Mary and one other person are viewing\"\n * is shown.\n *\n * Note that when you specify offsets, you must provide explicit number rules for\n * numbers from 0 up to and including the offset. If you use an offset of 3, for example,\n * you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for\n * plural categories \"one\" and \"other\".\n *\n * @param {string|expression} count The variable to be bound to.\n * @param {string} when The mapping between plural category to its corresponding strings.\n * @param {number=} offset Offset to deduct from the total number.\n *\n * @example\n    <example module=\"pluralizeExample\" name=\"ng-pluralize\">\n      <file name=\"index.html\">\n        <script>\n          angular.module('pluralizeExample', [])\n            .controller('ExampleController', ['$scope', function($scope) {\n              $scope.person1 = 'Igor';\n              $scope.person2 = 'Misko';\n              $scope.personCount = 1;\n            }]);\n        </script>\n        <div ng-controller=\"ExampleController\">\n          <label>Person 1:<input type=\"text\" ng-model=\"person1\" value=\"Igor\" /></label><br/>\n          <label>Person 2:<input type=\"text\" ng-model=\"person2\" value=\"Misko\" /></label><br/>\n          <label>Number of People:<input type=\"text\" ng-model=\"personCount\" value=\"1\" /></label><br/>\n\n          <!--- Example with simple pluralization rules for en locale --->\n          Without Offset:\n          <ng-pluralize count=\"personCount\"\n                        when=\"{'0': 'Nobody is viewing.',\n                               'one': '1 person is viewing.',\n                               'other': '{} people are viewing.'}\">\n          </ng-pluralize><br>\n\n          <!--- Example with offset --->\n          With Offset(2):\n          <ng-pluralize count=\"personCount\" offset=2\n                        when=\"{'0': 'Nobody is viewing.',\n                               '1': '{{person1}} is viewing.',\n                               '2': '{{person1}} and {{person2}} are viewing.',\n                               'one': '{{person1}}, {{person2}} and one other person are viewing.',\n                               'other': '{{person1}}, {{person2}} and {} other people are viewing.'}\">\n          </ng-pluralize>\n        </div>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should show correct pluralized string', function() {\n          var withoutOffset = element.all(by.css('ng-pluralize')).get(0);\n          var withOffset = element.all(by.css('ng-pluralize')).get(1);\n          var countInput = element(by.model('personCount'));\n\n          expect(withoutOffset.getText()).toEqual('1 person is viewing.');\n          expect(withOffset.getText()).toEqual('Igor is viewing.');\n\n          countInput.clear();\n          countInput.sendKeys('0');\n\n          expect(withoutOffset.getText()).toEqual('Nobody is viewing.');\n          expect(withOffset.getText()).toEqual('Nobody is viewing.');\n\n          countInput.clear();\n          countInput.sendKeys('2');\n\n          expect(withoutOffset.getText()).toEqual('2 people are viewing.');\n          expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');\n\n          countInput.clear();\n          countInput.sendKeys('3');\n\n          expect(withoutOffset.getText()).toEqual('3 people are viewing.');\n          expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');\n\n          countInput.clear();\n          countInput.sendKeys('4');\n\n          expect(withoutOffset.getText()).toEqual('4 people are viewing.');\n          expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');\n        });\n        it('should show data-bound names', function() {\n          var withOffset = element.all(by.css('ng-pluralize')).get(1);\n          var personCount = element(by.model('personCount'));\n          var person1 = element(by.model('person1'));\n          var person2 = element(by.model('person2'));\n          personCount.clear();\n          personCount.sendKeys('4');\n          person1.clear();\n          person1.sendKeys('Di');\n          person2.clear();\n          person2.sendKeys('Vojta');\n          expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');\n        });\n      </file>\n    </example>\n */\nvar ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale, $interpolate, $log) {\n  var BRACE = /{}/g,\n      IS_WHEN = /^when(Minus)?(.+)$/;\n\n  return {\n    link: function(scope, element, attr) {\n      var numberExp = attr.count,\n          whenExp = attr.$attr.when && element.attr(attr.$attr.when), // we have {{}} in attrs\n          offset = attr.offset || 0,\n          whens = scope.$eval(whenExp) || {},\n          whensExpFns = {},\n          startSymbol = $interpolate.startSymbol(),\n          endSymbol = $interpolate.endSymbol(),\n          braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,\n          watchRemover = angular.noop,\n          lastCount;\n\n      forEach(attr, function(expression, attributeName) {\n        var tmpMatch = IS_WHEN.exec(attributeName);\n        if (tmpMatch) {\n          var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);\n          whens[whenKey] = element.attr(attr.$attr[attributeName]);\n        }\n      });\n      forEach(whens, function(expression, key) {\n        whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));\n\n      });\n\n      scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {\n        var count = parseFloat(newVal);\n        var countIsNaN = isNumberNaN(count);\n\n        if (!countIsNaN && !(count in whens)) {\n          // If an explicit number rule such as 1, 2, 3... is defined, just use it.\n          // Otherwise, check it against pluralization rules in $locale service.\n          count = $locale.pluralCat(count - offset);\n        }\n\n        // If both `count` and `lastCount` are NaN, we don't need to re-register a watch.\n        // In JS `NaN !== NaN`, so we have to explicitly check.\n        if ((count !== lastCount) && !(countIsNaN && isNumberNaN(lastCount))) {\n          watchRemover();\n          var whenExpFn = whensExpFns[count];\n          if (isUndefined(whenExpFn)) {\n            if (newVal != null) {\n              $log.debug('ngPluralize: no rule defined for \\'' + count + '\\' in ' + whenExp);\n            }\n            watchRemover = noop;\n            updateElementText();\n          } else {\n            watchRemover = scope.$watch(whenExpFn, updateElementText);\n          }\n          lastCount = count;\n        }\n      });\n\n      function updateElementText(newText) {\n        element.text(newText || '');\n      }\n    }\n  };\n}];\n\n/* exported ngRepeatDirective */\n\n/**\n * @ngdoc directive\n * @name ngRepeat\n * @multiElement\n * @restrict A\n *\n * @description\n * The `ngRepeat` directive instantiates a template once per item from a collection. Each template\n * instance gets its own scope, where the given loop variable is set to the current collection item,\n * and `$index` is set to the item index or key.\n *\n * Special properties are exposed on the local scope of each template instance, including:\n *\n * | Variable  | Type            | Details                                                                     |\n * |-----------|-----------------|-----------------------------------------------------------------------------|\n * | `$index`  | {@type number}  | iterator offset of the repeated element (0..length-1)                       |\n * | `$first`  | {@type boolean} | true if the repeated element is first in the iterator.                      |\n * | `$middle` | {@type boolean} | true if the repeated element is between the first and last in the iterator. |\n * | `$last`   | {@type boolean} | true if the repeated element is last in the iterator.                       |\n * | `$even`   | {@type boolean} | true if the iterator position `$index` is even (otherwise false).           |\n * | `$odd`    | {@type boolean} | true if the iterator position `$index` is odd (otherwise false).            |\n *\n * <div class=\"alert alert-info\">\n *   Creating aliases for these properties is possible with {@link ng.directive:ngInit `ngInit`}.\n *   This may be useful when, for instance, nesting ngRepeats.\n * </div>\n *\n *\n * # Iterating over object properties\n *\n * It is possible to get `ngRepeat` to iterate over the properties of an object using the following\n * syntax:\n *\n * ```js\n * <div ng-repeat=\"(key, value) in myObj\"> ... </div>\n * ```\n *\n * However, there are a few limitations compared to array iteration:\n *\n * - The JavaScript specification does not define the order of keys\n *   returned for an object, so Angular relies on the order returned by the browser\n *   when running `for key in myObj`. Browsers generally follow the strategy of providing\n *   keys in the order in which they were defined, although there are exceptions when keys are deleted\n *   and reinstated. See the\n *   [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).\n *\n * - `ngRepeat` will silently *ignore* object keys starting with `$`, because\n *   it's a prefix used by Angular for public (`$`) and private (`$$`) properties.\n *\n * - The built-in filters {@link ng.orderBy orderBy} and {@link ng.filter filter} do not work with\n *   objects, and will throw an error if used with one.\n *\n * If you are hitting any of these limitations, the recommended workaround is to convert your object into an array\n * that is sorted into the order that you prefer before providing it to `ngRepeat`. You could\n * do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)\n * or implement a `$watch` on the object yourself.\n *\n *\n * # Tracking and Duplicates\n *\n * `ngRepeat` uses {@link $rootScope.Scope#$watchCollection $watchCollection} to detect changes in\n * the collection. When a change happens, `ngRepeat` then makes the corresponding changes to the DOM:\n *\n * * When an item is added, a new instance of the template is added to the DOM.\n * * When an item is removed, its template instance is removed from the DOM.\n * * When items are reordered, their respective templates are reordered in the DOM.\n *\n * To minimize creation of DOM elements, `ngRepeat` uses a function\n * to \"keep track\" of all items in the collection and their corresponding DOM elements.\n * For example, if an item is added to the collection, `ngRepeat` will know that all other items\n * already have DOM elements, and will not re-render them.\n *\n * The default tracking function (which tracks items by their identity) does not allow\n * duplicate items in arrays. This is because when there are duplicates, it is not possible\n * to maintain a one-to-one mapping between collection items and DOM elements.\n *\n * If you do need to repeat duplicate items, you can substitute the default tracking behavior\n * with your own using the `track by` expression.\n *\n * For example, you may track items by the index of each item in the collection, using the\n * special scope property `$index`:\n * ```html\n *    <div ng-repeat=\"n in [42, 42, 43, 43] track by $index\">\n *      {{n}}\n *    </div>\n * ```\n *\n * You may also use arbitrary expressions in `track by`, including references to custom functions\n * on the scope:\n * ```html\n *    <div ng-repeat=\"n in [42, 42, 43, 43] track by myTrackingFunction(n)\">\n *      {{n}}\n *    </div>\n * ```\n *\n * <div class=\"alert alert-success\">\n * If you are working with objects that have a unique identifier property, you should track\n * by this identifier instead of the object instance. Should you reload your data later, `ngRepeat`\n * will not have to rebuild the DOM elements for items it has already rendered, even if the\n * JavaScript objects in the collection have been substituted for new ones. For large collections,\n * this significantly improves rendering performance. If you don't have a unique identifier,\n * `track by $index` can also provide a performance boost.\n * </div>\n *\n * ```html\n *    <div ng-repeat=\"model in collection track by model.id\">\n *      {{model.name}}\n *    </div>\n * ```\n *\n * <br />\n * <div class=\"alert alert-warning\">\n * Avoid using `track by $index` when the repeated template contains\n * {@link guide/expression#one-time-binding one-time bindings}. In such cases, the `nth` DOM\n * element will always be matched with the `nth` item of the array, so the bindings on that element\n * will not be updated even when the corresponding item changes, essentially causing the view to get\n * out-of-sync with the underlying data.\n * </div>\n *\n * When no `track by` expression is provided, it is equivalent to tracking by the built-in\n * `$id` function, which tracks items by their identity:\n * ```html\n *    <div ng-repeat=\"obj in collection track by $id(obj)\">\n *      {{obj.prop}}\n *    </div>\n * ```\n *\n * <br />\n * <div class=\"alert alert-warning\">\n * **Note:** `track by` must always be the last expression:\n * </div>\n * ```\n *    <div ng-repeat=\"model in collection | orderBy: 'id' as filtered_result track by model.id\">\n *      {{model.name}}\n *    </div>\n * ```\n *\n *\n * # Special repeat start and end points\n * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending\n * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.\n * The **ng-repeat-start** directive works the same as **ng-repeat**, but will repeat all the HTML code (including the tag it's defined on)\n * up to and including the ending HTML tag where **ng-repeat-end** is placed.\n *\n * The example below makes use of this feature:\n * ```html\n *   <header ng-repeat-start=\"item in items\">\n *     Header {{ item }}\n *   </header>\n *   <div class=\"body\">\n *     Body {{ item }}\n *   </div>\n *   <footer ng-repeat-end>\n *     Footer {{ item }}\n *   </footer>\n * ```\n *\n * And with an input of {@type ['A','B']} for the items variable in the example above, the output will evaluate to:\n * ```html\n *   <header>\n *     Header A\n *   </header>\n *   <div class=\"body\">\n *     Body A\n *   </div>\n *   <footer>\n *     Footer A\n *   </footer>\n *   <header>\n *     Header B\n *   </header>\n *   <div class=\"body\">\n *     Body B\n *   </div>\n *   <footer>\n *     Footer B\n *   </footer>\n * ```\n *\n * The custom start and end points for ngRepeat also support all other HTML directive syntax flavors provided in AngularJS (such\n * as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).\n *\n * @animations\n * | Animation                        | Occurs                              |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#enter enter} | when a new item is added to the list or when an item is revealed after a filter |\n * | {@link ng.$animate#leave leave} | when an item is removed from the list or when an item is filtered out |\n * | {@link ng.$animate#move move } | when an adjacent item is filtered out causing a reorder or when the item contents are reordered |\n *\n * See the example below for defining CSS animations with ngRepeat.\n *\n * @element ANY\n * @scope\n * @priority 1000\n * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. These\n *   formats are currently supported:\n *\n *   * `variable in expression` – where variable is the user defined loop variable and `expression`\n *     is a scope expression giving the collection to enumerate.\n *\n *     For example: `album in artist.albums`.\n *\n *   * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,\n *     and `expression` is the scope expression giving the collection to enumerate.\n *\n *     For example: `(name, age) in {'adam':10, 'amalie':12}`.\n *\n *   * `variable in expression track by tracking_expression` – You can also provide an optional tracking expression\n *     which can be used to associate the objects in the collection with the DOM elements. If no tracking expression\n *     is specified, ng-repeat associates elements by identity. It is an error to have\n *     more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are\n *     mapped to the same DOM element, which is not possible.)\n *\n *     Note that the tracking expression must come last, after any filters, and the alias expression.\n *\n *     For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements\n *     will be associated by item identity in the array.\n *\n *     For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique\n *     `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements\n *     with the corresponding item in the array by identity. Moving the same object in array would move the DOM\n *     element in the same way in the DOM.\n *\n *     For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this\n *     case the object identity does not matter. Two objects are considered equivalent as long as their `id`\n *     property is same.\n *\n *     For example: `item in items | filter:searchText track by item.id` is a pattern that might be used to apply a filter\n *     to items in conjunction with a tracking expression.\n *\n *   * `variable in expression as alias_expression` – You can also provide an optional alias expression which will then store the\n *     intermediate results of the repeater after the filters have been applied. Typically this is used to render a special message\n *     when a filter is active on the repeater, but the filtered result set is empty.\n *\n *     For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after\n *     the items have been processed through the filter.\n *\n *     Please note that `as [variable name] is not an operator but rather a part of ngRepeat micro-syntax so it can be used only at the end\n *     (and not as operator, inside an expression).\n *\n *     For example: `item in items | filter : x | orderBy : order | limitTo : limit as results` .\n *\n * @example\n * This example uses `ngRepeat` to display a list of people. A filter is used to restrict the displayed\n * results by name or by age. New (entering) and removed (leaving) items are animated.\n  <example module=\"ngRepeat\" name=\"ngRepeat\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-repeat\">\n    <file name=\"index.html\">\n      <div ng-controller=\"repeatController\">\n        I have {{friends.length}} friends. They are:\n        <input type=\"search\" ng-model=\"q\" placeholder=\"filter friends...\" aria-label=\"filter friends\" />\n        <ul class=\"example-animate-container\">\n          <li class=\"animate-repeat\" ng-repeat=\"friend in friends | filter:q as results\">\n            [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.\n          </li>\n          <li class=\"animate-repeat\" ng-if=\"results.length === 0\">\n            <strong>No results found...</strong>\n          </li>\n        </ul>\n      </div>\n    </file>\n    <file name=\"script.js\">\n      angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {\n        $scope.friends = [\n          {name:'John', age:25, gender:'boy'},\n          {name:'Jessie', age:30, gender:'girl'},\n          {name:'Johanna', age:28, gender:'girl'},\n          {name:'Joy', age:15, gender:'girl'},\n          {name:'Mary', age:28, gender:'girl'},\n          {name:'Peter', age:95, gender:'boy'},\n          {name:'Sebastian', age:50, gender:'boy'},\n          {name:'Erika', age:27, gender:'girl'},\n          {name:'Patrick', age:40, gender:'boy'},\n          {name:'Samantha', age:60, gender:'girl'}\n        ];\n      });\n    </file>\n    <file name=\"animations.css\">\n      .example-animate-container {\n        background:white;\n        border:1px solid black;\n        list-style:none;\n        margin:0;\n        padding:0 10px;\n      }\n\n      .animate-repeat {\n        line-height:30px;\n        list-style:none;\n        box-sizing:border-box;\n      }\n\n      .animate-repeat.ng-move,\n      .animate-repeat.ng-enter,\n      .animate-repeat.ng-leave {\n        transition:all linear 0.5s;\n      }\n\n      .animate-repeat.ng-leave.ng-leave-active,\n      .animate-repeat.ng-move,\n      .animate-repeat.ng-enter {\n        opacity:0;\n        max-height:0;\n      }\n\n      .animate-repeat.ng-leave,\n      .animate-repeat.ng-move.ng-move-active,\n      .animate-repeat.ng-enter.ng-enter-active {\n        opacity:1;\n        max-height:30px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var friends = element.all(by.repeater('friend in friends'));\n\n      it('should render initial data set', function() {\n        expect(friends.count()).toBe(10);\n        expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');\n        expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');\n        expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');\n        expect(element(by.binding('friends.length')).getText())\n            .toMatch(\"I have 10 friends. They are:\");\n      });\n\n       it('should update repeater when filter predicate changes', function() {\n         expect(friends.count()).toBe(10);\n\n         element(by.model('q')).sendKeys('ma');\n\n         expect(friends.count()).toBe(2);\n         expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');\n         expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');\n       });\n      </file>\n    </example>\n */\nvar ngRepeatDirective = ['$parse', '$animate', '$compile', function($parse, $animate, $compile) {\n  var NG_REMOVED = '$$NG_REMOVED';\n  var ngRepeatMinErr = minErr('ngRepeat');\n\n  var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) {\n    // TODO(perf): generate setters to shave off ~40ms or 1-1.5%\n    scope[valueIdentifier] = value;\n    if (keyIdentifier) scope[keyIdentifier] = key;\n    scope.$index = index;\n    scope.$first = (index === 0);\n    scope.$last = (index === (arrayLength - 1));\n    scope.$middle = !(scope.$first || scope.$last);\n    // eslint-disable-next-line no-bitwise\n    scope.$odd = !(scope.$even = (index & 1) === 0);\n  };\n\n  var getBlockStart = function(block) {\n    return block.clone[0];\n  };\n\n  var getBlockEnd = function(block) {\n    return block.clone[block.clone.length - 1];\n  };\n\n\n  return {\n    restrict: 'A',\n    multiElement: true,\n    transclude: 'element',\n    priority: 1000,\n    terminal: true,\n    $$tlb: true,\n    compile: function ngRepeatCompile($element, $attr) {\n      var expression = $attr.ngRepeat;\n      var ngRepeatEndComment = $compile.$$createComment('end ngRepeat', expression);\n\n      var match = expression.match(/^\\s*([\\s\\S]+?)\\s+in\\s+([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?(?:\\s+track\\s+by\\s+([\\s\\S]+?))?\\s*$/);\n\n      if (!match) {\n        throw ngRepeatMinErr('iexp', 'Expected expression in form of \\'_item_ in _collection_[ track by _id_]\\' but got \\'{0}\\'.',\n            expression);\n      }\n\n      var lhs = match[1];\n      var rhs = match[2];\n      var aliasAs = match[3];\n      var trackByExp = match[4];\n\n      match = lhs.match(/^(?:(\\s*[$\\w]+)|\\(\\s*([$\\w]+)\\s*,\\s*([$\\w]+)\\s*\\))$/);\n\n      if (!match) {\n        throw ngRepeatMinErr('iidexp', '\\'_item_\\' in \\'_item_ in _collection_\\' should be an identifier or \\'(_key_, _value_)\\' expression, but got \\'{0}\\'.',\n            lhs);\n      }\n      var valueIdentifier = match[3] || match[1];\n      var keyIdentifier = match[2];\n\n      if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||\n          /^(null|undefined|this|\\$index|\\$first|\\$middle|\\$last|\\$even|\\$odd|\\$parent|\\$root|\\$id)$/.test(aliasAs))) {\n        throw ngRepeatMinErr('badident', 'alias \\'{0}\\' is invalid --- must be a valid JS identifier which is not a reserved name.',\n          aliasAs);\n      }\n\n      var trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn;\n      var hashFnLocals = {$id: hashKey};\n\n      if (trackByExp) {\n        trackByExpGetter = $parse(trackByExp);\n      } else {\n        trackByIdArrayFn = function(key, value) {\n          return hashKey(value);\n        };\n        trackByIdObjFn = function(key) {\n          return key;\n        };\n      }\n\n      return function ngRepeatLink($scope, $element, $attr, ctrl, $transclude) {\n\n        if (trackByExpGetter) {\n          trackByIdExpFn = function(key, value, index) {\n            // assign key, value, and $index to the locals so that they can be used in hash functions\n            if (keyIdentifier) hashFnLocals[keyIdentifier] = key;\n            hashFnLocals[valueIdentifier] = value;\n            hashFnLocals.$index = index;\n            return trackByExpGetter($scope, hashFnLocals);\n          };\n        }\n\n        // Store a list of elements from previous run. This is a hash where key is the item from the\n        // iterator, and the value is objects with following properties.\n        //   - scope: bound scope\n        //   - element: previous element.\n        //   - index: position\n        //\n        // We are using no-proto object so that we don't need to guard against inherited props via\n        // hasOwnProperty.\n        var lastBlockMap = createMap();\n\n        //watch props\n        $scope.$watchCollection(rhs, function ngRepeatAction(collection) {\n          var index, length,\n              previousNode = $element[0],     // node that cloned nodes should be inserted after\n                                              // initialized to the comment node anchor\n              nextNode,\n              // Same as lastBlockMap but it has the current state. It will become the\n              // lastBlockMap on the next iteration.\n              nextBlockMap = createMap(),\n              collectionLength,\n              key, value, // key/value of iteration\n              trackById,\n              trackByIdFn,\n              collectionKeys,\n              block,       // last object information {scope, element, id}\n              nextBlockOrder,\n              elementsToRemove;\n\n          if (aliasAs) {\n            $scope[aliasAs] = collection;\n          }\n\n          if (isArrayLike(collection)) {\n            collectionKeys = collection;\n            trackByIdFn = trackByIdExpFn || trackByIdArrayFn;\n          } else {\n            trackByIdFn = trackByIdExpFn || trackByIdObjFn;\n            // if object, extract keys, in enumeration order, unsorted\n            collectionKeys = [];\n            for (var itemKey in collection) {\n              if (hasOwnProperty.call(collection, itemKey) && itemKey.charAt(0) !== '$') {\n                collectionKeys.push(itemKey);\n              }\n            }\n          }\n\n          collectionLength = collectionKeys.length;\n          nextBlockOrder = new Array(collectionLength);\n\n          // locate existing items\n          for (index = 0; index < collectionLength; index++) {\n            key = (collection === collectionKeys) ? index : collectionKeys[index];\n            value = collection[key];\n            trackById = trackByIdFn(key, value, index);\n            if (lastBlockMap[trackById]) {\n              // found previously seen block\n              block = lastBlockMap[trackById];\n              delete lastBlockMap[trackById];\n              nextBlockMap[trackById] = block;\n              nextBlockOrder[index] = block;\n            } else if (nextBlockMap[trackById]) {\n              // if collision detected. restore lastBlockMap and throw an error\n              forEach(nextBlockOrder, function(block) {\n                if (block && block.scope) lastBlockMap[block.id] = block;\n              });\n              throw ngRepeatMinErr('dupes',\n                  'Duplicates in a repeater are not allowed. Use \\'track by\\' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}',\n                  expression, trackById, value);\n            } else {\n              // new never before seen block\n              nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined};\n              nextBlockMap[trackById] = true;\n            }\n          }\n\n          // remove leftover items\n          for (var blockKey in lastBlockMap) {\n            block = lastBlockMap[blockKey];\n            elementsToRemove = getBlockNodes(block.clone);\n            $animate.leave(elementsToRemove);\n            if (elementsToRemove[0].parentNode) {\n              // if the element was not removed yet because of pending animation, mark it as deleted\n              // so that we can ignore it later\n              for (index = 0, length = elementsToRemove.length; index < length; index++) {\n                elementsToRemove[index][NG_REMOVED] = true;\n              }\n            }\n            block.scope.$destroy();\n          }\n\n          // we are not using forEach for perf reasons (trying to avoid #call)\n          for (index = 0; index < collectionLength; index++) {\n            key = (collection === collectionKeys) ? index : collectionKeys[index];\n            value = collection[key];\n            block = nextBlockOrder[index];\n\n            if (block.scope) {\n              // if we have already seen this object, then we need to reuse the\n              // associated scope/element\n\n              nextNode = previousNode;\n\n              // skip nodes that are already pending removal via leave animation\n              do {\n                nextNode = nextNode.nextSibling;\n              } while (nextNode && nextNode[NG_REMOVED]);\n\n              if (getBlockStart(block) !== nextNode) {\n                // existing item which got moved\n                $animate.move(getBlockNodes(block.clone), null, previousNode);\n              }\n              previousNode = getBlockEnd(block);\n              updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);\n            } else {\n              // new item which we don't know about\n              $transclude(function ngRepeatTransclude(clone, scope) {\n                block.scope = scope;\n                // http://jsperf.com/clone-vs-createcomment\n                var endNode = ngRepeatEndComment.cloneNode(false);\n                clone[clone.length++] = endNode;\n\n                $animate.enter(clone, null, previousNode);\n                previousNode = endNode;\n                // Note: We only need the first/last node of the cloned nodes.\n                // However, we need to keep the reference to the jqlite wrapper as it might be changed later\n                // by a directive with templateUrl when its template arrives.\n                block.clone = clone;\n                nextBlockMap[block.id] = block;\n                updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);\n              });\n            }\n          }\n          lastBlockMap = nextBlockMap;\n        });\n      };\n    }\n  };\n}];\n\nvar NG_HIDE_CLASS = 'ng-hide';\nvar NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';\n/**\n * @ngdoc directive\n * @name ngShow\n * @multiElement\n *\n * @description\n * The `ngShow` directive shows or hides the given HTML element based on the expression provided to\n * the `ngShow` attribute.\n *\n * The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.\n * The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an\n * `!important` flag). For CSP mode please add `angular-csp.css` to your HTML file (see\n * {@link ng.directive:ngCsp ngCsp}).\n *\n * ```html\n * <!-- when $scope.myValue is truthy (element is visible) -->\n * <div ng-show=\"myValue\"></div>\n *\n * <!-- when $scope.myValue is falsy (element is hidden) -->\n * <div ng-show=\"myValue\" class=\"ng-hide\"></div>\n * ```\n *\n * When the `ngShow` expression evaluates to a falsy value then the `.ng-hide` CSS class is added\n * to the class attribute on the element causing it to become hidden. When truthy, the `.ng-hide`\n * CSS class is removed from the element causing the element not to appear hidden.\n *\n * ## Why is `!important` used?\n *\n * You may be wondering why `!important` is used for the `.ng-hide` CSS class. This is because the\n * `.ng-hide` selector can be easily overridden by heavier selectors. For example, something as\n * simple as changing the display style on a HTML list item would make hidden elements appear\n * visible. This also becomes a bigger issue when dealing with CSS frameworks.\n *\n * By using `!important`, the show and hide behavior will work as expected despite any clash between\n * CSS selector specificity (when `!important` isn't used with any conflicting styles). If a\n * developer chooses to override the styling to change how to hide an element then it is just a\n * matter of using `!important` in their own CSS code.\n *\n * ### Overriding `.ng-hide`\n *\n * By default, the `.ng-hide` class will style the element with `display: none !important`. If you\n * wish to change the hide behavior with `ngShow`/`ngHide`, you can simply overwrite the styles for\n * the `.ng-hide` CSS class. Note that the selector that needs to be used is actually\n * `.ng-hide:not(.ng-hide-animate)` to cope with extra animation classes that can be added.\n *\n * ```css\n * .ng-hide:not(.ng-hide-animate) {\n *   /&#42; These are just alternative ways of hiding an element &#42;/\n *   display: block!important;\n *   position: absolute;\n *   top: -9999px;\n *   left: -9999px;\n * }\n * ```\n *\n * By default you don't need to override anything in CSS and the animations will work around the\n * display style.\n *\n * ## A note about animations with `ngShow`\n *\n * Animations in `ngShow`/`ngHide` work with the show and hide events that are triggered when the\n * directive expression is true and false. This system works like the animation system present with\n * `ngClass` except that you must also include the `!important` flag to override the display\n * property so that the elements are not actually hidden during the animation.\n *\n * ```css\n * /&#42; A working example can be found at the bottom of this page. &#42;/\n * .my-element.ng-hide-add, .my-element.ng-hide-remove {\n *   transition: all 0.5s linear;\n * }\n *\n * .my-element.ng-hide-add { ... }\n * .my-element.ng-hide-add.ng-hide-add-active { ... }\n * .my-element.ng-hide-remove { ... }\n * .my-element.ng-hide-remove.ng-hide-remove-active { ... }\n * ```\n *\n * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display property\n * to block during animation states - ngAnimate will automatically handle the style toggling for you.\n *\n * @animations\n * | Animation                                           | Occurs                                                                                                        |\n * |-----------------------------------------------------|---------------------------------------------------------------------------------------------------------------|\n * | {@link $animate#addClass addClass} `.ng-hide`       | After the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden. |\n * | {@link $animate#removeClass removeClass} `.ng-hide` | After the `ngShow` expression evaluates to a truthy value and just before contents are set to visible.        |\n *\n * @element ANY\n * @param {expression} ngShow If the {@link guide/expression expression} is truthy/falsy then the\n *                            element is shown/hidden respectively.\n *\n * @example\n * A simple example, animating the element's opacity:\n *\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-show-simple\">\n    <file name=\"index.html\">\n      Show: <input type=\"checkbox\" ng-model=\"checked\" aria-label=\"Toggle ngShow\"><br />\n      <div class=\"check-element animate-show-hide\" ng-show=\"checked\">\n        I show up when your checkbox is checked.\n      </div>\n    </file>\n    <file name=\"animations.css\">\n      .animate-show-hide.ng-hide {\n        opacity: 0;\n      }\n\n      .animate-show-hide.ng-hide-add,\n      .animate-show-hide.ng-hide-remove {\n        transition: all linear 0.5s;\n      }\n\n      .check-element {\n        border: 1px solid black;\n        opacity: 1;\n        padding: 10px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should check ngShow', function() {\n        var checkbox = element(by.model('checked'));\n        var checkElem = element(by.css('.check-element'));\n\n        expect(checkElem.isDisplayed()).toBe(false);\n        checkbox.click();\n        expect(checkElem.isDisplayed()).toBe(true);\n      });\n    </file>\n  </example>\n *\n * <hr />\n * @example\n * A more complex example, featuring different show/hide animations:\n *\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-show-complex\">\n    <file name=\"index.html\">\n      Show: <input type=\"checkbox\" ng-model=\"checked\" aria-label=\"Toggle ngShow\"><br />\n      <div class=\"check-element funky-show-hide\" ng-show=\"checked\">\n        I show up when your checkbox is checked.\n      </div>\n    </file>\n    <file name=\"animations.css\">\n      body {\n        overflow: hidden;\n        perspective: 1000px;\n      }\n\n      .funky-show-hide.ng-hide-add {\n        transform: rotateZ(0);\n        transform-origin: right;\n        transition: all 0.5s ease-in-out;\n      }\n\n      .funky-show-hide.ng-hide-add.ng-hide-add-active {\n        transform: rotateZ(-135deg);\n      }\n\n      .funky-show-hide.ng-hide-remove {\n        transform: rotateY(90deg);\n        transform-origin: left;\n        transition: all 0.5s ease;\n      }\n\n      .funky-show-hide.ng-hide-remove.ng-hide-remove-active {\n        transform: rotateY(0);\n      }\n\n      .check-element {\n        border: 1px solid black;\n        opacity: 1;\n        padding: 10px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should check ngShow', function() {\n        var checkbox = element(by.model('checked'));\n        var checkElem = element(by.css('.check-element'));\n\n        expect(checkElem.isDisplayed()).toBe(false);\n        checkbox.click();\n        expect(checkElem.isDisplayed()).toBe(true);\n      });\n    </file>\n  </example>\n */\nvar ngShowDirective = ['$animate', function($animate) {\n  return {\n    restrict: 'A',\n    multiElement: true,\n    link: function(scope, element, attr) {\n      scope.$watch(attr.ngShow, function ngShowWatchAction(value) {\n        // we're adding a temporary, animation-specific class for ng-hide since this way\n        // we can control when the element is actually displayed on screen without having\n        // to have a global/greedy CSS selector that breaks when other animations are run.\n        // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845\n        $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {\n          tempClasses: NG_HIDE_IN_PROGRESS_CLASS\n        });\n      });\n    }\n  };\n}];\n\n\n/**\n * @ngdoc directive\n * @name ngHide\n * @multiElement\n *\n * @description\n * The `ngHide` directive shows or hides the given HTML element based on the expression provided to\n * the `ngHide` attribute.\n *\n * The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.\n * The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an\n * `!important` flag). For CSP mode please add `angular-csp.css` to your HTML file (see\n * {@link ng.directive:ngCsp ngCsp}).\n *\n * ```html\n * <!-- when $scope.myValue is truthy (element is hidden) -->\n * <div ng-hide=\"myValue\" class=\"ng-hide\"></div>\n *\n * <!-- when $scope.myValue is falsy (element is visible) -->\n * <div ng-hide=\"myValue\"></div>\n * ```\n *\n * When the `ngHide` expression evaluates to a truthy value then the `.ng-hide` CSS class is added\n * to the class attribute on the element causing it to become hidden. When falsy, the `.ng-hide`\n * CSS class is removed from the element causing the element not to appear hidden.\n *\n * ## Why is `!important` used?\n *\n * You may be wondering why `!important` is used for the `.ng-hide` CSS class. This is because the\n * `.ng-hide` selector can be easily overridden by heavier selectors. For example, something as\n * simple as changing the display style on a HTML list item would make hidden elements appear\n * visible. This also becomes a bigger issue when dealing with CSS frameworks.\n *\n * By using `!important`, the show and hide behavior will work as expected despite any clash between\n * CSS selector specificity (when `!important` isn't used with any conflicting styles). If a\n * developer chooses to override the styling to change how to hide an element then it is just a\n * matter of using `!important` in their own CSS code.\n *\n * ### Overriding `.ng-hide`\n *\n * By default, the `.ng-hide` class will style the element with `display: none !important`. If you\n * wish to change the hide behavior with `ngShow`/`ngHide`, you can simply overwrite the styles for\n * the `.ng-hide` CSS class. Note that the selector that needs to be used is actually\n * `.ng-hide:not(.ng-hide-animate)` to cope with extra animation classes that can be added.\n *\n * ```css\n * .ng-hide:not(.ng-hide-animate) {\n *   /&#42; These are just alternative ways of hiding an element &#42;/\n *   display: block!important;\n *   position: absolute;\n *   top: -9999px;\n *   left: -9999px;\n * }\n * ```\n *\n * By default you don't need to override in CSS anything and the animations will work around the\n * display style.\n *\n * ## A note about animations with `ngHide`\n *\n * Animations in `ngShow`/`ngHide` work with the show and hide events that are triggered when the\n * directive expression is true and false. This system works like the animation system present with\n * `ngClass` except that you must also include the `!important` flag to override the display\n * property so that the elements are not actually hidden during the animation.\n *\n * ```css\n * /&#42; A working example can be found at the bottom of this page. &#42;/\n * .my-element.ng-hide-add, .my-element.ng-hide-remove {\n *   transition: all 0.5s linear;\n * }\n *\n * .my-element.ng-hide-add { ... }\n * .my-element.ng-hide-add.ng-hide-add-active { ... }\n * .my-element.ng-hide-remove { ... }\n * .my-element.ng-hide-remove.ng-hide-remove-active { ... }\n * ```\n *\n * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display property\n * to block during animation states - ngAnimate will automatically handle the style toggling for you.\n *\n * @animations\n * | Animation                                           | Occurs                                                                                                     |\n * |-----------------------------------------------------|------------------------------------------------------------------------------------------------------------|\n * | {@link $animate#addClass addClass} `.ng-hide`       | After the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden.  |\n * | {@link $animate#removeClass removeClass} `.ng-hide` | After the `ngHide` expression evaluates to a non truthy value and just before contents are set to visible. |\n *\n *\n * @element ANY\n * @param {expression} ngHide If the {@link guide/expression expression} is truthy/falsy then the\n *                            element is hidden/shown respectively.\n *\n * @example\n * A simple example, animating the element's opacity:\n *\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-hide-simple\">\n    <file name=\"index.html\">\n      Hide: <input type=\"checkbox\" ng-model=\"checked\" aria-label=\"Toggle ngHide\"><br />\n      <div class=\"check-element animate-show-hide\" ng-hide=\"checked\">\n        I hide when your checkbox is checked.\n      </div>\n    </file>\n    <file name=\"animations.css\">\n      .animate-show-hide.ng-hide {\n        opacity: 0;\n      }\n\n      .animate-show-hide.ng-hide-add,\n      .animate-show-hide.ng-hide-remove {\n        transition: all linear 0.5s;\n      }\n\n      .check-element {\n        border: 1px solid black;\n        opacity: 1;\n        padding: 10px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should check ngHide', function() {\n        var checkbox = element(by.model('checked'));\n        var checkElem = element(by.css('.check-element'));\n\n        expect(checkElem.isDisplayed()).toBe(true);\n        checkbox.click();\n        expect(checkElem.isDisplayed()).toBe(false);\n      });\n    </file>\n  </example>\n *\n * <hr />\n * @example\n * A more complex example, featuring different show/hide animations:\n *\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-hide-complex\">\n    <file name=\"index.html\">\n      Hide: <input type=\"checkbox\" ng-model=\"checked\" aria-label=\"Toggle ngHide\"><br />\n      <div class=\"check-element funky-show-hide\" ng-hide=\"checked\">\n        I hide when your checkbox is checked.\n      </div>\n    </file>\n    <file name=\"animations.css\">\n      body {\n        overflow: hidden;\n        perspective: 1000px;\n      }\n\n      .funky-show-hide.ng-hide-add {\n        transform: rotateZ(0);\n        transform-origin: right;\n        transition: all 0.5s ease-in-out;\n      }\n\n      .funky-show-hide.ng-hide-add.ng-hide-add-active {\n        transform: rotateZ(-135deg);\n      }\n\n      .funky-show-hide.ng-hide-remove {\n        transform: rotateY(90deg);\n        transform-origin: left;\n        transition: all 0.5s ease;\n      }\n\n      .funky-show-hide.ng-hide-remove.ng-hide-remove-active {\n        transform: rotateY(0);\n      }\n\n      .check-element {\n        border: 1px solid black;\n        opacity: 1;\n        padding: 10px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should check ngHide', function() {\n        var checkbox = element(by.model('checked'));\n        var checkElem = element(by.css('.check-element'));\n\n        expect(checkElem.isDisplayed()).toBe(true);\n        checkbox.click();\n        expect(checkElem.isDisplayed()).toBe(false);\n      });\n    </file>\n  </example>\n */\nvar ngHideDirective = ['$animate', function($animate) {\n  return {\n    restrict: 'A',\n    multiElement: true,\n    link: function(scope, element, attr) {\n      scope.$watch(attr.ngHide, function ngHideWatchAction(value) {\n        // The comment inside of the ngShowDirective explains why we add and\n        // remove a temporary class for the show/hide animation\n        $animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {\n          tempClasses: NG_HIDE_IN_PROGRESS_CLASS\n        });\n      });\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngStyle\n * @restrict AC\n *\n * @description\n * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally.\n *\n * @knownIssue\n * You should not use {@link guide/interpolation interpolation} in the value of the `style`\n * attribute, when using the `ngStyle` directive on the same element.\n * See {@link guide/interpolation#known-issues here} for more info.\n *\n * @element ANY\n * @param {expression} ngStyle\n *\n * {@link guide/expression Expression} which evals to an\n * object whose keys are CSS style names and values are corresponding values for those CSS\n * keys.\n *\n * Since some CSS style names are not valid keys for an object, they must be quoted.\n * See the 'background-color' style in the example below.\n *\n * @example\n   <example name=\"ng-style\">\n     <file name=\"index.html\">\n        <input type=\"button\" value=\"set color\" ng-click=\"myStyle={color:'red'}\">\n        <input type=\"button\" value=\"set background\" ng-click=\"myStyle={'background-color':'blue'}\">\n        <input type=\"button\" value=\"clear\" ng-click=\"myStyle={}\">\n        <br/>\n        <span ng-style=\"myStyle\">Sample Text</span>\n        <pre>myStyle={{myStyle}}</pre>\n     </file>\n     <file name=\"style.css\">\n       span {\n         color: black;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       var colorSpan = element(by.css('span'));\n\n       it('should check ng-style', function() {\n         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');\n         element(by.css('input[value=\\'set color\\']')).click();\n         expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');\n         element(by.css('input[value=clear]')).click();\n         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');\n       });\n     </file>\n   </example>\n */\nvar ngStyleDirective = ngDirective(function(scope, element, attr) {\n  scope.$watch(attr.ngStyle, function ngStyleWatchAction(newStyles, oldStyles) {\n    if (oldStyles && (newStyles !== oldStyles)) {\n      forEach(oldStyles, function(val, style) { element.css(style, '');});\n    }\n    if (newStyles) element.css(newStyles);\n  }, true);\n});\n\n/**\n * @ngdoc directive\n * @name ngSwitch\n * @restrict EA\n *\n * @description\n * The `ngSwitch` directive is used to conditionally swap DOM structure on your template based on a scope expression.\n * Elements within `ngSwitch` but without `ngSwitchWhen` or `ngSwitchDefault` directives will be preserved at the location\n * as specified in the template.\n *\n * The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it\n * from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element\n * matches the value obtained from the evaluated expression. In other words, you define a container element\n * (where you place the directive), place an expression on the **`on=\"...\"` attribute**\n * (or the **`ng-switch=\"...\"` attribute**), define any inner elements inside of the directive and place\n * a when attribute per element. The when attribute is used to inform ngSwitch which element to display when the on\n * expression is evaluated. If a matching expression is not found via a when attribute then an element with the default\n * attribute is displayed.\n *\n * <div class=\"alert alert-info\">\n * Be aware that the attribute values to match against cannot be expressions. They are interpreted\n * as literal string values to match against.\n * For example, **`ng-switch-when=\"someVal\"`** will match against the string `\"someVal\"` not against the\n * value of the expression `$scope.someVal`.\n * </div>\n\n * @animations\n * | Animation                        | Occurs                              |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#enter enter}  | after the ngSwitch contents change and the matched child element is placed inside the container |\n * | {@link ng.$animate#leave leave}  | after the ngSwitch contents change and just before the former contents are removed from the DOM |\n *\n * @usage\n *\n * ```\n * <ANY ng-switch=\"expression\">\n *   <ANY ng-switch-when=\"matchValue1\">...</ANY>\n *   <ANY ng-switch-when=\"matchValue2\">...</ANY>\n *   <ANY ng-switch-default>...</ANY>\n * </ANY>\n * ```\n *\n *\n * @scope\n * @priority 1200\n * @param {*} ngSwitch|on expression to match against <code>ng-switch-when</code>.\n * On child elements add:\n *\n * * `ngSwitchWhen`: the case statement to match against. If match then this\n *   case will be displayed. If the same match appears multiple times, all the\n *   elements will be displayed. It is possible to associate multiple values to\n *   the same `ngSwitchWhen` by defining the optional attribute\n *   `ngSwitchWhenSeparator`. The separator will be used to split the value of\n *   the `ngSwitchWhen` attribute into multiple tokens, and the element will show\n *   if any of the `ngSwitch` evaluates to any of these tokens.\n * * `ngSwitchDefault`: the default case when no other case match. If there\n *   are multiple default cases, all of them will be displayed when no other\n *   case match.\n *\n *\n * @example\n  <example module=\"switchExample\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-switch\">\n    <file name=\"index.html\">\n      <div ng-controller=\"ExampleController\">\n        <select ng-model=\"selection\" ng-options=\"item for item in items\">\n        </select>\n        <code>selection={{selection}}</code>\n        <hr/>\n        <div class=\"animate-switch-container\"\n          ng-switch on=\"selection\">\n            <div class=\"animate-switch\" ng-switch-when=\"settings|options\" ng-switch-when-separator=\"|\">Settings Div</div>\n            <div class=\"animate-switch\" ng-switch-when=\"home\">Home Span</div>\n            <div class=\"animate-switch\" ng-switch-default>default</div>\n        </div>\n      </div>\n    </file>\n    <file name=\"script.js\">\n      angular.module('switchExample', ['ngAnimate'])\n        .controller('ExampleController', ['$scope', function($scope) {\n          $scope.items = ['settings', 'home', 'options', 'other'];\n          $scope.selection = $scope.items[0];\n        }]);\n    </file>\n    <file name=\"animations.css\">\n      .animate-switch-container {\n        position:relative;\n        background:white;\n        border:1px solid black;\n        height:40px;\n        overflow:hidden;\n      }\n\n      .animate-switch {\n        padding:10px;\n      }\n\n      .animate-switch.ng-animate {\n        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;\n\n        position:absolute;\n        top:0;\n        left:0;\n        right:0;\n        bottom:0;\n      }\n\n      .animate-switch.ng-leave.ng-leave-active,\n      .animate-switch.ng-enter {\n        top:-50px;\n      }\n      .animate-switch.ng-leave,\n      .animate-switch.ng-enter.ng-enter-active {\n        top:0;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var switchElem = element(by.css('[ng-switch]'));\n      var select = element(by.model('selection'));\n\n      it('should start in settings', function() {\n        expect(switchElem.getText()).toMatch(/Settings Div/);\n      });\n      it('should change to home', function() {\n        select.all(by.css('option')).get(1).click();\n        expect(switchElem.getText()).toMatch(/Home Span/);\n      });\n      it('should change to settings via \"options\"', function() {\n        select.all(by.css('option')).get(2).click();\n        expect(switchElem.getText()).toMatch(/Settings Div/);\n      });\n      it('should select default', function() {\n        select.all(by.css('option')).get(3).click();\n        expect(switchElem.getText()).toMatch(/default/);\n      });\n    </file>\n  </example>\n */\nvar ngSwitchDirective = ['$animate', '$compile', function($animate, $compile) {\n  return {\n    require: 'ngSwitch',\n\n    // asks for $scope to fool the BC controller module\n    controller: ['$scope', function NgSwitchController() {\n     this.cases = {};\n    }],\n    link: function(scope, element, attr, ngSwitchController) {\n      var watchExpr = attr.ngSwitch || attr.on,\n          selectedTranscludes = [],\n          selectedElements = [],\n          previousLeaveAnimations = [],\n          selectedScopes = [];\n\n      var spliceFactory = function(array, index) {\n          return function(response) {\n            if (response !== false) array.splice(index, 1);\n          };\n      };\n\n      scope.$watch(watchExpr, function ngSwitchWatchAction(value) {\n        var i, ii;\n\n        // Start with the last, in case the array is modified during the loop\n        while (previousLeaveAnimations.length) {\n          $animate.cancel(previousLeaveAnimations.pop());\n        }\n\n        for (i = 0, ii = selectedScopes.length; i < ii; ++i) {\n          var selected = getBlockNodes(selectedElements[i].clone);\n          selectedScopes[i].$destroy();\n          var runner = previousLeaveAnimations[i] = $animate.leave(selected);\n          runner.done(spliceFactory(previousLeaveAnimations, i));\n        }\n\n        selectedElements.length = 0;\n        selectedScopes.length = 0;\n\n        if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {\n          forEach(selectedTranscludes, function(selectedTransclude) {\n            selectedTransclude.transclude(function(caseElement, selectedScope) {\n              selectedScopes.push(selectedScope);\n              var anchor = selectedTransclude.element;\n              caseElement[caseElement.length++] = $compile.$$createComment('end ngSwitchWhen');\n              var block = { clone: caseElement };\n\n              selectedElements.push(block);\n              $animate.enter(caseElement, anchor.parent(), anchor);\n            });\n          });\n        }\n      });\n    }\n  };\n}];\n\nvar ngSwitchWhenDirective = ngDirective({\n  transclude: 'element',\n  priority: 1200,\n  require: '^ngSwitch',\n  multiElement: true,\n  link: function(scope, element, attrs, ctrl, $transclude) {\n\n    var cases = attrs.ngSwitchWhen.split(attrs.ngSwitchWhenSeparator).sort().filter(\n      // Filter duplicate cases\n      function(element, index, array) { return array[index - 1] !== element; }\n    );\n\n    forEach(cases, function(whenCase) {\n      ctrl.cases['!' + whenCase] = (ctrl.cases['!' + whenCase] || []);\n      ctrl.cases['!' + whenCase].push({ transclude: $transclude, element: element });\n    });\n  }\n});\n\nvar ngSwitchDefaultDirective = ngDirective({\n  transclude: 'element',\n  priority: 1200,\n  require: '^ngSwitch',\n  multiElement: true,\n  link: function(scope, element, attr, ctrl, $transclude) {\n    ctrl.cases['?'] = (ctrl.cases['?'] || []);\n    ctrl.cases['?'].push({ transclude: $transclude, element: element });\n   }\n});\n\n/**\n * @ngdoc directive\n * @name ngTransclude\n * @restrict EAC\n *\n * @description\n * Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.\n *\n * You can specify that you want to insert a named transclusion slot, instead of the default slot, by providing the slot name\n * as the value of the `ng-transclude` or `ng-transclude-slot` attribute.\n *\n * If the transcluded content is not empty (i.e. contains one or more DOM nodes, including whitespace text nodes), any existing\n * content of this element will be removed before the transcluded content is inserted.\n * If the transcluded content is empty (or only whitespace), the existing content is left intact. This lets you provide fallback\n * content in the case that no transcluded content is provided.\n *\n * @element ANY\n *\n * @param {string} ngTransclude|ngTranscludeSlot the name of the slot to insert at this point. If this is not provided, is empty\n *                                               or its value is the same as the name of the attribute then the default slot is used.\n *\n * @example\n * ### Basic transclusion\n * This example demonstrates basic transclusion of content into a component directive.\n * <example name=\"simpleTranscludeExample\" module=\"transcludeExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('transcludeExample', [])\n *        .directive('pane', function(){\n *           return {\n *             restrict: 'E',\n *             transclude: true,\n *             scope: { title:'@' },\n *             template: '<div style=\"border: 1px solid black;\">' +\n *                         '<div style=\"background-color: gray\">{{title}}</div>' +\n *                         '<ng-transclude></ng-transclude>' +\n *                       '</div>'\n *           };\n *       })\n *       .controller('ExampleController', ['$scope', function($scope) {\n *         $scope.title = 'Lorem Ipsum';\n *         $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';\n *       }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <input ng-model=\"title\" aria-label=\"title\"> <br/>\n *       <textarea ng-model=\"text\" aria-label=\"text\"></textarea> <br/>\n *       <pane title=\"{{title}}\"><span>{{text}}</span></pane>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *      it('should have transcluded', function() {\n *        var titleElement = element(by.model('title'));\n *        titleElement.clear();\n *        titleElement.sendKeys('TITLE');\n *        var textElement = element(by.model('text'));\n *        textElement.clear();\n *        textElement.sendKeys('TEXT');\n *        expect(element(by.binding('title')).getText()).toEqual('TITLE');\n *        expect(element(by.binding('text')).getText()).toEqual('TEXT');\n *      });\n *   </file>\n * </example>\n *\n * @example\n * ### Transclude fallback content\n * This example shows how to use `NgTransclude` with fallback content, that\n * is displayed if no transcluded content is provided.\n *\n * <example module=\"transcludeFallbackContentExample\" name=\"ng-transclude\">\n * <file name=\"index.html\">\n * <script>\n * angular.module('transcludeFallbackContentExample', [])\n * .directive('myButton', function(){\n *             return {\n *               restrict: 'E',\n *               transclude: true,\n *               scope: true,\n *               template: '<button style=\"cursor: pointer;\">' +\n *                           '<ng-transclude>' +\n *                             '<b style=\"color: red;\">Button1</b>' +\n *                           '</ng-transclude>' +\n *                         '</button>'\n *             };\n *         });\n * </script>\n * <!-- fallback button content -->\n * <my-button id=\"fallback\"></my-button>\n * <!-- modified button content -->\n * <my-button id=\"modified\">\n *   <i style=\"color: green;\">Button2</i>\n * </my-button>\n * </file>\n * <file name=\"protractor.js\" type=\"protractor\">\n * it('should have different transclude element content', function() {\n *          expect(element(by.id('fallback')).getText()).toBe('Button1');\n *          expect(element(by.id('modified')).getText()).toBe('Button2');\n *        });\n * </file>\n * </example>\n *\n * @example\n * ### Multi-slot transclusion\n * This example demonstrates using multi-slot transclusion in a component directive.\n * <example name=\"multiSlotTranscludeExample\" module=\"multiSlotTranscludeExample\">\n *   <file name=\"index.html\">\n *    <style>\n *      .title, .footer {\n *        background-color: gray\n *      }\n *    </style>\n *    <div ng-controller=\"ExampleController\">\n *      <input ng-model=\"title\" aria-label=\"title\"> <br/>\n *      <textarea ng-model=\"text\" aria-label=\"text\"></textarea> <br/>\n *      <pane>\n *        <pane-title><a ng-href=\"{{link}}\">{{title}}</a></pane-title>\n *        <pane-body><p>{{text}}</p></pane-body>\n *      </pane>\n *    </div>\n *   </file>\n *   <file name=\"app.js\">\n *    angular.module('multiSlotTranscludeExample', [])\n *     .directive('pane', function() {\n *        return {\n *          restrict: 'E',\n *          transclude: {\n *            'title': '?paneTitle',\n *            'body': 'paneBody',\n *            'footer': '?paneFooter'\n *          },\n *          template: '<div style=\"border: 1px solid black;\">' +\n *                      '<div class=\"title\" ng-transclude=\"title\">Fallback Title</div>' +\n *                      '<div ng-transclude=\"body\"></div>' +\n *                      '<div class=\"footer\" ng-transclude=\"footer\">Fallback Footer</div>' +\n *                    '</div>'\n *        };\n *    })\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.title = 'Lorem Ipsum';\n *      $scope.link = 'https://google.com';\n *      $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';\n *    }]);\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *      it('should have transcluded the title and the body', function() {\n *        var titleElement = element(by.model('title'));\n *        titleElement.clear();\n *        titleElement.sendKeys('TITLE');\n *        var textElement = element(by.model('text'));\n *        textElement.clear();\n *        textElement.sendKeys('TEXT');\n *        expect(element(by.css('.title')).getText()).toEqual('TITLE');\n *        expect(element(by.binding('text')).getText()).toEqual('TEXT');\n *        expect(element(by.css('.footer')).getText()).toEqual('Fallback Footer');\n *      });\n *   </file>\n * </example>\n */\nvar ngTranscludeMinErr = minErr('ngTransclude');\nvar ngTranscludeDirective = ['$compile', function($compile) {\n  return {\n    restrict: 'EAC',\n    terminal: true,\n    compile: function ngTranscludeCompile(tElement) {\n\n      // Remove and cache any original content to act as a fallback\n      var fallbackLinkFn = $compile(tElement.contents());\n      tElement.empty();\n\n      return function ngTranscludePostLink($scope, $element, $attrs, controller, $transclude) {\n\n        if (!$transclude) {\n          throw ngTranscludeMinErr('orphan',\n          'Illegal use of ngTransclude directive in the template! ' +\n          'No parent directive that requires a transclusion found. ' +\n          'Element: {0}',\n          startingTag($element));\n        }\n\n\n        // If the attribute is of the form: `ng-transclude=\"ng-transclude\"` then treat it like the default\n        if ($attrs.ngTransclude === $attrs.$attr.ngTransclude) {\n          $attrs.ngTransclude = '';\n        }\n        var slotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot;\n\n        // If the slot is required and no transclusion content is provided then this call will throw an error\n        $transclude(ngTranscludeCloneAttachFn, null, slotName);\n\n        // If the slot is optional and no transclusion content is provided then use the fallback content\n        if (slotName && !$transclude.isSlotFilled(slotName)) {\n          useFallbackContent();\n        }\n\n        function ngTranscludeCloneAttachFn(clone, transcludedScope) {\n          if (clone.length && notWhitespace(clone)) {\n            $element.append(clone);\n          } else {\n            useFallbackContent();\n            // There is nothing linked against the transcluded scope since no content was available,\n            // so it should be safe to clean up the generated scope.\n            transcludedScope.$destroy();\n          }\n        }\n\n        function useFallbackContent() {\n          // Since this is the fallback content rather than the transcluded content,\n          // we link against the scope of this directive rather than the transcluded scope\n          fallbackLinkFn($scope, function(clone) {\n            $element.append(clone);\n          });\n        }\n\n        function notWhitespace(nodes) {\n          for (var i = 0, ii = nodes.length; i < ii; i++) {\n            var node = nodes[i];\n            if (node.nodeType !== NODE_TYPE_TEXT || node.nodeValue.trim()) {\n              return true;\n            }\n          }\n        }\n      };\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name script\n * @restrict E\n *\n * @description\n * Load the content of a `<script>` element into {@link ng.$templateCache `$templateCache`}, so that the\n * template can be used by {@link ng.directive:ngInclude `ngInclude`},\n * {@link ngRoute.directive:ngView `ngView`}, or {@link guide/directive directives}. The type of the\n * `<script>` element must be specified as `text/ng-template`, and a cache name for the template must be\n * assigned through the element's `id`, which can then be used as a directive's `templateUrl`.\n *\n * @param {string} type Must be set to `'text/ng-template'`.\n * @param {string} id Cache name of the template.\n *\n * @example\n  <example  name=\"script-tag\">\n    <file name=\"index.html\">\n      <script type=\"text/ng-template\" id=\"/tpl.html\">\n        Content of the template.\n      </script>\n\n      <a ng-click=\"currentTpl='/tpl.html'\" id=\"tpl-link\">Load inlined template</a>\n      <div id=\"tpl-content\" ng-include src=\"currentTpl\"></div>\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should load template defined inside script tag', function() {\n        element(by.css('#tpl-link')).click();\n        expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);\n      });\n    </file>\n  </example>\n */\nvar scriptDirective = ['$templateCache', function($templateCache) {\n  return {\n    restrict: 'E',\n    terminal: true,\n    compile: function(element, attr) {\n      if (attr.type === 'text/ng-template') {\n        var templateUrl = attr.id,\n            text = element[0].text;\n\n        $templateCache.put(templateUrl, text);\n      }\n    }\n  };\n}];\n\n/* exported selectDirective, optionDirective */\n\nvar noopNgModelController = { $setViewValue: noop, $render: noop };\n\nfunction setOptionSelectedStatus(optionEl, value) {\n  optionEl.prop('selected', value); // needed for IE\n  /**\n   * When unselecting an option, setting the property to null / false should be enough\n   * However, screenreaders might react to the selected attribute instead, see\n   * https://github.com/angular/angular.js/issues/14419\n   * Note: \"selected\" is a boolean attr and will be removed when the \"value\" arg in attr() is false\n   * or null\n   */\n  optionEl.attr('selected', value);\n}\n\n/**\n * @ngdoc type\n * @name  select.SelectController\n * @description\n * The controller for the `<select>` directive. This provides support for reading\n * and writing the selected value(s) of the control and also coordinates dynamically\n * added `<option>` elements, perhaps by an `ngRepeat` directive.\n */\nvar SelectController =\n        ['$element', '$scope', /** @this */ function($element, $scope) {\n\n  var self = this,\n      optionsMap = new NgMap();\n\n  self.selectValueMap = {}; // Keys are the hashed values, values the original values\n\n  // If the ngModel doesn't get provided then provide a dummy noop version to prevent errors\n  self.ngModelCtrl = noopNgModelController;\n  self.multiple = false;\n\n  // The \"unknown\" option is one that is prepended to the list if the viewValue\n  // does not match any of the options. When it is rendered the value of the unknown\n  // option is '? XXX ?' where XXX is the hashKey of the value that is not known.\n  //\n  // We can't just jqLite('<option>') since jqLite is not smart enough\n  // to create it in <select> and IE barfs otherwise.\n  self.unknownOption = jqLite(window.document.createElement('option'));\n\n  // The empty option is an option with the value '' that te application developer can\n  // provide inside the select. When the model changes to a value that doesn't match an option,\n  // it is selected - so if an empty option is provided, no unknown option is generated.\n  // However, the empty option is not removed when the model matches an option. It is always selectable\n  // and indicates that a \"null\" selection has been made.\n  self.hasEmptyOption = false;\n  self.emptyOption = undefined;\n\n  self.renderUnknownOption = function(val) {\n    var unknownVal = self.generateUnknownOptionValue(val);\n    self.unknownOption.val(unknownVal);\n    $element.prepend(self.unknownOption);\n    setOptionSelectedStatus(self.unknownOption, true);\n    $element.val(unknownVal);\n  };\n\n  self.updateUnknownOption = function(val) {\n    var unknownVal = self.generateUnknownOptionValue(val);\n    self.unknownOption.val(unknownVal);\n    setOptionSelectedStatus(self.unknownOption, true);\n    $element.val(unknownVal);\n  };\n\n  self.generateUnknownOptionValue = function(val) {\n    return '? ' + hashKey(val) + ' ?';\n  };\n\n  self.removeUnknownOption = function() {\n    if (self.unknownOption.parent()) self.unknownOption.remove();\n  };\n\n  self.selectEmptyOption = function() {\n    if (self.emptyOption) {\n      $element.val('');\n      setOptionSelectedStatus(self.emptyOption, true);\n    }\n  };\n\n  self.unselectEmptyOption = function() {\n    if (self.hasEmptyOption) {\n      self.emptyOption.removeAttr('selected');\n    }\n  };\n\n  $scope.$on('$destroy', function() {\n    // disable unknown option so that we don't do work when the whole select is being destroyed\n    self.renderUnknownOption = noop;\n  });\n\n  // Read the value of the select control, the implementation of this changes depending\n  // upon whether the select can have multiple values and whether ngOptions is at work.\n  self.readValue = function readSingleValue() {\n    var val = $element.val();\n    // ngValue added option values are stored in the selectValueMap, normal interpolations are not\n    var realVal = val in self.selectValueMap ? self.selectValueMap[val] : val;\n\n    if (self.hasOption(realVal)) {\n      return realVal;\n    }\n\n    return null;\n  };\n\n\n  // Write the value to the select control, the implementation of this changes depending\n  // upon whether the select can have multiple values and whether ngOptions is at work.\n  self.writeValue = function writeSingleValue(value) {\n    // Make sure to remove the selected attribute from the previously selected option\n    // Otherwise, screen readers might get confused\n    var currentlySelectedOption = $element[0].options[$element[0].selectedIndex];\n    if (currentlySelectedOption) setOptionSelectedStatus(jqLite(currentlySelectedOption), false);\n\n    if (self.hasOption(value)) {\n      self.removeUnknownOption();\n\n      var hashedVal = hashKey(value);\n      $element.val(hashedVal in self.selectValueMap ? hashedVal : value);\n\n      // Set selected attribute and property on selected option for screen readers\n      var selectedOption = $element[0].options[$element[0].selectedIndex];\n      setOptionSelectedStatus(jqLite(selectedOption), true);\n    } else {\n      if (value == null && self.emptyOption) {\n        self.removeUnknownOption();\n        self.selectEmptyOption();\n      } else if (self.unknownOption.parent().length) {\n        self.updateUnknownOption(value);\n      } else {\n        self.renderUnknownOption(value);\n      }\n    }\n  };\n\n\n  // Tell the select control that an option, with the given value, has been added\n  self.addOption = function(value, element) {\n    // Skip comment nodes, as they only pollute the `optionsMap`\n    if (element[0].nodeType === NODE_TYPE_COMMENT) return;\n\n    assertNotHasOwnProperty(value, '\"option value\"');\n    if (value === '') {\n      self.hasEmptyOption = true;\n      self.emptyOption = element;\n    }\n    var count = optionsMap.get(value) || 0;\n    optionsMap.set(value, count + 1);\n    // Only render at the end of a digest. This improves render performance when many options\n    // are added during a digest and ensures all relevant options are correctly marked as selected\n    scheduleRender();\n  };\n\n  // Tell the select control that an option, with the given value, has been removed\n  self.removeOption = function(value) {\n    var count = optionsMap.get(value);\n    if (count) {\n      if (count === 1) {\n        optionsMap.delete(value);\n        if (value === '') {\n          self.hasEmptyOption = false;\n          self.emptyOption = undefined;\n        }\n      } else {\n        optionsMap.set(value, count - 1);\n      }\n    }\n  };\n\n  // Check whether the select control has an option matching the given value\n  self.hasOption = function(value) {\n    return !!optionsMap.get(value);\n  };\n\n\n  var renderScheduled = false;\n  function scheduleRender() {\n    if (renderScheduled) return;\n    renderScheduled = true;\n    $scope.$$postDigest(function() {\n      renderScheduled = false;\n      self.ngModelCtrl.$render();\n    });\n  }\n\n  var updateScheduled = false;\n  function scheduleViewValueUpdate(renderAfter) {\n    if (updateScheduled) return;\n\n    updateScheduled = true;\n\n    $scope.$$postDigest(function() {\n      if ($scope.$$destroyed) return;\n\n      updateScheduled = false;\n      self.ngModelCtrl.$setViewValue(self.readValue());\n      if (renderAfter) self.ngModelCtrl.$render();\n    });\n  }\n\n\n  self.registerOption = function(optionScope, optionElement, optionAttrs, interpolateValueFn, interpolateTextFn) {\n\n    if (optionAttrs.$attr.ngValue) {\n      // The value attribute is set by ngValue\n      var oldVal, hashedVal = NaN;\n      optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {\n\n        var removal;\n        var previouslySelected = optionElement.prop('selected');\n\n        if (isDefined(hashedVal)) {\n          self.removeOption(oldVal);\n          delete self.selectValueMap[hashedVal];\n          removal = true;\n        }\n\n        hashedVal = hashKey(newVal);\n        oldVal = newVal;\n        self.selectValueMap[hashedVal] = newVal;\n        self.addOption(newVal, optionElement);\n        // Set the attribute directly instead of using optionAttrs.$set - this stops the observer\n        // from firing a second time. Other $observers on value will also get the result of the\n        // ngValue expression, not the hashed value\n        optionElement.attr('value', hashedVal);\n\n        if (removal && previouslySelected) {\n          scheduleViewValueUpdate();\n        }\n\n      });\n    } else if (interpolateValueFn) {\n      // The value attribute is interpolated\n      optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {\n        // This method is overwritten in ngOptions and has side-effects!\n        self.readValue();\n\n        var removal;\n        var previouslySelected = optionElement.prop('selected');\n\n        if (isDefined(oldVal)) {\n          self.removeOption(oldVal);\n          removal = true;\n        }\n        oldVal = newVal;\n        self.addOption(newVal, optionElement);\n\n        if (removal && previouslySelected) {\n          scheduleViewValueUpdate();\n        }\n      });\n    } else if (interpolateTextFn) {\n      // The text content is interpolated\n      optionScope.$watch(interpolateTextFn, function interpolateWatchAction(newVal, oldVal) {\n        optionAttrs.$set('value', newVal);\n        var previouslySelected = optionElement.prop('selected');\n        if (oldVal !== newVal) {\n          self.removeOption(oldVal);\n        }\n        self.addOption(newVal, optionElement);\n\n        if (oldVal && previouslySelected) {\n          scheduleViewValueUpdate();\n        }\n      });\n    } else {\n      // The value attribute is static\n      self.addOption(optionAttrs.value, optionElement);\n    }\n\n\n    optionAttrs.$observe('disabled', function(newVal) {\n\n      // Since model updates will also select disabled options (like ngOptions),\n      // we only have to handle options becoming disabled, not enabled\n\n      if (newVal === 'true' || newVal && optionElement.prop('selected')) {\n        if (self.multiple) {\n          scheduleViewValueUpdate(true);\n        } else {\n          self.ngModelCtrl.$setViewValue(null);\n          self.ngModelCtrl.$render();\n        }\n      }\n    });\n\n    optionElement.on('$destroy', function() {\n      var currentValue = self.readValue();\n      var removeValue = optionAttrs.value;\n\n      self.removeOption(removeValue);\n      scheduleRender();\n\n      if (self.multiple && currentValue && currentValue.indexOf(removeValue) !== -1 ||\n          currentValue === removeValue\n      ) {\n        // When multiple (selected) options are destroyed at the same time, we don't want\n        // to run a model update for each of them. Instead, run a single update in the $$postDigest\n        scheduleViewValueUpdate(true);\n      }\n    });\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name select\n * @restrict E\n *\n * @description\n * HTML `select` element with angular data-binding.\n *\n * The `select` directive is used together with {@link ngModel `ngModel`} to provide data-binding\n * between the scope and the `<select>` control (including setting default values).\n * It also handles dynamic `<option>` elements, which can be added using the {@link ngRepeat `ngRepeat}` or\n * {@link ngOptions `ngOptions`} directives.\n *\n * When an item in the `<select>` menu is selected, the value of the selected option will be bound\n * to the model identified by the `ngModel` directive. With static or repeated options, this is\n * the content of the `value` attribute or the textContent of the `<option>`, if the value attribute is missing.\n * Value and textContent can be interpolated.\n *\n * ## Matching model and option values\n *\n * In general, the match between the model and an option is evaluated by strictly comparing the model\n * value against the value of the available options.\n *\n * If you are setting the option value with the option's `value` attribute, or textContent, the\n * value will always be a `string` which means that the model value must also be a string.\n * Otherwise the `select` directive cannot match them correctly.\n *\n * To bind the model to a non-string value, you can use one of the following strategies:\n * - the {@link ng.ngOptions `ngOptions`} directive\n *   ({@link ng.select#using-select-with-ngoptions-and-setting-a-default-value})\n * - the {@link ng.ngValue `ngValue`} directive, which allows arbitrary expressions to be\n *   option values ({@link ng.select#using-ngvalue-to-bind-the-model-to-an-array-of-objects Example})\n * - model $parsers / $formatters to convert the string value\n *   ({@link ng.select#binding-select-to-a-non-string-value-via-ngmodel-parsing-formatting Example})\n *\n * If the viewValue of `ngModel` does not match any of the options, then the control\n * will automatically add an \"unknown\" option, which it then removes when the mismatch is resolved.\n *\n * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can\n * be nested into the `<select>` element. This element will then represent the `null` or \"not selected\"\n * option. See example below for demonstration.\n *\n * ## Choosing between `ngRepeat` and `ngOptions`\n *\n * In many cases, `ngRepeat` can be used on `<option>` elements instead of {@link ng.directive:ngOptions\n * ngOptions} to achieve a similar result. However, `ngOptions` provides some benefits:\n * - more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the\n * comprehension expression\n * - reduced memory consumption by not creating a new scope for each repeated instance\n * - increased render speed by creating the options in a documentFragment instead of individually\n *\n * Specifically, select with repeated options slows down significantly starting at 2000 options in\n * Chrome and Internet Explorer / Edge.\n *\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} name Property name of the form under which the control is published.\n * @param {string=} multiple Allows multiple options to be selected. The selected values will be\n *     bound to the model as an array.\n * @param {string=} required Sets `required` validation error key if the value is not entered.\n * @param {string=} ngRequired Adds required attribute and required validation constraint to\n * the element when the ngRequired expression evaluates to true. Use ngRequired instead of required\n * when you want to data-bind to the required attribute.\n * @param {string=} ngChange Angular expression to be executed when selected option(s) changes due to user\n *    interaction with the select element.\n * @param {string=} ngOptions sets the options that the select is populated with and defines what is\n * set on the model on selection. See {@link ngOptions `ngOptions`}.\n * @param {string=} ngAttrSize sets the size of the select element dynamically. Uses the\n * {@link guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes ngAttr} directive.\n *\n * @example\n * ### Simple `select` elements with static options\n *\n * <example name=\"static-select\" module=\"staticSelect\">\n * <file name=\"index.html\">\n * <div ng-controller=\"ExampleController\">\n *   <form name=\"myForm\">\n *     <label for=\"singleSelect\"> Single select: </label><br>\n *     <select name=\"singleSelect\" ng-model=\"data.singleSelect\">\n *       <option value=\"option-1\">Option 1</option>\n *       <option value=\"option-2\">Option 2</option>\n *     </select><br>\n *\n *     <label for=\"singleSelect\"> Single select with \"not selected\" option and dynamic option values: </label><br>\n *     <select name=\"singleSelect\" id=\"singleSelect\" ng-model=\"data.singleSelect\">\n *       <option value=\"\">---Please select---</option> <!-- not selected / blank option -->\n *       <option value=\"{{data.option1}}\">Option 1</option> <!-- interpolation -->\n *       <option value=\"option-2\">Option 2</option>\n *     </select><br>\n *     <button ng-click=\"forceUnknownOption()\">Force unknown option</button><br>\n *     <tt>singleSelect = {{data.singleSelect}}</tt>\n *\n *     <hr>\n *     <label for=\"multipleSelect\"> Multiple select: </label><br>\n *     <select name=\"multipleSelect\" id=\"multipleSelect\" ng-model=\"data.multipleSelect\" multiple>\n *       <option value=\"option-1\">Option 1</option>\n *       <option value=\"option-2\">Option 2</option>\n *       <option value=\"option-3\">Option 3</option>\n *     </select><br>\n *     <tt>multipleSelect = {{data.multipleSelect}}</tt><br/>\n *   </form>\n * </div>\n * </file>\n * <file name=\"app.js\">\n *  angular.module('staticSelect', [])\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.data = {\n *       singleSelect: null,\n *       multipleSelect: [],\n *       option1: 'option-1'\n *      };\n *\n *      $scope.forceUnknownOption = function() {\n *        $scope.data.singleSelect = 'nonsense';\n *      };\n *   }]);\n * </file>\n *</example>\n *\n * ### Using `ngRepeat` to generate `select` options\n * <example name=\"select-ngrepeat\" module=\"ngrepeatSelect\">\n * <file name=\"index.html\">\n * <div ng-controller=\"ExampleController\">\n *   <form name=\"myForm\">\n *     <label for=\"repeatSelect\"> Repeat select: </label>\n *     <select name=\"repeatSelect\" id=\"repeatSelect\" ng-model=\"data.model\">\n *       <option ng-repeat=\"option in data.availableOptions\" value=\"{{option.id}}\">{{option.name}}</option>\n *     </select>\n *   </form>\n *   <hr>\n *   <tt>model = {{data.model}}</tt><br/>\n * </div>\n * </file>\n * <file name=\"app.js\">\n *  angular.module('ngrepeatSelect', [])\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.data = {\n *       model: null,\n *       availableOptions: [\n *         {id: '1', name: 'Option A'},\n *         {id: '2', name: 'Option B'},\n *         {id: '3', name: 'Option C'}\n *       ]\n *      };\n *   }]);\n * </file>\n *</example>\n *\n * ### Using `ngValue` to bind the model to an array of objects\n * <example name=\"select-ngvalue\" module=\"ngvalueSelect\">\n * <file name=\"index.html\">\n * <div ng-controller=\"ExampleController\">\n *   <form name=\"myForm\">\n *     <label for=\"ngvalueselect\"> ngvalue select: </label>\n *     <select size=\"6\" name=\"ngvalueselect\" ng-model=\"data.model\" multiple>\n *       <option ng-repeat=\"option in data.availableOptions\" ng-value=\"option.value\">{{option.name}}</option>\n *     </select>\n *   </form>\n *   <hr>\n *   <pre>model = {{data.model | json}}</pre><br/>\n * </div>\n * </file>\n * <file name=\"app.js\">\n *  angular.module('ngvalueSelect', [])\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.data = {\n *       model: null,\n *       availableOptions: [\n           {value: 'myString', name: 'string'},\n           {value: 1, name: 'integer'},\n           {value: true, name: 'boolean'},\n           {value: null, name: 'null'},\n           {value: {prop: 'value'}, name: 'object'},\n           {value: ['a'], name: 'array'}\n *       ]\n *      };\n *   }]);\n * </file>\n *</example>\n *\n * ### Using `select` with `ngOptions` and setting a default value\n * See the {@link ngOptions ngOptions documentation} for more `ngOptions` usage examples.\n *\n * <example name=\"select-with-default-values\" module=\"defaultValueSelect\">\n * <file name=\"index.html\">\n * <div ng-controller=\"ExampleController\">\n *   <form name=\"myForm\">\n *     <label for=\"mySelect\">Make a choice:</label>\n *     <select name=\"mySelect\" id=\"mySelect\"\n *       ng-options=\"option.name for option in data.availableOptions track by option.id\"\n *       ng-model=\"data.selectedOption\"></select>\n *   </form>\n *   <hr>\n *   <tt>option = {{data.selectedOption}}</tt><br/>\n * </div>\n * </file>\n * <file name=\"app.js\">\n *  angular.module('defaultValueSelect', [])\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.data = {\n *       availableOptions: [\n *         {id: '1', name: 'Option A'},\n *         {id: '2', name: 'Option B'},\n *         {id: '3', name: 'Option C'}\n *       ],\n *       selectedOption: {id: '3', name: 'Option C'} //This sets the default value of the select in the ui\n *       };\n *   }]);\n * </file>\n *</example>\n *\n *\n * ### Binding `select` to a non-string value via `ngModel` parsing / formatting\n *\n * <example name=\"select-with-non-string-options\" module=\"nonStringSelect\">\n *   <file name=\"index.html\">\n *     <select ng-model=\"model.id\" convert-to-number>\n *       <option value=\"0\">Zero</option>\n *       <option value=\"1\">One</option>\n *       <option value=\"2\">Two</option>\n *     </select>\n *     {{ model }}\n *   </file>\n *   <file name=\"app.js\">\n *     angular.module('nonStringSelect', [])\n *       .run(function($rootScope) {\n *         $rootScope.model = { id: 2 };\n *       })\n *       .directive('convertToNumber', function() {\n *         return {\n *           require: 'ngModel',\n *           link: function(scope, element, attrs, ngModel) {\n *             ngModel.$parsers.push(function(val) {\n *               return parseInt(val, 10);\n *             });\n *             ngModel.$formatters.push(function(val) {\n *               return '' + val;\n *             });\n *           }\n *         };\n *       });\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     it('should initialize to model', function() {\n *       expect(element(by.model('model.id')).$('option:checked').getText()).toEqual('Two');\n *     });\n *   </file>\n * </example>\n *\n */\nvar selectDirective = function() {\n\n  return {\n    restrict: 'E',\n    require: ['select', '?ngModel'],\n    controller: SelectController,\n    priority: 1,\n    link: {\n      pre: selectPreLink,\n      post: selectPostLink\n    }\n  };\n\n  function selectPreLink(scope, element, attr, ctrls) {\n\n      var selectCtrl = ctrls[0];\n      var ngModelCtrl = ctrls[1];\n\n      // if ngModel is not defined, we don't need to do anything but set the registerOption\n      // function to noop, so options don't get added internally\n      if (!ngModelCtrl) {\n        selectCtrl.registerOption = noop;\n        return;\n      }\n\n\n      selectCtrl.ngModelCtrl = ngModelCtrl;\n\n      // When the selected item(s) changes we delegate getting the value of the select control\n      // to the `readValue` method, which can be changed if the select can have multiple\n      // selected values or if the options are being generated by `ngOptions`\n      element.on('change', function() {\n        selectCtrl.removeUnknownOption();\n        scope.$apply(function() {\n          ngModelCtrl.$setViewValue(selectCtrl.readValue());\n        });\n      });\n\n      // If the select allows multiple values then we need to modify how we read and write\n      // values from and to the control; also what it means for the value to be empty and\n      // we have to add an extra watch since ngModel doesn't work well with arrays - it\n      // doesn't trigger rendering if only an item in the array changes.\n      if (attr.multiple) {\n        selectCtrl.multiple = true;\n\n        // Read value now needs to check each option to see if it is selected\n        selectCtrl.readValue = function readMultipleValue() {\n          var array = [];\n          forEach(element.find('option'), function(option) {\n            if (option.selected && !option.disabled) {\n              var val = option.value;\n              array.push(val in selectCtrl.selectValueMap ? selectCtrl.selectValueMap[val] : val);\n            }\n          });\n          return array;\n        };\n\n        // Write value now needs to set the selected property of each matching option\n        selectCtrl.writeValue = function writeMultipleValue(value) {\n          forEach(element.find('option'), function(option) {\n            var shouldBeSelected = !!value && (includes(value, option.value) ||\n                                               includes(value, selectCtrl.selectValueMap[option.value]));\n            var currentlySelected = option.selected;\n\n            // IE and Edge, adding options to the selection via shift+click/UP/DOWN,\n            // will de-select already selected options if \"selected\" on those options was set\n            // more than once (i.e. when the options were already selected)\n            // So we only modify the selected property if neccessary.\n            // Note: this behavior cannot be replicated via unit tests because it only shows in the\n            // actual user interface.\n            if (shouldBeSelected !== currentlySelected) {\n              setOptionSelectedStatus(jqLite(option), shouldBeSelected);\n            }\n\n          });\n        };\n\n        // we have to do it on each watch since ngModel watches reference, but\n        // we need to work of an array, so we need to see if anything was inserted/removed\n        var lastView, lastViewRef = NaN;\n        scope.$watch(function selectMultipleWatch() {\n          if (lastViewRef === ngModelCtrl.$viewValue && !equals(lastView, ngModelCtrl.$viewValue)) {\n            lastView = shallowCopy(ngModelCtrl.$viewValue);\n            ngModelCtrl.$render();\n          }\n          lastViewRef = ngModelCtrl.$viewValue;\n        });\n\n        // If we are a multiple select then value is now a collection\n        // so the meaning of $isEmpty changes\n        ngModelCtrl.$isEmpty = function(value) {\n          return !value || value.length === 0;\n        };\n\n      }\n    }\n\n    function selectPostLink(scope, element, attrs, ctrls) {\n      // if ngModel is not defined, we don't need to do anything\n      var ngModelCtrl = ctrls[1];\n      if (!ngModelCtrl) return;\n\n      var selectCtrl = ctrls[0];\n\n      // We delegate rendering to the `writeValue` method, which can be changed\n      // if the select can have multiple selected values or if the options are being\n      // generated by `ngOptions`.\n      // This must be done in the postLink fn to prevent $render to be called before\n      // all nodes have been linked correctly.\n      ngModelCtrl.$render = function() {\n        selectCtrl.writeValue(ngModelCtrl.$viewValue);\n      };\n    }\n};\n\n\n// The option directive is purely designed to communicate the existence (or lack of)\n// of dynamically created (and destroyed) option elements to their containing select\n// directive via its controller.\nvar optionDirective = ['$interpolate', function($interpolate) {\n  return {\n    restrict: 'E',\n    priority: 100,\n    compile: function(element, attr) {\n      var interpolateValueFn, interpolateTextFn;\n\n      if (isDefined(attr.ngValue)) {\n        // Will be handled by registerOption\n      } else if (isDefined(attr.value)) {\n        // If the value attribute is defined, check if it contains an interpolation\n        interpolateValueFn = $interpolate(attr.value, true);\n      } else {\n        // If the value attribute is not defined then we fall back to the\n        // text content of the option element, which may be interpolated\n        interpolateTextFn = $interpolate(element.text(), true);\n        if (!interpolateTextFn) {\n          attr.$set('value', element.text());\n        }\n      }\n\n      return function(scope, element, attr) {\n        // This is an optimization over using ^^ since we don't want to have to search\n        // all the way to the root of the DOM for every single option element\n        var selectCtrlName = '$selectController',\n            parent = element.parent(),\n            selectCtrl = parent.data(selectCtrlName) ||\n              parent.parent().data(selectCtrlName); // in case we are in optgroup\n\n        if (selectCtrl) {\n          selectCtrl.registerOption(scope, element, attr, interpolateValueFn, interpolateTextFn);\n        }\n      };\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngRequired\n * @restrict A\n *\n * @description\n *\n * ngRequired adds the required {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for {@link input `input`} and {@link select `select`} controls, but can also be\n * applied to custom controls.\n *\n * The directive sets the `required` attribute on the element if the Angular expression inside\n * `ngRequired` evaluates to true. A special directive for setting `required` is necessary because we\n * cannot use interpolation inside `required`. See the {@link guide/interpolation interpolation guide}\n * for more info.\n *\n * The validator will set the `required` error key to true if the `required` attribute is set and\n * calling {@link ngModel.NgModelController#$isEmpty `NgModelController.$isEmpty`} with the\n * {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`} returns `true`. For example, the\n * `$isEmpty()` implementation for `input[text]` checks the length of the `$viewValue`. When developing\n * custom controls, `$isEmpty()` can be overwritten to account for a $viewValue that is not string-based.\n *\n * @example\n * <example name=\"ngRequiredDirective\" module=\"ngRequiredExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('ngRequiredExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.required = true;\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"form\">\n *         <label for=\"required\">Toggle required: </label>\n *         <input type=\"checkbox\" ng-model=\"required\" id=\"required\" />\n *         <br>\n *         <label for=\"input\">This input must be filled if `required` is true: </label>\n *         <input type=\"text\" ng-model=\"model\" id=\"input\" name=\"input\" ng-required=\"required\" /><br>\n *         <hr>\n *         required error set? = <code>{{form.input.$error.required}}</code><br>\n *         model = <code>{{model}}</code>\n *       </form>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n       var required = element(by.binding('form.input.$error.required'));\n       var model = element(by.binding('model'));\n       var input = element(by.id('input'));\n\n       it('should set the required error', function() {\n         expect(required.getText()).toContain('true');\n\n         input.sendKeys('123');\n         expect(required.getText()).not.toContain('true');\n         expect(model.getText()).toContain('123');\n       });\n *   </file>\n * </example>\n */\nvar requiredDirective = function() {\n  return {\n    restrict: 'A',\n    require: '?ngModel',\n    link: function(scope, elm, attr, ctrl) {\n      if (!ctrl) return;\n      attr.required = true; // force truthy in case we are on non input element\n\n      ctrl.$validators.required = function(modelValue, viewValue) {\n        return !attr.required || !ctrl.$isEmpty(viewValue);\n      };\n\n      attr.$observe('required', function() {\n        ctrl.$validate();\n      });\n    }\n  };\n};\n\n/**\n * @ngdoc directive\n * @name ngPattern\n *\n * @description\n *\n * ngPattern adds the pattern {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `pattern` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * does not match a RegExp which is obtained by evaluating the Angular expression given in the\n * `ngPattern` attribute value:\n * * If the expression evaluates to a RegExp object, then this is used directly.\n * * If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it\n * in `^` and `$` characters. For instance, `\"abc\"` will be converted to `new RegExp('^abc$')`.\n *\n * <div class=\"alert alert-info\">\n * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n * start at the index of the last search's match, thus not taking the whole input value into\n * account.\n * </div>\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `pattern` attribute is used, with two\n * differences:\n * <ol>\n *   <li>\n *     `ngPattern` does not set the `pattern` attribute and therefore HTML5 constraint validation is\n *     not available.\n *   </li>\n *   <li>\n *     The `ngPattern` attribute must be an expression, while the `pattern` value must be\n *     interpolated.\n *   </li>\n * </ol>\n * </div>\n *\n * @example\n * <example name=\"ngPatternDirective\" module=\"ngPatternExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('ngPatternExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.regex = '\\\\d+';\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"form\">\n *         <label for=\"regex\">Set a pattern (regex string): </label>\n *         <input type=\"text\" ng-model=\"regex\" id=\"regex\" />\n *         <br>\n *         <label for=\"input\">This input is restricted by the current pattern: </label>\n *         <input type=\"text\" ng-model=\"model\" id=\"input\" name=\"input\" ng-pattern=\"regex\" /><br>\n *         <hr>\n *         input valid? = <code>{{form.input.$valid}}</code><br>\n *         model = <code>{{model}}</code>\n *       </form>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n       var model = element(by.binding('model'));\n       var input = element(by.id('input'));\n\n       it('should validate the input with the default pattern', function() {\n         input.sendKeys('aaa');\n         expect(model.getText()).not.toContain('aaa');\n\n         input.clear().then(function() {\n           input.sendKeys('123');\n           expect(model.getText()).toContain('123');\n         });\n       });\n *   </file>\n * </example>\n */\nvar patternDirective = function() {\n  return {\n    restrict: 'A',\n    require: '?ngModel',\n    link: function(scope, elm, attr, ctrl) {\n      if (!ctrl) return;\n\n      var regexp, patternExp = attr.ngPattern || attr.pattern;\n      attr.$observe('pattern', function(regex) {\n        if (isString(regex) && regex.length > 0) {\n          regex = new RegExp('^' + regex + '$');\n        }\n\n        if (regex && !regex.test) {\n          throw minErr('ngPattern')('noregexp',\n            'Expected {0} to be a RegExp but was {1}. Element: {2}', patternExp,\n            regex, startingTag(elm));\n        }\n\n        regexp = regex || undefined;\n        ctrl.$validate();\n      });\n\n      ctrl.$validators.pattern = function(modelValue, viewValue) {\n        // HTML5 pattern constraint validates the input value, so we validate the viewValue\n        return ctrl.$isEmpty(viewValue) || isUndefined(regexp) || regexp.test(viewValue);\n      };\n    }\n  };\n};\n\n/**\n * @ngdoc directive\n * @name ngMaxlength\n *\n * @description\n *\n * ngMaxlength adds the maxlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `maxlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * is longer than the integer obtained by evaluating the Angular expression given in the\n * `ngMaxlength` attribute value.\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `maxlength` attribute is used, with two\n * differences:\n * <ol>\n *   <li>\n *     `ngMaxlength` does not set the `maxlength` attribute and therefore HTML5 constraint\n *     validation is not available.\n *   </li>\n *   <li>\n *     The `ngMaxlength` attribute must be an expression, while the `maxlength` value must be\n *     interpolated.\n *   </li>\n * </ol>\n * </div>\n *\n * @example\n * <example name=\"ngMaxlengthDirective\" module=\"ngMaxlengthExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('ngMaxlengthExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.maxlength = 5;\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"form\">\n *         <label for=\"maxlength\">Set a maxlength: </label>\n *         <input type=\"number\" ng-model=\"maxlength\" id=\"maxlength\" />\n *         <br>\n *         <label for=\"input\">This input is restricted by the current maxlength: </label>\n *         <input type=\"text\" ng-model=\"model\" id=\"input\" name=\"input\" ng-maxlength=\"maxlength\" /><br>\n *         <hr>\n *         input valid? = <code>{{form.input.$valid}}</code><br>\n *         model = <code>{{model}}</code>\n *       </form>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n       var model = element(by.binding('model'));\n       var input = element(by.id('input'));\n\n       it('should validate the input with the default maxlength', function() {\n         input.sendKeys('abcdef');\n         expect(model.getText()).not.toContain('abcdef');\n\n         input.clear().then(function() {\n           input.sendKeys('abcde');\n           expect(model.getText()).toContain('abcde');\n         });\n       });\n *   </file>\n * </example>\n */\nvar maxlengthDirective = function() {\n  return {\n    restrict: 'A',\n    require: '?ngModel',\n    link: function(scope, elm, attr, ctrl) {\n      if (!ctrl) return;\n\n      var maxlength = -1;\n      attr.$observe('maxlength', function(value) {\n        var intVal = toInt(value);\n        maxlength = isNumberNaN(intVal) ? -1 : intVal;\n        ctrl.$validate();\n      });\n      ctrl.$validators.maxlength = function(modelValue, viewValue) {\n        return (maxlength < 0) || ctrl.$isEmpty(viewValue) || (viewValue.length <= maxlength);\n      };\n    }\n  };\n};\n\n/**\n * @ngdoc directive\n * @name ngMinlength\n *\n * @description\n *\n * ngMinlength adds the minlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `minlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * is shorter than the integer obtained by evaluating the Angular expression given in the\n * `ngMinlength` attribute value.\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `minlength` attribute is used, with two\n * differences:\n * <ol>\n *   <li>\n *     `ngMinlength` does not set the `minlength` attribute and therefore HTML5 constraint\n *     validation is not available.\n *   </li>\n *   <li>\n *     The `ngMinlength` value must be an expression, while the `minlength` value must be\n *     interpolated.\n *   </li>\n * </ol>\n * </div>\n *\n * @example\n * <example name=\"ngMinlengthDirective\" module=\"ngMinlengthExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('ngMinlengthExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.minlength = 3;\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"form\">\n *         <label for=\"minlength\">Set a minlength: </label>\n *         <input type=\"number\" ng-model=\"minlength\" id=\"minlength\" />\n *         <br>\n *         <label for=\"input\">This input is restricted by the current minlength: </label>\n *         <input type=\"text\" ng-model=\"model\" id=\"input\" name=\"input\" ng-minlength=\"minlength\" /><br>\n *         <hr>\n *         input valid? = <code>{{form.input.$valid}}</code><br>\n *         model = <code>{{model}}</code>\n *       </form>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n       var model = element(by.binding('model'));\n       var input = element(by.id('input'));\n\n       it('should validate the input with the default minlength', function() {\n         input.sendKeys('ab');\n         expect(model.getText()).not.toContain('ab');\n\n         input.sendKeys('abc');\n         expect(model.getText()).toContain('abc');\n       });\n *   </file>\n * </example>\n */\nvar minlengthDirective = function() {\n  return {\n    restrict: 'A',\n    require: '?ngModel',\n    link: function(scope, elm, attr, ctrl) {\n      if (!ctrl) return;\n\n      var minlength = 0;\n      attr.$observe('minlength', function(value) {\n        minlength = toInt(value) || 0;\n        ctrl.$validate();\n      });\n      ctrl.$validators.minlength = function(modelValue, viewValue) {\n        return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;\n      };\n    }\n  };\n};\n\nif (window.angular.bootstrap) {\n  // AngularJS is already loaded, so we can return here...\n  if (window.console) {\n    console.log('WARNING: Tried to load angular more than once.');\n  }\n  return;\n}\n\n// try to bind to jquery now so that one can write jqLite(fn)\n// but we will rebind on bootstrap again.\nbindJQuery();\n\npublishExternalAPI(angular);\n\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE: \"one\", TWO: \"two\", FEW: \"few\", MANY: \"many\", OTHER: \"other\"};\nfunction getDecimals(n) {\n  n = n + '';\n  var i = n.indexOf('.');\n  return (i == -1) ? 0 : n.length - i - 1;\n}\n\nfunction getVF(n, opt_precision) {\n  var v = opt_precision;\n\n  if (undefined === v) {\n    v = Math.min(getDecimals(n), 3);\n  }\n\n  var base = Math.pow(10, v);\n  var f = ((n * base) | 0) % base;\n  return {v: v, f: f};\n}\n\n$provide.value(\"$locale\", {\n  \"DATETIME_FORMATS\": {\n    \"AMPMS\": [\n      \"AM\",\n      \"PM\"\n    ],\n    \"DAY\": [\n      \"Sunday\",\n      \"Monday\",\n      \"Tuesday\",\n      \"Wednesday\",\n      \"Thursday\",\n      \"Friday\",\n      \"Saturday\"\n    ],\n    \"ERANAMES\": [\n      \"Before Christ\",\n      \"Anno Domini\"\n    ],\n    \"ERAS\": [\n      \"BC\",\n      \"AD\"\n    ],\n    \"FIRSTDAYOFWEEK\": 6,\n    \"MONTH\": [\n      \"January\",\n      \"February\",\n      \"March\",\n      \"April\",\n      \"May\",\n      \"June\",\n      \"July\",\n      \"August\",\n      \"September\",\n      \"October\",\n      \"November\",\n      \"December\"\n    ],\n    \"SHORTDAY\": [\n      \"Sun\",\n      \"Mon\",\n      \"Tue\",\n      \"Wed\",\n      \"Thu\",\n      \"Fri\",\n      \"Sat\"\n    ],\n    \"SHORTMONTH\": [\n      \"Jan\",\n      \"Feb\",\n      \"Mar\",\n      \"Apr\",\n      \"May\",\n      \"Jun\",\n      \"Jul\",\n      \"Aug\",\n      \"Sep\",\n      \"Oct\",\n      \"Nov\",\n      \"Dec\"\n    ],\n    \"STANDALONEMONTH\": [\n      \"January\",\n      \"February\",\n      \"March\",\n      \"April\",\n      \"May\",\n      \"June\",\n      \"July\",\n      \"August\",\n      \"September\",\n      \"October\",\n      \"November\",\n      \"December\"\n    ],\n    \"WEEKENDRANGE\": [\n      5,\n      6\n    ],\n    \"fullDate\": \"EEEE, MMMM d, y\",\n    \"longDate\": \"MMMM d, y\",\n    \"medium\": \"MMM d, y h:mm:ss a\",\n    \"mediumDate\": \"MMM d, y\",\n    \"mediumTime\": \"h:mm:ss a\",\n    \"short\": \"M/d/yy h:mm a\",\n    \"shortDate\": \"M/d/yy\",\n    \"shortTime\": \"h:mm a\"\n  },\n  \"NUMBER_FORMATS\": {\n    \"CURRENCY_SYM\": \"$\",\n    \"DECIMAL_SEP\": \".\",\n    \"GROUP_SEP\": \",\",\n    \"PATTERNS\": [\n      {\n        \"gSize\": 3,\n        \"lgSize\": 3,\n        \"maxFrac\": 3,\n        \"minFrac\": 0,\n        \"minInt\": 1,\n        \"negPre\": \"-\",\n        \"negSuf\": \"\",\n        \"posPre\": \"\",\n        \"posSuf\": \"\"\n      },\n      {\n        \"gSize\": 3,\n        \"lgSize\": 3,\n        \"maxFrac\": 2,\n        \"minFrac\": 2,\n        \"minInt\": 1,\n        \"negPre\": \"-\\u00a4\",\n        \"negSuf\": \"\",\n        \"posPre\": \"\\u00a4\",\n        \"posSuf\": \"\"\n      }\n    ]\n  },\n  \"id\": \"en-us\",\n  \"localeID\": \"en_US\",\n  \"pluralCat\": function(n, opt_precision) {  var i = n | 0;  var vf = getVF(n, opt_precision);  if (i == 1 && vf.v == 0) {    return PLURAL_CATEGORY.ONE;  }  return PLURAL_CATEGORY.OTHER;}\n});\n}]);\n\n  jqLite(function() {\n    angularInit(window.document, bootstrap);\n  });\n\n})(window);\n\n!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('<style type=\"text/css\">@charset \"UTF-8\";[ng\\\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular/angular.js\n// module id = 10\n// module chunks = 0","module.exports = \"\\n<!--\\nCopyright 2017-present Open Networking Foundation\\n\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\");\\nyou may not use this file except in compliance with the License.\\nYou may obtain a copy of the License at\\n\\nhttp://www.apache.org/licenses/LICENSE-2.0\\n\\nUnless required by applicable law or agreed to in writing, software\\ndistributed under the License is distributed on an \\\"AS IS\\\" BASIS,\\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\nSee the License for the specific language governing permissions and\\nlimitations under the License.\\n-->\\n\\n<div class = \\\"elinepanel\\\">\\n  <h1>ELine Overview</h1>\\n  <form ng-submit=\\\"vm.saveEline(vm.eng.eline)\\\">\\n    <div class=\\\"form-group\\\" ng-hide=\\\"vm.eng.createMode\\\">\\n      <label>ID</label><br/>\\n      <p>{{vm.eng.eline.id}}</p>\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"name\\\">Name</label>\\n      <input required class=\\\"form-control\\\" id=\\\"name\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.name\\\" ng-model=\\\"vm.eng.eline.name\\\">\\n    </div>\\n    <div class=\\\"form-group\\\" ng-hide=\\\"vm.eng.createMode\\\">\\n      <label>Backend Status</label><br/>\\n      <p>{{vm.eng.eline.backend_status}}</p>\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"cpi1\\\">Connect point 1 ID</label>\\n      <input required class=\\\"form-control\\\" id=\\\"cpi1\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.connect_point_1_id\\\" ng-model=\\\"vm.eng.eline.connect_point_1_id\\\">\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"cpi2\\\">Connect point 2 ID</label>\\n      <input required class=\\\"form-control\\\" id=\\\"cpi2\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.connect_point_2_id\\\" ng-model=\\\"vm.eng.eline.connect_point_2_id\\\">\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"bwps\\\">Bandwidth Profile</label>\\n      <select required class=\\\"form-control\\\"\\n              id=\\\"bwps\\\"\\n              ng-model=\\\"vm.eng.eline.bwp\\\"\\n              ng-options=\\\"bwp.name as bwp.name for bwp in vm.eng.bwps | orderBy:'name'\\\"\\n      >\\n      </select>\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"sitename\\\">CORD Site Name</label>\\n      <input required class=\\\"form-control\\\" id=\\\"sitename\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.cord_site_name\\\" ng-model=\\\"vm.eng.eline.cord_site_name\\\">\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"vlanids\\\">Vlan IDs</label>\\n      <input required class=\\\"form-control\\\" id=\\\"vlanids\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.vlanids\\\" ng-model=\\\"vm.eng.eline.vlanids\\\">\\n    </div>\\n    <div class=\\\"form-group\\\" style=\\\"text-align: center\\\">\\n      <button type=\\\"submit\\\" class=\\\"btn btn-success btn-block\\\">Save Changes</button>\\n    </div>\\n  </form>\\n  <button type=\\\"button\\\" class=\\\"btn btn-danger btn-block\\\" ng-click=\\\"vm.eng.elinePanel({}, vm.eng.eline, false)\\\">Close</button>\\n  <button type=\\\"button\\\" class=\\\"btn btn-danger delete-eline\\\" ng-click=\\\"vm.deleteEline(vm.eng.eline)\\\">Delete Eline</button>\\n</div>\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/components/eline-side.component.html\n// module id = 11\n// module chunks = 0","module.exports = \"\\n<!--\\nCopyright 2017-present Open Networking Foundation\\n\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\");\\nyou may not use this file except in compliance with the License.\\nYou may obtain a copy of the License at\\n\\nhttp://www.apache.org/licenses/LICENSE-2.0\\n\\nUnless required by applicable law or agreed to in writing, software\\ndistributed under the License is distributed on an \\\"AS IS\\\" BASIS,\\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\nSee the License for the specific language governing permissions and\\nlimitations under the License.\\n-->\\n\\n\\n<div class = \\\"row\\\">\\n  <div class = \\\"col-xs-12\\\">\\n    <h1>Enterprise Network Map</h1>\\n    <div map-lazy-load=\\\"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4\\\">\\n      <ng-map\\n        default-style=\\\"false\\\"\\n        id=\\\"foobar\\\"\\n        center=\\\"0,0\\\"\\n        disable-default-u-i=\\\"true\\\"\\n        map-type-id=\\\"ROADMAP\\\"\\n        zoom-control=\\\"true\\\"\\n        min-zoom=\\\"2\\\"\\n        styles=\\\"{{vm.mapStyles}}\\\"\\n      >\\n        <!--Markers-->\\n        <marker\\n          ng-repeat=\\\"uni in vm.unis\\\"\\n          id=\\\"marker-{{uni.id}}\\\"\\n          position=\\\"{{uni.latlng.toString()}}\\\"\\n          icon=\\\"{{vm.MapConfig.marker}}\\\"\\n          on-click=\\\"vm.showUni(uni)\\\"\\n        >\\n        </marker>\\n\\n        <!--Marker Info Window-->\\n\\n        <info-window id = \\\"uni-info\\\">\\n          <div class = \\\"marker-info\\\">\\n            <h4>{{vm.current_uni.name}}</h4>\\n            <p>\\n              <b>LatLng: </b>{{vm.current_uni.latlng.toString()}}<br/>\\n              <b>Cpe id: </b>{{vm.current_uni.cpe_id}}<br/>\\n              <b>Tenant: </b>{{vm.current_uni.tenant}}<br/>\\n            </p>\\n            <button ng-show=\\\"vm.canCreateEline\\\" ng-click=\\\"vm.createConnection(vm.current_uni)()\\\">Create connection</button>\\n            <button ng-show=\\\"!vm.canCreateEline && !uni.eline_start\\\" ng-click=\\\"vm.finishConnection(vm.current_uni)\\\">Finish connection</button>\\n          </div>\\n        </info-window>\\n\\n        <!--Connections-->\\n\\n        <shape\\n          ng-repeat=\\\"eline in vm.elines\\\"\\n          name=\\\"polyline\\\"\\n          id=\\\"eline-{{eline.id}}\\\"\\n          path=\\\"{{eline.path}}\\\"\\n          stroke-color=\\\"{{vm.colorLine(eline.backend_status)}}\\\"\\n          stroke-opacity=\\\"1.0\\\"\\n          stroke-weight=\\\"5\\\"\\n          on-click=\\\"vm.elinePanel({{eline}}, true)\\\"\\n        >\\n        </shape>\\n\\n      </ng-map>\\n\\n    </div>\\n    Changes may not display until page refresh.\\n  </div>\\n</div>\\n<!--\\\"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4\\\"-->\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/components/engMap.component.html\n// module id = 12\n// module chunks = 0","/**\n * @license\n * Lodash <https://lodash.com/>\n * Copyright JS Foundation and other contributors <https://js.foundation/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n;(function() {\n\n  /** Used as a safe reference for `undefined` in pre-ES5 environments. */\n  var undefined;\n\n  /** Used as the semantic version number. */\n  var VERSION = '4.17.4';\n\n  /** Used as the size to enable large array optimizations. */\n  var LARGE_ARRAY_SIZE = 200;\n\n  /** Error message constants. */\n  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',\n      FUNC_ERROR_TEXT = 'Expected a function';\n\n  /** Used to stand-in for `undefined` hash values. */\n  var HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n  /** Used as the maximum memoize cache size. */\n  var MAX_MEMOIZE_SIZE = 500;\n\n  /** Used as the internal argument placeholder. */\n  var PLACEHOLDER = '__lodash_placeholder__';\n\n  /** Used to compose bitmasks for cloning. */\n  var CLONE_DEEP_FLAG = 1,\n      CLONE_FLAT_FLAG = 2,\n      CLONE_SYMBOLS_FLAG = 4;\n\n  /** Used to compose bitmasks for value comparisons. */\n  var COMPARE_PARTIAL_FLAG = 1,\n      COMPARE_UNORDERED_FLAG = 2;\n\n  /** Used to compose bitmasks for function metadata. */\n  var WRAP_BIND_FLAG = 1,\n      WRAP_BIND_KEY_FLAG = 2,\n      WRAP_CURRY_BOUND_FLAG = 4,\n      WRAP_CURRY_FLAG = 8,\n      WRAP_CURRY_RIGHT_FLAG = 16,\n      WRAP_PARTIAL_FLAG = 32,\n      WRAP_PARTIAL_RIGHT_FLAG = 64,\n      WRAP_ARY_FLAG = 128,\n      WRAP_REARG_FLAG = 256,\n      WRAP_FLIP_FLAG = 512;\n\n  /** Used as default options for `_.truncate`. */\n  var DEFAULT_TRUNC_LENGTH = 30,\n      DEFAULT_TRUNC_OMISSION = '...';\n\n  /** Used to detect hot functions by number of calls within a span of milliseconds. */\n  var HOT_COUNT = 800,\n      HOT_SPAN = 16;\n\n  /** Used to indicate the type of lazy iteratees. */\n  var LAZY_FILTER_FLAG = 1,\n      LAZY_MAP_FLAG = 2,\n      LAZY_WHILE_FLAG = 3;\n\n  /** Used as references for various `Number` constants. */\n  var INFINITY = 1 / 0,\n      MAX_SAFE_INTEGER = 9007199254740991,\n      MAX_INTEGER = 1.7976931348623157e+308,\n      NAN = 0 / 0;\n\n  /** Used as references for the maximum length and index of an array. */\n  var MAX_ARRAY_LENGTH = 4294967295,\n      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,\n      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\n\n  /** Used to associate wrap methods with their bit flags. */\n  var wrapFlags = [\n    ['ary', WRAP_ARY_FLAG],\n    ['bind', WRAP_BIND_FLAG],\n    ['bindKey', WRAP_BIND_KEY_FLAG],\n    ['curry', WRAP_CURRY_FLAG],\n    ['curryRight', WRAP_CURRY_RIGHT_FLAG],\n    ['flip', WRAP_FLIP_FLAG],\n    ['partial', WRAP_PARTIAL_FLAG],\n    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],\n    ['rearg', WRAP_REARG_FLAG]\n  ];\n\n  /** `Object#toString` result references. */\n  var argsTag = '[object Arguments]',\n      arrayTag = '[object Array]',\n      asyncTag = '[object AsyncFunction]',\n      boolTag = '[object Boolean]',\n      dateTag = '[object Date]',\n      domExcTag = '[object DOMException]',\n      errorTag = '[object Error]',\n      funcTag = '[object Function]',\n      genTag = '[object GeneratorFunction]',\n      mapTag = '[object Map]',\n      numberTag = '[object Number]',\n      nullTag = '[object Null]',\n      objectTag = '[object Object]',\n      promiseTag = '[object Promise]',\n      proxyTag = '[object Proxy]',\n      regexpTag = '[object RegExp]',\n      setTag = '[object Set]',\n      stringTag = '[object String]',\n      symbolTag = '[object Symbol]',\n      undefinedTag = '[object Undefined]',\n      weakMapTag = '[object WeakMap]',\n      weakSetTag = '[object WeakSet]';\n\n  var arrayBufferTag = '[object ArrayBuffer]',\n      dataViewTag = '[object DataView]',\n      float32Tag = '[object Float32Array]',\n      float64Tag = '[object Float64Array]',\n      int8Tag = '[object Int8Array]',\n      int16Tag = '[object Int16Array]',\n      int32Tag = '[object Int32Array]',\n      uint8Tag = '[object Uint8Array]',\n      uint8ClampedTag = '[object Uint8ClampedArray]',\n      uint16Tag = '[object Uint16Array]',\n      uint32Tag = '[object Uint32Array]';\n\n  /** Used to match empty string literals in compiled template source. */\n  var reEmptyStringLeading = /\\b__p \\+= '';/g,\n      reEmptyStringMiddle = /\\b(__p \\+=) '' \\+/g,\n      reEmptyStringTrailing = /(__e\\(.*?\\)|\\b__t\\)) \\+\\n'';/g;\n\n  /** Used to match HTML entities and HTML characters. */\n  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,\n      reUnescapedHtml = /[&<>\"']/g,\n      reHasEscapedHtml = RegExp(reEscapedHtml.source),\n      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n\n  /** Used to match template delimiters. */\n  var reEscape = /<%-([\\s\\S]+?)%>/g,\n      reEvaluate = /<%([\\s\\S]+?)%>/g,\n      reInterpolate = /<%=([\\s\\S]+?)%>/g;\n\n  /** Used to match property names within property paths. */\n  var reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n      reIsPlainProp = /^\\w*$/,\n      reLeadingDot = /^\\./,\n      rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n  /**\n   * Used to match `RegExp`\n   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n   */\n  var reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g,\n      reHasRegExpChar = RegExp(reRegExpChar.source);\n\n  /** Used to match leading and trailing whitespace. */\n  var reTrim = /^\\s+|\\s+$/g,\n      reTrimStart = /^\\s+/,\n      reTrimEnd = /\\s+$/;\n\n  /** Used to match wrap detail comments. */\n  var reWrapComment = /\\{(?:\\n\\/\\* \\[wrapped with .+\\] \\*\\/)?\\n?/,\n      reWrapDetails = /\\{\\n\\/\\* \\[wrapped with (.+)\\] \\*/,\n      reSplitDetails = /,? & /;\n\n  /** Used to match words composed of alphanumeric characters. */\n  var reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n  /** Used to match backslashes in property paths. */\n  var reEscapeChar = /\\\\(\\\\)?/g;\n\n  /**\n   * Used to match\n   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).\n   */\n  var reEsTemplate = /\\$\\{([^\\\\}]*(?:\\\\.[^\\\\}]*)*)\\}/g;\n\n  /** Used to match `RegExp` flags from their coerced string values. */\n  var reFlags = /\\w*$/;\n\n  /** Used to detect bad signed hexadecimal string values. */\n  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n  /** Used to detect binary string values. */\n  var reIsBinary = /^0b[01]+$/i;\n\n  /** Used to detect host constructors (Safari). */\n  var reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n  /** Used to detect octal string values. */\n  var reIsOctal = /^0o[0-7]+$/i;\n\n  /** Used to detect unsigned integer values. */\n  var reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n  /** Used to match Latin Unicode letters (excluding mathematical operators). */\n  var reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n  /** Used to ensure capturing order of template delimiters. */\n  var reNoMatch = /($^)/;\n\n  /** Used to match unescaped characters in compiled string literals. */\n  var reUnescapedString = /['\\n\\r\\u2028\\u2029\\\\]/g;\n\n  /** Used to compose unicode character classes. */\n  var rsAstralRange = '\\\\ud800-\\\\udfff',\n      rsComboMarksRange = '\\\\u0300-\\\\u036f',\n      reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n      rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n      rsDingbatRange = '\\\\u2700-\\\\u27bf',\n      rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n      rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n      rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n      rsPunctuationRange = '\\\\u2000-\\\\u206f',\n      rsSpaceRange = ' \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000',\n      rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n      rsVarRange = '\\\\ufe0e\\\\ufe0f',\n      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n  /** Used to compose unicode capture groups. */\n  var rsApos = \"['\\u2019]\",\n      rsAstral = '[' + rsAstralRange + ']',\n      rsBreak = '[' + rsBreakRange + ']',\n      rsCombo = '[' + rsComboRange + ']',\n      rsDigits = '\\\\d+',\n      rsDingbat = '[' + rsDingbatRange + ']',\n      rsLower = '[' + rsLowerRange + ']',\n      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n      rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n      rsNonAstral = '[^' + rsAstralRange + ']',\n      rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n      rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n      rsUpper = '[' + rsUpperRange + ']',\n      rsZWJ = '\\\\u200d';\n\n  /** Used to compose unicode regexes. */\n  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',\n      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',\n      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n      reOptMod = rsModifier + '?',\n      rsOptVar = '[' + rsVarRange + ']?',\n      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n      rsOrdLower = '\\\\d*(?:(?:1st|2nd|3rd|(?![123])\\\\dth)\\\\b)',\n      rsOrdUpper = '\\\\d*(?:(?:1ST|2ND|3RD|(?![123])\\\\dTH)\\\\b)',\n      rsSeq = rsOptVar + reOptMod + rsOptJoin,\n      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,\n      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n  /** Used to match apostrophes. */\n  var reApos = RegExp(rsApos, 'g');\n\n  /**\n   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n   */\n  var reComboMark = RegExp(rsCombo, 'g');\n\n  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\n  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n  /** Used to match complex or compound words. */\n  var reUnicodeWord = RegExp([\n    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',\n    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,\n    rsUpper + '+' + rsOptContrUpper,\n    rsOrdUpper,\n    rsOrdLower,\n    rsDigits,\n    rsEmoji\n  ].join('|'), 'g');\n\n  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\n  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');\n\n  /** Used to detect strings that need a more robust regexp to match words. */\n  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n  /** Used to assign default `context` object properties. */\n  var contextProps = [\n    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',\n    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',\n    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',\n    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',\n    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'\n  ];\n\n  /** Used to make template sourceURLs easier to identify. */\n  var templateCounter = -1;\n\n  /** Used to identify `toStringTag` values of typed arrays. */\n  var typedArrayTags = {};\n  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n  typedArrayTags[uint32Tag] = true;\n  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\n  typedArrayTags[errorTag] = typedArrayTags[funcTag] =\n  typedArrayTags[mapTag] = typedArrayTags[numberTag] =\n  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =\n  typedArrayTags[setTag] = typedArrayTags[stringTag] =\n  typedArrayTags[weakMapTag] = false;\n\n  /** Used to identify `toStringTag` values supported by `_.clone`. */\n  var cloneableTags = {};\n  cloneableTags[argsTag] = cloneableTags[arrayTag] =\n  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\n  cloneableTags[boolTag] = cloneableTags[dateTag] =\n  cloneableTags[float32Tag] = cloneableTags[float64Tag] =\n  cloneableTags[int8Tag] = cloneableTags[int16Tag] =\n  cloneableTags[int32Tag] = cloneableTags[mapTag] =\n  cloneableTags[numberTag] = cloneableTags[objectTag] =\n  cloneableTags[regexpTag] = cloneableTags[setTag] =\n  cloneableTags[stringTag] = cloneableTags[symbolTag] =\n  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\n  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\n  cloneableTags[errorTag] = cloneableTags[funcTag] =\n  cloneableTags[weakMapTag] = false;\n\n  /** Used to map Latin Unicode letters to basic Latin letters. */\n  var deburredLetters = {\n    // Latin-1 Supplement block.\n    '\\xc0': 'A',  '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n    '\\xe0': 'a',  '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n    '\\xc7': 'C',  '\\xe7': 'c',\n    '\\xd0': 'D',  '\\xf0': 'd',\n    '\\xc8': 'E',  '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n    '\\xe8': 'e',  '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n    '\\xcc': 'I',  '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n    '\\xec': 'i',  '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n    '\\xd1': 'N',  '\\xf1': 'n',\n    '\\xd2': 'O',  '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n    '\\xf2': 'o',  '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n    '\\xd9': 'U',  '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n    '\\xf9': 'u',  '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n    '\\xdd': 'Y',  '\\xfd': 'y', '\\xff': 'y',\n    '\\xc6': 'Ae', '\\xe6': 'ae',\n    '\\xde': 'Th', '\\xfe': 'th',\n    '\\xdf': 'ss',\n    // Latin Extended-A block.\n    '\\u0100': 'A',  '\\u0102': 'A', '\\u0104': 'A',\n    '\\u0101': 'a',  '\\u0103': 'a', '\\u0105': 'a',\n    '\\u0106': 'C',  '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n    '\\u0107': 'c',  '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n    '\\u010e': 'D',  '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n    '\\u0112': 'E',  '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n    '\\u0113': 'e',  '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n    '\\u011c': 'G',  '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n    '\\u011d': 'g',  '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n    '\\u0124': 'H',  '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n    '\\u0128': 'I',  '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n    '\\u0129': 'i',  '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n    '\\u0134': 'J',  '\\u0135': 'j',\n    '\\u0136': 'K',  '\\u0137': 'k', '\\u0138': 'k',\n    '\\u0139': 'L',  '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n    '\\u013a': 'l',  '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n    '\\u0143': 'N',  '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n    '\\u0144': 'n',  '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n    '\\u014c': 'O',  '\\u014e': 'O', '\\u0150': 'O',\n    '\\u014d': 'o',  '\\u014f': 'o', '\\u0151': 'o',\n    '\\u0154': 'R',  '\\u0156': 'R', '\\u0158': 'R',\n    '\\u0155': 'r',  '\\u0157': 'r', '\\u0159': 'r',\n    '\\u015a': 'S',  '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n    '\\u015b': 's',  '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n    '\\u0162': 'T',  '\\u0164': 'T', '\\u0166': 'T',\n    '\\u0163': 't',  '\\u0165': 't', '\\u0167': 't',\n    '\\u0168': 'U',  '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n    '\\u0169': 'u',  '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n    '\\u0174': 'W',  '\\u0175': 'w',\n    '\\u0176': 'Y',  '\\u0177': 'y', '\\u0178': 'Y',\n    '\\u0179': 'Z',  '\\u017b': 'Z', '\\u017d': 'Z',\n    '\\u017a': 'z',  '\\u017c': 'z', '\\u017e': 'z',\n    '\\u0132': 'IJ', '\\u0133': 'ij',\n    '\\u0152': 'Oe', '\\u0153': 'oe',\n    '\\u0149': \"'n\", '\\u017f': 's'\n  };\n\n  /** Used to map characters to HTML entities. */\n  var htmlEscapes = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  };\n\n  /** Used to map HTML entities to characters. */\n  var htmlUnescapes = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#39;': \"'\"\n  };\n\n  /** Used to escape characters for inclusion in compiled string literals. */\n  var stringEscapes = {\n    '\\\\': '\\\\',\n    \"'\": \"'\",\n    '\\n': 'n',\n    '\\r': 'r',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  /** Built-in method references without a dependency on `root`. */\n  var freeParseFloat = parseFloat,\n      freeParseInt = parseInt;\n\n  /** Detect free variable `global` from Node.js. */\n  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n  /** Detect free variable `self`. */\n  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n  /** Used as a reference to the global object. */\n  var root = freeGlobal || freeSelf || Function('return this')();\n\n  /** Detect free variable `exports`. */\n  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n  /** Detect free variable `module`. */\n  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n  /** Detect the popular CommonJS extension `module.exports`. */\n  var moduleExports = freeModule && freeModule.exports === freeExports;\n\n  /** Detect free variable `process` from Node.js. */\n  var freeProcess = moduleExports && freeGlobal.process;\n\n  /** Used to access faster Node.js helpers. */\n  var nodeUtil = (function() {\n    try {\n      return freeProcess && freeProcess.binding && freeProcess.binding('util');\n    } catch (e) {}\n  }());\n\n  /* Node.js helper references. */\n  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,\n      nodeIsDate = nodeUtil && nodeUtil.isDate,\n      nodeIsMap = nodeUtil && nodeUtil.isMap,\n      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,\n      nodeIsSet = nodeUtil && nodeUtil.isSet,\n      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Adds the key-value `pair` to `map`.\n   *\n   * @private\n   * @param {Object} map The map to modify.\n   * @param {Array} pair The key-value pair to add.\n   * @returns {Object} Returns `map`.\n   */\n  function addMapEntry(map, pair) {\n    // Don't return `map.set` because it's not chainable in IE 11.\n    map.set(pair[0], pair[1]);\n    return map;\n  }\n\n  /**\n   * Adds `value` to `set`.\n   *\n   * @private\n   * @param {Object} set The set to modify.\n   * @param {*} value The value to add.\n   * @returns {Object} Returns `set`.\n   */\n  function addSetEntry(set, value) {\n    // Don't return `set.add` because it's not chainable in IE 11.\n    set.add(value);\n    return set;\n  }\n\n  /**\n   * A faster alternative to `Function#apply`, this function invokes `func`\n   * with the `this` binding of `thisArg` and the arguments of `args`.\n   *\n   * @private\n   * @param {Function} func The function to invoke.\n   * @param {*} thisArg The `this` binding of `func`.\n   * @param {Array} args The arguments to invoke `func` with.\n   * @returns {*} Returns the result of `func`.\n   */\n  function apply(func, thisArg, args) {\n    switch (args.length) {\n      case 0: return func.call(thisArg);\n      case 1: return func.call(thisArg, args[0]);\n      case 2: return func.call(thisArg, args[0], args[1]);\n      case 3: return func.call(thisArg, args[0], args[1], args[2]);\n    }\n    return func.apply(thisArg, args);\n  }\n\n  /**\n   * A specialized version of `baseAggregator` for arrays.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} setter The function to set `accumulator` values.\n   * @param {Function} iteratee The iteratee to transform keys.\n   * @param {Object} accumulator The initial aggregated object.\n   * @returns {Function} Returns `accumulator`.\n   */\n  function arrayAggregator(array, setter, iteratee, accumulator) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      var value = array[index];\n      setter(accumulator, value, iteratee(value), array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.forEach` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayEach(array, iteratee) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (iteratee(array[index], index, array) === false) {\n        break;\n      }\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.forEachRight` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayEachRight(array, iteratee) {\n    var length = array == null ? 0 : array.length;\n\n    while (length--) {\n      if (iteratee(array[length], length, array) === false) {\n        break;\n      }\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.every` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {boolean} Returns `true` if all elements pass the predicate check,\n   *  else `false`.\n   */\n  function arrayEvery(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (!predicate(array[index], index, array)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  /**\n   * A specialized version of `_.filter` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {Array} Returns the new filtered array.\n   */\n  function arrayFilter(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length,\n        resIndex = 0,\n        result = [];\n\n    while (++index < length) {\n      var value = array[index];\n      if (predicate(value, index, array)) {\n        result[resIndex++] = value;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * A specialized version of `_.includes` for arrays without support for\n   * specifying an index to search from.\n   *\n   * @private\n   * @param {Array} [array] The array to inspect.\n   * @param {*} target The value to search for.\n   * @returns {boolean} Returns `true` if `target` is found, else `false`.\n   */\n  function arrayIncludes(array, value) {\n    var length = array == null ? 0 : array.length;\n    return !!length && baseIndexOf(array, value, 0) > -1;\n  }\n\n  /**\n   * This function is like `arrayIncludes` except that it accepts a comparator.\n   *\n   * @private\n   * @param {Array} [array] The array to inspect.\n   * @param {*} target The value to search for.\n   * @param {Function} comparator The comparator invoked per element.\n   * @returns {boolean} Returns `true` if `target` is found, else `false`.\n   */\n  function arrayIncludesWith(array, value, comparator) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (comparator(value, array[index])) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * A specialized version of `_.map` for arrays without support for iteratee\n   * shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns the new mapped array.\n   */\n  function arrayMap(array, iteratee) {\n    var index = -1,\n        length = array == null ? 0 : array.length,\n        result = Array(length);\n\n    while (++index < length) {\n      result[index] = iteratee(array[index], index, array);\n    }\n    return result;\n  }\n\n  /**\n   * Appends the elements of `values` to `array`.\n   *\n   * @private\n   * @param {Array} array The array to modify.\n   * @param {Array} values The values to append.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayPush(array, values) {\n    var index = -1,\n        length = values.length,\n        offset = array.length;\n\n    while (++index < length) {\n      array[offset + index] = values[index];\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.reduce` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} [accumulator] The initial value.\n   * @param {boolean} [initAccum] Specify using the first element of `array` as\n   *  the initial value.\n   * @returns {*} Returns the accumulated value.\n   */\n  function arrayReduce(array, iteratee, accumulator, initAccum) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    if (initAccum && length) {\n      accumulator = array[++index];\n    }\n    while (++index < length) {\n      accumulator = iteratee(accumulator, array[index], index, array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.reduceRight` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} [accumulator] The initial value.\n   * @param {boolean} [initAccum] Specify using the last element of `array` as\n   *  the initial value.\n   * @returns {*} Returns the accumulated value.\n   */\n  function arrayReduceRight(array, iteratee, accumulator, initAccum) {\n    var length = array == null ? 0 : array.length;\n    if (initAccum && length) {\n      accumulator = array[--length];\n    }\n    while (length--) {\n      accumulator = iteratee(accumulator, array[length], length, array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.some` for arrays without support for iteratee\n   * shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {boolean} Returns `true` if any element passes the predicate check,\n   *  else `false`.\n   */\n  function arraySome(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (predicate(array[index], index, array)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Gets the size of an ASCII `string`.\n   *\n   * @private\n   * @param {string} string The string inspect.\n   * @returns {number} Returns the string size.\n   */\n  var asciiSize = baseProperty('length');\n\n  /**\n   * Converts an ASCII `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function asciiToArray(string) {\n    return string.split('');\n  }\n\n  /**\n   * Splits an ASCII `string` into an array of its words.\n   *\n   * @private\n   * @param {string} The string to inspect.\n   * @returns {Array} Returns the words of `string`.\n   */\n  function asciiWords(string) {\n    return string.match(reAsciiWord) || [];\n  }\n\n  /**\n   * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n   * without support for iteratee shorthands, which iterates over `collection`\n   * using `eachFunc`.\n   *\n   * @private\n   * @param {Array|Object} collection The collection to inspect.\n   * @param {Function} predicate The function invoked per iteration.\n   * @param {Function} eachFunc The function to iterate over `collection`.\n   * @returns {*} Returns the found element or its key, else `undefined`.\n   */\n  function baseFindKey(collection, predicate, eachFunc) {\n    var result;\n    eachFunc(collection, function(value, key, collection) {\n      if (predicate(value, key, collection)) {\n        result = key;\n        return false;\n      }\n    });\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.findIndex` and `_.findLastIndex` without\n   * support for iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {Function} predicate The function invoked per iteration.\n   * @param {number} fromIndex The index to search from.\n   * @param {boolean} [fromRight] Specify iterating from right to left.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseFindIndex(array, predicate, fromIndex, fromRight) {\n    var length = array.length,\n        index = fromIndex + (fromRight ? 1 : -1);\n\n    while ((fromRight ? index-- : ++index < length)) {\n      if (predicate(array[index], index, array)) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseIndexOf(array, value, fromIndex) {\n    return value === value\n      ? strictIndexOf(array, value, fromIndex)\n      : baseFindIndex(array, baseIsNaN, fromIndex);\n  }\n\n  /**\n   * This function is like `baseIndexOf` except that it accepts a comparator.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @param {Function} comparator The comparator invoked per element.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseIndexOfWith(array, value, fromIndex, comparator) {\n    var index = fromIndex - 1,\n        length = array.length;\n\n    while (++index < length) {\n      if (comparator(array[index], value)) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * The base implementation of `_.isNaN` without support for number objects.\n   *\n   * @private\n   * @param {*} value The value to check.\n   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n   */\n  function baseIsNaN(value) {\n    return value !== value;\n  }\n\n  /**\n   * The base implementation of `_.mean` and `_.meanBy` without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {number} Returns the mean.\n   */\n  function baseMean(array, iteratee) {\n    var length = array == null ? 0 : array.length;\n    return length ? (baseSum(array, iteratee) / length) : NAN;\n  }\n\n  /**\n   * The base implementation of `_.property` without support for deep paths.\n   *\n   * @private\n   * @param {string} key The key of the property to get.\n   * @returns {Function} Returns the new accessor function.\n   */\n  function baseProperty(key) {\n    return function(object) {\n      return object == null ? undefined : object[key];\n    };\n  }\n\n  /**\n   * The base implementation of `_.propertyOf` without support for deep paths.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @returns {Function} Returns the new accessor function.\n   */\n  function basePropertyOf(object) {\n    return function(key) {\n      return object == null ? undefined : object[key];\n    };\n  }\n\n  /**\n   * The base implementation of `_.reduce` and `_.reduceRight`, without support\n   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.\n   *\n   * @private\n   * @param {Array|Object} collection The collection to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} accumulator The initial value.\n   * @param {boolean} initAccum Specify using the first or last element of\n   *  `collection` as the initial value.\n   * @param {Function} eachFunc The function to iterate over `collection`.\n   * @returns {*} Returns the accumulated value.\n   */\n  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {\n    eachFunc(collection, function(value, index, collection) {\n      accumulator = initAccum\n        ? (initAccum = false, value)\n        : iteratee(accumulator, value, index, collection);\n    });\n    return accumulator;\n  }\n\n  /**\n   * The base implementation of `_.sortBy` which uses `comparer` to define the\n   * sort order of `array` and replaces criteria objects with their corresponding\n   * values.\n   *\n   * @private\n   * @param {Array} array The array to sort.\n   * @param {Function} comparer The function to define sort order.\n   * @returns {Array} Returns `array`.\n   */\n  function baseSortBy(array, comparer) {\n    var length = array.length;\n\n    array.sort(comparer);\n    while (length--) {\n      array[length] = array[length].value;\n    }\n    return array;\n  }\n\n  /**\n   * The base implementation of `_.sum` and `_.sumBy` without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {number} Returns the sum.\n   */\n  function baseSum(array, iteratee) {\n    var result,\n        index = -1,\n        length = array.length;\n\n    while (++index < length) {\n      var current = iteratee(array[index]);\n      if (current !== undefined) {\n        result = result === undefined ? current : (result + current);\n      }\n    }\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.times` without support for iteratee shorthands\n   * or max array length checks.\n   *\n   * @private\n   * @param {number} n The number of times to invoke `iteratee`.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns the array of results.\n   */\n  function baseTimes(n, iteratee) {\n    var index = -1,\n        result = Array(n);\n\n    while (++index < n) {\n      result[index] = iteratee(index);\n    }\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array\n   * of key-value pairs for `object` corresponding to the property names of `props`.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @param {Array} props The property names to get values for.\n   * @returns {Object} Returns the key-value pairs.\n   */\n  function baseToPairs(object, props) {\n    return arrayMap(props, function(key) {\n      return [key, object[key]];\n    });\n  }\n\n  /**\n   * The base implementation of `_.unary` without support for storing metadata.\n   *\n   * @private\n   * @param {Function} func The function to cap arguments for.\n   * @returns {Function} Returns the new capped function.\n   */\n  function baseUnary(func) {\n    return function(value) {\n      return func(value);\n    };\n  }\n\n  /**\n   * The base implementation of `_.values` and `_.valuesIn` which creates an\n   * array of `object` property values corresponding to the property names\n   * of `props`.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @param {Array} props The property names to get values for.\n   * @returns {Object} Returns the array of property values.\n   */\n  function baseValues(object, props) {\n    return arrayMap(props, function(key) {\n      return object[key];\n    });\n  }\n\n  /**\n   * Checks if a `cache` value for `key` exists.\n   *\n   * @private\n   * @param {Object} cache The cache to query.\n   * @param {string} key The key of the entry to check.\n   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n   */\n  function cacheHas(cache, key) {\n    return cache.has(key);\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol\n   * that is not found in the character symbols.\n   *\n   * @private\n   * @param {Array} strSymbols The string symbols to inspect.\n   * @param {Array} chrSymbols The character symbols to find.\n   * @returns {number} Returns the index of the first unmatched string symbol.\n   */\n  function charsStartIndex(strSymbols, chrSymbols) {\n    var index = -1,\n        length = strSymbols.length;\n\n    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n    return index;\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol\n   * that is not found in the character symbols.\n   *\n   * @private\n   * @param {Array} strSymbols The string symbols to inspect.\n   * @param {Array} chrSymbols The character symbols to find.\n   * @returns {number} Returns the index of the last unmatched string symbol.\n   */\n  function charsEndIndex(strSymbols, chrSymbols) {\n    var index = strSymbols.length;\n\n    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n    return index;\n  }\n\n  /**\n   * Gets the number of `placeholder` occurrences in `array`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} placeholder The placeholder to search for.\n   * @returns {number} Returns the placeholder count.\n   */\n  function countHolders(array, placeholder) {\n    var length = array.length,\n        result = 0;\n\n    while (length--) {\n      if (array[length] === placeholder) {\n        ++result;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n   * letters to basic Latin letters.\n   *\n   * @private\n   * @param {string} letter The matched letter to deburr.\n   * @returns {string} Returns the deburred letter.\n   */\n  var deburrLetter = basePropertyOf(deburredLetters);\n\n  /**\n   * Used by `_.escape` to convert characters to HTML entities.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @returns {string} Returns the escaped character.\n   */\n  var escapeHtmlChar = basePropertyOf(htmlEscapes);\n\n  /**\n   * Used by `_.template` to escape characters for inclusion in compiled string literals.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @returns {string} Returns the escaped character.\n   */\n  function escapeStringChar(chr) {\n    return '\\\\' + stringEscapes[chr];\n  }\n\n  /**\n   * Gets the value at `key` of `object`.\n   *\n   * @private\n   * @param {Object} [object] The object to query.\n   * @param {string} key The key of the property to get.\n   * @returns {*} Returns the property value.\n   */\n  function getValue(object, key) {\n    return object == null ? undefined : object[key];\n  }\n\n  /**\n   * Checks if `string` contains Unicode symbols.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n   */\n  function hasUnicode(string) {\n    return reHasUnicode.test(string);\n  }\n\n  /**\n   * Checks if `string` contains a word composed of Unicode symbols.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {boolean} Returns `true` if a word is found, else `false`.\n   */\n  function hasUnicodeWord(string) {\n    return reHasUnicodeWord.test(string);\n  }\n\n  /**\n   * Converts `iterator` to an array.\n   *\n   * @private\n   * @param {Object} iterator The iterator to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function iteratorToArray(iterator) {\n    var data,\n        result = [];\n\n    while (!(data = iterator.next()).done) {\n      result.push(data.value);\n    }\n    return result;\n  }\n\n  /**\n   * Converts `map` to its key-value pairs.\n   *\n   * @private\n   * @param {Object} map The map to convert.\n   * @returns {Array} Returns the key-value pairs.\n   */\n  function mapToArray(map) {\n    var index = -1,\n        result = Array(map.size);\n\n    map.forEach(function(value, key) {\n      result[++index] = [key, value];\n    });\n    return result;\n  }\n\n  /**\n   * Creates a unary function that invokes `func` with its argument transformed.\n   *\n   * @private\n   * @param {Function} func The function to wrap.\n   * @param {Function} transform The argument transform.\n   * @returns {Function} Returns the new function.\n   */\n  function overArg(func, transform) {\n    return function(arg) {\n      return func(transform(arg));\n    };\n  }\n\n  /**\n   * Replaces all `placeholder` elements in `array` with an internal placeholder\n   * and returns an array of their indexes.\n   *\n   * @private\n   * @param {Array} array The array to modify.\n   * @param {*} placeholder The placeholder to replace.\n   * @returns {Array} Returns the new array of placeholder indexes.\n   */\n  function replaceHolders(array, placeholder) {\n    var index = -1,\n        length = array.length,\n        resIndex = 0,\n        result = [];\n\n    while (++index < length) {\n      var value = array[index];\n      if (value === placeholder || value === PLACEHOLDER) {\n        array[index] = PLACEHOLDER;\n        result[resIndex++] = index;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Converts `set` to an array of its values.\n   *\n   * @private\n   * @param {Object} set The set to convert.\n   * @returns {Array} Returns the values.\n   */\n  function setToArray(set) {\n    var index = -1,\n        result = Array(set.size);\n\n    set.forEach(function(value) {\n      result[++index] = value;\n    });\n    return result;\n  }\n\n  /**\n   * Converts `set` to its value-value pairs.\n   *\n   * @private\n   * @param {Object} set The set to convert.\n   * @returns {Array} Returns the value-value pairs.\n   */\n  function setToPairs(set) {\n    var index = -1,\n        result = Array(set.size);\n\n    set.forEach(function(value) {\n      result[++index] = [value, value];\n    });\n    return result;\n  }\n\n  /**\n   * A specialized version of `_.indexOf` which performs strict equality\n   * comparisons of values, i.e. `===`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function strictIndexOf(array, value, fromIndex) {\n    var index = fromIndex - 1,\n        length = array.length;\n\n    while (++index < length) {\n      if (array[index] === value) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * A specialized version of `_.lastIndexOf` which performs strict equality\n   * comparisons of values, i.e. `===`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function strictLastIndexOf(array, value, fromIndex) {\n    var index = fromIndex + 1;\n    while (index--) {\n      if (array[index] === value) {\n        return index;\n      }\n    }\n    return index;\n  }\n\n  /**\n   * Gets the number of symbols in `string`.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {number} Returns the string size.\n   */\n  function stringSize(string) {\n    return hasUnicode(string)\n      ? unicodeSize(string)\n      : asciiSize(string);\n  }\n\n  /**\n   * Converts `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function stringToArray(string) {\n    return hasUnicode(string)\n      ? unicodeToArray(string)\n      : asciiToArray(string);\n  }\n\n  /**\n   * Used by `_.unescape` to convert HTML entities to characters.\n   *\n   * @private\n   * @param {string} chr The matched character to unescape.\n   * @returns {string} Returns the unescaped character.\n   */\n  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);\n\n  /**\n   * Gets the size of a Unicode `string`.\n   *\n   * @private\n   * @param {string} string The string inspect.\n   * @returns {number} Returns the string size.\n   */\n  function unicodeSize(string) {\n    var result = reUnicode.lastIndex = 0;\n    while (reUnicode.test(string)) {\n      ++result;\n    }\n    return result;\n  }\n\n  /**\n   * Converts a Unicode `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function unicodeToArray(string) {\n    return string.match(reUnicode) || [];\n  }\n\n  /**\n   * Splits a Unicode `string` into an array of its words.\n   *\n   * @private\n   * @param {string} The string to inspect.\n   * @returns {Array} Returns the words of `string`.\n   */\n  function unicodeWords(string) {\n    return string.match(reUnicodeWord) || [];\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Create a new pristine `lodash` function using the `context` object.\n   *\n   * @static\n   * @memberOf _\n   * @since 1.1.0\n   * @category Util\n   * @param {Object} [context=root] The context object.\n   * @returns {Function} Returns a new `lodash` function.\n   * @example\n   *\n   * _.mixin({ 'foo': _.constant('foo') });\n   *\n   * var lodash = _.runInContext();\n   * lodash.mixin({ 'bar': lodash.constant('bar') });\n   *\n   * _.isFunction(_.foo);\n   * // => true\n   * _.isFunction(_.bar);\n   * // => false\n   *\n   * lodash.isFunction(lodash.foo);\n   * // => false\n   * lodash.isFunction(lodash.bar);\n   * // => true\n   *\n   * // Create a suped-up `defer` in Node.js.\n   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;\n   */\n  var runInContext = (function runInContext(context) {\n    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));\n\n    /** Built-in constructor references. */\n    var Array = context.Array,\n        Date = context.Date,\n        Error = context.Error,\n        Function = context.Function,\n        Math = context.Math,\n        Object = context.Object,\n        RegExp = context.RegExp,\n        String = context.String,\n        TypeError = context.TypeError;\n\n    /** Used for built-in method references. */\n    var arrayProto = Array.prototype,\n        funcProto = Function.prototype,\n        objectProto = Object.prototype;\n\n    /** Used to detect overreaching core-js shims. */\n    var coreJsData = context['__core-js_shared__'];\n\n    /** Used to resolve the decompiled source of functions. */\n    var funcToString = funcProto.toString;\n\n    /** Used to check objects for own properties. */\n    var hasOwnProperty = objectProto.hasOwnProperty;\n\n    /** Used to generate unique IDs. */\n    var idCounter = 0;\n\n    /** Used to detect methods masquerading as native. */\n    var maskSrcKey = (function() {\n      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n      return uid ? ('Symbol(src)_1.' + uid) : '';\n    }());\n\n    /**\n     * Used to resolve the\n     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n     * of values.\n     */\n    var nativeObjectToString = objectProto.toString;\n\n    /** Used to infer the `Object` constructor. */\n    var objectCtorString = funcToString.call(Object);\n\n    /** Used to restore the original `_` reference in `_.noConflict`. */\n    var oldDash = root._;\n\n    /** Used to detect if a method is native. */\n    var reIsNative = RegExp('^' +\n      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n      .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n    );\n\n    /** Built-in value references. */\n    var Buffer = moduleExports ? context.Buffer : undefined,\n        Symbol = context.Symbol,\n        Uint8Array = context.Uint8Array,\n        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,\n        getPrototype = overArg(Object.getPrototypeOf, Object),\n        objectCreate = Object.create,\n        propertyIsEnumerable = objectProto.propertyIsEnumerable,\n        splice = arrayProto.splice,\n        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,\n        symIterator = Symbol ? Symbol.iterator : undefined,\n        symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n    var defineProperty = (function() {\n      try {\n        var func = getNative(Object, 'defineProperty');\n        func({}, '', {});\n        return func;\n      } catch (e) {}\n    }());\n\n    /** Mocked built-ins. */\n    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,\n        ctxNow = Date && Date.now !== root.Date.now && Date.now,\n        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;\n\n    /* Built-in method references for those with the same name as other `lodash` methods. */\n    var nativeCeil = Math.ceil,\n        nativeFloor = Math.floor,\n        nativeGetSymbols = Object.getOwnPropertySymbols,\n        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n        nativeIsFinite = context.isFinite,\n        nativeJoin = arrayProto.join,\n        nativeKeys = overArg(Object.keys, Object),\n        nativeMax = Math.max,\n        nativeMin = Math.min,\n        nativeNow = Date.now,\n        nativeParseInt = context.parseInt,\n        nativeRandom = Math.random,\n        nativeReverse = arrayProto.reverse;\n\n    /* Built-in method references that are verified to be native. */\n    var DataView = getNative(context, 'DataView'),\n        Map = getNative(context, 'Map'),\n        Promise = getNative(context, 'Promise'),\n        Set = getNative(context, 'Set'),\n        WeakMap = getNative(context, 'WeakMap'),\n        nativeCreate = getNative(Object, 'create');\n\n    /** Used to store function metadata. */\n    var metaMap = WeakMap && new WeakMap;\n\n    /** Used to lookup unminified function names. */\n    var realNames = {};\n\n    /** Used to detect maps, sets, and weakmaps. */\n    var dataViewCtorString = toSource(DataView),\n        mapCtorString = toSource(Map),\n        promiseCtorString = toSource(Promise),\n        setCtorString = toSource(Set),\n        weakMapCtorString = toSource(WeakMap);\n\n    /** Used to convert symbols to primitives and strings. */\n    var symbolProto = Symbol ? Symbol.prototype : undefined,\n        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,\n        symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a `lodash` object which wraps `value` to enable implicit method\n     * chain sequences. Methods that operate on and return arrays, collections,\n     * and functions can be chained together. Methods that retrieve a single value\n     * or may return a primitive value will automatically end the chain sequence\n     * and return the unwrapped value. Otherwise, the value must be unwrapped\n     * with `_#value`.\n     *\n     * Explicit chain sequences, which must be unwrapped with `_#value`, may be\n     * enabled using `_.chain`.\n     *\n     * The execution of chained methods is lazy, that is, it's deferred until\n     * `_#value` is implicitly or explicitly called.\n     *\n     * Lazy evaluation allows several methods to support shortcut fusion.\n     * Shortcut fusion is an optimization to merge iteratee calls; this avoids\n     * the creation of intermediate arrays and can greatly reduce the number of\n     * iteratee executions. Sections of a chain sequence qualify for shortcut\n     * fusion if the section is applied to an array and iteratees accept only\n     * one argument. The heuristic for whether a section qualifies for shortcut\n     * fusion is subject to change.\n     *\n     * Chaining is supported in custom builds as long as the `_#value` method is\n     * directly or indirectly included in the build.\n     *\n     * In addition to lodash methods, wrappers have `Array` and `String` methods.\n     *\n     * The wrapper `Array` methods are:\n     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`\n     *\n     * The wrapper `String` methods are:\n     * `replace` and `split`\n     *\n     * The wrapper methods that support shortcut fusion are:\n     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,\n     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,\n     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`\n     *\n     * The chainable wrapper methods are:\n     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,\n     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,\n     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,\n     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,\n     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,\n     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,\n     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,\n     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,\n     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,\n     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,\n     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,\n     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,\n     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,\n     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,\n     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,\n     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,\n     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,\n     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,\n     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,\n     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,\n     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,\n     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,\n     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,\n     * `zipObject`, `zipObjectDeep`, and `zipWith`\n     *\n     * The wrapper methods that are **not** chainable by default are:\n     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,\n     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,\n     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,\n     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,\n     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,\n     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,\n     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,\n     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,\n     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,\n     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,\n     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,\n     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,\n     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,\n     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,\n     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,\n     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,\n     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,\n     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,\n     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,\n     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,\n     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,\n     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,\n     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,\n     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,\n     * `upperFirst`, `value`, and `words`\n     *\n     * @name _\n     * @constructor\n     * @category Seq\n     * @param {*} value The value to wrap in a `lodash` instance.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var wrapped = _([1, 2, 3]);\n     *\n     * // Returns an unwrapped value.\n     * wrapped.reduce(_.add);\n     * // => 6\n     *\n     * // Returns a wrapped value.\n     * var squares = wrapped.map(square);\n     *\n     * _.isArray(squares);\n     * // => false\n     *\n     * _.isArray(squares.value());\n     * // => true\n     */\n    function lodash(value) {\n      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\n        if (value instanceof LodashWrapper) {\n          return value;\n        }\n        if (hasOwnProperty.call(value, '__wrapped__')) {\n          return wrapperClone(value);\n        }\n      }\n      return new LodashWrapper(value);\n    }\n\n    /**\n     * The base implementation of `_.create` without support for assigning\n     * properties to the created object.\n     *\n     * @private\n     * @param {Object} proto The object to inherit from.\n     * @returns {Object} Returns the new object.\n     */\n    var baseCreate = (function() {\n      function object() {}\n      return function(proto) {\n        if (!isObject(proto)) {\n          return {};\n        }\n        if (objectCreate) {\n          return objectCreate(proto);\n        }\n        object.prototype = proto;\n        var result = new object;\n        object.prototype = undefined;\n        return result;\n      };\n    }());\n\n    /**\n     * The function whose prototype chain sequence wrappers inherit from.\n     *\n     * @private\n     */\n    function baseLodash() {\n      // No operation performed.\n    }\n\n    /**\n     * The base constructor for creating `lodash` wrapper objects.\n     *\n     * @private\n     * @param {*} value The value to wrap.\n     * @param {boolean} [chainAll] Enable explicit method chain sequences.\n     */\n    function LodashWrapper(value, chainAll) {\n      this.__wrapped__ = value;\n      this.__actions__ = [];\n      this.__chain__ = !!chainAll;\n      this.__index__ = 0;\n      this.__values__ = undefined;\n    }\n\n    /**\n     * By default, the template delimiters used by lodash are like those in\n     * embedded Ruby (ERB) as well as ES2015 template strings. Change the\n     * following template settings to use alternative delimiters.\n     *\n     * @static\n     * @memberOf _\n     * @type {Object}\n     */\n    lodash.templateSettings = {\n\n      /**\n       * Used to detect `data` property values to be HTML-escaped.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'escape': reEscape,\n\n      /**\n       * Used to detect code to be evaluated.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'evaluate': reEvaluate,\n\n      /**\n       * Used to detect `data` property values to inject.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'interpolate': reInterpolate,\n\n      /**\n       * Used to reference the data object in the template text.\n       *\n       * @memberOf _.templateSettings\n       * @type {string}\n       */\n      'variable': '',\n\n      /**\n       * Used to import variables into the compiled template.\n       *\n       * @memberOf _.templateSettings\n       * @type {Object}\n       */\n      'imports': {\n\n        /**\n         * A reference to the `lodash` function.\n         *\n         * @memberOf _.templateSettings.imports\n         * @type {Function}\n         */\n        '_': lodash\n      }\n    };\n\n    // Ensure wrappers are instances of `baseLodash`.\n    lodash.prototype = baseLodash.prototype;\n    lodash.prototype.constructor = lodash;\n\n    LodashWrapper.prototype = baseCreate(baseLodash.prototype);\n    LodashWrapper.prototype.constructor = LodashWrapper;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\n     *\n     * @private\n     * @constructor\n     * @param {*} value The value to wrap.\n     */\n    function LazyWrapper(value) {\n      this.__wrapped__ = value;\n      this.__actions__ = [];\n      this.__dir__ = 1;\n      this.__filtered__ = false;\n      this.__iteratees__ = [];\n      this.__takeCount__ = MAX_ARRAY_LENGTH;\n      this.__views__ = [];\n    }\n\n    /**\n     * Creates a clone of the lazy wrapper object.\n     *\n     * @private\n     * @name clone\n     * @memberOf LazyWrapper\n     * @returns {Object} Returns the cloned `LazyWrapper` object.\n     */\n    function lazyClone() {\n      var result = new LazyWrapper(this.__wrapped__);\n      result.__actions__ = copyArray(this.__actions__);\n      result.__dir__ = this.__dir__;\n      result.__filtered__ = this.__filtered__;\n      result.__iteratees__ = copyArray(this.__iteratees__);\n      result.__takeCount__ = this.__takeCount__;\n      result.__views__ = copyArray(this.__views__);\n      return result;\n    }\n\n    /**\n     * Reverses the direction of lazy iteration.\n     *\n     * @private\n     * @name reverse\n     * @memberOf LazyWrapper\n     * @returns {Object} Returns the new reversed `LazyWrapper` object.\n     */\n    function lazyReverse() {\n      if (this.__filtered__) {\n        var result = new LazyWrapper(this);\n        result.__dir__ = -1;\n        result.__filtered__ = true;\n      } else {\n        result = this.clone();\n        result.__dir__ *= -1;\n      }\n      return result;\n    }\n\n    /**\n     * Extracts the unwrapped value from its lazy wrapper.\n     *\n     * @private\n     * @name value\n     * @memberOf LazyWrapper\n     * @returns {*} Returns the unwrapped value.\n     */\n    function lazyValue() {\n      var array = this.__wrapped__.value(),\n          dir = this.__dir__,\n          isArr = isArray(array),\n          isRight = dir < 0,\n          arrLength = isArr ? array.length : 0,\n          view = getView(0, arrLength, this.__views__),\n          start = view.start,\n          end = view.end,\n          length = end - start,\n          index = isRight ? end : (start - 1),\n          iteratees = this.__iteratees__,\n          iterLength = iteratees.length,\n          resIndex = 0,\n          takeCount = nativeMin(length, this.__takeCount__);\n\n      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {\n        return baseWrapperValue(array, this.__actions__);\n      }\n      var result = [];\n\n      outer:\n      while (length-- && resIndex < takeCount) {\n        index += dir;\n\n        var iterIndex = -1,\n            value = array[index];\n\n        while (++iterIndex < iterLength) {\n          var data = iteratees[iterIndex],\n              iteratee = data.iteratee,\n              type = data.type,\n              computed = iteratee(value);\n\n          if (type == LAZY_MAP_FLAG) {\n            value = computed;\n          } else if (!computed) {\n            if (type == LAZY_FILTER_FLAG) {\n              continue outer;\n            } else {\n              break outer;\n            }\n          }\n        }\n        result[resIndex++] = value;\n      }\n      return result;\n    }\n\n    // Ensure `LazyWrapper` is an instance of `baseLodash`.\n    LazyWrapper.prototype = baseCreate(baseLodash.prototype);\n    LazyWrapper.prototype.constructor = LazyWrapper;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a hash object.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function Hash(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the hash.\n     *\n     * @private\n     * @name clear\n     * @memberOf Hash\n     */\n    function hashClear() {\n      this.__data__ = nativeCreate ? nativeCreate(null) : {};\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the hash.\n     *\n     * @private\n     * @name delete\n     * @memberOf Hash\n     * @param {Object} hash The hash to modify.\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function hashDelete(key) {\n      var result = this.has(key) && delete this.__data__[key];\n      this.size -= result ? 1 : 0;\n      return result;\n    }\n\n    /**\n     * Gets the hash value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf Hash\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function hashGet(key) {\n      var data = this.__data__;\n      if (nativeCreate) {\n        var result = data[key];\n        return result === HASH_UNDEFINED ? undefined : result;\n      }\n      return hasOwnProperty.call(data, key) ? data[key] : undefined;\n    }\n\n    /**\n     * Checks if a hash value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf Hash\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function hashHas(key) {\n      var data = this.__data__;\n      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n    }\n\n    /**\n     * Sets the hash `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf Hash\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the hash instance.\n     */\n    function hashSet(key, value) {\n      var data = this.__data__;\n      this.size += this.has(key) ? 0 : 1;\n      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n      return this;\n    }\n\n    // Add methods to `Hash`.\n    Hash.prototype.clear = hashClear;\n    Hash.prototype['delete'] = hashDelete;\n    Hash.prototype.get = hashGet;\n    Hash.prototype.has = hashHas;\n    Hash.prototype.set = hashSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an list cache object.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function ListCache(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the list cache.\n     *\n     * @private\n     * @name clear\n     * @memberOf ListCache\n     */\n    function listCacheClear() {\n      this.__data__ = [];\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the list cache.\n     *\n     * @private\n     * @name delete\n     * @memberOf ListCache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function listCacheDelete(key) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      if (index < 0) {\n        return false;\n      }\n      var lastIndex = data.length - 1;\n      if (index == lastIndex) {\n        data.pop();\n      } else {\n        splice.call(data, index, 1);\n      }\n      --this.size;\n      return true;\n    }\n\n    /**\n     * Gets the list cache value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf ListCache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function listCacheGet(key) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      return index < 0 ? undefined : data[index][1];\n    }\n\n    /**\n     * Checks if a list cache value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf ListCache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function listCacheHas(key) {\n      return assocIndexOf(this.__data__, key) > -1;\n    }\n\n    /**\n     * Sets the list cache `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf ListCache\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the list cache instance.\n     */\n    function listCacheSet(key, value) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      if (index < 0) {\n        ++this.size;\n        data.push([key, value]);\n      } else {\n        data[index][1] = value;\n      }\n      return this;\n    }\n\n    // Add methods to `ListCache`.\n    ListCache.prototype.clear = listCacheClear;\n    ListCache.prototype['delete'] = listCacheDelete;\n    ListCache.prototype.get = listCacheGet;\n    ListCache.prototype.has = listCacheHas;\n    ListCache.prototype.set = listCacheSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a map cache object to store key-value pairs.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function MapCache(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the map.\n     *\n     * @private\n     * @name clear\n     * @memberOf MapCache\n     */\n    function mapCacheClear() {\n      this.size = 0;\n      this.__data__ = {\n        'hash': new Hash,\n        'map': new (Map || ListCache),\n        'string': new Hash\n      };\n    }\n\n    /**\n     * Removes `key` and its value from the map.\n     *\n     * @private\n     * @name delete\n     * @memberOf MapCache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function mapCacheDelete(key) {\n      var result = getMapData(this, key)['delete'](key);\n      this.size -= result ? 1 : 0;\n      return result;\n    }\n\n    /**\n     * Gets the map value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf MapCache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function mapCacheGet(key) {\n      return getMapData(this, key).get(key);\n    }\n\n    /**\n     * Checks if a map value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf MapCache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function mapCacheHas(key) {\n      return getMapData(this, key).has(key);\n    }\n\n    /**\n     * Sets the map `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf MapCache\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the map cache instance.\n     */\n    function mapCacheSet(key, value) {\n      var data = getMapData(this, key),\n          size = data.size;\n\n      data.set(key, value);\n      this.size += data.size == size ? 0 : 1;\n      return this;\n    }\n\n    // Add methods to `MapCache`.\n    MapCache.prototype.clear = mapCacheClear;\n    MapCache.prototype['delete'] = mapCacheDelete;\n    MapCache.prototype.get = mapCacheGet;\n    MapCache.prototype.has = mapCacheHas;\n    MapCache.prototype.set = mapCacheSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     *\n     * Creates an array cache object to store unique values.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [values] The values to cache.\n     */\n    function SetCache(values) {\n      var index = -1,\n          length = values == null ? 0 : values.length;\n\n      this.__data__ = new MapCache;\n      while (++index < length) {\n        this.add(values[index]);\n      }\n    }\n\n    /**\n     * Adds `value` to the array cache.\n     *\n     * @private\n     * @name add\n     * @memberOf SetCache\n     * @alias push\n     * @param {*} value The value to cache.\n     * @returns {Object} Returns the cache instance.\n     */\n    function setCacheAdd(value) {\n      this.__data__.set(value, HASH_UNDEFINED);\n      return this;\n    }\n\n    /**\n     * Checks if `value` is in the array cache.\n     *\n     * @private\n     * @name has\n     * @memberOf SetCache\n     * @param {*} value The value to search for.\n     * @returns {number} Returns `true` if `value` is found, else `false`.\n     */\n    function setCacheHas(value) {\n      return this.__data__.has(value);\n    }\n\n    // Add methods to `SetCache`.\n    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\n    SetCache.prototype.has = setCacheHas;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a stack cache object to store key-value pairs.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function Stack(entries) {\n      var data = this.__data__ = new ListCache(entries);\n      this.size = data.size;\n    }\n\n    /**\n     * Removes all key-value entries from the stack.\n     *\n     * @private\n     * @name clear\n     * @memberOf Stack\n     */\n    function stackClear() {\n      this.__data__ = new ListCache;\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the stack.\n     *\n     * @private\n     * @name delete\n     * @memberOf Stack\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function stackDelete(key) {\n      var data = this.__data__,\n          result = data['delete'](key);\n\n      this.size = data.size;\n      return result;\n    }\n\n    /**\n     * Gets the stack value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf Stack\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function stackGet(key) {\n      return this.__data__.get(key);\n    }\n\n    /**\n     * Checks if a stack value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf Stack\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function stackHas(key) {\n      return this.__data__.has(key);\n    }\n\n    /**\n     * Sets the stack `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf Stack\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the stack cache instance.\n     */\n    function stackSet(key, value) {\n      var data = this.__data__;\n      if (data instanceof ListCache) {\n        var pairs = data.__data__;\n        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n          pairs.push([key, value]);\n          this.size = ++data.size;\n          return this;\n        }\n        data = this.__data__ = new MapCache(pairs);\n      }\n      data.set(key, value);\n      this.size = data.size;\n      return this;\n    }\n\n    // Add methods to `Stack`.\n    Stack.prototype.clear = stackClear;\n    Stack.prototype['delete'] = stackDelete;\n    Stack.prototype.get = stackGet;\n    Stack.prototype.has = stackHas;\n    Stack.prototype.set = stackSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an array of the enumerable property names of the array-like `value`.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @param {boolean} inherited Specify returning inherited property names.\n     * @returns {Array} Returns the array of property names.\n     */\n    function arrayLikeKeys(value, inherited) {\n      var isArr = isArray(value),\n          isArg = !isArr && isArguments(value),\n          isBuff = !isArr && !isArg && isBuffer(value),\n          isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n          skipIndexes = isArr || isArg || isBuff || isType,\n          result = skipIndexes ? baseTimes(value.length, String) : [],\n          length = result.length;\n\n      for (var key in value) {\n        if ((inherited || hasOwnProperty.call(value, key)) &&\n            !(skipIndexes && (\n               // Safari 9 has enumerable `arguments.length` in strict mode.\n               key == 'length' ||\n               // Node.js 0.10 has enumerable non-index properties on buffers.\n               (isBuff && (key == 'offset' || key == 'parent')) ||\n               // PhantomJS 2 has enumerable non-index properties on typed arrays.\n               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n               // Skip index properties.\n               isIndex(key, length)\n            ))) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `_.sample` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to sample.\n     * @returns {*} Returns the random element.\n     */\n    function arraySample(array) {\n      var length = array.length;\n      return length ? array[baseRandom(0, length - 1)] : undefined;\n    }\n\n    /**\n     * A specialized version of `_.sampleSize` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to sample.\n     * @param {number} n The number of elements to sample.\n     * @returns {Array} Returns the random elements.\n     */\n    function arraySampleSize(array, n) {\n      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));\n    }\n\n    /**\n     * A specialized version of `_.shuffle` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     */\n    function arrayShuffle(array) {\n      return shuffleSelf(copyArray(array));\n    }\n\n    /**\n     * This function is like `assignValue` except that it doesn't assign\n     * `undefined` values.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function assignMergeValue(object, key, value) {\n      if ((value !== undefined && !eq(object[key], value)) ||\n          (value === undefined && !(key in object))) {\n        baseAssignValue(object, key, value);\n      }\n    }\n\n    /**\n     * Assigns `value` to `key` of `object` if the existing value is not equivalent\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function assignValue(object, key, value) {\n      var objValue = object[key];\n      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n          (value === undefined && !(key in object))) {\n        baseAssignValue(object, key, value);\n      }\n    }\n\n    /**\n     * Gets the index at which the `key` is found in `array` of key-value pairs.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {*} key The key to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     */\n    function assocIndexOf(array, key) {\n      var length = array.length;\n      while (length--) {\n        if (eq(array[length][0], key)) {\n          return length;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * Aggregates elements of `collection` on `accumulator` with keys transformed\n     * by `iteratee` and values set by `setter`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} setter The function to set `accumulator` values.\n     * @param {Function} iteratee The iteratee to transform keys.\n     * @param {Object} accumulator The initial aggregated object.\n     * @returns {Function} Returns `accumulator`.\n     */\n    function baseAggregator(collection, setter, iteratee, accumulator) {\n      baseEach(collection, function(value, key, collection) {\n        setter(accumulator, value, iteratee(value), collection);\n      });\n      return accumulator;\n    }\n\n    /**\n     * The base implementation of `_.assign` without support for multiple sources\n     * or `customizer` functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @returns {Object} Returns `object`.\n     */\n    function baseAssign(object, source) {\n      return object && copyObject(source, keys(source), object);\n    }\n\n    /**\n     * The base implementation of `_.assignIn` without support for multiple sources\n     * or `customizer` functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @returns {Object} Returns `object`.\n     */\n    function baseAssignIn(object, source) {\n      return object && copyObject(source, keysIn(source), object);\n    }\n\n    /**\n     * The base implementation of `assignValue` and `assignMergeValue` without\n     * value checks.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function baseAssignValue(object, key, value) {\n      if (key == '__proto__' && defineProperty) {\n        defineProperty(object, key, {\n          'configurable': true,\n          'enumerable': true,\n          'value': value,\n          'writable': true\n        });\n      } else {\n        object[key] = value;\n      }\n    }\n\n    /**\n     * The base implementation of `_.at` without support for individual paths.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {string[]} paths The property paths to pick.\n     * @returns {Array} Returns the picked elements.\n     */\n    function baseAt(object, paths) {\n      var index = -1,\n          length = paths.length,\n          result = Array(length),\n          skip = object == null;\n\n      while (++index < length) {\n        result[index] = skip ? undefined : get(object, paths[index]);\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.clamp` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {number} number The number to clamp.\n     * @param {number} [lower] The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the clamped number.\n     */\n    function baseClamp(number, lower, upper) {\n      if (number === number) {\n        if (upper !== undefined) {\n          number = number <= upper ? number : upper;\n        }\n        if (lower !== undefined) {\n          number = number >= lower ? number : lower;\n        }\n      }\n      return number;\n    }\n\n    /**\n     * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n     * traversed objects.\n     *\n     * @private\n     * @param {*} value The value to clone.\n     * @param {boolean} bitmask The bitmask flags.\n     *  1 - Deep clone\n     *  2 - Flatten inherited properties\n     *  4 - Clone symbols\n     * @param {Function} [customizer] The function to customize cloning.\n     * @param {string} [key] The key of `value`.\n     * @param {Object} [object] The parent object of `value`.\n     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n     * @returns {*} Returns the cloned value.\n     */\n    function baseClone(value, bitmask, customizer, key, object, stack) {\n      var result,\n          isDeep = bitmask & CLONE_DEEP_FLAG,\n          isFlat = bitmask & CLONE_FLAT_FLAG,\n          isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n      if (customizer) {\n        result = object ? customizer(value, key, object, stack) : customizer(value);\n      }\n      if (result !== undefined) {\n        return result;\n      }\n      if (!isObject(value)) {\n        return value;\n      }\n      var isArr = isArray(value);\n      if (isArr) {\n        result = initCloneArray(value);\n        if (!isDeep) {\n          return copyArray(value, result);\n        }\n      } else {\n        var tag = getTag(value),\n            isFunc = tag == funcTag || tag == genTag;\n\n        if (isBuffer(value)) {\n          return cloneBuffer(value, isDeep);\n        }\n        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n          result = (isFlat || isFunc) ? {} : initCloneObject(value);\n          if (!isDeep) {\n            return isFlat\n              ? copySymbolsIn(value, baseAssignIn(result, value))\n              : copySymbols(value, baseAssign(result, value));\n          }\n        } else {\n          if (!cloneableTags[tag]) {\n            return object ? value : {};\n          }\n          result = initCloneByTag(value, tag, baseClone, isDeep);\n        }\n      }\n      // Check for circular references and return its corresponding clone.\n      stack || (stack = new Stack);\n      var stacked = stack.get(value);\n      if (stacked) {\n        return stacked;\n      }\n      stack.set(value, result);\n\n      var keysFunc = isFull\n        ? (isFlat ? getAllKeysIn : getAllKeys)\n        : (isFlat ? keysIn : keys);\n\n      var props = isArr ? undefined : keysFunc(value);\n      arrayEach(props || value, function(subValue, key) {\n        if (props) {\n          key = subValue;\n          subValue = value[key];\n        }\n        // Recursively populate clone (susceptible to call stack limits).\n        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.conforms` which doesn't clone `source`.\n     *\n     * @private\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseConforms(source) {\n      var props = keys(source);\n      return function(object) {\n        return baseConformsTo(object, source, props);\n      };\n    }\n\n    /**\n     * The base implementation of `_.conformsTo` which accepts `props` to check.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n     */\n    function baseConformsTo(object, source, props) {\n      var length = props.length;\n      if (object == null) {\n        return !length;\n      }\n      object = Object(object);\n      while (length--) {\n        var key = props[length],\n            predicate = source[key],\n            value = object[key];\n\n        if ((value === undefined && !(key in object)) || !predicate(value)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * The base implementation of `_.delay` and `_.defer` which accepts `args`\n     * to provide to `func`.\n     *\n     * @private\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @param {Array} args The arguments to provide to `func`.\n     * @returns {number|Object} Returns the timer id or timeout object.\n     */\n    function baseDelay(func, wait, args) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return setTimeout(function() { func.apply(undefined, args); }, wait);\n    }\n\n    /**\n     * The base implementation of methods like `_.difference` without support\n     * for excluding multiple arrays or iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Array} values The values to exclude.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     */\n    function baseDifference(array, values, iteratee, comparator) {\n      var index = -1,\n          includes = arrayIncludes,\n          isCommon = true,\n          length = array.length,\n          result = [],\n          valuesLength = values.length;\n\n      if (!length) {\n        return result;\n      }\n      if (iteratee) {\n        values = arrayMap(values, baseUnary(iteratee));\n      }\n      if (comparator) {\n        includes = arrayIncludesWith;\n        isCommon = false;\n      }\n      else if (values.length >= LARGE_ARRAY_SIZE) {\n        includes = cacheHas;\n        isCommon = false;\n        values = new SetCache(values);\n      }\n      outer:\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee == null ? value : iteratee(value);\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (isCommon && computed === computed) {\n          var valuesIndex = valuesLength;\n          while (valuesIndex--) {\n            if (values[valuesIndex] === computed) {\n              continue outer;\n            }\n          }\n          result.push(value);\n        }\n        else if (!includes(values, computed, comparator)) {\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.forEach` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     */\n    var baseEach = createBaseEach(baseForOwn);\n\n    /**\n     * The base implementation of `_.forEachRight` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     */\n    var baseEachRight = createBaseEach(baseForOwnRight, true);\n\n    /**\n     * The base implementation of `_.every` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`\n     */\n    function baseEvery(collection, predicate) {\n      var result = true;\n      baseEach(collection, function(value, index, collection) {\n        result = !!predicate(value, index, collection);\n        return result;\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of methods like `_.max` and `_.min` which accepts a\n     * `comparator` to determine the extremum value.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The iteratee invoked per iteration.\n     * @param {Function} comparator The comparator used to compare values.\n     * @returns {*} Returns the extremum value.\n     */\n    function baseExtremum(array, iteratee, comparator) {\n      var index = -1,\n          length = array.length;\n\n      while (++index < length) {\n        var value = array[index],\n            current = iteratee(value);\n\n        if (current != null && (computed === undefined\n              ? (current === current && !isSymbol(current))\n              : comparator(current, computed)\n            )) {\n          var computed = current,\n              result = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.fill` without an iteratee call guard.\n     *\n     * @private\n     * @param {Array} array The array to fill.\n     * @param {*} value The value to fill `array` with.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns `array`.\n     */\n    function baseFill(array, value, start, end) {\n      var length = array.length;\n\n      start = toInteger(start);\n      if (start < 0) {\n        start = -start > length ? 0 : (length + start);\n      }\n      end = (end === undefined || end > length) ? length : toInteger(end);\n      if (end < 0) {\n        end += length;\n      }\n      end = start > end ? 0 : toLength(end);\n      while (start < end) {\n        array[start++] = value;\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.filter` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     */\n    function baseFilter(collection, predicate) {\n      var result = [];\n      baseEach(collection, function(value, index, collection) {\n        if (predicate(value, index, collection)) {\n          result.push(value);\n        }\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.flatten` with support for restricting flattening.\n     *\n     * @private\n     * @param {Array} array The array to flatten.\n     * @param {number} depth The maximum recursion depth.\n     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n     * @param {Array} [result=[]] The initial result value.\n     * @returns {Array} Returns the new flattened array.\n     */\n    function baseFlatten(array, depth, predicate, isStrict, result) {\n      var index = -1,\n          length = array.length;\n\n      predicate || (predicate = isFlattenable);\n      result || (result = []);\n\n      while (++index < length) {\n        var value = array[index];\n        if (depth > 0 && predicate(value)) {\n          if (depth > 1) {\n            // Recursively flatten arrays (susceptible to call stack limits).\n            baseFlatten(value, depth - 1, predicate, isStrict, result);\n          } else {\n            arrayPush(result, value);\n          }\n        } else if (!isStrict) {\n          result[result.length] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `baseForOwn` which iterates over `object`\n     * properties returned by `keysFunc` and invokes `iteratee` for each property.\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @returns {Object} Returns `object`.\n     */\n    var baseFor = createBaseFor();\n\n    /**\n     * This function is like `baseFor` except that it iterates over properties\n     * in the opposite order.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @returns {Object} Returns `object`.\n     */\n    var baseForRight = createBaseFor(true);\n\n    /**\n     * The base implementation of `_.forOwn` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForOwn(object, iteratee) {\n      return object && baseFor(object, iteratee, keys);\n    }\n\n    /**\n     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForOwnRight(object, iteratee) {\n      return object && baseForRight(object, iteratee, keys);\n    }\n\n    /**\n     * The base implementation of `_.functions` which creates an array of\n     * `object` function property names filtered from `props`.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Array} props The property names to filter.\n     * @returns {Array} Returns the function names.\n     */\n    function baseFunctions(object, props) {\n      return arrayFilter(props, function(key) {\n        return isFunction(object[key]);\n      });\n    }\n\n    /**\n     * The base implementation of `_.get` without support for default values.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to get.\n     * @returns {*} Returns the resolved value.\n     */\n    function baseGet(object, path) {\n      path = castPath(path, object);\n\n      var index = 0,\n          length = path.length;\n\n      while (object != null && index < length) {\n        object = object[toKey(path[index++])];\n      }\n      return (index && index == length) ? object : undefined;\n    }\n\n    /**\n     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n     * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n     * symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @param {Function} symbolsFunc The function to get the symbols of `object`.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function baseGetAllKeys(object, keysFunc, symbolsFunc) {\n      var result = keysFunc(object);\n      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n    }\n\n    /**\n     * The base implementation of `getTag` without fallbacks for buggy environments.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the `toStringTag`.\n     */\n    function baseGetTag(value) {\n      if (value == null) {\n        return value === undefined ? undefinedTag : nullTag;\n      }\n      return (symToStringTag && symToStringTag in Object(value))\n        ? getRawTag(value)\n        : objectToString(value);\n    }\n\n    /**\n     * The base implementation of `_.gt` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than `other`,\n     *  else `false`.\n     */\n    function baseGt(value, other) {\n      return value > other;\n    }\n\n    /**\n     * The base implementation of `_.has` without support for deep paths.\n     *\n     * @private\n     * @param {Object} [object] The object to query.\n     * @param {Array|string} key The key to check.\n     * @returns {boolean} Returns `true` if `key` exists, else `false`.\n     */\n    function baseHas(object, key) {\n      return object != null && hasOwnProperty.call(object, key);\n    }\n\n    /**\n     * The base implementation of `_.hasIn` without support for deep paths.\n     *\n     * @private\n     * @param {Object} [object] The object to query.\n     * @param {Array|string} key The key to check.\n     * @returns {boolean} Returns `true` if `key` exists, else `false`.\n     */\n    function baseHasIn(object, key) {\n      return object != null && key in Object(object);\n    }\n\n    /**\n     * The base implementation of `_.inRange` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {number} number The number to check.\n     * @param {number} start The start of the range.\n     * @param {number} end The end of the range.\n     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n     */\n    function baseInRange(number, start, end) {\n      return number >= nativeMin(start, end) && number < nativeMax(start, end);\n    }\n\n    /**\n     * The base implementation of methods like `_.intersection`, without support\n     * for iteratee shorthands, that accepts an array of arrays to inspect.\n     *\n     * @private\n     * @param {Array} arrays The arrays to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of shared values.\n     */\n    function baseIntersection(arrays, iteratee, comparator) {\n      var includes = comparator ? arrayIncludesWith : arrayIncludes,\n          length = arrays[0].length,\n          othLength = arrays.length,\n          othIndex = othLength,\n          caches = Array(othLength),\n          maxLength = Infinity,\n          result = [];\n\n      while (othIndex--) {\n        var array = arrays[othIndex];\n        if (othIndex && iteratee) {\n          array = arrayMap(array, baseUnary(iteratee));\n        }\n        maxLength = nativeMin(array.length, maxLength);\n        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n          ? new SetCache(othIndex && array)\n          : undefined;\n      }\n      array = arrays[0];\n\n      var index = -1,\n          seen = caches[0];\n\n      outer:\n      while (++index < length && result.length < maxLength) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (!(seen\n              ? cacheHas(seen, computed)\n              : includes(result, computed, comparator)\n            )) {\n          othIndex = othLength;\n          while (--othIndex) {\n            var cache = caches[othIndex];\n            if (!(cache\n                  ? cacheHas(cache, computed)\n                  : includes(arrays[othIndex], computed, comparator))\n                ) {\n              continue outer;\n            }\n          }\n          if (seen) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.invert` and `_.invertBy` which inverts\n     * `object` with values transformed by `iteratee` and set by `setter`.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} setter The function to set `accumulator` values.\n     * @param {Function} iteratee The iteratee to transform values.\n     * @param {Object} accumulator The initial inverted object.\n     * @returns {Function} Returns `accumulator`.\n     */\n    function baseInverter(object, setter, iteratee, accumulator) {\n      baseForOwn(object, function(value, key, object) {\n        setter(accumulator, iteratee(value), key, object);\n      });\n      return accumulator;\n    }\n\n    /**\n     * The base implementation of `_.invoke` without support for individual\n     * method arguments.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {Array} args The arguments to invoke the method with.\n     * @returns {*} Returns the result of the invoked method.\n     */\n    function baseInvoke(object, path, args) {\n      path = castPath(path, object);\n      object = parent(object, path);\n      var func = object == null ? object : object[toKey(last(path))];\n      return func == null ? undefined : apply(func, object, args);\n    }\n\n    /**\n     * The base implementation of `_.isArguments`.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n     */\n    function baseIsArguments(value) {\n      return isObjectLike(value) && baseGetTag(value) == argsTag;\n    }\n\n    /**\n     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n     */\n    function baseIsArrayBuffer(value) {\n      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;\n    }\n\n    /**\n     * The base implementation of `_.isDate` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n     */\n    function baseIsDate(value) {\n      return isObjectLike(value) && baseGetTag(value) == dateTag;\n    }\n\n    /**\n     * The base implementation of `_.isEqual` which supports partial comparisons\n     * and tracks traversed objects.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @param {boolean} bitmask The bitmask flags.\n     *  1 - Unordered comparison\n     *  2 - Partial comparison\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     */\n    function baseIsEqual(value, other, bitmask, customizer, stack) {\n      if (value === other) {\n        return true;\n      }\n      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n        return value !== value && other !== other;\n      }\n      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n    }\n\n    /**\n     * A specialized version of `baseIsEqual` for arrays and objects which performs\n     * deep comparisons and tracks traversed objects enabling objects with circular\n     * references to be compared.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n      var objIsArr = isArray(object),\n          othIsArr = isArray(other),\n          objTag = objIsArr ? arrayTag : getTag(object),\n          othTag = othIsArr ? arrayTag : getTag(other);\n\n      objTag = objTag == argsTag ? objectTag : objTag;\n      othTag = othTag == argsTag ? objectTag : othTag;\n\n      var objIsObj = objTag == objectTag,\n          othIsObj = othTag == objectTag,\n          isSameTag = objTag == othTag;\n\n      if (isSameTag && isBuffer(object)) {\n        if (!isBuffer(other)) {\n          return false;\n        }\n        objIsArr = true;\n        objIsObj = false;\n      }\n      if (isSameTag && !objIsObj) {\n        stack || (stack = new Stack);\n        return (objIsArr || isTypedArray(object))\n          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n      }\n      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n        if (objIsWrapped || othIsWrapped) {\n          var objUnwrapped = objIsWrapped ? object.value() : object,\n              othUnwrapped = othIsWrapped ? other.value() : other;\n\n          stack || (stack = new Stack);\n          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n        }\n      }\n      if (!isSameTag) {\n        return false;\n      }\n      stack || (stack = new Stack);\n      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n    }\n\n    /**\n     * The base implementation of `_.isMap` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n     */\n    function baseIsMap(value) {\n      return isObjectLike(value) && getTag(value) == mapTag;\n    }\n\n    /**\n     * The base implementation of `_.isMatch` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @param {Array} matchData The property names, values, and compare flags to match.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     */\n    function baseIsMatch(object, source, matchData, customizer) {\n      var index = matchData.length,\n          length = index,\n          noCustomizer = !customizer;\n\n      if (object == null) {\n        return !length;\n      }\n      object = Object(object);\n      while (index--) {\n        var data = matchData[index];\n        if ((noCustomizer && data[2])\n              ? data[1] !== object[data[0]]\n              : !(data[0] in object)\n            ) {\n          return false;\n        }\n      }\n      while (++index < length) {\n        data = matchData[index];\n        var key = data[0],\n            objValue = object[key],\n            srcValue = data[1];\n\n        if (noCustomizer && data[2]) {\n          if (objValue === undefined && !(key in object)) {\n            return false;\n          }\n        } else {\n          var stack = new Stack;\n          if (customizer) {\n            var result = customizer(objValue, srcValue, key, object, source, stack);\n          }\n          if (!(result === undefined\n                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n                : result\n              )) {\n            return false;\n          }\n        }\n      }\n      return true;\n    }\n\n    /**\n     * The base implementation of `_.isNative` without bad shim checks.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a native function,\n     *  else `false`.\n     */\n    function baseIsNative(value) {\n      if (!isObject(value) || isMasked(value)) {\n        return false;\n      }\n      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n      return pattern.test(toSource(value));\n    }\n\n    /**\n     * The base implementation of `_.isRegExp` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n     */\n    function baseIsRegExp(value) {\n      return isObjectLike(value) && baseGetTag(value) == regexpTag;\n    }\n\n    /**\n     * The base implementation of `_.isSet` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n     */\n    function baseIsSet(value) {\n      return isObjectLike(value) && getTag(value) == setTag;\n    }\n\n    /**\n     * The base implementation of `_.isTypedArray` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n     */\n    function baseIsTypedArray(value) {\n      return isObjectLike(value) &&\n        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n    }\n\n    /**\n     * The base implementation of `_.iteratee`.\n     *\n     * @private\n     * @param {*} [value=_.identity] The value to convert to an iteratee.\n     * @returns {Function} Returns the iteratee.\n     */\n    function baseIteratee(value) {\n      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n      if (typeof value == 'function') {\n        return value;\n      }\n      if (value == null) {\n        return identity;\n      }\n      if (typeof value == 'object') {\n        return isArray(value)\n          ? baseMatchesProperty(value[0], value[1])\n          : baseMatches(value);\n      }\n      return property(value);\n    }\n\n    /**\n     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function baseKeys(object) {\n      if (!isPrototype(object)) {\n        return nativeKeys(object);\n      }\n      var result = [];\n      for (var key in Object(object)) {\n        if (hasOwnProperty.call(object, key) && key != 'constructor') {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function baseKeysIn(object) {\n      if (!isObject(object)) {\n        return nativeKeysIn(object);\n      }\n      var isProto = isPrototype(object),\n          result = [];\n\n      for (var key in object) {\n        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.lt` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than `other`,\n     *  else `false`.\n     */\n    function baseLt(value, other) {\n      return value < other;\n    }\n\n    /**\n     * The base implementation of `_.map` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array} Returns the new mapped array.\n     */\n    function baseMap(collection, iteratee) {\n      var index = -1,\n          result = isArrayLike(collection) ? Array(collection.length) : [];\n\n      baseEach(collection, function(value, key, collection) {\n        result[++index] = iteratee(value, key, collection);\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.matches` which doesn't clone `source`.\n     *\n     * @private\n     * @param {Object} source The object of property values to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseMatches(source) {\n      var matchData = getMatchData(source);\n      if (matchData.length == 1 && matchData[0][2]) {\n        return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n      }\n      return function(object) {\n        return object === source || baseIsMatch(object, source, matchData);\n      };\n    }\n\n    /**\n     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n     *\n     * @private\n     * @param {string} path The path of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseMatchesProperty(path, srcValue) {\n      if (isKey(path) && isStrictComparable(srcValue)) {\n        return matchesStrictComparable(toKey(path), srcValue);\n      }\n      return function(object) {\n        var objValue = get(object, path);\n        return (objValue === undefined && objValue === srcValue)\n          ? hasIn(object, path)\n          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n      };\n    }\n\n    /**\n     * The base implementation of `_.merge` without support for multiple sources.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {number} srcIndex The index of `source`.\n     * @param {Function} [customizer] The function to customize merged values.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     */\n    function baseMerge(object, source, srcIndex, customizer, stack) {\n      if (object === source) {\n        return;\n      }\n      baseFor(source, function(srcValue, key) {\n        if (isObject(srcValue)) {\n          stack || (stack = new Stack);\n          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n        }\n        else {\n          var newValue = customizer\n            ? customizer(object[key], srcValue, (key + ''), object, source, stack)\n            : undefined;\n\n          if (newValue === undefined) {\n            newValue = srcValue;\n          }\n          assignMergeValue(object, key, newValue);\n        }\n      }, keysIn);\n    }\n\n    /**\n     * A specialized version of `baseMerge` for arrays and objects which performs\n     * deep merges and tracks traversed objects enabling objects with circular\n     * references to be merged.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {string} key The key of the value to merge.\n     * @param {number} srcIndex The index of `source`.\n     * @param {Function} mergeFunc The function to merge values.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     */\n    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n      var objValue = object[key],\n          srcValue = source[key],\n          stacked = stack.get(srcValue);\n\n      if (stacked) {\n        assignMergeValue(object, key, stacked);\n        return;\n      }\n      var newValue = customizer\n        ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n        : undefined;\n\n      var isCommon = newValue === undefined;\n\n      if (isCommon) {\n        var isArr = isArray(srcValue),\n            isBuff = !isArr && isBuffer(srcValue),\n            isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n        newValue = srcValue;\n        if (isArr || isBuff || isTyped) {\n          if (isArray(objValue)) {\n            newValue = objValue;\n          }\n          else if (isArrayLikeObject(objValue)) {\n            newValue = copyArray(objValue);\n          }\n          else if (isBuff) {\n            isCommon = false;\n            newValue = cloneBuffer(srcValue, true);\n          }\n          else if (isTyped) {\n            isCommon = false;\n            newValue = cloneTypedArray(srcValue, true);\n          }\n          else {\n            newValue = [];\n          }\n        }\n        else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n          newValue = objValue;\n          if (isArguments(objValue)) {\n            newValue = toPlainObject(objValue);\n          }\n          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {\n            newValue = initCloneObject(srcValue);\n          }\n        }\n        else {\n          isCommon = false;\n        }\n      }\n      if (isCommon) {\n        // Recursively merge objects and arrays (susceptible to call stack limits).\n        stack.set(srcValue, newValue);\n        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n        stack['delete'](srcValue);\n      }\n      assignMergeValue(object, key, newValue);\n    }\n\n    /**\n     * The base implementation of `_.nth` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {Array} array The array to query.\n     * @param {number} n The index of the element to return.\n     * @returns {*} Returns the nth element of `array`.\n     */\n    function baseNth(array, n) {\n      var length = array.length;\n      if (!length) {\n        return;\n      }\n      n += n < 0 ? length : 0;\n      return isIndex(n, length) ? array[n] : undefined;\n    }\n\n    /**\n     * The base implementation of `_.orderBy` without param guards.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n     * @param {string[]} orders The sort orders of `iteratees`.\n     * @returns {Array} Returns the new sorted array.\n     */\n    function baseOrderBy(collection, iteratees, orders) {\n      var index = -1;\n      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));\n\n      var result = baseMap(collection, function(value, key, collection) {\n        var criteria = arrayMap(iteratees, function(iteratee) {\n          return iteratee(value);\n        });\n        return { 'criteria': criteria, 'index': ++index, 'value': value };\n      });\n\n      return baseSortBy(result, function(object, other) {\n        return compareMultiple(object, other, orders);\n      });\n    }\n\n    /**\n     * The base implementation of `_.pick` without support for individual\n     * property identifiers.\n     *\n     * @private\n     * @param {Object} object The source object.\n     * @param {string[]} paths The property paths to pick.\n     * @returns {Object} Returns the new object.\n     */\n    function basePick(object, paths) {\n      return basePickBy(object, paths, function(value, path) {\n        return hasIn(object, path);\n      });\n    }\n\n    /**\n     * The base implementation of  `_.pickBy` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The source object.\n     * @param {string[]} paths The property paths to pick.\n     * @param {Function} predicate The function invoked per property.\n     * @returns {Object} Returns the new object.\n     */\n    function basePickBy(object, paths, predicate) {\n      var index = -1,\n          length = paths.length,\n          result = {};\n\n      while (++index < length) {\n        var path = paths[index],\n            value = baseGet(object, path);\n\n        if (predicate(value, path)) {\n          baseSet(result, castPath(path, object), value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseProperty` which supports deep paths.\n     *\n     * @private\n     * @param {Array|string} path The path of the property to get.\n     * @returns {Function} Returns the new accessor function.\n     */\n    function basePropertyDeep(path) {\n      return function(object) {\n        return baseGet(object, path);\n      };\n    }\n\n    /**\n     * The base implementation of `_.pullAllBy` without support for iteratee\n     * shorthands.\n     *\n     * @private\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns `array`.\n     */\n    function basePullAll(array, values, iteratee, comparator) {\n      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,\n          index = -1,\n          length = values.length,\n          seen = array;\n\n      if (array === values) {\n        values = copyArray(values);\n      }\n      if (iteratee) {\n        seen = arrayMap(array, baseUnary(iteratee));\n      }\n      while (++index < length) {\n        var fromIndex = 0,\n            value = values[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {\n          if (seen !== array) {\n            splice.call(seen, fromIndex, 1);\n          }\n          splice.call(array, fromIndex, 1);\n        }\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.pullAt` without support for individual\n     * indexes or capturing the removed elements.\n     *\n     * @private\n     * @param {Array} array The array to modify.\n     * @param {number[]} indexes The indexes of elements to remove.\n     * @returns {Array} Returns `array`.\n     */\n    function basePullAt(array, indexes) {\n      var length = array ? indexes.length : 0,\n          lastIndex = length - 1;\n\n      while (length--) {\n        var index = indexes[length];\n        if (length == lastIndex || index !== previous) {\n          var previous = index;\n          if (isIndex(index)) {\n            splice.call(array, index, 1);\n          } else {\n            baseUnset(array, index);\n          }\n        }\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.random` without support for returning\n     * floating-point numbers.\n     *\n     * @private\n     * @param {number} lower The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the random number.\n     */\n    function baseRandom(lower, upper) {\n      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));\n    }\n\n    /**\n     * The base implementation of `_.range` and `_.rangeRight` which doesn't\n     * coerce arguments.\n     *\n     * @private\n     * @param {number} start The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} step The value to increment or decrement by.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Array} Returns the range of numbers.\n     */\n    function baseRange(start, end, step, fromRight) {\n      var index = -1,\n          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n          result = Array(length);\n\n      while (length--) {\n        result[fromRight ? length : ++index] = start;\n        start += step;\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.repeat` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {string} string The string to repeat.\n     * @param {number} n The number of times to repeat the string.\n     * @returns {string} Returns the repeated string.\n     */\n    function baseRepeat(string, n) {\n      var result = '';\n      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {\n        return result;\n      }\n      // Leverage the exponentiation by squaring algorithm for a faster repeat.\n      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.\n      do {\n        if (n % 2) {\n          result += string;\n        }\n        n = nativeFloor(n / 2);\n        if (n) {\n          string += string;\n        }\n      } while (n);\n\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @returns {Function} Returns the new function.\n     */\n    function baseRest(func, start) {\n      return setToString(overRest(func, start, identity), func + '');\n    }\n\n    /**\n     * The base implementation of `_.sample`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to sample.\n     * @returns {*} Returns the random element.\n     */\n    function baseSample(collection) {\n      return arraySample(values(collection));\n    }\n\n    /**\n     * The base implementation of `_.sampleSize` without param guards.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to sample.\n     * @param {number} n The number of elements to sample.\n     * @returns {Array} Returns the random elements.\n     */\n    function baseSampleSize(collection, n) {\n      var array = values(collection);\n      return shuffleSelf(array, baseClamp(n, 0, array.length));\n    }\n\n    /**\n     * The base implementation of `_.set`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @param {Function} [customizer] The function to customize path creation.\n     * @returns {Object} Returns `object`.\n     */\n    function baseSet(object, path, value, customizer) {\n      if (!isObject(object)) {\n        return object;\n      }\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length,\n          lastIndex = length - 1,\n          nested = object;\n\n      while (nested != null && ++index < length) {\n        var key = toKey(path[index]),\n            newValue = value;\n\n        if (index != lastIndex) {\n          var objValue = nested[key];\n          newValue = customizer ? customizer(objValue, key, nested) : undefined;\n          if (newValue === undefined) {\n            newValue = isObject(objValue)\n              ? objValue\n              : (isIndex(path[index + 1]) ? [] : {});\n          }\n        }\n        assignValue(nested, key, newValue);\n        nested = nested[key];\n      }\n      return object;\n    }\n\n    /**\n     * The base implementation of `setData` without support for hot loop shorting.\n     *\n     * @private\n     * @param {Function} func The function to associate metadata with.\n     * @param {*} data The metadata.\n     * @returns {Function} Returns `func`.\n     */\n    var baseSetData = !metaMap ? identity : function(func, data) {\n      metaMap.set(func, data);\n      return func;\n    };\n\n    /**\n     * The base implementation of `setToString` without support for hot loop shorting.\n     *\n     * @private\n     * @param {Function} func The function to modify.\n     * @param {Function} string The `toString` result.\n     * @returns {Function} Returns `func`.\n     */\n    var baseSetToString = !defineProperty ? identity : function(func, string) {\n      return defineProperty(func, 'toString', {\n        'configurable': true,\n        'enumerable': false,\n        'value': constant(string),\n        'writable': true\n      });\n    };\n\n    /**\n     * The base implementation of `_.shuffle`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     */\n    function baseShuffle(collection) {\n      return shuffleSelf(values(collection));\n    }\n\n    /**\n     * The base implementation of `_.slice` without an iteratee call guard.\n     *\n     * @private\n     * @param {Array} array The array to slice.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function baseSlice(array, start, end) {\n      var index = -1,\n          length = array.length;\n\n      if (start < 0) {\n        start = -start > length ? 0 : (length + start);\n      }\n      end = end > length ? length : end;\n      if (end < 0) {\n        end += length;\n      }\n      length = start > end ? 0 : ((end - start) >>> 0);\n      start >>>= 0;\n\n      var result = Array(length);\n      while (++index < length) {\n        result[index] = array[index + start];\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.some` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     */\n    function baseSome(collection, predicate) {\n      var result;\n\n      baseEach(collection, function(value, index, collection) {\n        result = predicate(value, index, collection);\n        return !result;\n      });\n      return !!result;\n    }\n\n    /**\n     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which\n     * performs a binary search of `array` to determine the index at which `value`\n     * should be inserted into `array` in order to maintain its sort order.\n     *\n     * @private\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     */\n    function baseSortedIndex(array, value, retHighest) {\n      var low = 0,\n          high = array == null ? low : array.length;\n\n      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\n        while (low < high) {\n          var mid = (low + high) >>> 1,\n              computed = array[mid];\n\n          if (computed !== null && !isSymbol(computed) &&\n              (retHighest ? (computed <= value) : (computed < value))) {\n            low = mid + 1;\n          } else {\n            high = mid;\n          }\n        }\n        return high;\n      }\n      return baseSortedIndexBy(array, value, identity, retHighest);\n    }\n\n    /**\n     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`\n     * which invokes `iteratee` for `value` and each element of `array` to compute\n     * their sort ranking. The iteratee is invoked with one argument; (value).\n     *\n     * @private\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} iteratee The iteratee invoked per element.\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     */\n    function baseSortedIndexBy(array, value, iteratee, retHighest) {\n      value = iteratee(value);\n\n      var low = 0,\n          high = array == null ? 0 : array.length,\n          valIsNaN = value !== value,\n          valIsNull = value === null,\n          valIsSymbol = isSymbol(value),\n          valIsUndefined = value === undefined;\n\n      while (low < high) {\n        var mid = nativeFloor((low + high) / 2),\n            computed = iteratee(array[mid]),\n            othIsDefined = computed !== undefined,\n            othIsNull = computed === null,\n            othIsReflexive = computed === computed,\n            othIsSymbol = isSymbol(computed);\n\n        if (valIsNaN) {\n          var setLow = retHighest || othIsReflexive;\n        } else if (valIsUndefined) {\n          setLow = othIsReflexive && (retHighest || othIsDefined);\n        } else if (valIsNull) {\n          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);\n        } else if (valIsSymbol) {\n          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);\n        } else if (othIsNull || othIsSymbol) {\n          setLow = false;\n        } else {\n          setLow = retHighest ? (computed <= value) : (computed < value);\n        }\n        if (setLow) {\n          low = mid + 1;\n        } else {\n          high = mid;\n        }\n      }\n      return nativeMin(high, MAX_ARRAY_INDEX);\n    }\n\n    /**\n     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without\n     * support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     */\n    function baseSortedUniq(array, iteratee) {\n      var index = -1,\n          length = array.length,\n          resIndex = 0,\n          result = [];\n\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        if (!index || !eq(computed, seen)) {\n          var seen = computed;\n          result[resIndex++] = value === 0 ? 0 : value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.toNumber` which doesn't ensure correct\n     * conversions of binary, hexadecimal, or octal string values.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {number} Returns the number.\n     */\n    function baseToNumber(value) {\n      if (typeof value == 'number') {\n        return value;\n      }\n      if (isSymbol(value)) {\n        return NAN;\n      }\n      return +value;\n    }\n\n    /**\n     * The base implementation of `_.toString` which doesn't convert nullish\n     * values to empty strings.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {string} Returns the string.\n     */\n    function baseToString(value) {\n      // Exit early for strings to avoid a performance hit in some environments.\n      if (typeof value == 'string') {\n        return value;\n      }\n      if (isArray(value)) {\n        // Recursively convert values (susceptible to call stack limits).\n        return arrayMap(value, baseToString) + '';\n      }\n      if (isSymbol(value)) {\n        return symbolToString ? symbolToString.call(value) : '';\n      }\n      var result = (value + '');\n      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n    }\n\n    /**\n     * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     */\n    function baseUniq(array, iteratee, comparator) {\n      var index = -1,\n          includes = arrayIncludes,\n          length = array.length,\n          isCommon = true,\n          result = [],\n          seen = result;\n\n      if (comparator) {\n        isCommon = false;\n        includes = arrayIncludesWith;\n      }\n      else if (length >= LARGE_ARRAY_SIZE) {\n        var set = iteratee ? null : createSet(array);\n        if (set) {\n          return setToArray(set);\n        }\n        isCommon = false;\n        includes = cacheHas;\n        seen = new SetCache;\n      }\n      else {\n        seen = iteratee ? [] : result;\n      }\n      outer:\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (isCommon && computed === computed) {\n          var seenIndex = seen.length;\n          while (seenIndex--) {\n            if (seen[seenIndex] === computed) {\n              continue outer;\n            }\n          }\n          if (iteratee) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n        else if (!includes(seen, computed, comparator)) {\n          if (seen !== result) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.unset`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The property path to unset.\n     * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n     */\n    function baseUnset(object, path) {\n      path = castPath(path, object);\n      object = parent(object, path);\n      return object == null || delete object[toKey(last(path))];\n    }\n\n    /**\n     * The base implementation of `_.update`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to update.\n     * @param {Function} updater The function to produce the updated value.\n     * @param {Function} [customizer] The function to customize path creation.\n     * @returns {Object} Returns `object`.\n     */\n    function baseUpdate(object, path, updater, customizer) {\n      return baseSet(object, path, updater(baseGet(object, path)), customizer);\n    }\n\n    /**\n     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`\n     * without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to query.\n     * @param {Function} predicate The function invoked per iteration.\n     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function baseWhile(array, predicate, isDrop, fromRight) {\n      var length = array.length,\n          index = fromRight ? length : -1;\n\n      while ((fromRight ? index-- : ++index < length) &&\n        predicate(array[index], index, array)) {}\n\n      return isDrop\n        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))\n        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));\n    }\n\n    /**\n     * The base implementation of `wrapperValue` which returns the result of\n     * performing a sequence of actions on the unwrapped `value`, where each\n     * successive action is supplied the return value of the previous.\n     *\n     * @private\n     * @param {*} value The unwrapped value.\n     * @param {Array} actions Actions to perform to resolve the unwrapped value.\n     * @returns {*} Returns the resolved value.\n     */\n    function baseWrapperValue(value, actions) {\n      var result = value;\n      if (result instanceof LazyWrapper) {\n        result = result.value();\n      }\n      return arrayReduce(actions, function(result, action) {\n        return action.func.apply(action.thisArg, arrayPush([result], action.args));\n      }, result);\n    }\n\n    /**\n     * The base implementation of methods like `_.xor`, without support for\n     * iteratee shorthands, that accepts an array of arrays to inspect.\n     *\n     * @private\n     * @param {Array} arrays The arrays to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of values.\n     */\n    function baseXor(arrays, iteratee, comparator) {\n      var length = arrays.length;\n      if (length < 2) {\n        return length ? baseUniq(arrays[0]) : [];\n      }\n      var index = -1,\n          result = Array(length);\n\n      while (++index < length) {\n        var array = arrays[index],\n            othIndex = -1;\n\n        while (++othIndex < length) {\n          if (othIndex != index) {\n            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);\n          }\n        }\n      }\n      return baseUniq(baseFlatten(result, 1), iteratee, comparator);\n    }\n\n    /**\n     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.\n     *\n     * @private\n     * @param {Array} props The property identifiers.\n     * @param {Array} values The property values.\n     * @param {Function} assignFunc The function to assign values.\n     * @returns {Object} Returns the new object.\n     */\n    function baseZipObject(props, values, assignFunc) {\n      var index = -1,\n          length = props.length,\n          valsLength = values.length,\n          result = {};\n\n      while (++index < length) {\n        var value = index < valsLength ? values[index] : undefined;\n        assignFunc(result, props[index], value);\n      }\n      return result;\n    }\n\n    /**\n     * Casts `value` to an empty array if it's not an array like object.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {Array|Object} Returns the cast array-like object.\n     */\n    function castArrayLikeObject(value) {\n      return isArrayLikeObject(value) ? value : [];\n    }\n\n    /**\n     * Casts `value` to `identity` if it's not a function.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {Function} Returns cast function.\n     */\n    function castFunction(value) {\n      return typeof value == 'function' ? value : identity;\n    }\n\n    /**\n     * Casts `value` to a path array if it's not one.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @param {Object} [object] The object to query keys on.\n     * @returns {Array} Returns the cast property path array.\n     */\n    function castPath(value, object) {\n      if (isArray(value)) {\n        return value;\n      }\n      return isKey(value, object) ? [value] : stringToPath(toString(value));\n    }\n\n    /**\n     * A `baseRest` alias which can be replaced with `identity` by module\n     * replacement plugins.\n     *\n     * @private\n     * @type {Function}\n     * @param {Function} func The function to apply a rest parameter to.\n     * @returns {Function} Returns the new function.\n     */\n    var castRest = baseRest;\n\n    /**\n     * Casts `array` to a slice if it's needed.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {number} start The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the cast slice.\n     */\n    function castSlice(array, start, end) {\n      var length = array.length;\n      end = end === undefined ? length : end;\n      return (!start && end >= length) ? array : baseSlice(array, start, end);\n    }\n\n    /**\n     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).\n     *\n     * @private\n     * @param {number|Object} id The timer id or timeout object of the timer to clear.\n     */\n    var clearTimeout = ctxClearTimeout || function(id) {\n      return root.clearTimeout(id);\n    };\n\n    /**\n     * Creates a clone of  `buffer`.\n     *\n     * @private\n     * @param {Buffer} buffer The buffer to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Buffer} Returns the cloned buffer.\n     */\n    function cloneBuffer(buffer, isDeep) {\n      if (isDeep) {\n        return buffer.slice();\n      }\n      var length = buffer.length,\n          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n      buffer.copy(result);\n      return result;\n    }\n\n    /**\n     * Creates a clone of `arrayBuffer`.\n     *\n     * @private\n     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n     * @returns {ArrayBuffer} Returns the cloned array buffer.\n     */\n    function cloneArrayBuffer(arrayBuffer) {\n      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n      new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n      return result;\n    }\n\n    /**\n     * Creates a clone of `dataView`.\n     *\n     * @private\n     * @param {Object} dataView The data view to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned data view.\n     */\n    function cloneDataView(dataView, isDeep) {\n      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n    }\n\n    /**\n     * Creates a clone of `map`.\n     *\n     * @private\n     * @param {Object} map The map to clone.\n     * @param {Function} cloneFunc The function to clone values.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned map.\n     */\n    function cloneMap(map, isDeep, cloneFunc) {\n      var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);\n      return arrayReduce(array, addMapEntry, new map.constructor);\n    }\n\n    /**\n     * Creates a clone of `regexp`.\n     *\n     * @private\n     * @param {Object} regexp The regexp to clone.\n     * @returns {Object} Returns the cloned regexp.\n     */\n    function cloneRegExp(regexp) {\n      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n      result.lastIndex = regexp.lastIndex;\n      return result;\n    }\n\n    /**\n     * Creates a clone of `set`.\n     *\n     * @private\n     * @param {Object} set The set to clone.\n     * @param {Function} cloneFunc The function to clone values.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned set.\n     */\n    function cloneSet(set, isDeep, cloneFunc) {\n      var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);\n      return arrayReduce(array, addSetEntry, new set.constructor);\n    }\n\n    /**\n     * Creates a clone of the `symbol` object.\n     *\n     * @private\n     * @param {Object} symbol The symbol object to clone.\n     * @returns {Object} Returns the cloned symbol object.\n     */\n    function cloneSymbol(symbol) {\n      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n    }\n\n    /**\n     * Creates a clone of `typedArray`.\n     *\n     * @private\n     * @param {Object} typedArray The typed array to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned typed array.\n     */\n    function cloneTypedArray(typedArray, isDeep) {\n      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n    }\n\n    /**\n     * Compares values to sort them in ascending order.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {number} Returns the sort order indicator for `value`.\n     */\n    function compareAscending(value, other) {\n      if (value !== other) {\n        var valIsDefined = value !== undefined,\n            valIsNull = value === null,\n            valIsReflexive = value === value,\n            valIsSymbol = isSymbol(value);\n\n        var othIsDefined = other !== undefined,\n            othIsNull = other === null,\n            othIsReflexive = other === other,\n            othIsSymbol = isSymbol(other);\n\n        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n            (valIsNull && othIsDefined && othIsReflexive) ||\n            (!valIsDefined && othIsReflexive) ||\n            !valIsReflexive) {\n          return 1;\n        }\n        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n            (othIsNull && valIsDefined && valIsReflexive) ||\n            (!othIsDefined && valIsReflexive) ||\n            !othIsReflexive) {\n          return -1;\n        }\n      }\n      return 0;\n    }\n\n    /**\n     * Used by `_.orderBy` to compare multiple properties of a value to another\n     * and stable sort them.\n     *\n     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,\n     * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n     * of corresponding values.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {boolean[]|string[]} orders The order to sort by for each property.\n     * @returns {number} Returns the sort order indicator for `object`.\n     */\n    function compareMultiple(object, other, orders) {\n      var index = -1,\n          objCriteria = object.criteria,\n          othCriteria = other.criteria,\n          length = objCriteria.length,\n          ordersLength = orders.length;\n\n      while (++index < length) {\n        var result = compareAscending(objCriteria[index], othCriteria[index]);\n        if (result) {\n          if (index >= ordersLength) {\n            return result;\n          }\n          var order = orders[index];\n          return result * (order == 'desc' ? -1 : 1);\n        }\n      }\n      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n      // that causes it, under certain circumstances, to provide the same value for\n      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n      // for more details.\n      //\n      // This also ensures a stable sort in V8 and other engines.\n      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n      return object.index - other.index;\n    }\n\n    /**\n     * Creates an array that is the composition of partially applied arguments,\n     * placeholders, and provided arguments into a single array of arguments.\n     *\n     * @private\n     * @param {Array} args The provided arguments.\n     * @param {Array} partials The arguments to prepend to those provided.\n     * @param {Array} holders The `partials` placeholder indexes.\n     * @params {boolean} [isCurried] Specify composing for a curried function.\n     * @returns {Array} Returns the new array of composed arguments.\n     */\n    function composeArgs(args, partials, holders, isCurried) {\n      var argsIndex = -1,\n          argsLength = args.length,\n          holdersLength = holders.length,\n          leftIndex = -1,\n          leftLength = partials.length,\n          rangeLength = nativeMax(argsLength - holdersLength, 0),\n          result = Array(leftLength + rangeLength),\n          isUncurried = !isCurried;\n\n      while (++leftIndex < leftLength) {\n        result[leftIndex] = partials[leftIndex];\n      }\n      while (++argsIndex < holdersLength) {\n        if (isUncurried || argsIndex < argsLength) {\n          result[holders[argsIndex]] = args[argsIndex];\n        }\n      }\n      while (rangeLength--) {\n        result[leftIndex++] = args[argsIndex++];\n      }\n      return result;\n    }\n\n    /**\n     * This function is like `composeArgs` except that the arguments composition\n     * is tailored for `_.partialRight`.\n     *\n     * @private\n     * @param {Array} args The provided arguments.\n     * @param {Array} partials The arguments to append to those provided.\n     * @param {Array} holders The `partials` placeholder indexes.\n     * @params {boolean} [isCurried] Specify composing for a curried function.\n     * @returns {Array} Returns the new array of composed arguments.\n     */\n    function composeArgsRight(args, partials, holders, isCurried) {\n      var argsIndex = -1,\n          argsLength = args.length,\n          holdersIndex = -1,\n          holdersLength = holders.length,\n          rightIndex = -1,\n          rightLength = partials.length,\n          rangeLength = nativeMax(argsLength - holdersLength, 0),\n          result = Array(rangeLength + rightLength),\n          isUncurried = !isCurried;\n\n      while (++argsIndex < rangeLength) {\n        result[argsIndex] = args[argsIndex];\n      }\n      var offset = argsIndex;\n      while (++rightIndex < rightLength) {\n        result[offset + rightIndex] = partials[rightIndex];\n      }\n      while (++holdersIndex < holdersLength) {\n        if (isUncurried || argsIndex < argsLength) {\n          result[offset + holders[holdersIndex]] = args[argsIndex++];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Copies the values of `source` to `array`.\n     *\n     * @private\n     * @param {Array} source The array to copy values from.\n     * @param {Array} [array=[]] The array to copy values to.\n     * @returns {Array} Returns `array`.\n     */\n    function copyArray(source, array) {\n      var index = -1,\n          length = source.length;\n\n      array || (array = Array(length));\n      while (++index < length) {\n        array[index] = source[index];\n      }\n      return array;\n    }\n\n    /**\n     * Copies properties of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy properties from.\n     * @param {Array} props The property identifiers to copy.\n     * @param {Object} [object={}] The object to copy properties to.\n     * @param {Function} [customizer] The function to customize copied values.\n     * @returns {Object} Returns `object`.\n     */\n    function copyObject(source, props, object, customizer) {\n      var isNew = !object;\n      object || (object = {});\n\n      var index = -1,\n          length = props.length;\n\n      while (++index < length) {\n        var key = props[index];\n\n        var newValue = customizer\n          ? customizer(object[key], source[key], key, object, source)\n          : undefined;\n\n        if (newValue === undefined) {\n          newValue = source[key];\n        }\n        if (isNew) {\n          baseAssignValue(object, key, newValue);\n        } else {\n          assignValue(object, key, newValue);\n        }\n      }\n      return object;\n    }\n\n    /**\n     * Copies own symbols of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy symbols from.\n     * @param {Object} [object={}] The object to copy symbols to.\n     * @returns {Object} Returns `object`.\n     */\n    function copySymbols(source, object) {\n      return copyObject(source, getSymbols(source), object);\n    }\n\n    /**\n     * Copies own and inherited symbols of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy symbols from.\n     * @param {Object} [object={}] The object to copy symbols to.\n     * @returns {Object} Returns `object`.\n     */\n    function copySymbolsIn(source, object) {\n      return copyObject(source, getSymbolsIn(source), object);\n    }\n\n    /**\n     * Creates a function like `_.groupBy`.\n     *\n     * @private\n     * @param {Function} setter The function to set accumulator values.\n     * @param {Function} [initializer] The accumulator object initializer.\n     * @returns {Function} Returns the new aggregator function.\n     */\n    function createAggregator(setter, initializer) {\n      return function(collection, iteratee) {\n        var func = isArray(collection) ? arrayAggregator : baseAggregator,\n            accumulator = initializer ? initializer() : {};\n\n        return func(collection, setter, getIteratee(iteratee, 2), accumulator);\n      };\n    }\n\n    /**\n     * Creates a function like `_.assign`.\n     *\n     * @private\n     * @param {Function} assigner The function to assign values.\n     * @returns {Function} Returns the new assigner function.\n     */\n    function createAssigner(assigner) {\n      return baseRest(function(object, sources) {\n        var index = -1,\n            length = sources.length,\n            customizer = length > 1 ? sources[length - 1] : undefined,\n            guard = length > 2 ? sources[2] : undefined;\n\n        customizer = (assigner.length > 3 && typeof customizer == 'function')\n          ? (length--, customizer)\n          : undefined;\n\n        if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n          customizer = length < 3 ? undefined : customizer;\n          length = 1;\n        }\n        object = Object(object);\n        while (++index < length) {\n          var source = sources[index];\n          if (source) {\n            assigner(object, source, index, customizer);\n          }\n        }\n        return object;\n      });\n    }\n\n    /**\n     * Creates a `baseEach` or `baseEachRight` function.\n     *\n     * @private\n     * @param {Function} eachFunc The function to iterate over a collection.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new base function.\n     */\n    function createBaseEach(eachFunc, fromRight) {\n      return function(collection, iteratee) {\n        if (collection == null) {\n          return collection;\n        }\n        if (!isArrayLike(collection)) {\n          return eachFunc(collection, iteratee);\n        }\n        var length = collection.length,\n            index = fromRight ? length : -1,\n            iterable = Object(collection);\n\n        while ((fromRight ? index-- : ++index < length)) {\n          if (iteratee(iterable[index], index, iterable) === false) {\n            break;\n          }\n        }\n        return collection;\n      };\n    }\n\n    /**\n     * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new base function.\n     */\n    function createBaseFor(fromRight) {\n      return function(object, iteratee, keysFunc) {\n        var index = -1,\n            iterable = Object(object),\n            props = keysFunc(object),\n            length = props.length;\n\n        while (length--) {\n          var key = props[fromRight ? length : ++index];\n          if (iteratee(iterable[key], key, iterable) === false) {\n            break;\n          }\n        }\n        return object;\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with the optional `this`\n     * binding of `thisArg`.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createBind(func, bitmask, thisArg) {\n      var isBind = bitmask & WRAP_BIND_FLAG,\n          Ctor = createCtor(func);\n\n      function wrapper() {\n        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n        return fn.apply(isBind ? thisArg : this, arguments);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a function like `_.lowerFirst`.\n     *\n     * @private\n     * @param {string} methodName The name of the `String` case method to use.\n     * @returns {Function} Returns the new case function.\n     */\n    function createCaseFirst(methodName) {\n      return function(string) {\n        string = toString(string);\n\n        var strSymbols = hasUnicode(string)\n          ? stringToArray(string)\n          : undefined;\n\n        var chr = strSymbols\n          ? strSymbols[0]\n          : string.charAt(0);\n\n        var trailing = strSymbols\n          ? castSlice(strSymbols, 1).join('')\n          : string.slice(1);\n\n        return chr[methodName]() + trailing;\n      };\n    }\n\n    /**\n     * Creates a function like `_.camelCase`.\n     *\n     * @private\n     * @param {Function} callback The function to combine each word.\n     * @returns {Function} Returns the new compounder function.\n     */\n    function createCompounder(callback) {\n      return function(string) {\n        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n      };\n    }\n\n    /**\n     * Creates a function that produces an instance of `Ctor` regardless of\n     * whether it was invoked as part of a `new` expression or by `call` or `apply`.\n     *\n     * @private\n     * @param {Function} Ctor The constructor to wrap.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createCtor(Ctor) {\n      return function() {\n        // Use a `switch` statement to work with class constructors. See\n        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\n        // for more details.\n        var args = arguments;\n        switch (args.length) {\n          case 0: return new Ctor;\n          case 1: return new Ctor(args[0]);\n          case 2: return new Ctor(args[0], args[1]);\n          case 3: return new Ctor(args[0], args[1], args[2]);\n          case 4: return new Ctor(args[0], args[1], args[2], args[3]);\n          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\n          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\n          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\n        }\n        var thisBinding = baseCreate(Ctor.prototype),\n            result = Ctor.apply(thisBinding, args);\n\n        // Mimic the constructor's `return` behavior.\n        // See https://es5.github.io/#x13.2.2 for more details.\n        return isObject(result) ? result : thisBinding;\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to enable currying.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {number} arity The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createCurry(func, bitmask, arity) {\n      var Ctor = createCtor(func);\n\n      function wrapper() {\n        var length = arguments.length,\n            args = Array(length),\n            index = length,\n            placeholder = getHolder(wrapper);\n\n        while (index--) {\n          args[index] = arguments[index];\n        }\n        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)\n          ? []\n          : replaceHolders(args, placeholder);\n\n        length -= holders.length;\n        if (length < arity) {\n          return createRecurry(\n            func, bitmask, createHybrid, wrapper.placeholder, undefined,\n            args, holders, undefined, undefined, arity - length);\n        }\n        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n        return apply(fn, this, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a `_.find` or `_.findLast` function.\n     *\n     * @private\n     * @param {Function} findIndexFunc The function to find the collection index.\n     * @returns {Function} Returns the new find function.\n     */\n    function createFind(findIndexFunc) {\n      return function(collection, predicate, fromIndex) {\n        var iterable = Object(collection);\n        if (!isArrayLike(collection)) {\n          var iteratee = getIteratee(predicate, 3);\n          collection = keys(collection);\n          predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n        }\n        var index = findIndexFunc(collection, predicate, fromIndex);\n        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n      };\n    }\n\n    /**\n     * Creates a `_.flow` or `_.flowRight` function.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new flow function.\n     */\n    function createFlow(fromRight) {\n      return flatRest(function(funcs) {\n        var length = funcs.length,\n            index = length,\n            prereq = LodashWrapper.prototype.thru;\n\n        if (fromRight) {\n          funcs.reverse();\n        }\n        while (index--) {\n          var func = funcs[index];\n          if (typeof func != 'function') {\n            throw new TypeError(FUNC_ERROR_TEXT);\n          }\n          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {\n            var wrapper = new LodashWrapper([], true);\n          }\n        }\n        index = wrapper ? index : length;\n        while (++index < length) {\n          func = funcs[index];\n\n          var funcName = getFuncName(func),\n              data = funcName == 'wrapper' ? getData(func) : undefined;\n\n          if (data && isLaziable(data[0]) &&\n                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&\n                !data[4].length && data[9] == 1\n              ) {\n            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);\n          } else {\n            wrapper = (func.length == 1 && isLaziable(func))\n              ? wrapper[funcName]()\n              : wrapper.thru(func);\n          }\n        }\n        return function() {\n          var args = arguments,\n              value = args[0];\n\n          if (wrapper && args.length == 1 && isArray(value)) {\n            return wrapper.plant(value).value();\n          }\n          var index = 0,\n              result = length ? funcs[index].apply(this, args) : value;\n\n          while (++index < length) {\n            result = funcs[index].call(this, result);\n          }\n          return result;\n        };\n      });\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with optional `this`\n     * binding of `thisArg`, partial application, and currying.\n     *\n     * @private\n     * @param {Function|string} func The function or method name to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to prepend to those provided to\n     *  the new function.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [partialsRight] The arguments to append to those provided\n     *  to the new function.\n     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\n      var isAry = bitmask & WRAP_ARY_FLAG,\n          isBind = bitmask & WRAP_BIND_FLAG,\n          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,\n          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),\n          isFlip = bitmask & WRAP_FLIP_FLAG,\n          Ctor = isBindKey ? undefined : createCtor(func);\n\n      function wrapper() {\n        var length = arguments.length,\n            args = Array(length),\n            index = length;\n\n        while (index--) {\n          args[index] = arguments[index];\n        }\n        if (isCurried) {\n          var placeholder = getHolder(wrapper),\n              holdersCount = countHolders(args, placeholder);\n        }\n        if (partials) {\n          args = composeArgs(args, partials, holders, isCurried);\n        }\n        if (partialsRight) {\n          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);\n        }\n        length -= holdersCount;\n        if (isCurried && length < arity) {\n          var newHolders = replaceHolders(args, placeholder);\n          return createRecurry(\n            func, bitmask, createHybrid, wrapper.placeholder, thisArg,\n            args, newHolders, argPos, ary, arity - length\n          );\n        }\n        var thisBinding = isBind ? thisArg : this,\n            fn = isBindKey ? thisBinding[func] : func;\n\n        length = args.length;\n        if (argPos) {\n          args = reorder(args, argPos);\n        } else if (isFlip && length > 1) {\n          args.reverse();\n        }\n        if (isAry && ary < length) {\n          args.length = ary;\n        }\n        if (this && this !== root && this instanceof wrapper) {\n          fn = Ctor || createCtor(fn);\n        }\n        return fn.apply(thisBinding, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a function like `_.invertBy`.\n     *\n     * @private\n     * @param {Function} setter The function to set accumulator values.\n     * @param {Function} toIteratee The function to resolve iteratees.\n     * @returns {Function} Returns the new inverter function.\n     */\n    function createInverter(setter, toIteratee) {\n      return function(object, iteratee) {\n        return baseInverter(object, setter, toIteratee(iteratee), {});\n      };\n    }\n\n    /**\n     * Creates a function that performs a mathematical operation on two values.\n     *\n     * @private\n     * @param {Function} operator The function to perform the operation.\n     * @param {number} [defaultValue] The value used for `undefined` arguments.\n     * @returns {Function} Returns the new mathematical operation function.\n     */\n    function createMathOperation(operator, defaultValue) {\n      return function(value, other) {\n        var result;\n        if (value === undefined && other === undefined) {\n          return defaultValue;\n        }\n        if (value !== undefined) {\n          result = value;\n        }\n        if (other !== undefined) {\n          if (result === undefined) {\n            return other;\n          }\n          if (typeof value == 'string' || typeof other == 'string') {\n            value = baseToString(value);\n            other = baseToString(other);\n          } else {\n            value = baseToNumber(value);\n            other = baseToNumber(other);\n          }\n          result = operator(value, other);\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function like `_.over`.\n     *\n     * @private\n     * @param {Function} arrayFunc The function to iterate over iteratees.\n     * @returns {Function} Returns the new over function.\n     */\n    function createOver(arrayFunc) {\n      return flatRest(function(iteratees) {\n        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));\n        return baseRest(function(args) {\n          var thisArg = this;\n          return arrayFunc(iteratees, function(iteratee) {\n            return apply(iteratee, thisArg, args);\n          });\n        });\n      });\n    }\n\n    /**\n     * Creates the padding for `string` based on `length`. The `chars` string\n     * is truncated if the number of characters exceeds `length`.\n     *\n     * @private\n     * @param {number} length The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padding for `string`.\n     */\n    function createPadding(length, chars) {\n      chars = chars === undefined ? ' ' : baseToString(chars);\n\n      var charsLength = chars.length;\n      if (charsLength < 2) {\n        return charsLength ? baseRepeat(chars, length) : chars;\n      }\n      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));\n      return hasUnicode(chars)\n        ? castSlice(stringToArray(result), 0, length).join('')\n        : result.slice(0, length);\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with the `this` binding\n     * of `thisArg` and `partials` prepended to the arguments it receives.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {Array} partials The arguments to prepend to those provided to\n     *  the new function.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createPartial(func, bitmask, thisArg, partials) {\n      var isBind = bitmask & WRAP_BIND_FLAG,\n          Ctor = createCtor(func);\n\n      function wrapper() {\n        var argsIndex = -1,\n            argsLength = arguments.length,\n            leftIndex = -1,\n            leftLength = partials.length,\n            args = Array(leftLength + argsLength),\n            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n\n        while (++leftIndex < leftLength) {\n          args[leftIndex] = partials[leftIndex];\n        }\n        while (argsLength--) {\n          args[leftIndex++] = arguments[++argsIndex];\n        }\n        return apply(fn, isBind ? thisArg : this, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a `_.range` or `_.rangeRight` function.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new range function.\n     */\n    function createRange(fromRight) {\n      return function(start, end, step) {\n        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {\n          end = step = undefined;\n        }\n        // Ensure the sign of `-0` is preserved.\n        start = toFinite(start);\n        if (end === undefined) {\n          end = start;\n          start = 0;\n        } else {\n          end = toFinite(end);\n        }\n        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);\n        return baseRange(start, end, step, fromRight);\n      };\n    }\n\n    /**\n     * Creates a function that performs a relational operation on two values.\n     *\n     * @private\n     * @param {Function} operator The function to perform the operation.\n     * @returns {Function} Returns the new relational operation function.\n     */\n    function createRelationalOperation(operator) {\n      return function(value, other) {\n        if (!(typeof value == 'string' && typeof other == 'string')) {\n          value = toNumber(value);\n          other = toNumber(other);\n        }\n        return operator(value, other);\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to continue currying.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {Function} wrapFunc The function to create the `func` wrapper.\n     * @param {*} placeholder The placeholder value.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to prepend to those provided to\n     *  the new function.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {\n      var isCurry = bitmask & WRAP_CURRY_FLAG,\n          newHolders = isCurry ? holders : undefined,\n          newHoldersRight = isCurry ? undefined : holders,\n          newPartials = isCurry ? partials : undefined,\n          newPartialsRight = isCurry ? undefined : partials;\n\n      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);\n      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);\n\n      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {\n        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);\n      }\n      var newData = [\n        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,\n        newHoldersRight, argPos, ary, arity\n      ];\n\n      var result = wrapFunc.apply(undefined, newData);\n      if (isLaziable(func)) {\n        setData(result, newData);\n      }\n      result.placeholder = placeholder;\n      return setWrapToString(result, func, bitmask);\n    }\n\n    /**\n     * Creates a function like `_.round`.\n     *\n     * @private\n     * @param {string} methodName The name of the `Math` method to use when rounding.\n     * @returns {Function} Returns the new round function.\n     */\n    function createRound(methodName) {\n      var func = Math[methodName];\n      return function(number, precision) {\n        number = toNumber(number);\n        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);\n        if (precision) {\n          // Shift with exponential notation to avoid floating-point issues.\n          // See [MDN](https://mdn.io/round#Examples) for more details.\n          var pair = (toString(number) + 'e').split('e'),\n              value = func(pair[0] + 'e' + (+pair[1] + precision));\n\n          pair = (toString(value) + 'e').split('e');\n          return +(pair[0] + 'e' + (+pair[1] - precision));\n        }\n        return func(number);\n      };\n    }\n\n    /**\n     * Creates a set object of `values`.\n     *\n     * @private\n     * @param {Array} values The values to add to the set.\n     * @returns {Object} Returns the new set.\n     */\n    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n      return new Set(values);\n    };\n\n    /**\n     * Creates a `_.toPairs` or `_.toPairsIn` function.\n     *\n     * @private\n     * @param {Function} keysFunc The function to get the keys of a given object.\n     * @returns {Function} Returns the new pairs function.\n     */\n    function createToPairs(keysFunc) {\n      return function(object) {\n        var tag = getTag(object);\n        if (tag == mapTag) {\n          return mapToArray(object);\n        }\n        if (tag == setTag) {\n          return setToPairs(object);\n        }\n        return baseToPairs(object, keysFunc(object));\n      };\n    }\n\n    /**\n     * Creates a function that either curries or invokes `func` with optional\n     * `this` binding and partially applied arguments.\n     *\n     * @private\n     * @param {Function|string} func The function or method name to wrap.\n     * @param {number} bitmask The bitmask flags.\n     *    1 - `_.bind`\n     *    2 - `_.bindKey`\n     *    4 - `_.curry` or `_.curryRight` of a bound function\n     *    8 - `_.curry`\n     *   16 - `_.curryRight`\n     *   32 - `_.partial`\n     *   64 - `_.partialRight`\n     *  128 - `_.rearg`\n     *  256 - `_.ary`\n     *  512 - `_.flip`\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to be partially applied.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\n      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;\n      if (!isBindKey && typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var length = partials ? partials.length : 0;\n      if (!length) {\n        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);\n        partials = holders = undefined;\n      }\n      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);\n      arity = arity === undefined ? arity : toInteger(arity);\n      length -= holders ? holders.length : 0;\n\n      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {\n        var partialsRight = partials,\n            holdersRight = holders;\n\n        partials = holders = undefined;\n      }\n      var data = isBindKey ? undefined : getData(func);\n\n      var newData = [\n        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,\n        argPos, ary, arity\n      ];\n\n      if (data) {\n        mergeData(newData, data);\n      }\n      func = newData[0];\n      bitmask = newData[1];\n      thisArg = newData[2];\n      partials = newData[3];\n      holders = newData[4];\n      arity = newData[9] = newData[9] === undefined\n        ? (isBindKey ? 0 : func.length)\n        : nativeMax(newData[9] - length, 0);\n\n      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {\n        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);\n      }\n      if (!bitmask || bitmask == WRAP_BIND_FLAG) {\n        var result = createBind(func, bitmask, thisArg);\n      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {\n        result = createCurry(func, bitmask, arity);\n      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {\n        result = createPartial(func, bitmask, thisArg, partials);\n      } else {\n        result = createHybrid.apply(undefined, newData);\n      }\n      var setter = data ? baseSetData : setData;\n      return setWrapToString(setter(result, newData), func, bitmask);\n    }\n\n    /**\n     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties\n     * of source objects to the destination object for all destination properties\n     * that resolve to `undefined`.\n     *\n     * @private\n     * @param {*} objValue The destination value.\n     * @param {*} srcValue The source value.\n     * @param {string} key The key of the property to assign.\n     * @param {Object} object The parent object of `objValue`.\n     * @returns {*} Returns the value to assign.\n     */\n    function customDefaultsAssignIn(objValue, srcValue, key, object) {\n      if (objValue === undefined ||\n          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n        return srcValue;\n      }\n      return objValue;\n    }\n\n    /**\n     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n     * objects into destination objects that are passed thru.\n     *\n     * @private\n     * @param {*} objValue The destination value.\n     * @param {*} srcValue The source value.\n     * @param {string} key The key of the property to merge.\n     * @param {Object} object The parent object of `objValue`.\n     * @param {Object} source The parent object of `srcValue`.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     * @returns {*} Returns the value to assign.\n     */\n    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n      if (isObject(objValue) && isObject(srcValue)) {\n        // Recursively merge objects and arrays (susceptible to call stack limits).\n        stack.set(srcValue, objValue);\n        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n        stack['delete'](srcValue);\n      }\n      return objValue;\n    }\n\n    /**\n     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n     * objects.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @param {string} key The key of the property to inspect.\n     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n     */\n    function customOmitClone(value) {\n      return isPlainObject(value) ? undefined : value;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for arrays with support for\n     * partial deep comparisons.\n     *\n     * @private\n     * @param {Array} array The array to compare.\n     * @param {Array} other The other array to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `array` and `other` objects.\n     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n     */\n    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n          arrLength = array.length,\n          othLength = other.length;\n\n      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n        return false;\n      }\n      // Assume cyclic values are equal.\n      var stacked = stack.get(array);\n      if (stacked && stack.get(other)) {\n        return stacked == other;\n      }\n      var index = -1,\n          result = true,\n          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n      stack.set(array, other);\n      stack.set(other, array);\n\n      // Ignore non-index properties.\n      while (++index < arrLength) {\n        var arrValue = array[index],\n            othValue = other[index];\n\n        if (customizer) {\n          var compared = isPartial\n            ? customizer(othValue, arrValue, index, other, array, stack)\n            : customizer(arrValue, othValue, index, array, other, stack);\n        }\n        if (compared !== undefined) {\n          if (compared) {\n            continue;\n          }\n          result = false;\n          break;\n        }\n        // Recursively compare arrays (susceptible to call stack limits).\n        if (seen) {\n          if (!arraySome(other, function(othValue, othIndex) {\n                if (!cacheHas(seen, othIndex) &&\n                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n                  return seen.push(othIndex);\n                }\n              })) {\n            result = false;\n            break;\n          }\n        } else if (!(\n              arrValue === othValue ||\n                equalFunc(arrValue, othValue, bitmask, customizer, stack)\n            )) {\n          result = false;\n          break;\n        }\n      }\n      stack['delete'](array);\n      stack['delete'](other);\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for comparing objects of\n     * the same `toStringTag`.\n     *\n     * **Note:** This function only supports comparing values with tags of\n     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {string} tag The `toStringTag` of the objects to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n      switch (tag) {\n        case dataViewTag:\n          if ((object.byteLength != other.byteLength) ||\n              (object.byteOffset != other.byteOffset)) {\n            return false;\n          }\n          object = object.buffer;\n          other = other.buffer;\n\n        case arrayBufferTag:\n          if ((object.byteLength != other.byteLength) ||\n              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n            return false;\n          }\n          return true;\n\n        case boolTag:\n        case dateTag:\n        case numberTag:\n          // Coerce booleans to `1` or `0` and dates to milliseconds.\n          // Invalid dates are coerced to `NaN`.\n          return eq(+object, +other);\n\n        case errorTag:\n          return object.name == other.name && object.message == other.message;\n\n        case regexpTag:\n        case stringTag:\n          // Coerce regexes to strings and treat strings, primitives and objects,\n          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n          // for more details.\n          return object == (other + '');\n\n        case mapTag:\n          var convert = mapToArray;\n\n        case setTag:\n          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n          convert || (convert = setToArray);\n\n          if (object.size != other.size && !isPartial) {\n            return false;\n          }\n          // Assume cyclic values are equal.\n          var stacked = stack.get(object);\n          if (stacked) {\n            return stacked == other;\n          }\n          bitmask |= COMPARE_UNORDERED_FLAG;\n\n          // Recursively compare objects (susceptible to call stack limits).\n          stack.set(object, other);\n          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n          stack['delete'](object);\n          return result;\n\n        case symbolTag:\n          if (symbolValueOf) {\n            return symbolValueOf.call(object) == symbolValueOf.call(other);\n          }\n      }\n      return false;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for objects with support for\n     * partial deep comparisons.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n          objProps = getAllKeys(object),\n          objLength = objProps.length,\n          othProps = getAllKeys(other),\n          othLength = othProps.length;\n\n      if (objLength != othLength && !isPartial) {\n        return false;\n      }\n      var index = objLength;\n      while (index--) {\n        var key = objProps[index];\n        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n          return false;\n        }\n      }\n      // Assume cyclic values are equal.\n      var stacked = stack.get(object);\n      if (stacked && stack.get(other)) {\n        return stacked == other;\n      }\n      var result = true;\n      stack.set(object, other);\n      stack.set(other, object);\n\n      var skipCtor = isPartial;\n      while (++index < objLength) {\n        key = objProps[index];\n        var objValue = object[key],\n            othValue = other[key];\n\n        if (customizer) {\n          var compared = isPartial\n            ? customizer(othValue, objValue, key, other, object, stack)\n            : customizer(objValue, othValue, key, object, other, stack);\n        }\n        // Recursively compare objects (susceptible to call stack limits).\n        if (!(compared === undefined\n              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n              : compared\n            )) {\n          result = false;\n          break;\n        }\n        skipCtor || (skipCtor = key == 'constructor');\n      }\n      if (result && !skipCtor) {\n        var objCtor = object.constructor,\n            othCtor = other.constructor;\n\n        // Non `Object` object instances with different constructors are not equal.\n        if (objCtor != othCtor &&\n            ('constructor' in object && 'constructor' in other) &&\n            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n              typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n          result = false;\n        }\n      }\n      stack['delete'](object);\n      stack['delete'](other);\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseRest` which flattens the rest array.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @returns {Function} Returns the new function.\n     */\n    function flatRest(func) {\n      return setToString(overRest(func, undefined, flatten), func + '');\n    }\n\n    /**\n     * Creates an array of own enumerable property names and symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function getAllKeys(object) {\n      return baseGetAllKeys(object, keys, getSymbols);\n    }\n\n    /**\n     * Creates an array of own and inherited enumerable property names and\n     * symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function getAllKeysIn(object) {\n      return baseGetAllKeys(object, keysIn, getSymbolsIn);\n    }\n\n    /**\n     * Gets metadata for `func`.\n     *\n     * @private\n     * @param {Function} func The function to query.\n     * @returns {*} Returns the metadata for `func`.\n     */\n    var getData = !metaMap ? noop : function(func) {\n      return metaMap.get(func);\n    };\n\n    /**\n     * Gets the name of `func`.\n     *\n     * @private\n     * @param {Function} func The function to query.\n     * @returns {string} Returns the function name.\n     */\n    function getFuncName(func) {\n      var result = (func.name + ''),\n          array = realNames[result],\n          length = hasOwnProperty.call(realNames, result) ? array.length : 0;\n\n      while (length--) {\n        var data = array[length],\n            otherFunc = data.func;\n        if (otherFunc == null || otherFunc == func) {\n          return data.name;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Gets the argument placeholder value for `func`.\n     *\n     * @private\n     * @param {Function} func The function to inspect.\n     * @returns {*} Returns the placeholder value.\n     */\n    function getHolder(func) {\n      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;\n      return object.placeholder;\n    }\n\n    /**\n     * Gets the appropriate \"iteratee\" function. If `_.iteratee` is customized,\n     * this function returns the custom method, otherwise it returns `baseIteratee`.\n     * If arguments are provided, the chosen function is invoked with them and\n     * its result is returned.\n     *\n     * @private\n     * @param {*} [value] The value to convert to an iteratee.\n     * @param {number} [arity] The arity of the created iteratee.\n     * @returns {Function} Returns the chosen function or its result.\n     */\n    function getIteratee() {\n      var result = lodash.iteratee || iteratee;\n      result = result === iteratee ? baseIteratee : result;\n      return arguments.length ? result(arguments[0], arguments[1]) : result;\n    }\n\n    /**\n     * Gets the data for `map`.\n     *\n     * @private\n     * @param {Object} map The map to query.\n     * @param {string} key The reference key.\n     * @returns {*} Returns the map data.\n     */\n    function getMapData(map, key) {\n      var data = map.__data__;\n      return isKeyable(key)\n        ? data[typeof key == 'string' ? 'string' : 'hash']\n        : data.map;\n    }\n\n    /**\n     * Gets the property names, values, and compare flags of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the match data of `object`.\n     */\n    function getMatchData(object) {\n      var result = keys(object),\n          length = result.length;\n\n      while (length--) {\n        var key = result[length],\n            value = object[key];\n\n        result[length] = [key, value, isStrictComparable(value)];\n      }\n      return result;\n    }\n\n    /**\n     * Gets the native function at `key` of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {string} key The key of the method to get.\n     * @returns {*} Returns the function if it's native, else `undefined`.\n     */\n    function getNative(object, key) {\n      var value = getValue(object, key);\n      return baseIsNative(value) ? value : undefined;\n    }\n\n    /**\n     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the raw `toStringTag`.\n     */\n    function getRawTag(value) {\n      var isOwn = hasOwnProperty.call(value, symToStringTag),\n          tag = value[symToStringTag];\n\n      try {\n        value[symToStringTag] = undefined;\n        var unmasked = true;\n      } catch (e) {}\n\n      var result = nativeObjectToString.call(value);\n      if (unmasked) {\n        if (isOwn) {\n          value[symToStringTag] = tag;\n        } else {\n          delete value[symToStringTag];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array of the own enumerable symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of symbols.\n     */\n    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n      if (object == null) {\n        return [];\n      }\n      object = Object(object);\n      return arrayFilter(nativeGetSymbols(object), function(symbol) {\n        return propertyIsEnumerable.call(object, symbol);\n      });\n    };\n\n    /**\n     * Creates an array of the own and inherited enumerable symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of symbols.\n     */\n    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n      var result = [];\n      while (object) {\n        arrayPush(result, getSymbols(object));\n        object = getPrototype(object);\n      }\n      return result;\n    };\n\n    /**\n     * Gets the `toStringTag` of `value`.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the `toStringTag`.\n     */\n    var getTag = baseGetTag;\n\n    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\n    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n        (Map && getTag(new Map) != mapTag) ||\n        (Promise && getTag(Promise.resolve()) != promiseTag) ||\n        (Set && getTag(new Set) != setTag) ||\n        (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n      getTag = function(value) {\n        var result = baseGetTag(value),\n            Ctor = result == objectTag ? value.constructor : undefined,\n            ctorString = Ctor ? toSource(Ctor) : '';\n\n        if (ctorString) {\n          switch (ctorString) {\n            case dataViewCtorString: return dataViewTag;\n            case mapCtorString: return mapTag;\n            case promiseCtorString: return promiseTag;\n            case setCtorString: return setTag;\n            case weakMapCtorString: return weakMapTag;\n          }\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Gets the view, applying any `transforms` to the `start` and `end` positions.\n     *\n     * @private\n     * @param {number} start The start of the view.\n     * @param {number} end The end of the view.\n     * @param {Array} transforms The transformations to apply to the view.\n     * @returns {Object} Returns an object containing the `start` and `end`\n     *  positions of the view.\n     */\n    function getView(start, end, transforms) {\n      var index = -1,\n          length = transforms.length;\n\n      while (++index < length) {\n        var data = transforms[index],\n            size = data.size;\n\n        switch (data.type) {\n          case 'drop':      start += size; break;\n          case 'dropRight': end -= size; break;\n          case 'take':      end = nativeMin(end, start + size); break;\n          case 'takeRight': start = nativeMax(start, end - size); break;\n        }\n      }\n      return { 'start': start, 'end': end };\n    }\n\n    /**\n     * Extracts wrapper details from the `source` body comment.\n     *\n     * @private\n     * @param {string} source The source to inspect.\n     * @returns {Array} Returns the wrapper details.\n     */\n    function getWrapDetails(source) {\n      var match = source.match(reWrapDetails);\n      return match ? match[1].split(reSplitDetails) : [];\n    }\n\n    /**\n     * Checks if `path` exists on `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @param {Function} hasFunc The function to check properties.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     */\n    function hasPath(object, path, hasFunc) {\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length,\n          result = false;\n\n      while (++index < length) {\n        var key = toKey(path[index]);\n        if (!(result = object != null && hasFunc(object, key))) {\n          break;\n        }\n        object = object[key];\n      }\n      if (result || ++index != length) {\n        return result;\n      }\n      length = object == null ? 0 : object.length;\n      return !!length && isLength(length) && isIndex(key, length) &&\n        (isArray(object) || isArguments(object));\n    }\n\n    /**\n     * Initializes an array clone.\n     *\n     * @private\n     * @param {Array} array The array to clone.\n     * @returns {Array} Returns the initialized clone.\n     */\n    function initCloneArray(array) {\n      var length = array.length,\n          result = array.constructor(length);\n\n      // Add properties assigned by `RegExp#exec`.\n      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n        result.index = array.index;\n        result.input = array.input;\n      }\n      return result;\n    }\n\n    /**\n     * Initializes an object clone.\n     *\n     * @private\n     * @param {Object} object The object to clone.\n     * @returns {Object} Returns the initialized clone.\n     */\n    function initCloneObject(object) {\n      return (typeof object.constructor == 'function' && !isPrototype(object))\n        ? baseCreate(getPrototype(object))\n        : {};\n    }\n\n    /**\n     * Initializes an object clone based on its `toStringTag`.\n     *\n     * **Note:** This function only supports cloning values with tags of\n     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n     *\n     * @private\n     * @param {Object} object The object to clone.\n     * @param {string} tag The `toStringTag` of the object to clone.\n     * @param {Function} cloneFunc The function to clone values.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the initialized clone.\n     */\n    function initCloneByTag(object, tag, cloneFunc, isDeep) {\n      var Ctor = object.constructor;\n      switch (tag) {\n        case arrayBufferTag:\n          return cloneArrayBuffer(object);\n\n        case boolTag:\n        case dateTag:\n          return new Ctor(+object);\n\n        case dataViewTag:\n          return cloneDataView(object, isDeep);\n\n        case float32Tag: case float64Tag:\n        case int8Tag: case int16Tag: case int32Tag:\n        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n          return cloneTypedArray(object, isDeep);\n\n        case mapTag:\n          return cloneMap(object, isDeep, cloneFunc);\n\n        case numberTag:\n        case stringTag:\n          return new Ctor(object);\n\n        case regexpTag:\n          return cloneRegExp(object);\n\n        case setTag:\n          return cloneSet(object, isDeep, cloneFunc);\n\n        case symbolTag:\n          return cloneSymbol(object);\n      }\n    }\n\n    /**\n     * Inserts wrapper `details` in a comment at the top of the `source` body.\n     *\n     * @private\n     * @param {string} source The source to modify.\n     * @returns {Array} details The details to insert.\n     * @returns {string} Returns the modified source.\n     */\n    function insertWrapDetails(source, details) {\n      var length = details.length;\n      if (!length) {\n        return source;\n      }\n      var lastIndex = length - 1;\n      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];\n      details = details.join(length > 2 ? ', ' : ' ');\n      return source.replace(reWrapComment, '{\\n/* [wrapped with ' + details + '] */\\n');\n    }\n\n    /**\n     * Checks if `value` is a flattenable `arguments` object or array.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n     */\n    function isFlattenable(value) {\n      return isArray(value) || isArguments(value) ||\n        !!(spreadableSymbol && value && value[spreadableSymbol]);\n    }\n\n    /**\n     * Checks if `value` is a valid array-like index.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n     */\n    function isIndex(value, length) {\n      length = length == null ? MAX_SAFE_INTEGER : length;\n      return !!length &&\n        (typeof value == 'number' || reIsUint.test(value)) &&\n        (value > -1 && value % 1 == 0 && value < length);\n    }\n\n    /**\n     * Checks if the given arguments are from an iteratee call.\n     *\n     * @private\n     * @param {*} value The potential iteratee value argument.\n     * @param {*} index The potential iteratee index or key argument.\n     * @param {*} object The potential iteratee object argument.\n     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n     *  else `false`.\n     */\n    function isIterateeCall(value, index, object) {\n      if (!isObject(object)) {\n        return false;\n      }\n      var type = typeof index;\n      if (type == 'number'\n            ? (isArrayLike(object) && isIndex(index, object.length))\n            : (type == 'string' && index in object)\n          ) {\n        return eq(object[index], value);\n      }\n      return false;\n    }\n\n    /**\n     * Checks if `value` is a property name and not a property path.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @param {Object} [object] The object to query keys on.\n     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n     */\n    function isKey(value, object) {\n      if (isArray(value)) {\n        return false;\n      }\n      var type = typeof value;\n      if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n          value == null || isSymbol(value)) {\n        return true;\n      }\n      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n        (object != null && value in Object(object));\n    }\n\n    /**\n     * Checks if `value` is suitable for use as unique object key.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n     */\n    function isKeyable(value) {\n      var type = typeof value;\n      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n        ? (value !== '__proto__')\n        : (value === null);\n    }\n\n    /**\n     * Checks if `func` has a lazy counterpart.\n     *\n     * @private\n     * @param {Function} func The function to check.\n     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,\n     *  else `false`.\n     */\n    function isLaziable(func) {\n      var funcName = getFuncName(func),\n          other = lodash[funcName];\n\n      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {\n        return false;\n      }\n      if (func === other) {\n        return true;\n      }\n      var data = getData(other);\n      return !!data && func === data[0];\n    }\n\n    /**\n     * Checks if `func` has its source masked.\n     *\n     * @private\n     * @param {Function} func The function to check.\n     * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n     */\n    function isMasked(func) {\n      return !!maskSrcKey && (maskSrcKey in func);\n    }\n\n    /**\n     * Checks if `func` is capable of being masked.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.\n     */\n    var isMaskable = coreJsData ? isFunction : stubFalse;\n\n    /**\n     * Checks if `value` is likely a prototype object.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n     */\n    function isPrototype(value) {\n      var Ctor = value && value.constructor,\n          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n      return value === proto;\n    }\n\n    /**\n     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` if suitable for strict\n     *  equality comparisons, else `false`.\n     */\n    function isStrictComparable(value) {\n      return value === value && !isObject(value);\n    }\n\n    /**\n     * A specialized version of `matchesProperty` for source values suitable\n     * for strict equality comparisons, i.e. `===`.\n     *\n     * @private\n     * @param {string} key The key of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function matchesStrictComparable(key, srcValue) {\n      return function(object) {\n        if (object == null) {\n          return false;\n        }\n        return object[key] === srcValue &&\n          (srcValue !== undefined || (key in Object(object)));\n      };\n    }\n\n    /**\n     * A specialized version of `_.memoize` which clears the memoized function's\n     * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n     *\n     * @private\n     * @param {Function} func The function to have its output memoized.\n     * @returns {Function} Returns the new memoized function.\n     */\n    function memoizeCapped(func) {\n      var result = memoize(func, function(key) {\n        if (cache.size === MAX_MEMOIZE_SIZE) {\n          cache.clear();\n        }\n        return key;\n      });\n\n      var cache = result.cache;\n      return result;\n    }\n\n    /**\n     * Merges the function metadata of `source` into `data`.\n     *\n     * Merging metadata reduces the number of wrappers used to invoke a function.\n     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\n     * may be applied regardless of execution order. Methods like `_.ary` and\n     * `_.rearg` modify function arguments, making the order in which they are\n     * executed important, preventing the merging of metadata. However, we make\n     * an exception for a safe combined case where curried functions have `_.ary`\n     * and or `_.rearg` applied.\n     *\n     * @private\n     * @param {Array} data The destination metadata.\n     * @param {Array} source The source metadata.\n     * @returns {Array} Returns `data`.\n     */\n    function mergeData(data, source) {\n      var bitmask = data[1],\n          srcBitmask = source[1],\n          newBitmask = bitmask | srcBitmask,\n          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);\n\n      var isCombo =\n        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||\n        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||\n        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));\n\n      // Exit early if metadata can't be merged.\n      if (!(isCommon || isCombo)) {\n        return data;\n      }\n      // Use source `thisArg` if available.\n      if (srcBitmask & WRAP_BIND_FLAG) {\n        data[2] = source[2];\n        // Set when currying a bound function.\n        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;\n      }\n      // Compose partial arguments.\n      var value = source[3];\n      if (value) {\n        var partials = data[3];\n        data[3] = partials ? composeArgs(partials, value, source[4]) : value;\n        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];\n      }\n      // Compose partial right arguments.\n      value = source[5];\n      if (value) {\n        partials = data[5];\n        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;\n        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];\n      }\n      // Use source `argPos` if available.\n      value = source[7];\n      if (value) {\n        data[7] = value;\n      }\n      // Use source `ary` if it's smaller.\n      if (srcBitmask & WRAP_ARY_FLAG) {\n        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\n      }\n      // Use source `arity` if one is not provided.\n      if (data[9] == null) {\n        data[9] = source[9];\n      }\n      // Use source `func` and merge bitmasks.\n      data[0] = source[0];\n      data[1] = newBitmask;\n\n      return data;\n    }\n\n    /**\n     * This function is like\n     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n     * except that it includes inherited enumerable properties.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function nativeKeysIn(object) {\n      var result = [];\n      if (object != null) {\n        for (var key in Object(object)) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Converts `value` to a string using `Object.prototype.toString`.\n     *\n     * @private\n     * @param {*} value The value to convert.\n     * @returns {string} Returns the converted string.\n     */\n    function objectToString(value) {\n      return nativeObjectToString.call(value);\n    }\n\n    /**\n     * A specialized version of `baseRest` which transforms the rest array.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @param {Function} transform The rest array transform.\n     * @returns {Function} Returns the new function.\n     */\n    function overRest(func, start, transform) {\n      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n      return function() {\n        var args = arguments,\n            index = -1,\n            length = nativeMax(args.length - start, 0),\n            array = Array(length);\n\n        while (++index < length) {\n          array[index] = args[start + index];\n        }\n        index = -1;\n        var otherArgs = Array(start + 1);\n        while (++index < start) {\n          otherArgs[index] = args[index];\n        }\n        otherArgs[start] = transform(array);\n        return apply(func, this, otherArgs);\n      };\n    }\n\n    /**\n     * Gets the parent value at `path` of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array} path The path to get the parent value of.\n     * @returns {*} Returns the parent value.\n     */\n    function parent(object, path) {\n      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n    }\n\n    /**\n     * Reorder `array` according to the specified indexes where the element at\n     * the first index is assigned as the first element, the element at\n     * the second index is assigned as the second element, and so on.\n     *\n     * @private\n     * @param {Array} array The array to reorder.\n     * @param {Array} indexes The arranged array indexes.\n     * @returns {Array} Returns `array`.\n     */\n    function reorder(array, indexes) {\n      var arrLength = array.length,\n          length = nativeMin(indexes.length, arrLength),\n          oldArray = copyArray(array);\n\n      while (length--) {\n        var index = indexes[length];\n        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\n      }\n      return array;\n    }\n\n    /**\n     * Sets metadata for `func`.\n     *\n     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\n     * period of time, it will trip its breaker and transition to an identity\n     * function to avoid garbage collection pauses in V8. See\n     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)\n     * for more details.\n     *\n     * @private\n     * @param {Function} func The function to associate metadata with.\n     * @param {*} data The metadata.\n     * @returns {Function} Returns `func`.\n     */\n    var setData = shortOut(baseSetData);\n\n    /**\n     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).\n     *\n     * @private\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @returns {number|Object} Returns the timer id or timeout object.\n     */\n    var setTimeout = ctxSetTimeout || function(func, wait) {\n      return root.setTimeout(func, wait);\n    };\n\n    /**\n     * Sets the `toString` method of `func` to return `string`.\n     *\n     * @private\n     * @param {Function} func The function to modify.\n     * @param {Function} string The `toString` result.\n     * @returns {Function} Returns `func`.\n     */\n    var setToString = shortOut(baseSetToString);\n\n    /**\n     * Sets the `toString` method of `wrapper` to mimic the source of `reference`\n     * with wrapper details in a comment at the top of the source body.\n     *\n     * @private\n     * @param {Function} wrapper The function to modify.\n     * @param {Function} reference The reference function.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @returns {Function} Returns `wrapper`.\n     */\n    function setWrapToString(wrapper, reference, bitmask) {\n      var source = (reference + '');\n      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));\n    }\n\n    /**\n     * Creates a function that'll short out and invoke `identity` instead\n     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n     * milliseconds.\n     *\n     * @private\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new shortable function.\n     */\n    function shortOut(func) {\n      var count = 0,\n          lastCalled = 0;\n\n      return function() {\n        var stamp = nativeNow(),\n            remaining = HOT_SPAN - (stamp - lastCalled);\n\n        lastCalled = stamp;\n        if (remaining > 0) {\n          if (++count >= HOT_COUNT) {\n            return arguments[0];\n          }\n        } else {\n          count = 0;\n        }\n        return func.apply(undefined, arguments);\n      };\n    }\n\n    /**\n     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.\n     *\n     * @private\n     * @param {Array} array The array to shuffle.\n     * @param {number} [size=array.length] The size of `array`.\n     * @returns {Array} Returns `array`.\n     */\n    function shuffleSelf(array, size) {\n      var index = -1,\n          length = array.length,\n          lastIndex = length - 1;\n\n      size = size === undefined ? length : size;\n      while (++index < size) {\n        var rand = baseRandom(index, lastIndex),\n            value = array[rand];\n\n        array[rand] = array[index];\n        array[index] = value;\n      }\n      array.length = size;\n      return array;\n    }\n\n    /**\n     * Converts `string` to a property path array.\n     *\n     * @private\n     * @param {string} string The string to convert.\n     * @returns {Array} Returns the property path array.\n     */\n    var stringToPath = memoizeCapped(function(string) {\n      var result = [];\n      if (reLeadingDot.test(string)) {\n        result.push('');\n      }\n      string.replace(rePropName, function(match, number, quote, string) {\n        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));\n      });\n      return result;\n    });\n\n    /**\n     * Converts `value` to a string key if it's not a string or symbol.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {string|symbol} Returns the key.\n     */\n    function toKey(value) {\n      if (typeof value == 'string' || isSymbol(value)) {\n        return value;\n      }\n      var result = (value + '');\n      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n    }\n\n    /**\n     * Converts `func` to its source code.\n     *\n     * @private\n     * @param {Function} func The function to convert.\n     * @returns {string} Returns the source code.\n     */\n    function toSource(func) {\n      if (func != null) {\n        try {\n          return funcToString.call(func);\n        } catch (e) {}\n        try {\n          return (func + '');\n        } catch (e) {}\n      }\n      return '';\n    }\n\n    /**\n     * Updates wrapper `details` based on `bitmask` flags.\n     *\n     * @private\n     * @returns {Array} details The details to modify.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @returns {Array} Returns `details`.\n     */\n    function updateWrapDetails(details, bitmask) {\n      arrayEach(wrapFlags, function(pair) {\n        var value = '_.' + pair[0];\n        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {\n          details.push(value);\n        }\n      });\n      return details.sort();\n    }\n\n    /**\n     * Creates a clone of `wrapper`.\n     *\n     * @private\n     * @param {Object} wrapper The wrapper to clone.\n     * @returns {Object} Returns the cloned wrapper.\n     */\n    function wrapperClone(wrapper) {\n      if (wrapper instanceof LazyWrapper) {\n        return wrapper.clone();\n      }\n      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);\n      result.__actions__ = copyArray(wrapper.__actions__);\n      result.__index__  = wrapper.__index__;\n      result.__values__ = wrapper.__values__;\n      return result;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an array of elements split into groups the length of `size`.\n     * If `array` can't be split evenly, the final chunk will be the remaining\n     * elements.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to process.\n     * @param {number} [size=1] The length of each chunk\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the new array of chunks.\n     * @example\n     *\n     * _.chunk(['a', 'b', 'c', 'd'], 2);\n     * // => [['a', 'b'], ['c', 'd']]\n     *\n     * _.chunk(['a', 'b', 'c', 'd'], 3);\n     * // => [['a', 'b', 'c'], ['d']]\n     */\n    function chunk(array, size, guard) {\n      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {\n        size = 1;\n      } else {\n        size = nativeMax(toInteger(size), 0);\n      }\n      var length = array == null ? 0 : array.length;\n      if (!length || size < 1) {\n        return [];\n      }\n      var index = 0,\n          resIndex = 0,\n          result = Array(nativeCeil(length / size));\n\n      while (index < length) {\n        result[resIndex++] = baseSlice(array, index, (index += size));\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array with all falsey values removed. The values `false`, `null`,\n     * `0`, `\"\"`, `undefined`, and `NaN` are falsey.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to compact.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.compact([0, 1, false, 2, '', 3]);\n     * // => [1, 2, 3]\n     */\n    function compact(array) {\n      var index = -1,\n          length = array == null ? 0 : array.length,\n          resIndex = 0,\n          result = [];\n\n      while (++index < length) {\n        var value = array[index];\n        if (value) {\n          result[resIndex++] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Creates a new array concatenating `array` with any additional arrays\n     * and/or values.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to concatenate.\n     * @param {...*} [values] The values to concatenate.\n     * @returns {Array} Returns the new concatenated array.\n     * @example\n     *\n     * var array = [1];\n     * var other = _.concat(array, 2, [3], [[4]]);\n     *\n     * console.log(other);\n     * // => [1, 2, 3, [4]]\n     *\n     * console.log(array);\n     * // => [1]\n     */\n    function concat() {\n      var length = arguments.length;\n      if (!length) {\n        return [];\n      }\n      var args = Array(length - 1),\n          array = arguments[0],\n          index = length;\n\n      while (index--) {\n        args[index - 1] = arguments[index];\n      }\n      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));\n    }\n\n    /**\n     * Creates an array of `array` values not included in the other given arrays\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. The order and references of result values are\n     * determined by the first array.\n     *\n     * **Note:** Unlike `_.pullAll`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.without, _.xor\n     * @example\n     *\n     * _.difference([2, 1], [2, 3]);\n     * // => [1]\n     */\n    var difference = baseRest(function(array, values) {\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))\n        : [];\n    });\n\n    /**\n     * This method is like `_.difference` except that it accepts `iteratee` which\n     * is invoked for each element of `array` and `values` to generate the criterion\n     * by which they're compared. The order and references of result values are\n     * determined by the first array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');\n     * // => [{ 'x': 2 }]\n     */\n    var differenceBy = baseRest(function(array, values) {\n      var iteratee = last(values);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))\n        : [];\n    });\n\n    /**\n     * This method is like `_.difference` except that it accepts `comparator`\n     * which is invoked to compare elements of `array` to `values`. The order and\n     * references of result values are determined by the first array. The comparator\n     * is invoked with two arguments: (arrVal, othVal).\n     *\n     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     *\n     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n     * // => [{ 'x': 2, 'y': 1 }]\n     */\n    var differenceWith = baseRest(function(array, values) {\n      var comparator = last(values);\n      if (isArrayLikeObject(comparator)) {\n        comparator = undefined;\n      }\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n        : [];\n    });\n\n    /**\n     * Creates a slice of `array` with `n` elements dropped from the beginning.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to drop.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.drop([1, 2, 3]);\n     * // => [2, 3]\n     *\n     * _.drop([1, 2, 3], 2);\n     * // => [3]\n     *\n     * _.drop([1, 2, 3], 5);\n     * // => []\n     *\n     * _.drop([1, 2, 3], 0);\n     * // => [1, 2, 3]\n     */\n    function drop(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      return baseSlice(array, n < 0 ? 0 : n, length);\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements dropped from the end.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to drop.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.dropRight([1, 2, 3]);\n     * // => [1, 2]\n     *\n     * _.dropRight([1, 2, 3], 2);\n     * // => [1]\n     *\n     * _.dropRight([1, 2, 3], 5);\n     * // => []\n     *\n     * _.dropRight([1, 2, 3], 0);\n     * // => [1, 2, 3]\n     */\n    function dropRight(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      n = length - n;\n      return baseSlice(array, 0, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` excluding elements dropped from the end.\n     * Elements are dropped until `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.dropRightWhile(users, function(o) { return !o.active; });\n     * // => objects for ['barney']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.dropRightWhile(users, ['active', false]);\n     * // => objects for ['barney']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.dropRightWhile(users, 'active');\n     * // => objects for ['barney', 'fred', 'pebbles']\n     */\n    function dropRightWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), true, true)\n        : [];\n    }\n\n    /**\n     * Creates a slice of `array` excluding elements dropped from the beginning.\n     * Elements are dropped until `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.dropWhile(users, function(o) { return !o.active; });\n     * // => objects for ['pebbles']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.dropWhile(users, { 'user': 'barney', 'active': false });\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.dropWhile(users, ['active', false]);\n     * // => objects for ['pebbles']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.dropWhile(users, 'active');\n     * // => objects for ['barney', 'fred', 'pebbles']\n     */\n    function dropWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), true)\n        : [];\n    }\n\n    /**\n     * Fills elements of `array` with `value` from `start` up to, but not\n     * including, `end`.\n     *\n     * **Note:** This method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Array\n     * @param {Array} array The array to fill.\n     * @param {*} value The value to fill `array` with.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _.fill(array, 'a');\n     * console.log(array);\n     * // => ['a', 'a', 'a']\n     *\n     * _.fill(Array(3), 2);\n     * // => [2, 2, 2]\n     *\n     * _.fill([4, 6, 8, 10], '*', 1, 3);\n     * // => [4, '*', '*', 10]\n     */\n    function fill(array, value, start, end) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {\n        start = 0;\n        end = length;\n      }\n      return baseFill(array, value, start, end);\n    }\n\n    /**\n     * This method is like `_.find` except that it returns the index of the first\n     * element `predicate` returns truthy for instead of the element itself.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {number} Returns the index of the found element, else `-1`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.findIndex(users, function(o) { return o.user == 'barney'; });\n     * // => 0\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findIndex(users, { 'user': 'fred', 'active': false });\n     * // => 1\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findIndex(users, ['active', false]);\n     * // => 0\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findIndex(users, 'active');\n     * // => 2\n     */\n    function findIndex(array, predicate, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = fromIndex == null ? 0 : toInteger(fromIndex);\n      if (index < 0) {\n        index = nativeMax(length + index, 0);\n      }\n      return baseFindIndex(array, getIteratee(predicate, 3), index);\n    }\n\n    /**\n     * This method is like `_.findIndex` except that it iterates over elements\n     * of `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=array.length-1] The index to search from.\n     * @returns {number} Returns the index of the found element, else `-1`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });\n     * // => 2\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findLastIndex(users, { 'user': 'barney', 'active': true });\n     * // => 0\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findLastIndex(users, ['active', false]);\n     * // => 2\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findLastIndex(users, 'active');\n     * // => 0\n     */\n    function findLastIndex(array, predicate, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = length - 1;\n      if (fromIndex !== undefined) {\n        index = toInteger(fromIndex);\n        index = fromIndex < 0\n          ? nativeMax(length + index, 0)\n          : nativeMin(index, length - 1);\n      }\n      return baseFindIndex(array, getIteratee(predicate, 3), index, true);\n    }\n\n    /**\n     * Flattens `array` a single level deep.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * _.flatten([1, [2, [3, [4]], 5]]);\n     * // => [1, 2, [3, [4]], 5]\n     */\n    function flatten(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseFlatten(array, 1) : [];\n    }\n\n    /**\n     * Recursively flattens `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * _.flattenDeep([1, [2, [3, [4]], 5]]);\n     * // => [1, 2, 3, 4, 5]\n     */\n    function flattenDeep(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseFlatten(array, INFINITY) : [];\n    }\n\n    /**\n     * Recursively flatten `array` up to `depth` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.4.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @param {number} [depth=1] The maximum recursion depth.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * var array = [1, [2, [3, [4]], 5]];\n     *\n     * _.flattenDepth(array, 1);\n     * // => [1, 2, [3, [4]], 5]\n     *\n     * _.flattenDepth(array, 2);\n     * // => [1, 2, 3, [4], 5]\n     */\n    function flattenDepth(array, depth) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      depth = depth === undefined ? 1 : toInteger(depth);\n      return baseFlatten(array, depth);\n    }\n\n    /**\n     * The inverse of `_.toPairs`; this method returns an object composed\n     * from key-value `pairs`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} pairs The key-value pairs.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.fromPairs([['a', 1], ['b', 2]]);\n     * // => { 'a': 1, 'b': 2 }\n     */\n    function fromPairs(pairs) {\n      var index = -1,\n          length = pairs == null ? 0 : pairs.length,\n          result = {};\n\n      while (++index < length) {\n        var pair = pairs[index];\n        result[pair[0]] = pair[1];\n      }\n      return result;\n    }\n\n    /**\n     * Gets the first element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @alias first\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {*} Returns the first element of `array`.\n     * @example\n     *\n     * _.head([1, 2, 3]);\n     * // => 1\n     *\n     * _.head([]);\n     * // => undefined\n     */\n    function head(array) {\n      return (array && array.length) ? array[0] : undefined;\n    }\n\n    /**\n     * Gets the index at which the first occurrence of `value` is found in `array`\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. If `fromIndex` is negative, it's used as the\n     * offset from the end of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.indexOf([1, 2, 1, 2], 2);\n     * // => 1\n     *\n     * // Search from the `fromIndex`.\n     * _.indexOf([1, 2, 1, 2], 2, 2);\n     * // => 3\n     */\n    function indexOf(array, value, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = fromIndex == null ? 0 : toInteger(fromIndex);\n      if (index < 0) {\n        index = nativeMax(length + index, 0);\n      }\n      return baseIndexOf(array, value, index);\n    }\n\n    /**\n     * Gets all but the last element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.initial([1, 2, 3]);\n     * // => [1, 2]\n     */\n    function initial(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseSlice(array, 0, -1) : [];\n    }\n\n    /**\n     * Creates an array of unique values that are included in all given arrays\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. The order and references of result values are\n     * determined by the first array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * _.intersection([2, 1], [2, 3]);\n     * // => [2]\n     */\n    var intersection = baseRest(function(arrays) {\n      var mapped = arrayMap(arrays, castArrayLikeObject);\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped)\n        : [];\n    });\n\n    /**\n     * This method is like `_.intersection` except that it accepts `iteratee`\n     * which is invoked for each element of each `arrays` to generate the criterion\n     * by which they're compared. The order and references of result values are\n     * determined by the first array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [2.1]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }]\n     */\n    var intersectionBy = baseRest(function(arrays) {\n      var iteratee = last(arrays),\n          mapped = arrayMap(arrays, castArrayLikeObject);\n\n      if (iteratee === last(mapped)) {\n        iteratee = undefined;\n      } else {\n        mapped.pop();\n      }\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped, getIteratee(iteratee, 2))\n        : [];\n    });\n\n    /**\n     * This method is like `_.intersection` except that it accepts `comparator`\n     * which is invoked to compare elements of `arrays`. The order and references\n     * of result values are determined by the first array. The comparator is\n     * invoked with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.intersectionWith(objects, others, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }]\n     */\n    var intersectionWith = baseRest(function(arrays) {\n      var comparator = last(arrays),\n          mapped = arrayMap(arrays, castArrayLikeObject);\n\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      if (comparator) {\n        mapped.pop();\n      }\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped, undefined, comparator)\n        : [];\n    });\n\n    /**\n     * Converts all elements in `array` into a string separated by `separator`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to convert.\n     * @param {string} [separator=','] The element separator.\n     * @returns {string} Returns the joined string.\n     * @example\n     *\n     * _.join(['a', 'b', 'c'], '~');\n     * // => 'a~b~c'\n     */\n    function join(array, separator) {\n      return array == null ? '' : nativeJoin.call(array, separator);\n    }\n\n    /**\n     * Gets the last element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {*} Returns the last element of `array`.\n     * @example\n     *\n     * _.last([1, 2, 3]);\n     * // => 3\n     */\n    function last(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? array[length - 1] : undefined;\n    }\n\n    /**\n     * This method is like `_.indexOf` except that it iterates over elements of\n     * `array` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=array.length-1] The index to search from.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.lastIndexOf([1, 2, 1, 2], 2);\n     * // => 3\n     *\n     * // Search from the `fromIndex`.\n     * _.lastIndexOf([1, 2, 1, 2], 2, 2);\n     * // => 1\n     */\n    function lastIndexOf(array, value, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = length;\n      if (fromIndex !== undefined) {\n        index = toInteger(fromIndex);\n        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);\n      }\n      return value === value\n        ? strictLastIndexOf(array, value, index)\n        : baseFindIndex(array, baseIsNaN, index, true);\n    }\n\n    /**\n     * Gets the element at index `n` of `array`. If `n` is negative, the nth\n     * element from the end is returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.11.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=0] The index of the element to return.\n     * @returns {*} Returns the nth element of `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'd'];\n     *\n     * _.nth(array, 1);\n     * // => 'b'\n     *\n     * _.nth(array, -2);\n     * // => 'c';\n     */\n    function nth(array, n) {\n      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;\n    }\n\n    /**\n     * Removes all given values from `array` using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`\n     * to remove elements from an array by predicate.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {...*} [values] The values to remove.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n     *\n     * _.pull(array, 'a', 'c');\n     * console.log(array);\n     * // => ['b', 'b']\n     */\n    var pull = baseRest(pullAll);\n\n    /**\n     * This method is like `_.pull` except that it accepts an array of values to remove.\n     *\n     * **Note:** Unlike `_.difference`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n     *\n     * _.pullAll(array, ['a', 'c']);\n     * console.log(array);\n     * // => ['b', 'b']\n     */\n    function pullAll(array, values) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values)\n        : array;\n    }\n\n    /**\n     * This method is like `_.pullAll` except that it accepts `iteratee` which is\n     * invoked for each element of `array` and `values` to generate the criterion\n     * by which they're compared. The iteratee is invoked with one argument: (value).\n     *\n     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];\n     *\n     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');\n     * console.log(array);\n     * // => [{ 'x': 2 }]\n     */\n    function pullAllBy(array, values, iteratee) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values, getIteratee(iteratee, 2))\n        : array;\n    }\n\n    /**\n     * This method is like `_.pullAll` except that it accepts `comparator` which\n     * is invoked to compare elements of `array` to `values`. The comparator is\n     * invoked with two arguments: (arrVal, othVal).\n     *\n     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];\n     *\n     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);\n     * console.log(array);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]\n     */\n    function pullAllWith(array, values, comparator) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values, undefined, comparator)\n        : array;\n    }\n\n    /**\n     * Removes elements from `array` corresponding to `indexes` and returns an\n     * array of removed elements.\n     *\n     * **Note:** Unlike `_.at`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {...(number|number[])} [indexes] The indexes of elements to remove.\n     * @returns {Array} Returns the new array of removed elements.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'd'];\n     * var pulled = _.pullAt(array, [1, 3]);\n     *\n     * console.log(array);\n     * // => ['a', 'c']\n     *\n     * console.log(pulled);\n     * // => ['b', 'd']\n     */\n    var pullAt = flatRest(function(array, indexes) {\n      var length = array == null ? 0 : array.length,\n          result = baseAt(array, indexes);\n\n      basePullAt(array, arrayMap(indexes, function(index) {\n        return isIndex(index, length) ? +index : index;\n      }).sort(compareAscending));\n\n      return result;\n    });\n\n    /**\n     * Removes all elements from `array` that `predicate` returns truthy for\n     * and returns an array of the removed elements. The predicate is invoked\n     * with three arguments: (value, index, array).\n     *\n     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n     * to pull elements from an array by value.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new array of removed elements.\n     * @example\n     *\n     * var array = [1, 2, 3, 4];\n     * var evens = _.remove(array, function(n) {\n     *   return n % 2 == 0;\n     * });\n     *\n     * console.log(array);\n     * // => [1, 3]\n     *\n     * console.log(evens);\n     * // => [2, 4]\n     */\n    function remove(array, predicate) {\n      var result = [];\n      if (!(array && array.length)) {\n        return result;\n      }\n      var index = -1,\n          indexes = [],\n          length = array.length;\n\n      predicate = getIteratee(predicate, 3);\n      while (++index < length) {\n        var value = array[index];\n        if (predicate(value, index, array)) {\n          result.push(value);\n          indexes.push(index);\n        }\n      }\n      basePullAt(array, indexes);\n      return result;\n    }\n\n    /**\n     * Reverses `array` so that the first element becomes the last, the second\n     * element becomes the second to last, and so on.\n     *\n     * **Note:** This method mutates `array` and is based on\n     * [`Array#reverse`](https://mdn.io/Array/reverse).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _.reverse(array);\n     * // => [3, 2, 1]\n     *\n     * console.log(array);\n     * // => [3, 2, 1]\n     */\n    function reverse(array) {\n      return array == null ? array : nativeReverse.call(array);\n    }\n\n    /**\n     * Creates a slice of `array` from `start` up to, but not including, `end`.\n     *\n     * **Note:** This method is used instead of\n     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are\n     * returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to slice.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function slice(array, start, end) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {\n        start = 0;\n        end = length;\n      }\n      else {\n        start = start == null ? 0 : toInteger(start);\n        end = end === undefined ? length : toInteger(end);\n      }\n      return baseSlice(array, start, end);\n    }\n\n    /**\n     * Uses a binary search to determine the lowest index at which `value`\n     * should be inserted into `array` in order to maintain its sort order.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * _.sortedIndex([30, 50], 40);\n     * // => 1\n     */\n    function sortedIndex(array, value) {\n      return baseSortedIndex(array, value);\n    }\n\n    /**\n     * This method is like `_.sortedIndex` except that it accepts `iteratee`\n     * which is invoked for `value` and each element of `array` to compute their\n     * sort ranking. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * var objects = [{ 'x': 4 }, { 'x': 5 }];\n     *\n     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n     * // => 0\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');\n     * // => 0\n     */\n    function sortedIndexBy(array, value, iteratee) {\n      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));\n    }\n\n    /**\n     * This method is like `_.indexOf` except that it performs a binary\n     * search on a sorted `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);\n     * // => 1\n     */\n    function sortedIndexOf(array, value) {\n      var length = array == null ? 0 : array.length;\n      if (length) {\n        var index = baseSortedIndex(array, value);\n        if (index < length && eq(array[index], value)) {\n          return index;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * This method is like `_.sortedIndex` except that it returns the highest\n     * index at which `value` should be inserted into `array` in order to\n     * maintain its sort order.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);\n     * // => 4\n     */\n    function sortedLastIndex(array, value) {\n      return baseSortedIndex(array, value, true);\n    }\n\n    /**\n     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`\n     * which is invoked for `value` and each element of `array` to compute their\n     * sort ranking. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * var objects = [{ 'x': 4 }, { 'x': 5 }];\n     *\n     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n     * // => 1\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');\n     * // => 1\n     */\n    function sortedLastIndexBy(array, value, iteratee) {\n      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);\n    }\n\n    /**\n     * This method is like `_.lastIndexOf` except that it performs a binary\n     * search on a sorted `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);\n     * // => 3\n     */\n    function sortedLastIndexOf(array, value) {\n      var length = array == null ? 0 : array.length;\n      if (length) {\n        var index = baseSortedIndex(array, value, true) - 1;\n        if (eq(array[index], value)) {\n          return index;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * This method is like `_.uniq` except that it's designed and optimized\n     * for sorted arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.sortedUniq([1, 1, 2]);\n     * // => [1, 2]\n     */\n    function sortedUniq(array) {\n      return (array && array.length)\n        ? baseSortedUniq(array)\n        : [];\n    }\n\n    /**\n     * This method is like `_.uniqBy` except that it's designed and optimized\n     * for sorted arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);\n     * // => [1.1, 2.3]\n     */\n    function sortedUniqBy(array, iteratee) {\n      return (array && array.length)\n        ? baseSortedUniq(array, getIteratee(iteratee, 2))\n        : [];\n    }\n\n    /**\n     * Gets all but the first element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.tail([1, 2, 3]);\n     * // => [2, 3]\n     */\n    function tail(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseSlice(array, 1, length) : [];\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements taken from the beginning.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to take.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.take([1, 2, 3]);\n     * // => [1]\n     *\n     * _.take([1, 2, 3], 2);\n     * // => [1, 2]\n     *\n     * _.take([1, 2, 3], 5);\n     * // => [1, 2, 3]\n     *\n     * _.take([1, 2, 3], 0);\n     * // => []\n     */\n    function take(array, n, guard) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      return baseSlice(array, 0, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements taken from the end.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to take.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.takeRight([1, 2, 3]);\n     * // => [3]\n     *\n     * _.takeRight([1, 2, 3], 2);\n     * // => [2, 3]\n     *\n     * _.takeRight([1, 2, 3], 5);\n     * // => [1, 2, 3]\n     *\n     * _.takeRight([1, 2, 3], 0);\n     * // => []\n     */\n    function takeRight(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      n = length - n;\n      return baseSlice(array, n < 0 ? 0 : n, length);\n    }\n\n    /**\n     * Creates a slice of `array` with elements taken from the end. Elements are\n     * taken until `predicate` returns falsey. The predicate is invoked with\n     * three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.takeRightWhile(users, function(o) { return !o.active; });\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });\n     * // => objects for ['pebbles']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.takeRightWhile(users, ['active', false]);\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.takeRightWhile(users, 'active');\n     * // => []\n     */\n    function takeRightWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), false, true)\n        : [];\n    }\n\n    /**\n     * Creates a slice of `array` with elements taken from the beginning. Elements\n     * are taken until `predicate` returns falsey. The predicate is invoked with\n     * three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.takeWhile(users, function(o) { return !o.active; });\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.takeWhile(users, { 'user': 'barney', 'active': false });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.takeWhile(users, ['active', false]);\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.takeWhile(users, 'active');\n     * // => []\n     */\n    function takeWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3))\n        : [];\n    }\n\n    /**\n     * Creates an array of unique values, in order, from all given arrays using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * _.union([2], [1, 2]);\n     * // => [2, 1]\n     */\n    var union = baseRest(function(arrays) {\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));\n    });\n\n    /**\n     * This method is like `_.union` except that it accepts `iteratee` which is\n     * invoked for each element of each `arrays` to generate the criterion by\n     * which uniqueness is computed. Result values are chosen from the first\n     * array in which the value occurs. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * _.unionBy([2.1], [1.2, 2.3], Math.floor);\n     * // => [2.1, 1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }, { 'x': 2 }]\n     */\n    var unionBy = baseRest(function(arrays) {\n      var iteratee = last(arrays);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));\n    });\n\n    /**\n     * This method is like `_.union` except that it accepts `comparator` which\n     * is invoked to compare elements of `arrays`. Result values are chosen from\n     * the first array in which the value occurs. The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.unionWith(objects, others, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n     */\n    var unionWith = baseRest(function(arrays) {\n      var comparator = last(arrays);\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);\n    });\n\n    /**\n     * Creates a duplicate-free version of an array, using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons, in which only the first occurrence of each element\n     * is kept. The order of result values is determined by the order they occur\n     * in the array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.uniq([2, 1, 2]);\n     * // => [2, 1]\n     */\n    function uniq(array) {\n      return (array && array.length) ? baseUniq(array) : [];\n    }\n\n    /**\n     * This method is like `_.uniq` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * uniqueness is computed. The order of result values is determined by the\n     * order they occur in the array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n     * // => [2.1, 1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }, { 'x': 2 }]\n     */\n    function uniqBy(array, iteratee) {\n      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];\n    }\n\n    /**\n     * This method is like `_.uniq` except that it accepts `comparator` which\n     * is invoked to compare elements of `array`. The order of result values is\n     * determined by the order they occur in the array.The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.uniqWith(objects, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n     */\n    function uniqWith(array, comparator) {\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];\n    }\n\n    /**\n     * This method is like `_.zip` except that it accepts an array of grouped\n     * elements and creates an array regrouping the elements to their pre-zip\n     * configuration.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.2.0\n     * @category Array\n     * @param {Array} array The array of grouped elements to process.\n     * @returns {Array} Returns the new array of regrouped elements.\n     * @example\n     *\n     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);\n     * // => [['a', 1, true], ['b', 2, false]]\n     *\n     * _.unzip(zipped);\n     * // => [['a', 'b'], [1, 2], [true, false]]\n     */\n    function unzip(array) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      var length = 0;\n      array = arrayFilter(array, function(group) {\n        if (isArrayLikeObject(group)) {\n          length = nativeMax(group.length, length);\n          return true;\n        }\n      });\n      return baseTimes(length, function(index) {\n        return arrayMap(array, baseProperty(index));\n      });\n    }\n\n    /**\n     * This method is like `_.unzip` except that it accepts `iteratee` to specify\n     * how regrouped values should be combined. The iteratee is invoked with the\n     * elements of each group: (...group).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Array\n     * @param {Array} array The array of grouped elements to process.\n     * @param {Function} [iteratee=_.identity] The function to combine\n     *  regrouped values.\n     * @returns {Array} Returns the new array of regrouped elements.\n     * @example\n     *\n     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);\n     * // => [[1, 10, 100], [2, 20, 200]]\n     *\n     * _.unzipWith(zipped, _.add);\n     * // => [3, 30, 300]\n     */\n    function unzipWith(array, iteratee) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      var result = unzip(array);\n      if (iteratee == null) {\n        return result;\n      }\n      return arrayMap(result, function(group) {\n        return apply(iteratee, undefined, group);\n      });\n    }\n\n    /**\n     * Creates an array excluding all given values using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * **Note:** Unlike `_.pull`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...*} [values] The values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.difference, _.xor\n     * @example\n     *\n     * _.without([2, 1, 2, 3], 1, 2);\n     * // => [3]\n     */\n    var without = baseRest(function(array, values) {\n      return isArrayLikeObject(array)\n        ? baseDifference(array, values)\n        : [];\n    });\n\n    /**\n     * Creates an array of unique values that is the\n     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)\n     * of the given arrays. The order of result values is determined by the order\n     * they occur in the arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.difference, _.without\n     * @example\n     *\n     * _.xor([2, 1], [2, 3]);\n     * // => [1, 3]\n     */\n    var xor = baseRest(function(arrays) {\n      return baseXor(arrayFilter(arrays, isArrayLikeObject));\n    });\n\n    /**\n     * This method is like `_.xor` except that it accepts `iteratee` which is\n     * invoked for each element of each `arrays` to generate the criterion by\n     * which by which they're compared. The order of result values is determined\n     * by the order they occur in the arrays. The iteratee is invoked with one\n     * argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [1.2, 3.4]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 2 }]\n     */\n    var xorBy = baseRest(function(arrays) {\n      var iteratee = last(arrays);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));\n    });\n\n    /**\n     * This method is like `_.xor` except that it accepts `comparator` which is\n     * invoked to compare elements of `arrays`. The order of result values is\n     * determined by the order they occur in the arrays. The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.xorWith(objects, others, _.isEqual);\n     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n     */\n    var xorWith = baseRest(function(arrays) {\n      var comparator = last(arrays);\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);\n    });\n\n    /**\n     * Creates an array of grouped elements, the first of which contains the\n     * first elements of the given arrays, the second of which contains the\n     * second elements of the given arrays, and so on.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to process.\n     * @returns {Array} Returns the new array of grouped elements.\n     * @example\n     *\n     * _.zip(['a', 'b'], [1, 2], [true, false]);\n     * // => [['a', 1, true], ['b', 2, false]]\n     */\n    var zip = baseRest(unzip);\n\n    /**\n     * This method is like `_.fromPairs` except that it accepts two arrays,\n     * one of property identifiers and one of corresponding values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.4.0\n     * @category Array\n     * @param {Array} [props=[]] The property identifiers.\n     * @param {Array} [values=[]] The property values.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.zipObject(['a', 'b'], [1, 2]);\n     * // => { 'a': 1, 'b': 2 }\n     */\n    function zipObject(props, values) {\n      return baseZipObject(props || [], values || [], assignValue);\n    }\n\n    /**\n     * This method is like `_.zipObject` except that it supports property paths.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.1.0\n     * @category Array\n     * @param {Array} [props=[]] The property identifiers.\n     * @param {Array} [values=[]] The property values.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);\n     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }\n     */\n    function zipObjectDeep(props, values) {\n      return baseZipObject(props || [], values || [], baseSet);\n    }\n\n    /**\n     * This method is like `_.zip` except that it accepts `iteratee` to specify\n     * how grouped values should be combined. The iteratee is invoked with the\n     * elements of each group: (...group).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to process.\n     * @param {Function} [iteratee=_.identity] The function to combine\n     *  grouped values.\n     * @returns {Array} Returns the new array of grouped elements.\n     * @example\n     *\n     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {\n     *   return a + b + c;\n     * });\n     * // => [111, 222]\n     */\n    var zipWith = baseRest(function(arrays) {\n      var length = arrays.length,\n          iteratee = length > 1 ? arrays[length - 1] : undefined;\n\n      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;\n      return unzipWith(arrays, iteratee);\n    });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a `lodash` wrapper instance that wraps `value` with explicit method\n     * chain sequences enabled. The result of such sequences must be unwrapped\n     * with `_#value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.3.0\n     * @category Seq\n     * @param {*} value The value to wrap.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36 },\n     *   { 'user': 'fred',    'age': 40 },\n     *   { 'user': 'pebbles', 'age': 1 }\n     * ];\n     *\n     * var youngest = _\n     *   .chain(users)\n     *   .sortBy('age')\n     *   .map(function(o) {\n     *     return o.user + ' is ' + o.age;\n     *   })\n     *   .head()\n     *   .value();\n     * // => 'pebbles is 1'\n     */\n    function chain(value) {\n      var result = lodash(value);\n      result.__chain__ = true;\n      return result;\n    }\n\n    /**\n     * This method invokes `interceptor` and returns `value`. The interceptor\n     * is invoked with one argument; (value). The purpose of this method is to\n     * \"tap into\" a method chain sequence in order to modify intermediate results.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @param {*} value The value to provide to `interceptor`.\n     * @param {Function} interceptor The function to invoke.\n     * @returns {*} Returns `value`.\n     * @example\n     *\n     * _([1, 2, 3])\n     *  .tap(function(array) {\n     *    // Mutate input array.\n     *    array.pop();\n     *  })\n     *  .reverse()\n     *  .value();\n     * // => [2, 1]\n     */\n    function tap(value, interceptor) {\n      interceptor(value);\n      return value;\n    }\n\n    /**\n     * This method is like `_.tap` except that it returns the result of `interceptor`.\n     * The purpose of this method is to \"pass thru\" values replacing intermediate\n     * results in a method chain sequence.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Seq\n     * @param {*} value The value to provide to `interceptor`.\n     * @param {Function} interceptor The function to invoke.\n     * @returns {*} Returns the result of `interceptor`.\n     * @example\n     *\n     * _('  abc  ')\n     *  .chain()\n     *  .trim()\n     *  .thru(function(value) {\n     *    return [value];\n     *  })\n     *  .value();\n     * // => ['abc']\n     */\n    function thru(value, interceptor) {\n      return interceptor(value);\n    }\n\n    /**\n     * This method is the wrapper version of `_.at`.\n     *\n     * @name at\n     * @memberOf _\n     * @since 1.0.0\n     * @category Seq\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n     *\n     * _(object).at(['a[0].b.c', 'a[1]']).value();\n     * // => [3, 4]\n     */\n    var wrapperAt = flatRest(function(paths) {\n      var length = paths.length,\n          start = length ? paths[0] : 0,\n          value = this.__wrapped__,\n          interceptor = function(object) { return baseAt(object, paths); };\n\n      if (length > 1 || this.__actions__.length ||\n          !(value instanceof LazyWrapper) || !isIndex(start)) {\n        return this.thru(interceptor);\n      }\n      value = value.slice(start, +start + (length ? 1 : 0));\n      value.__actions__.push({\n        'func': thru,\n        'args': [interceptor],\n        'thisArg': undefined\n      });\n      return new LodashWrapper(value, this.__chain__).thru(function(array) {\n        if (length && !array.length) {\n          array.push(undefined);\n        }\n        return array;\n      });\n    });\n\n    /**\n     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.\n     *\n     * @name chain\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 }\n     * ];\n     *\n     * // A sequence without explicit chaining.\n     * _(users).head();\n     * // => { 'user': 'barney', 'age': 36 }\n     *\n     * // A sequence with explicit chaining.\n     * _(users)\n     *   .chain()\n     *   .head()\n     *   .pick('user')\n     *   .value();\n     * // => { 'user': 'barney' }\n     */\n    function wrapperChain() {\n      return chain(this);\n    }\n\n    /**\n     * Executes the chain sequence and returns the wrapped result.\n     *\n     * @name commit\n     * @memberOf _\n     * @since 3.2.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2];\n     * var wrapped = _(array).push(3);\n     *\n     * console.log(array);\n     * // => [1, 2]\n     *\n     * wrapped = wrapped.commit();\n     * console.log(array);\n     * // => [1, 2, 3]\n     *\n     * wrapped.last();\n     * // => 3\n     *\n     * console.log(array);\n     * // => [1, 2, 3]\n     */\n    function wrapperCommit() {\n      return new LodashWrapper(this.value(), this.__chain__);\n    }\n\n    /**\n     * Gets the next value on a wrapped object following the\n     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).\n     *\n     * @name next\n     * @memberOf _\n     * @since 4.0.0\n     * @category Seq\n     * @returns {Object} Returns the next iterator value.\n     * @example\n     *\n     * var wrapped = _([1, 2]);\n     *\n     * wrapped.next();\n     * // => { 'done': false, 'value': 1 }\n     *\n     * wrapped.next();\n     * // => { 'done': false, 'value': 2 }\n     *\n     * wrapped.next();\n     * // => { 'done': true, 'value': undefined }\n     */\n    function wrapperNext() {\n      if (this.__values__ === undefined) {\n        this.__values__ = toArray(this.value());\n      }\n      var done = this.__index__ >= this.__values__.length,\n          value = done ? undefined : this.__values__[this.__index__++];\n\n      return { 'done': done, 'value': value };\n    }\n\n    /**\n     * Enables the wrapper to be iterable.\n     *\n     * @name Symbol.iterator\n     * @memberOf _\n     * @since 4.0.0\n     * @category Seq\n     * @returns {Object} Returns the wrapper object.\n     * @example\n     *\n     * var wrapped = _([1, 2]);\n     *\n     * wrapped[Symbol.iterator]() === wrapped;\n     * // => true\n     *\n     * Array.from(wrapped);\n     * // => [1, 2]\n     */\n    function wrapperToIterator() {\n      return this;\n    }\n\n    /**\n     * Creates a clone of the chain sequence planting `value` as the wrapped value.\n     *\n     * @name plant\n     * @memberOf _\n     * @since 3.2.0\n     * @category Seq\n     * @param {*} value The value to plant.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var wrapped = _([1, 2]).map(square);\n     * var other = wrapped.plant([3, 4]);\n     *\n     * other.value();\n     * // => [9, 16]\n     *\n     * wrapped.value();\n     * // => [1, 4]\n     */\n    function wrapperPlant(value) {\n      var result,\n          parent = this;\n\n      while (parent instanceof baseLodash) {\n        var clone = wrapperClone(parent);\n        clone.__index__ = 0;\n        clone.__values__ = undefined;\n        if (result) {\n          previous.__wrapped__ = clone;\n        } else {\n          result = clone;\n        }\n        var previous = clone;\n        parent = parent.__wrapped__;\n      }\n      previous.__wrapped__ = value;\n      return result;\n    }\n\n    /**\n     * This method is the wrapper version of `_.reverse`.\n     *\n     * **Note:** This method mutates the wrapped array.\n     *\n     * @name reverse\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _(array).reverse().value()\n     * // => [3, 2, 1]\n     *\n     * console.log(array);\n     * // => [3, 2, 1]\n     */\n    function wrapperReverse() {\n      var value = this.__wrapped__;\n      if (value instanceof LazyWrapper) {\n        var wrapped = value;\n        if (this.__actions__.length) {\n          wrapped = new LazyWrapper(this);\n        }\n        wrapped = wrapped.reverse();\n        wrapped.__actions__.push({\n          'func': thru,\n          'args': [reverse],\n          'thisArg': undefined\n        });\n        return new LodashWrapper(wrapped, this.__chain__);\n      }\n      return this.thru(reverse);\n    }\n\n    /**\n     * Executes the chain sequence to resolve the unwrapped value.\n     *\n     * @name value\n     * @memberOf _\n     * @since 0.1.0\n     * @alias toJSON, valueOf\n     * @category Seq\n     * @returns {*} Returns the resolved unwrapped value.\n     * @example\n     *\n     * _([1, 2, 3]).value();\n     * // => [1, 2, 3]\n     */\n    function wrapperValue() {\n      return baseWrapperValue(this.__wrapped__, this.__actions__);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The corresponding value of\n     * each key is the number of times the key was returned by `iteratee`. The\n     * iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * _.countBy([6.1, 4.2, 6.3], Math.floor);\n     * // => { '4': 1, '6': 2 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.countBy(['one', 'two', 'three'], 'length');\n     * // => { '3': 2, '5': 1 }\n     */\n    var countBy = createAggregator(function(result, value, key) {\n      if (hasOwnProperty.call(result, key)) {\n        ++result[key];\n      } else {\n        baseAssignValue(result, key, 1);\n      }\n    });\n\n    /**\n     * Checks if `predicate` returns truthy for **all** elements of `collection`.\n     * Iteration is stopped once `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index|key, collection).\n     *\n     * **Note:** This method returns `true` for\n     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because\n     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of\n     * elements of empty collections.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`.\n     * @example\n     *\n     * _.every([true, 1, null, 'yes'], Boolean);\n     * // => false\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': false },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.every(users, { 'user': 'barney', 'active': false });\n     * // => false\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.every(users, ['active', false]);\n     * // => true\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.every(users, 'active');\n     * // => false\n     */\n    function every(collection, predicate, guard) {\n      var func = isArray(collection) ? arrayEvery : baseEvery;\n      if (guard && isIterateeCall(collection, predicate, guard)) {\n        predicate = undefined;\n      }\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Iterates over elements of `collection`, returning an array of all elements\n     * `predicate` returns truthy for. The predicate is invoked with three\n     * arguments: (value, index|key, collection).\n     *\n     * **Note:** Unlike `_.remove`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     * @see _.reject\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * _.filter(users, function(o) { return !o.active; });\n     * // => objects for ['fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.filter(users, { 'age': 36, 'active': true });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.filter(users, ['active', false]);\n     * // => objects for ['fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.filter(users, 'active');\n     * // => objects for ['barney']\n     */\n    function filter(collection, predicate) {\n      var func = isArray(collection) ? arrayFilter : baseFilter;\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Iterates over elements of `collection`, returning the first element\n     * `predicate` returns truthy for. The predicate is invoked with three\n     * arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36, 'active': true },\n     *   { 'user': 'fred',    'age': 40, 'active': false },\n     *   { 'user': 'pebbles', 'age': 1,  'active': true }\n     * ];\n     *\n     * _.find(users, function(o) { return o.age < 40; });\n     * // => object for 'barney'\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.find(users, { 'age': 1, 'active': true });\n     * // => object for 'pebbles'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.find(users, ['active', false]);\n     * // => object for 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.find(users, 'active');\n     * // => object for 'barney'\n     */\n    var find = createFind(findIndex);\n\n    /**\n     * This method is like `_.find` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=collection.length-1] The index to search from.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * _.findLast([1, 2, 3, 4], function(n) {\n     *   return n % 2 == 1;\n     * });\n     * // => 3\n     */\n    var findLast = createFind(findLastIndex);\n\n    /**\n     * Creates a flattened array of values by running each element in `collection`\n     * thru `iteratee` and flattening the mapped results. The iteratee is invoked\n     * with three arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [n, n];\n     * }\n     *\n     * _.flatMap([1, 2], duplicate);\n     * // => [1, 1, 2, 2]\n     */\n    function flatMap(collection, iteratee) {\n      return baseFlatten(map(collection, iteratee), 1);\n    }\n\n    /**\n     * This method is like `_.flatMap` except that it recursively flattens the\n     * mapped results.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [[[n, n]]];\n     * }\n     *\n     * _.flatMapDeep([1, 2], duplicate);\n     * // => [1, 1, 2, 2]\n     */\n    function flatMapDeep(collection, iteratee) {\n      return baseFlatten(map(collection, iteratee), INFINITY);\n    }\n\n    /**\n     * This method is like `_.flatMap` except that it recursively flattens the\n     * mapped results up to `depth` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {number} [depth=1] The maximum recursion depth.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [[[n, n]]];\n     * }\n     *\n     * _.flatMapDepth([1, 2], duplicate, 2);\n     * // => [[1, 1], [2, 2]]\n     */\n    function flatMapDepth(collection, iteratee, depth) {\n      depth = depth === undefined ? 1 : toInteger(depth);\n      return baseFlatten(map(collection, iteratee), depth);\n    }\n\n    /**\n     * Iterates over elements of `collection` and invokes `iteratee` for each element.\n     * The iteratee is invoked with three arguments: (value, index|key, collection).\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * **Note:** As with other \"Collections\" methods, objects with a \"length\"\n     * property are iterated like arrays. To avoid this behavior use `_.forIn`\n     * or `_.forOwn` for object iteration.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @alias each\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     * @see _.forEachRight\n     * @example\n     *\n     * _.forEach([1, 2], function(value) {\n     *   console.log(value);\n     * });\n     * // => Logs `1` then `2`.\n     *\n     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n     */\n    function forEach(collection, iteratee) {\n      var func = isArray(collection) ? arrayEach : baseEach;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.forEach` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @alias eachRight\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     * @see _.forEach\n     * @example\n     *\n     * _.forEachRight([1, 2], function(value) {\n     *   console.log(value);\n     * });\n     * // => Logs `2` then `1`.\n     */\n    function forEachRight(collection, iteratee) {\n      var func = isArray(collection) ? arrayEachRight : baseEachRight;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The order of grouped values\n     * is determined by the order they occur in `collection`. The corresponding\n     * value of each key is an array of elements responsible for generating the\n     * key. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * _.groupBy([6.1, 4.2, 6.3], Math.floor);\n     * // => { '4': [4.2], '6': [6.1, 6.3] }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.groupBy(['one', 'two', 'three'], 'length');\n     * // => { '3': ['one', 'two'], '5': ['three'] }\n     */\n    var groupBy = createAggregator(function(result, value, key) {\n      if (hasOwnProperty.call(result, key)) {\n        result[key].push(value);\n      } else {\n        baseAssignValue(result, key, [value]);\n      }\n    });\n\n    /**\n     * Checks if `value` is in `collection`. If `collection` is a string, it's\n     * checked for a substring of `value`, otherwise\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * is used for equality comparisons. If `fromIndex` is negative, it's used as\n     * the offset from the end of `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n     * @returns {boolean} Returns `true` if `value` is found, else `false`.\n     * @example\n     *\n     * _.includes([1, 2, 3], 1);\n     * // => true\n     *\n     * _.includes([1, 2, 3], 1, 2);\n     * // => false\n     *\n     * _.includes({ 'a': 1, 'b': 2 }, 1);\n     * // => true\n     *\n     * _.includes('abcd', 'bc');\n     * // => true\n     */\n    function includes(collection, value, fromIndex, guard) {\n      collection = isArrayLike(collection) ? collection : values(collection);\n      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;\n\n      var length = collection.length;\n      if (fromIndex < 0) {\n        fromIndex = nativeMax(length + fromIndex, 0);\n      }\n      return isString(collection)\n        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)\n        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);\n    }\n\n    /**\n     * Invokes the method at `path` of each element in `collection`, returning\n     * an array of the results of each invoked method. Any additional arguments\n     * are provided to each invoked method. If `path` is a function, it's invoked\n     * for, and `this` bound to, each element in `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Array|Function|string} path The path of the method to invoke or\n     *  the function invoked per iteration.\n     * @param {...*} [args] The arguments to invoke each method with.\n     * @returns {Array} Returns the array of results.\n     * @example\n     *\n     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');\n     * // => [[1, 5, 7], [1, 2, 3]]\n     *\n     * _.invokeMap([123, 456], String.prototype.split, '');\n     * // => [['1', '2', '3'], ['4', '5', '6']]\n     */\n    var invokeMap = baseRest(function(collection, path, args) {\n      var index = -1,\n          isFunc = typeof path == 'function',\n          result = isArrayLike(collection) ? Array(collection.length) : [];\n\n      baseEach(collection, function(value) {\n        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);\n      });\n      return result;\n    });\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The corresponding value of\n     * each key is the last element responsible for generating the key. The\n     * iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * var array = [\n     *   { 'dir': 'left', 'code': 97 },\n     *   { 'dir': 'right', 'code': 100 }\n     * ];\n     *\n     * _.keyBy(array, function(o) {\n     *   return String.fromCharCode(o.code);\n     * });\n     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n     *\n     * _.keyBy(array, 'dir');\n     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }\n     */\n    var keyBy = createAggregator(function(result, value, key) {\n      baseAssignValue(result, key, value);\n    });\n\n    /**\n     * Creates an array of values by running each element in `collection` thru\n     * `iteratee`. The iteratee is invoked with three arguments:\n     * (value, index|key, collection).\n     *\n     * Many lodash methods are guarded to work as iteratees for methods like\n     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n     *\n     * The guarded methods are:\n     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,\n     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,\n     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,\n     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new mapped array.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * _.map([4, 8], square);\n     * // => [16, 64]\n     *\n     * _.map({ 'a': 4, 'b': 8 }, square);\n     * // => [16, 64] (iteration order is not guaranteed)\n     *\n     * var users = [\n     *   { 'user': 'barney' },\n     *   { 'user': 'fred' }\n     * ];\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.map(users, 'user');\n     * // => ['barney', 'fred']\n     */\n    function map(collection, iteratee) {\n      var func = isArray(collection) ? arrayMap : baseMap;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.sortBy` except that it allows specifying the sort\n     * orders of the iteratees to sort by. If `orders` is unspecified, all values\n     * are sorted in ascending order. Otherwise, specify an order of \"desc\" for\n     * descending or \"asc\" for ascending sort order of corresponding values.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]\n     *  The iteratees to sort by.\n     * @param {string[]} [orders] The sort orders of `iteratees`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'fred',   'age': 48 },\n     *   { 'user': 'barney', 'age': 34 },\n     *   { 'user': 'fred',   'age': 40 },\n     *   { 'user': 'barney', 'age': 36 }\n     * ];\n     *\n     * // Sort by `user` in ascending order and by `age` in descending order.\n     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);\n     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n     */\n    function orderBy(collection, iteratees, orders, guard) {\n      if (collection == null) {\n        return [];\n      }\n      if (!isArray(iteratees)) {\n        iteratees = iteratees == null ? [] : [iteratees];\n      }\n      orders = guard ? undefined : orders;\n      if (!isArray(orders)) {\n        orders = orders == null ? [] : [orders];\n      }\n      return baseOrderBy(collection, iteratees, orders);\n    }\n\n    /**\n     * Creates an array of elements split into two groups, the first of which\n     * contains elements `predicate` returns truthy for, the second of which\n     * contains elements `predicate` returns falsey for. The predicate is\n     * invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the array of grouped elements.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36, 'active': false },\n     *   { 'user': 'fred',    'age': 40, 'active': true },\n     *   { 'user': 'pebbles', 'age': 1,  'active': false }\n     * ];\n     *\n     * _.partition(users, function(o) { return o.active; });\n     * // => objects for [['fred'], ['barney', 'pebbles']]\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.partition(users, { 'age': 1, 'active': false });\n     * // => objects for [['pebbles'], ['barney', 'fred']]\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.partition(users, ['active', false]);\n     * // => objects for [['barney', 'pebbles'], ['fred']]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.partition(users, 'active');\n     * // => objects for [['fred'], ['barney', 'pebbles']]\n     */\n    var partition = createAggregator(function(result, value, key) {\n      result[key ? 0 : 1].push(value);\n    }, function() { return [[], []]; });\n\n    /**\n     * Reduces `collection` to a value which is the accumulated result of running\n     * each element in `collection` thru `iteratee`, where each successive\n     * invocation is supplied the return value of the previous. If `accumulator`\n     * is not given, the first element of `collection` is used as the initial\n     * value. The iteratee is invoked with four arguments:\n     * (accumulator, value, index|key, collection).\n     *\n     * Many lodash methods are guarded to work as iteratees for methods like\n     * `_.reduce`, `_.reduceRight`, and `_.transform`.\n     *\n     * The guarded methods are:\n     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,\n     * and `sortBy`\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @returns {*} Returns the accumulated value.\n     * @see _.reduceRight\n     * @example\n     *\n     * _.reduce([1, 2], function(sum, n) {\n     *   return sum + n;\n     * }, 0);\n     * // => 3\n     *\n     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n     *   (result[value] || (result[value] = [])).push(key);\n     *   return result;\n     * }, {});\n     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)\n     */\n    function reduce(collection, iteratee, accumulator) {\n      var func = isArray(collection) ? arrayReduce : baseReduce,\n          initAccum = arguments.length < 3;\n\n      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);\n    }\n\n    /**\n     * This method is like `_.reduce` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @returns {*} Returns the accumulated value.\n     * @see _.reduce\n     * @example\n     *\n     * var array = [[0, 1], [2, 3], [4, 5]];\n     *\n     * _.reduceRight(array, function(flattened, other) {\n     *   return flattened.concat(other);\n     * }, []);\n     * // => [4, 5, 2, 3, 0, 1]\n     */\n    function reduceRight(collection, iteratee, accumulator) {\n      var func = isArray(collection) ? arrayReduceRight : baseReduce,\n          initAccum = arguments.length < 3;\n\n      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);\n    }\n\n    /**\n     * The opposite of `_.filter`; this method returns the elements of `collection`\n     * that `predicate` does **not** return truthy for.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     * @see _.filter\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': false },\n     *   { 'user': 'fred',   'age': 40, 'active': true }\n     * ];\n     *\n     * _.reject(users, function(o) { return !o.active; });\n     * // => objects for ['fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.reject(users, { 'age': 40, 'active': true });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.reject(users, ['active', false]);\n     * // => objects for ['fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.reject(users, 'active');\n     * // => objects for ['barney']\n     */\n    function reject(collection, predicate) {\n      var func = isArray(collection) ? arrayFilter : baseFilter;\n      return func(collection, negate(getIteratee(predicate, 3)));\n    }\n\n    /**\n     * Gets a random element from `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to sample.\n     * @returns {*} Returns the random element.\n     * @example\n     *\n     * _.sample([1, 2, 3, 4]);\n     * // => 2\n     */\n    function sample(collection) {\n      var func = isArray(collection) ? arraySample : baseSample;\n      return func(collection);\n    }\n\n    /**\n     * Gets `n` random elements at unique keys from `collection` up to the\n     * size of `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to sample.\n     * @param {number} [n=1] The number of elements to sample.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the random elements.\n     * @example\n     *\n     * _.sampleSize([1, 2, 3], 2);\n     * // => [3, 1]\n     *\n     * _.sampleSize([1, 2, 3], 4);\n     * // => [2, 3, 1]\n     */\n    function sampleSize(collection, n, guard) {\n      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {\n        n = 1;\n      } else {\n        n = toInteger(n);\n      }\n      var func = isArray(collection) ? arraySampleSize : baseSampleSize;\n      return func(collection, n);\n    }\n\n    /**\n     * Creates an array of shuffled values, using a version of the\n     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     * @example\n     *\n     * _.shuffle([1, 2, 3, 4]);\n     * // => [4, 1, 3, 2]\n     */\n    function shuffle(collection) {\n      var func = isArray(collection) ? arrayShuffle : baseShuffle;\n      return func(collection);\n    }\n\n    /**\n     * Gets the size of `collection` by returning its length for array-like\n     * values or the number of own enumerable string keyed properties for objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to inspect.\n     * @returns {number} Returns the collection size.\n     * @example\n     *\n     * _.size([1, 2, 3]);\n     * // => 3\n     *\n     * _.size({ 'a': 1, 'b': 2 });\n     * // => 2\n     *\n     * _.size('pebbles');\n     * // => 7\n     */\n    function size(collection) {\n      if (collection == null) {\n        return 0;\n      }\n      if (isArrayLike(collection)) {\n        return isString(collection) ? stringSize(collection) : collection.length;\n      }\n      var tag = getTag(collection);\n      if (tag == mapTag || tag == setTag) {\n        return collection.size;\n      }\n      return baseKeys(collection).length;\n    }\n\n    /**\n     * Checks if `predicate` returns truthy for **any** element of `collection`.\n     * Iteration is stopped once `predicate` returns truthy. The predicate is\n     * invoked with three arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     * @example\n     *\n     * _.some([null, 0, 'yes', false], Boolean);\n     * // => true\n     *\n     * var users = [\n     *   { 'user': 'barney', 'active': true },\n     *   { 'user': 'fred',   'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.some(users, { 'user': 'barney', 'active': false });\n     * // => false\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.some(users, ['active', false]);\n     * // => true\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.some(users, 'active');\n     * // => true\n     */\n    function some(collection, predicate, guard) {\n      var func = isArray(collection) ? arraySome : baseSome;\n      if (guard && isIterateeCall(collection, predicate, guard)) {\n        predicate = undefined;\n      }\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Creates an array of elements, sorted in ascending order by the results of\n     * running each element in a collection thru each iteratee. This method\n     * performs a stable sort, that is, it preserves the original sort order of\n     * equal elements. The iteratees are invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {...(Function|Function[])} [iteratees=[_.identity]]\n     *  The iteratees to sort by.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'fred',   'age': 48 },\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 },\n     *   { 'user': 'barney', 'age': 34 }\n     * ];\n     *\n     * _.sortBy(users, [function(o) { return o.user; }]);\n     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n     *\n     * _.sortBy(users, ['user', 'age']);\n     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]\n     */\n    var sortBy = baseRest(function(collection, iteratees) {\n      if (collection == null) {\n        return [];\n      }\n      var length = iteratees.length;\n      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n        iteratees = [];\n      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n        iteratees = [iteratees[0]];\n      }\n      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n    });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Gets the timestamp of the number of milliseconds that have elapsed since\n     * the Unix epoch (1 January 1970 00:00:00 UTC).\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Date\n     * @returns {number} Returns the timestamp.\n     * @example\n     *\n     * _.defer(function(stamp) {\n     *   console.log(_.now() - stamp);\n     * }, _.now());\n     * // => Logs the number of milliseconds it took for the deferred invocation.\n     */\n    var now = ctxNow || function() {\n      return root.Date.now();\n    };\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * The opposite of `_.before`; this method creates a function that invokes\n     * `func` once it's called `n` or more times.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {number} n The number of calls before `func` is invoked.\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * var saves = ['profile', 'settings'];\n     *\n     * var done = _.after(saves.length, function() {\n     *   console.log('done saving!');\n     * });\n     *\n     * _.forEach(saves, function(type) {\n     *   asyncSave({ 'type': type, 'complete': done });\n     * });\n     * // => Logs 'done saving!' after the two async saves have completed.\n     */\n    function after(n, func) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      n = toInteger(n);\n      return function() {\n        if (--n < 1) {\n          return func.apply(this, arguments);\n        }\n      };\n    }\n\n    /**\n     * Creates a function that invokes `func`, with up to `n` arguments,\n     * ignoring any additional arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to cap arguments for.\n     * @param {number} [n=func.length] The arity cap.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new capped function.\n     * @example\n     *\n     * _.map(['6', '8', '10'], _.ary(parseInt, 1));\n     * // => [6, 8, 10]\n     */\n    function ary(func, n, guard) {\n      n = guard ? undefined : n;\n      n = (func && n == null) ? func.length : n;\n      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);\n    }\n\n    /**\n     * Creates a function that invokes `func`, with the `this` binding and arguments\n     * of the created function, while it's called less than `n` times. Subsequent\n     * calls to the created function return the result of the last `func` invocation.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {number} n The number of calls at which `func` is no longer invoked.\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * jQuery(element).on('click', _.before(5, addContactToList));\n     * // => Allows adding up to 4 contacts to the list.\n     */\n    function before(n, func) {\n      var result;\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      n = toInteger(n);\n      return function() {\n        if (--n > 0) {\n          result = func.apply(this, arguments);\n        }\n        if (n <= 1) {\n          func = undefined;\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of `thisArg`\n     * and `partials` prepended to the arguments it receives.\n     *\n     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,\n     * may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** Unlike native `Function#bind`, this method doesn't set the \"length\"\n     * property of bound functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to bind.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new bound function.\n     * @example\n     *\n     * function greet(greeting, punctuation) {\n     *   return greeting + ' ' + this.user + punctuation;\n     * }\n     *\n     * var object = { 'user': 'fred' };\n     *\n     * var bound = _.bind(greet, object, 'hi');\n     * bound('!');\n     * // => 'hi fred!'\n     *\n     * // Bound with placeholders.\n     * var bound = _.bind(greet, object, _, '!');\n     * bound('hi');\n     * // => 'hi fred!'\n     */\n    var bind = baseRest(function(func, thisArg, partials) {\n      var bitmask = WRAP_BIND_FLAG;\n      if (partials.length) {\n        var holders = replaceHolders(partials, getHolder(bind));\n        bitmask |= WRAP_PARTIAL_FLAG;\n      }\n      return createWrap(func, bitmask, thisArg, partials, holders);\n    });\n\n    /**\n     * Creates a function that invokes the method at `object[key]` with `partials`\n     * prepended to the arguments it receives.\n     *\n     * This method differs from `_.bind` by allowing bound functions to reference\n     * methods that may be redefined or don't yet exist. See\n     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)\n     * for more details.\n     *\n     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.10.0\n     * @category Function\n     * @param {Object} object The object to invoke the method on.\n     * @param {string} key The key of the method.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new bound function.\n     * @example\n     *\n     * var object = {\n     *   'user': 'fred',\n     *   'greet': function(greeting, punctuation) {\n     *     return greeting + ' ' + this.user + punctuation;\n     *   }\n     * };\n     *\n     * var bound = _.bindKey(object, 'greet', 'hi');\n     * bound('!');\n     * // => 'hi fred!'\n     *\n     * object.greet = function(greeting, punctuation) {\n     *   return greeting + 'ya ' + this.user + punctuation;\n     * };\n     *\n     * bound('!');\n     * // => 'hiya fred!'\n     *\n     * // Bound with placeholders.\n     * var bound = _.bindKey(object, 'greet', _, '!');\n     * bound('hi');\n     * // => 'hiya fred!'\n     */\n    var bindKey = baseRest(function(object, key, partials) {\n      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;\n      if (partials.length) {\n        var holders = replaceHolders(partials, getHolder(bindKey));\n        bitmask |= WRAP_PARTIAL_FLAG;\n      }\n      return createWrap(key, bitmask, object, partials, holders);\n    });\n\n    /**\n     * Creates a function that accepts arguments of `func` and either invokes\n     * `func` returning its result, if at least `arity` number of arguments have\n     * been provided, or returns a function that accepts the remaining `func`\n     * arguments, and so on. The arity of `func` may be specified if `func.length`\n     * is not sufficient.\n     *\n     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,\n     * may be used as a placeholder for provided arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of curried functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Function\n     * @param {Function} func The function to curry.\n     * @param {number} [arity=func.length] The arity of `func`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new curried function.\n     * @example\n     *\n     * var abc = function(a, b, c) {\n     *   return [a, b, c];\n     * };\n     *\n     * var curried = _.curry(abc);\n     *\n     * curried(1)(2)(3);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2)(3);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2, 3);\n     * // => [1, 2, 3]\n     *\n     * // Curried with placeholders.\n     * curried(1)(_, 3)(2);\n     * // => [1, 2, 3]\n     */\n    function curry(func, arity, guard) {\n      arity = guard ? undefined : arity;\n      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n      result.placeholder = curry.placeholder;\n      return result;\n    }\n\n    /**\n     * This method is like `_.curry` except that arguments are applied to `func`\n     * in the manner of `_.partialRight` instead of `_.partial`.\n     *\n     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for provided arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of curried functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to curry.\n     * @param {number} [arity=func.length] The arity of `func`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new curried function.\n     * @example\n     *\n     * var abc = function(a, b, c) {\n     *   return [a, b, c];\n     * };\n     *\n     * var curried = _.curryRight(abc);\n     *\n     * curried(3)(2)(1);\n     * // => [1, 2, 3]\n     *\n     * curried(2, 3)(1);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2, 3);\n     * // => [1, 2, 3]\n     *\n     * // Curried with placeholders.\n     * curried(3)(1, _)(2);\n     * // => [1, 2, 3]\n     */\n    function curryRight(func, arity, guard) {\n      arity = guard ? undefined : arity;\n      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n      result.placeholder = curryRight.placeholder;\n      return result;\n    }\n\n    /**\n     * Creates a debounced function that delays invoking `func` until after `wait`\n     * milliseconds have elapsed since the last time the debounced function was\n     * invoked. The debounced function comes with a `cancel` method to cancel\n     * delayed `func` invocations and a `flush` method to immediately invoke them.\n     * Provide `options` to indicate whether `func` should be invoked on the\n     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n     * with the last arguments provided to the debounced function. Subsequent\n     * calls to the debounced function return the result of the last `func`\n     * invocation.\n     *\n     * **Note:** If `leading` and `trailing` options are `true`, `func` is\n     * invoked on the trailing edge of the timeout only if the debounced function\n     * is invoked more than once during the `wait` timeout.\n     *\n     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n     * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n     *\n     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n     * for details over the differences between `_.debounce` and `_.throttle`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to debounce.\n     * @param {number} [wait=0] The number of milliseconds to delay.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.leading=false]\n     *  Specify invoking on the leading edge of the timeout.\n     * @param {number} [options.maxWait]\n     *  The maximum time `func` is allowed to be delayed before it's invoked.\n     * @param {boolean} [options.trailing=true]\n     *  Specify invoking on the trailing edge of the timeout.\n     * @returns {Function} Returns the new debounced function.\n     * @example\n     *\n     * // Avoid costly calculations while the window size is in flux.\n     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n     *\n     * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n     * jQuery(element).on('click', _.debounce(sendMail, 300, {\n     *   'leading': true,\n     *   'trailing': false\n     * }));\n     *\n     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n     * var source = new EventSource('/stream');\n     * jQuery(source).on('message', debounced);\n     *\n     * // Cancel the trailing debounced invocation.\n     * jQuery(window).on('popstate', debounced.cancel);\n     */\n    function debounce(func, wait, options) {\n      var lastArgs,\n          lastThis,\n          maxWait,\n          result,\n          timerId,\n          lastCallTime,\n          lastInvokeTime = 0,\n          leading = false,\n          maxing = false,\n          trailing = true;\n\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      wait = toNumber(wait) || 0;\n      if (isObject(options)) {\n        leading = !!options.leading;\n        maxing = 'maxWait' in options;\n        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n        trailing = 'trailing' in options ? !!options.trailing : trailing;\n      }\n\n      function invokeFunc(time) {\n        var args = lastArgs,\n            thisArg = lastThis;\n\n        lastArgs = lastThis = undefined;\n        lastInvokeTime = time;\n        result = func.apply(thisArg, args);\n        return result;\n      }\n\n      function leadingEdge(time) {\n        // Reset any `maxWait` timer.\n        lastInvokeTime = time;\n        // Start the timer for the trailing edge.\n        timerId = setTimeout(timerExpired, wait);\n        // Invoke the leading edge.\n        return leading ? invokeFunc(time) : result;\n      }\n\n      function remainingWait(time) {\n        var timeSinceLastCall = time - lastCallTime,\n            timeSinceLastInvoke = time - lastInvokeTime,\n            result = wait - timeSinceLastCall;\n\n        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n      }\n\n      function shouldInvoke(time) {\n        var timeSinceLastCall = time - lastCallTime,\n            timeSinceLastInvoke = time - lastInvokeTime;\n\n        // Either this is the first call, activity has stopped and we're at the\n        // trailing edge, the system time has gone backwards and we're treating\n        // it as the trailing edge, or we've hit the `maxWait` limit.\n        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n      }\n\n      function timerExpired() {\n        var time = now();\n        if (shouldInvoke(time)) {\n          return trailingEdge(time);\n        }\n        // Restart the timer.\n        timerId = setTimeout(timerExpired, remainingWait(time));\n      }\n\n      function trailingEdge(time) {\n        timerId = undefined;\n\n        // Only invoke if we have `lastArgs` which means `func` has been\n        // debounced at least once.\n        if (trailing && lastArgs) {\n          return invokeFunc(time);\n        }\n        lastArgs = lastThis = undefined;\n        return result;\n      }\n\n      function cancel() {\n        if (timerId !== undefined) {\n          clearTimeout(timerId);\n        }\n        lastInvokeTime = 0;\n        lastArgs = lastCallTime = lastThis = timerId = undefined;\n      }\n\n      function flush() {\n        return timerId === undefined ? result : trailingEdge(now());\n      }\n\n      function debounced() {\n        var time = now(),\n            isInvoking = shouldInvoke(time);\n\n        lastArgs = arguments;\n        lastThis = this;\n        lastCallTime = time;\n\n        if (isInvoking) {\n          if (timerId === undefined) {\n            return leadingEdge(lastCallTime);\n          }\n          if (maxing) {\n            // Handle invocations in a tight loop.\n            timerId = setTimeout(timerExpired, wait);\n            return invokeFunc(lastCallTime);\n          }\n        }\n        if (timerId === undefined) {\n          timerId = setTimeout(timerExpired, wait);\n        }\n        return result;\n      }\n      debounced.cancel = cancel;\n      debounced.flush = flush;\n      return debounced;\n    }\n\n    /**\n     * Defers invoking the `func` until the current call stack has cleared. Any\n     * additional arguments are provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to defer.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {number} Returns the timer id.\n     * @example\n     *\n     * _.defer(function(text) {\n     *   console.log(text);\n     * }, 'deferred');\n     * // => Logs 'deferred' after one millisecond.\n     */\n    var defer = baseRest(function(func, args) {\n      return baseDelay(func, 1, args);\n    });\n\n    /**\n     * Invokes `func` after `wait` milliseconds. Any additional arguments are\n     * provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {number} Returns the timer id.\n     * @example\n     *\n     * _.delay(function(text) {\n     *   console.log(text);\n     * }, 1000, 'later');\n     * // => Logs 'later' after one second.\n     */\n    var delay = baseRest(function(func, wait, args) {\n      return baseDelay(func, toNumber(wait) || 0, args);\n    });\n\n    /**\n     * Creates a function that invokes `func` with arguments reversed.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to flip arguments for.\n     * @returns {Function} Returns the new flipped function.\n     * @example\n     *\n     * var flipped = _.flip(function() {\n     *   return _.toArray(arguments);\n     * });\n     *\n     * flipped('a', 'b', 'c', 'd');\n     * // => ['d', 'c', 'b', 'a']\n     */\n    function flip(func) {\n      return createWrap(func, WRAP_FLIP_FLAG);\n    }\n\n    /**\n     * Creates a function that memoizes the result of `func`. If `resolver` is\n     * provided, it determines the cache key for storing the result based on the\n     * arguments provided to the memoized function. By default, the first argument\n     * provided to the memoized function is used as the map cache key. The `func`\n     * is invoked with the `this` binding of the memoized function.\n     *\n     * **Note:** The cache is exposed as the `cache` property on the memoized\n     * function. Its creation may be customized by replacing the `_.memoize.Cache`\n     * constructor with one whose instances implement the\n     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n     * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to have its output memoized.\n     * @param {Function} [resolver] The function to resolve the cache key.\n     * @returns {Function} Returns the new memoized function.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     * var other = { 'c': 3, 'd': 4 };\n     *\n     * var values = _.memoize(_.values);\n     * values(object);\n     * // => [1, 2]\n     *\n     * values(other);\n     * // => [3, 4]\n     *\n     * object.a = 2;\n     * values(object);\n     * // => [1, 2]\n     *\n     * // Modify the result cache.\n     * values.cache.set(object, ['a', 'b']);\n     * values(object);\n     * // => ['a', 'b']\n     *\n     * // Replace `_.memoize.Cache`.\n     * _.memoize.Cache = WeakMap;\n     */\n    function memoize(func, resolver) {\n      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var memoized = function() {\n        var args = arguments,\n            key = resolver ? resolver.apply(this, args) : args[0],\n            cache = memoized.cache;\n\n        if (cache.has(key)) {\n          return cache.get(key);\n        }\n        var result = func.apply(this, args);\n        memoized.cache = cache.set(key, result) || cache;\n        return result;\n      };\n      memoized.cache = new (memoize.Cache || MapCache);\n      return memoized;\n    }\n\n    // Expose `MapCache`.\n    memoize.Cache = MapCache;\n\n    /**\n     * Creates a function that negates the result of the predicate `func`. The\n     * `func` predicate is invoked with the `this` binding and arguments of the\n     * created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} predicate The predicate to negate.\n     * @returns {Function} Returns the new negated function.\n     * @example\n     *\n     * function isEven(n) {\n     *   return n % 2 == 0;\n     * }\n     *\n     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n     * // => [1, 3, 5]\n     */\n    function negate(predicate) {\n      if (typeof predicate != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return function() {\n        var args = arguments;\n        switch (args.length) {\n          case 0: return !predicate.call(this);\n          case 1: return !predicate.call(this, args[0]);\n          case 2: return !predicate.call(this, args[0], args[1]);\n          case 3: return !predicate.call(this, args[0], args[1], args[2]);\n        }\n        return !predicate.apply(this, args);\n      };\n    }\n\n    /**\n     * Creates a function that is restricted to invoking `func` once. Repeat calls\n     * to the function return the value of the first invocation. The `func` is\n     * invoked with the `this` binding and arguments of the created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * var initialize = _.once(createApplication);\n     * initialize();\n     * initialize();\n     * // => `createApplication` is invoked once\n     */\n    function once(func) {\n      return before(2, func);\n    }\n\n    /**\n     * Creates a function that invokes `func` with its arguments transformed.\n     *\n     * @static\n     * @since 4.0.0\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to wrap.\n     * @param {...(Function|Function[])} [transforms=[_.identity]]\n     *  The argument transforms.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * function doubled(n) {\n     *   return n * 2;\n     * }\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var func = _.overArgs(function(x, y) {\n     *   return [x, y];\n     * }, [square, doubled]);\n     *\n     * func(9, 3);\n     * // => [81, 6]\n     *\n     * func(10, 5);\n     * // => [100, 10]\n     */\n    var overArgs = castRest(function(func, transforms) {\n      transforms = (transforms.length == 1 && isArray(transforms[0]))\n        ? arrayMap(transforms[0], baseUnary(getIteratee()))\n        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));\n\n      var funcsLength = transforms.length;\n      return baseRest(function(args) {\n        var index = -1,\n            length = nativeMin(args.length, funcsLength);\n\n        while (++index < length) {\n          args[index] = transforms[index].call(this, args[index]);\n        }\n        return apply(func, this, args);\n      });\n    });\n\n    /**\n     * Creates a function that invokes `func` with `partials` prepended to the\n     * arguments it receives. This method is like `_.bind` except it does **not**\n     * alter the `this` binding.\n     *\n     * The `_.partial.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of partially\n     * applied functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.2.0\n     * @category Function\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new partially applied function.\n     * @example\n     *\n     * function greet(greeting, name) {\n     *   return greeting + ' ' + name;\n     * }\n     *\n     * var sayHelloTo = _.partial(greet, 'hello');\n     * sayHelloTo('fred');\n     * // => 'hello fred'\n     *\n     * // Partially applied with placeholders.\n     * var greetFred = _.partial(greet, _, 'fred');\n     * greetFred('hi');\n     * // => 'hi fred'\n     */\n    var partial = baseRest(function(func, partials) {\n      var holders = replaceHolders(partials, getHolder(partial));\n      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);\n    });\n\n    /**\n     * This method is like `_.partial` except that partially applied arguments\n     * are appended to the arguments it receives.\n     *\n     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of partially\n     * applied functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Function\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new partially applied function.\n     * @example\n     *\n     * function greet(greeting, name) {\n     *   return greeting + ' ' + name;\n     * }\n     *\n     * var greetFred = _.partialRight(greet, 'fred');\n     * greetFred('hi');\n     * // => 'hi fred'\n     *\n     * // Partially applied with placeholders.\n     * var sayHelloTo = _.partialRight(greet, 'hello', _);\n     * sayHelloTo('fred');\n     * // => 'hello fred'\n     */\n    var partialRight = baseRest(function(func, partials) {\n      var holders = replaceHolders(partials, getHolder(partialRight));\n      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);\n    });\n\n    /**\n     * Creates a function that invokes `func` with arguments arranged according\n     * to the specified `indexes` where the argument value at the first index is\n     * provided as the first argument, the argument value at the second index is\n     * provided as the second argument, and so on.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to rearrange arguments for.\n     * @param {...(number|number[])} indexes The arranged argument indexes.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var rearged = _.rearg(function(a, b, c) {\n     *   return [a, b, c];\n     * }, [2, 0, 1]);\n     *\n     * rearged('b', 'c', 'a')\n     * // => ['a', 'b', 'c']\n     */\n    var rearg = flatRest(function(func, indexes) {\n      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);\n    });\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of the\n     * created function and arguments from `start` and beyond provided as\n     * an array.\n     *\n     * **Note:** This method is based on the\n     * [rest parameter](https://mdn.io/rest_parameters).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var say = _.rest(function(what, names) {\n     *   return what + ' ' + _.initial(names).join(', ') +\n     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n     * });\n     *\n     * say('hello', 'fred', 'barney', 'pebbles');\n     * // => 'hello fred, barney, & pebbles'\n     */\n    function rest(func, start) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      start = start === undefined ? start : toInteger(start);\n      return baseRest(func, start);\n    }\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of the\n     * create function and an array of arguments much like\n     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).\n     *\n     * **Note:** This method is based on the\n     * [spread operator](https://mdn.io/spread_operator).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Function\n     * @param {Function} func The function to spread arguments over.\n     * @param {number} [start=0] The start position of the spread.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var say = _.spread(function(who, what) {\n     *   return who + ' says ' + what;\n     * });\n     *\n     * say(['fred', 'hello']);\n     * // => 'fred says hello'\n     *\n     * var numbers = Promise.all([\n     *   Promise.resolve(40),\n     *   Promise.resolve(36)\n     * ]);\n     *\n     * numbers.then(_.spread(function(x, y) {\n     *   return x + y;\n     * }));\n     * // => a Promise of 76\n     */\n    function spread(func, start) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      start = start == null ? 0 : nativeMax(toInteger(start), 0);\n      return baseRest(function(args) {\n        var array = args[start],\n            otherArgs = castSlice(args, 0, start);\n\n        if (array) {\n          arrayPush(otherArgs, array);\n        }\n        return apply(func, this, otherArgs);\n      });\n    }\n\n    /**\n     * Creates a throttled function that only invokes `func` at most once per\n     * every `wait` milliseconds. The throttled function comes with a `cancel`\n     * method to cancel delayed `func` invocations and a `flush` method to\n     * immediately invoke them. Provide `options` to indicate whether `func`\n     * should be invoked on the leading and/or trailing edge of the `wait`\n     * timeout. The `func` is invoked with the last arguments provided to the\n     * throttled function. Subsequent calls to the throttled function return the\n     * result of the last `func` invocation.\n     *\n     * **Note:** If `leading` and `trailing` options are `true`, `func` is\n     * invoked on the trailing edge of the timeout only if the throttled function\n     * is invoked more than once during the `wait` timeout.\n     *\n     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n     * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n     *\n     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n     * for details over the differences between `_.throttle` and `_.debounce`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to throttle.\n     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.leading=true]\n     *  Specify invoking on the leading edge of the timeout.\n     * @param {boolean} [options.trailing=true]\n     *  Specify invoking on the trailing edge of the timeout.\n     * @returns {Function} Returns the new throttled function.\n     * @example\n     *\n     * // Avoid excessively updating the position while scrolling.\n     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n     *\n     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n     * jQuery(element).on('click', throttled);\n     *\n     * // Cancel the trailing throttled invocation.\n     * jQuery(window).on('popstate', throttled.cancel);\n     */\n    function throttle(func, wait, options) {\n      var leading = true,\n          trailing = true;\n\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      if (isObject(options)) {\n        leading = 'leading' in options ? !!options.leading : leading;\n        trailing = 'trailing' in options ? !!options.trailing : trailing;\n      }\n      return debounce(func, wait, {\n        'leading': leading,\n        'maxWait': wait,\n        'trailing': trailing\n      });\n    }\n\n    /**\n     * Creates a function that accepts up to one argument, ignoring any\n     * additional arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to cap arguments for.\n     * @returns {Function} Returns the new capped function.\n     * @example\n     *\n     * _.map(['6', '8', '10'], _.unary(parseInt));\n     * // => [6, 8, 10]\n     */\n    function unary(func) {\n      return ary(func, 1);\n    }\n\n    /**\n     * Creates a function that provides `value` to `wrapper` as its first\n     * argument. Any additional arguments provided to the function are appended\n     * to those provided to the `wrapper`. The wrapper is invoked with the `this`\n     * binding of the created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {*} value The value to wrap.\n     * @param {Function} [wrapper=identity] The wrapper function.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var p = _.wrap(_.escape, function(func, text) {\n     *   return '<p>' + func(text) + '</p>';\n     * });\n     *\n     * p('fred, barney, & pebbles');\n     * // => '<p>fred, barney, &amp; pebbles</p>'\n     */\n    function wrap(value, wrapper) {\n      return partial(castFunction(wrapper), value);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Casts `value` as an array if it's not one.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.4.0\n     * @category Lang\n     * @param {*} value The value to inspect.\n     * @returns {Array} Returns the cast array.\n     * @example\n     *\n     * _.castArray(1);\n     * // => [1]\n     *\n     * _.castArray({ 'a': 1 });\n     * // => [{ 'a': 1 }]\n     *\n     * _.castArray('abc');\n     * // => ['abc']\n     *\n     * _.castArray(null);\n     * // => [null]\n     *\n     * _.castArray(undefined);\n     * // => [undefined]\n     *\n     * _.castArray();\n     * // => []\n     *\n     * var array = [1, 2, 3];\n     * console.log(_.castArray(array) === array);\n     * // => true\n     */\n    function castArray() {\n      if (!arguments.length) {\n        return [];\n      }\n      var value = arguments[0];\n      return isArray(value) ? value : [value];\n    }\n\n    /**\n     * Creates a shallow clone of `value`.\n     *\n     * **Note:** This method is loosely based on the\n     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n     * and supports cloning arrays, array buffers, booleans, date objects, maps,\n     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n     * arrays. The own enumerable properties of `arguments` objects are cloned\n     * as plain objects. An empty object is returned for uncloneable values such\n     * as error objects, functions, DOM nodes, and WeakMaps.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to clone.\n     * @returns {*} Returns the cloned value.\n     * @see _.cloneDeep\n     * @example\n     *\n     * var objects = [{ 'a': 1 }, { 'b': 2 }];\n     *\n     * var shallow = _.clone(objects);\n     * console.log(shallow[0] === objects[0]);\n     * // => true\n     */\n    function clone(value) {\n      return baseClone(value, CLONE_SYMBOLS_FLAG);\n    }\n\n    /**\n     * This method is like `_.clone` except that it accepts `customizer` which\n     * is invoked to produce the cloned value. If `customizer` returns `undefined`,\n     * cloning is handled by the method instead. The `customizer` is invoked with\n     * up to four arguments; (value [, index|key, object, stack]).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to clone.\n     * @param {Function} [customizer] The function to customize cloning.\n     * @returns {*} Returns the cloned value.\n     * @see _.cloneDeepWith\n     * @example\n     *\n     * function customizer(value) {\n     *   if (_.isElement(value)) {\n     *     return value.cloneNode(false);\n     *   }\n     * }\n     *\n     * var el = _.cloneWith(document.body, customizer);\n     *\n     * console.log(el === document.body);\n     * // => false\n     * console.log(el.nodeName);\n     * // => 'BODY'\n     * console.log(el.childNodes.length);\n     * // => 0\n     */\n    function cloneWith(value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);\n    }\n\n    /**\n     * This method is like `_.clone` except that it recursively clones `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Lang\n     * @param {*} value The value to recursively clone.\n     * @returns {*} Returns the deep cloned value.\n     * @see _.clone\n     * @example\n     *\n     * var objects = [{ 'a': 1 }, { 'b': 2 }];\n     *\n     * var deep = _.cloneDeep(objects);\n     * console.log(deep[0] === objects[0]);\n     * // => false\n     */\n    function cloneDeep(value) {\n      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n    }\n\n    /**\n     * This method is like `_.cloneWith` except that it recursively clones `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to recursively clone.\n     * @param {Function} [customizer] The function to customize cloning.\n     * @returns {*} Returns the deep cloned value.\n     * @see _.cloneWith\n     * @example\n     *\n     * function customizer(value) {\n     *   if (_.isElement(value)) {\n     *     return value.cloneNode(true);\n     *   }\n     * }\n     *\n     * var el = _.cloneDeepWith(document.body, customizer);\n     *\n     * console.log(el === document.body);\n     * // => false\n     * console.log(el.nodeName);\n     * // => 'BODY'\n     * console.log(el.childNodes.length);\n     * // => 20\n     */\n    function cloneDeepWith(value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n    }\n\n    /**\n     * Checks if `object` conforms to `source` by invoking the predicate\n     * properties of `source` with the corresponding property values of `object`.\n     *\n     * **Note:** This method is equivalent to `_.conforms` when `source` is\n     * partially applied.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.14.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     *\n     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });\n     * // => true\n     *\n     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });\n     * // => false\n     */\n    function conformsTo(object, source) {\n      return source == null || baseConformsTo(object, source, keys(source));\n    }\n\n    /**\n     * Performs a\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * comparison between two values to determine if they are equivalent.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     * var other = { 'a': 1 };\n     *\n     * _.eq(object, object);\n     * // => true\n     *\n     * _.eq(object, other);\n     * // => false\n     *\n     * _.eq('a', 'a');\n     * // => true\n     *\n     * _.eq('a', Object('a'));\n     * // => false\n     *\n     * _.eq(NaN, NaN);\n     * // => true\n     */\n    function eq(value, other) {\n      return value === other || (value !== value && other !== other);\n    }\n\n    /**\n     * Checks if `value` is greater than `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than `other`,\n     *  else `false`.\n     * @see _.lt\n     * @example\n     *\n     * _.gt(3, 1);\n     * // => true\n     *\n     * _.gt(3, 3);\n     * // => false\n     *\n     * _.gt(1, 3);\n     * // => false\n     */\n    var gt = createRelationalOperation(baseGt);\n\n    /**\n     * Checks if `value` is greater than or equal to `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than or equal to\n     *  `other`, else `false`.\n     * @see _.lte\n     * @example\n     *\n     * _.gte(3, 1);\n     * // => true\n     *\n     * _.gte(3, 3);\n     * // => true\n     *\n     * _.gte(1, 3);\n     * // => false\n     */\n    var gte = createRelationalOperation(function(value, other) {\n      return value >= other;\n    });\n\n    /**\n     * Checks if `value` is likely an `arguments` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n     *  else `false`.\n     * @example\n     *\n     * _.isArguments(function() { return arguments; }());\n     * // => true\n     *\n     * _.isArguments([1, 2, 3]);\n     * // => false\n     */\n    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n        !propertyIsEnumerable.call(value, 'callee');\n    };\n\n    /**\n     * Checks if `value` is classified as an `Array` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n     * @example\n     *\n     * _.isArray([1, 2, 3]);\n     * // => true\n     *\n     * _.isArray(document.body.children);\n     * // => false\n     *\n     * _.isArray('abc');\n     * // => false\n     *\n     * _.isArray(_.noop);\n     * // => false\n     */\n    var isArray = Array.isArray;\n\n    /**\n     * Checks if `value` is classified as an `ArrayBuffer` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n     * @example\n     *\n     * _.isArrayBuffer(new ArrayBuffer(2));\n     * // => true\n     *\n     * _.isArrayBuffer(new Array(2));\n     * // => false\n     */\n    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;\n\n    /**\n     * Checks if `value` is array-like. A value is considered array-like if it's\n     * not a function and has a `value.length` that's an integer greater than or\n     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n     * @example\n     *\n     * _.isArrayLike([1, 2, 3]);\n     * // => true\n     *\n     * _.isArrayLike(document.body.children);\n     * // => true\n     *\n     * _.isArrayLike('abc');\n     * // => true\n     *\n     * _.isArrayLike(_.noop);\n     * // => false\n     */\n    function isArrayLike(value) {\n      return value != null && isLength(value.length) && !isFunction(value);\n    }\n\n    /**\n     * This method is like `_.isArrayLike` except that it also checks if `value`\n     * is an object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array-like object,\n     *  else `false`.\n     * @example\n     *\n     * _.isArrayLikeObject([1, 2, 3]);\n     * // => true\n     *\n     * _.isArrayLikeObject(document.body.children);\n     * // => true\n     *\n     * _.isArrayLikeObject('abc');\n     * // => false\n     *\n     * _.isArrayLikeObject(_.noop);\n     * // => false\n     */\n    function isArrayLikeObject(value) {\n      return isObjectLike(value) && isArrayLike(value);\n    }\n\n    /**\n     * Checks if `value` is classified as a boolean primitive or object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.\n     * @example\n     *\n     * _.isBoolean(false);\n     * // => true\n     *\n     * _.isBoolean(null);\n     * // => false\n     */\n    function isBoolean(value) {\n      return value === true || value === false ||\n        (isObjectLike(value) && baseGetTag(value) == boolTag);\n    }\n\n    /**\n     * Checks if `value` is a buffer.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n     * @example\n     *\n     * _.isBuffer(new Buffer(2));\n     * // => true\n     *\n     * _.isBuffer(new Uint8Array(2));\n     * // => false\n     */\n    var isBuffer = nativeIsBuffer || stubFalse;\n\n    /**\n     * Checks if `value` is classified as a `Date` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n     * @example\n     *\n     * _.isDate(new Date);\n     * // => true\n     *\n     * _.isDate('Mon April 23 2012');\n     * // => false\n     */\n    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;\n\n    /**\n     * Checks if `value` is likely a DOM element.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n     * @example\n     *\n     * _.isElement(document.body);\n     * // => true\n     *\n     * _.isElement('<body>');\n     * // => false\n     */\n    function isElement(value) {\n      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);\n    }\n\n    /**\n     * Checks if `value` is an empty object, collection, map, or set.\n     *\n     * Objects are considered empty if they have no own enumerable string keyed\n     * properties.\n     *\n     * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n     * jQuery-like collections are considered empty if they have a `length` of `0`.\n     * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n     * @example\n     *\n     * _.isEmpty(null);\n     * // => true\n     *\n     * _.isEmpty(true);\n     * // => true\n     *\n     * _.isEmpty(1);\n     * // => true\n     *\n     * _.isEmpty([1, 2, 3]);\n     * // => false\n     *\n     * _.isEmpty({ 'a': 1 });\n     * // => false\n     */\n    function isEmpty(value) {\n      if (value == null) {\n        return true;\n      }\n      if (isArrayLike(value) &&\n          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n            isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n        return !value.length;\n      }\n      var tag = getTag(value);\n      if (tag == mapTag || tag == setTag) {\n        return !value.size;\n      }\n      if (isPrototype(value)) {\n        return !baseKeys(value).length;\n      }\n      for (var key in value) {\n        if (hasOwnProperty.call(value, key)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * Performs a deep comparison between two values to determine if they are\n     * equivalent.\n     *\n     * **Note:** This method supports comparing arrays, array buffers, booleans,\n     * date objects, error objects, maps, numbers, `Object` objects, regexes,\n     * sets, strings, symbols, and typed arrays. `Object` objects are compared\n     * by their own, not inherited, enumerable properties. Functions and DOM\n     * nodes are compared by strict equality, i.e. `===`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     * var other = { 'a': 1 };\n     *\n     * _.isEqual(object, other);\n     * // => true\n     *\n     * object === other;\n     * // => false\n     */\n    function isEqual(value, other) {\n      return baseIsEqual(value, other);\n    }\n\n    /**\n     * This method is like `_.isEqual` except that it accepts `customizer` which\n     * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n     * are handled by the method instead. The `customizer` is invoked with up to\n     * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * function isGreeting(value) {\n     *   return /^h(?:i|ello)$/.test(value);\n     * }\n     *\n     * function customizer(objValue, othValue) {\n     *   if (isGreeting(objValue) && isGreeting(othValue)) {\n     *     return true;\n     *   }\n     * }\n     *\n     * var array = ['hello', 'goodbye'];\n     * var other = ['hi', 'goodbye'];\n     *\n     * _.isEqualWith(array, other, customizer);\n     * // => true\n     */\n    function isEqualWith(value, other, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      var result = customizer ? customizer(value, other) : undefined;\n      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;\n    }\n\n    /**\n     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,\n     * `SyntaxError`, `TypeError`, or `URIError` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.\n     * @example\n     *\n     * _.isError(new Error);\n     * // => true\n     *\n     * _.isError(Error);\n     * // => false\n     */\n    function isError(value) {\n      if (!isObjectLike(value)) {\n        return false;\n      }\n      var tag = baseGetTag(value);\n      return tag == errorTag || tag == domExcTag ||\n        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));\n    }\n\n    /**\n     * Checks if `value` is a finite primitive number.\n     *\n     * **Note:** This method is based on\n     * [`Number.isFinite`](https://mdn.io/Number/isFinite).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n     * @example\n     *\n     * _.isFinite(3);\n     * // => true\n     *\n     * _.isFinite(Number.MIN_VALUE);\n     * // => true\n     *\n     * _.isFinite(Infinity);\n     * // => false\n     *\n     * _.isFinite('3');\n     * // => false\n     */\n    function isFinite(value) {\n      return typeof value == 'number' && nativeIsFinite(value);\n    }\n\n    /**\n     * Checks if `value` is classified as a `Function` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n     * @example\n     *\n     * _.isFunction(_);\n     * // => true\n     *\n     * _.isFunction(/abc/);\n     * // => false\n     */\n    function isFunction(value) {\n      if (!isObject(value)) {\n        return false;\n      }\n      // The use of `Object#toString` avoids issues with the `typeof` operator\n      // in Safari 9 which returns 'object' for typed arrays and other constructors.\n      var tag = baseGetTag(value);\n      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n    }\n\n    /**\n     * Checks if `value` is an integer.\n     *\n     * **Note:** This method is based on\n     * [`Number.isInteger`](https://mdn.io/Number/isInteger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.\n     * @example\n     *\n     * _.isInteger(3);\n     * // => true\n     *\n     * _.isInteger(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isInteger(Infinity);\n     * // => false\n     *\n     * _.isInteger('3');\n     * // => false\n     */\n    function isInteger(value) {\n      return typeof value == 'number' && value == toInteger(value);\n    }\n\n    /**\n     * Checks if `value` is a valid array-like length.\n     *\n     * **Note:** This method is loosely based on\n     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n     * @example\n     *\n     * _.isLength(3);\n     * // => true\n     *\n     * _.isLength(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isLength(Infinity);\n     * // => false\n     *\n     * _.isLength('3');\n     * // => false\n     */\n    function isLength(value) {\n      return typeof value == 'number' &&\n        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n    }\n\n    /**\n     * Checks if `value` is the\n     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n     * @example\n     *\n     * _.isObject({});\n     * // => true\n     *\n     * _.isObject([1, 2, 3]);\n     * // => true\n     *\n     * _.isObject(_.noop);\n     * // => true\n     *\n     * _.isObject(null);\n     * // => false\n     */\n    function isObject(value) {\n      var type = typeof value;\n      return value != null && (type == 'object' || type == 'function');\n    }\n\n    /**\n     * Checks if `value` is object-like. A value is object-like if it's not `null`\n     * and has a `typeof` result of \"object\".\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n     * @example\n     *\n     * _.isObjectLike({});\n     * // => true\n     *\n     * _.isObjectLike([1, 2, 3]);\n     * // => true\n     *\n     * _.isObjectLike(_.noop);\n     * // => false\n     *\n     * _.isObjectLike(null);\n     * // => false\n     */\n    function isObjectLike(value) {\n      return value != null && typeof value == 'object';\n    }\n\n    /**\n     * Checks if `value` is classified as a `Map` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n     * @example\n     *\n     * _.isMap(new Map);\n     * // => true\n     *\n     * _.isMap(new WeakMap);\n     * // => false\n     */\n    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\n    /**\n     * Performs a partial deep comparison between `object` and `source` to\n     * determine if `object` contains equivalent property values.\n     *\n     * **Note:** This method is equivalent to `_.matches` when `source` is\n     * partially applied.\n     *\n     * Partial comparisons will match empty array and empty object `source`\n     * values against any array or object value, respectively. See `_.isEqual`\n     * for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     *\n     * _.isMatch(object, { 'b': 2 });\n     * // => true\n     *\n     * _.isMatch(object, { 'b': 1 });\n     * // => false\n     */\n    function isMatch(object, source) {\n      return object === source || baseIsMatch(object, source, getMatchData(source));\n    }\n\n    /**\n     * This method is like `_.isMatch` except that it accepts `customizer` which\n     * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n     * are handled by the method instead. The `customizer` is invoked with five\n     * arguments: (objValue, srcValue, index|key, object, source).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     * @example\n     *\n     * function isGreeting(value) {\n     *   return /^h(?:i|ello)$/.test(value);\n     * }\n     *\n     * function customizer(objValue, srcValue) {\n     *   if (isGreeting(objValue) && isGreeting(srcValue)) {\n     *     return true;\n     *   }\n     * }\n     *\n     * var object = { 'greeting': 'hello' };\n     * var source = { 'greeting': 'hi' };\n     *\n     * _.isMatchWith(object, source, customizer);\n     * // => true\n     */\n    function isMatchWith(object, source, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseIsMatch(object, source, getMatchData(source), customizer);\n    }\n\n    /**\n     * Checks if `value` is `NaN`.\n     *\n     * **Note:** This method is based on\n     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as\n     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for\n     * `undefined` and other non-number values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n     * @example\n     *\n     * _.isNaN(NaN);\n     * // => true\n     *\n     * _.isNaN(new Number(NaN));\n     * // => true\n     *\n     * isNaN(undefined);\n     * // => true\n     *\n     * _.isNaN(undefined);\n     * // => false\n     */\n    function isNaN(value) {\n      // An `NaN` primitive is the only value that is not equal to itself.\n      // Perform the `toStringTag` check first to avoid errors with some\n      // ActiveX objects in IE.\n      return isNumber(value) && value != +value;\n    }\n\n    /**\n     * Checks if `value` is a pristine native function.\n     *\n     * **Note:** This method can't reliably detect native functions in the presence\n     * of the core-js package because core-js circumvents this kind of detection.\n     * Despite multiple requests, the core-js maintainer has made it clear: any\n     * attempt to fix the detection will be obstructed. As a result, we're left\n     * with little choice but to throw an error. Unfortunately, this also affects\n     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),\n     * which rely on core-js.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a native function,\n     *  else `false`.\n     * @example\n     *\n     * _.isNative(Array.prototype.push);\n     * // => true\n     *\n     * _.isNative(_);\n     * // => false\n     */\n    function isNative(value) {\n      if (isMaskable(value)) {\n        throw new Error(CORE_ERROR_TEXT);\n      }\n      return baseIsNative(value);\n    }\n\n    /**\n     * Checks if `value` is `null`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n     * @example\n     *\n     * _.isNull(null);\n     * // => true\n     *\n     * _.isNull(void 0);\n     * // => false\n     */\n    function isNull(value) {\n      return value === null;\n    }\n\n    /**\n     * Checks if `value` is `null` or `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n     * @example\n     *\n     * _.isNil(null);\n     * // => true\n     *\n     * _.isNil(void 0);\n     * // => true\n     *\n     * _.isNil(NaN);\n     * // => false\n     */\n    function isNil(value) {\n      return value == null;\n    }\n\n    /**\n     * Checks if `value` is classified as a `Number` primitive or object.\n     *\n     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are\n     * classified as numbers, use the `_.isFinite` method.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a number, else `false`.\n     * @example\n     *\n     * _.isNumber(3);\n     * // => true\n     *\n     * _.isNumber(Number.MIN_VALUE);\n     * // => true\n     *\n     * _.isNumber(Infinity);\n     * // => true\n     *\n     * _.isNumber('3');\n     * // => false\n     */\n    function isNumber(value) {\n      return typeof value == 'number' ||\n        (isObjectLike(value) && baseGetTag(value) == numberTag);\n    }\n\n    /**\n     * Checks if `value` is a plain object, that is, an object created by the\n     * `Object` constructor or one with a `[[Prototype]]` of `null`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.8.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * _.isPlainObject(new Foo);\n     * // => false\n     *\n     * _.isPlainObject([1, 2, 3]);\n     * // => false\n     *\n     * _.isPlainObject({ 'x': 0, 'y': 0 });\n     * // => true\n     *\n     * _.isPlainObject(Object.create(null));\n     * // => true\n     */\n    function isPlainObject(value) {\n      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n        return false;\n      }\n      var proto = getPrototype(value);\n      if (proto === null) {\n        return true;\n      }\n      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n      return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n        funcToString.call(Ctor) == objectCtorString;\n    }\n\n    /**\n     * Checks if `value` is classified as a `RegExp` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n     * @example\n     *\n     * _.isRegExp(/abc/);\n     * // => true\n     *\n     * _.isRegExp('/abc/');\n     * // => false\n     */\n    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;\n\n    /**\n     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754\n     * double precision number which isn't the result of a rounded unsafe integer.\n     *\n     * **Note:** This method is based on\n     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.\n     * @example\n     *\n     * _.isSafeInteger(3);\n     * // => true\n     *\n     * _.isSafeInteger(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isSafeInteger(Infinity);\n     * // => false\n     *\n     * _.isSafeInteger('3');\n     * // => false\n     */\n    function isSafeInteger(value) {\n      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;\n    }\n\n    /**\n     * Checks if `value` is classified as a `Set` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n     * @example\n     *\n     * _.isSet(new Set);\n     * // => true\n     *\n     * _.isSet(new WeakSet);\n     * // => false\n     */\n    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\n    /**\n     * Checks if `value` is classified as a `String` primitive or object.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n     * @example\n     *\n     * _.isString('abc');\n     * // => true\n     *\n     * _.isString(1);\n     * // => false\n     */\n    function isString(value) {\n      return typeof value == 'string' ||\n        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n    }\n\n    /**\n     * Checks if `value` is classified as a `Symbol` primitive or object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n     * @example\n     *\n     * _.isSymbol(Symbol.iterator);\n     * // => true\n     *\n     * _.isSymbol('abc');\n     * // => false\n     */\n    function isSymbol(value) {\n      return typeof value == 'symbol' ||\n        (isObjectLike(value) && baseGetTag(value) == symbolTag);\n    }\n\n    /**\n     * Checks if `value` is classified as a typed array.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n     * @example\n     *\n     * _.isTypedArray(new Uint8Array);\n     * // => true\n     *\n     * _.isTypedArray([]);\n     * // => false\n     */\n    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\n    /**\n     * Checks if `value` is `undefined`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n     * @example\n     *\n     * _.isUndefined(void 0);\n     * // => true\n     *\n     * _.isUndefined(null);\n     * // => false\n     */\n    function isUndefined(value) {\n      return value === undefined;\n    }\n\n    /**\n     * Checks if `value` is classified as a `WeakMap` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.\n     * @example\n     *\n     * _.isWeakMap(new WeakMap);\n     * // => true\n     *\n     * _.isWeakMap(new Map);\n     * // => false\n     */\n    function isWeakMap(value) {\n      return isObjectLike(value) && getTag(value) == weakMapTag;\n    }\n\n    /**\n     * Checks if `value` is classified as a `WeakSet` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.\n     * @example\n     *\n     * _.isWeakSet(new WeakSet);\n     * // => true\n     *\n     * _.isWeakSet(new Set);\n     * // => false\n     */\n    function isWeakSet(value) {\n      return isObjectLike(value) && baseGetTag(value) == weakSetTag;\n    }\n\n    /**\n     * Checks if `value` is less than `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than `other`,\n     *  else `false`.\n     * @see _.gt\n     * @example\n     *\n     * _.lt(1, 3);\n     * // => true\n     *\n     * _.lt(3, 3);\n     * // => false\n     *\n     * _.lt(3, 1);\n     * // => false\n     */\n    var lt = createRelationalOperation(baseLt);\n\n    /**\n     * Checks if `value` is less than or equal to `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than or equal to\n     *  `other`, else `false`.\n     * @see _.gte\n     * @example\n     *\n     * _.lte(1, 3);\n     * // => true\n     *\n     * _.lte(3, 3);\n     * // => true\n     *\n     * _.lte(3, 1);\n     * // => false\n     */\n    var lte = createRelationalOperation(function(value, other) {\n      return value <= other;\n    });\n\n    /**\n     * Converts `value` to an array.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {Array} Returns the converted array.\n     * @example\n     *\n     * _.toArray({ 'a': 1, 'b': 2 });\n     * // => [1, 2]\n     *\n     * _.toArray('abc');\n     * // => ['a', 'b', 'c']\n     *\n     * _.toArray(1);\n     * // => []\n     *\n     * _.toArray(null);\n     * // => []\n     */\n    function toArray(value) {\n      if (!value) {\n        return [];\n      }\n      if (isArrayLike(value)) {\n        return isString(value) ? stringToArray(value) : copyArray(value);\n      }\n      if (symIterator && value[symIterator]) {\n        return iteratorToArray(value[symIterator]());\n      }\n      var tag = getTag(value),\n          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);\n\n      return func(value);\n    }\n\n    /**\n     * Converts `value` to a finite number.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.12.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted number.\n     * @example\n     *\n     * _.toFinite(3.2);\n     * // => 3.2\n     *\n     * _.toFinite(Number.MIN_VALUE);\n     * // => 5e-324\n     *\n     * _.toFinite(Infinity);\n     * // => 1.7976931348623157e+308\n     *\n     * _.toFinite('3.2');\n     * // => 3.2\n     */\n    function toFinite(value) {\n      if (!value) {\n        return value === 0 ? value : 0;\n      }\n      value = toNumber(value);\n      if (value === INFINITY || value === -INFINITY) {\n        var sign = (value < 0 ? -1 : 1);\n        return sign * MAX_INTEGER;\n      }\n      return value === value ? value : 0;\n    }\n\n    /**\n     * Converts `value` to an integer.\n     *\n     * **Note:** This method is loosely based on\n     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toInteger(3.2);\n     * // => 3\n     *\n     * _.toInteger(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toInteger(Infinity);\n     * // => 1.7976931348623157e+308\n     *\n     * _.toInteger('3.2');\n     * // => 3\n     */\n    function toInteger(value) {\n      var result = toFinite(value),\n          remainder = result % 1;\n\n      return result === result ? (remainder ? result - remainder : result) : 0;\n    }\n\n    /**\n     * Converts `value` to an integer suitable for use as the length of an\n     * array-like object.\n     *\n     * **Note:** This method is based on\n     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toLength(3.2);\n     * // => 3\n     *\n     * _.toLength(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toLength(Infinity);\n     * // => 4294967295\n     *\n     * _.toLength('3.2');\n     * // => 3\n     */\n    function toLength(value) {\n      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;\n    }\n\n    /**\n     * Converts `value` to a number.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to process.\n     * @returns {number} Returns the number.\n     * @example\n     *\n     * _.toNumber(3.2);\n     * // => 3.2\n     *\n     * _.toNumber(Number.MIN_VALUE);\n     * // => 5e-324\n     *\n     * _.toNumber(Infinity);\n     * // => Infinity\n     *\n     * _.toNumber('3.2');\n     * // => 3.2\n     */\n    function toNumber(value) {\n      if (typeof value == 'number') {\n        return value;\n      }\n      if (isSymbol(value)) {\n        return NAN;\n      }\n      if (isObject(value)) {\n        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n        value = isObject(other) ? (other + '') : other;\n      }\n      if (typeof value != 'string') {\n        return value === 0 ? value : +value;\n      }\n      value = value.replace(reTrim, '');\n      var isBinary = reIsBinary.test(value);\n      return (isBinary || reIsOctal.test(value))\n        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n        : (reIsBadHex.test(value) ? NAN : +value);\n    }\n\n    /**\n     * Converts `value` to a plain object flattening inherited enumerable string\n     * keyed properties of `value` to own properties of the plain object.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {Object} Returns the converted plain object.\n     * @example\n     *\n     * function Foo() {\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.assign({ 'a': 1 }, new Foo);\n     * // => { 'a': 1, 'b': 2 }\n     *\n     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n     * // => { 'a': 1, 'b': 2, 'c': 3 }\n     */\n    function toPlainObject(value) {\n      return copyObject(value, keysIn(value));\n    }\n\n    /**\n     * Converts `value` to a safe integer. A safe integer can be compared and\n     * represented correctly.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toSafeInteger(3.2);\n     * // => 3\n     *\n     * _.toSafeInteger(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toSafeInteger(Infinity);\n     * // => 9007199254740991\n     *\n     * _.toSafeInteger('3.2');\n     * // => 3\n     */\n    function toSafeInteger(value) {\n      return value\n        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)\n        : (value === 0 ? value : 0);\n    }\n\n    /**\n     * Converts `value` to a string. An empty string is returned for `null`\n     * and `undefined` values. The sign of `-0` is preserved.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.toString(null);\n     * // => ''\n     *\n     * _.toString(-0);\n     * // => '-0'\n     *\n     * _.toString([1, 2, 3]);\n     * // => '1,2,3'\n     */\n    function toString(value) {\n      return value == null ? '' : baseToString(value);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Assigns own enumerable string keyed properties of source objects to the\n     * destination object. Source objects are applied from left to right.\n     * Subsequent sources overwrite property assignments of previous sources.\n     *\n     * **Note:** This method mutates `object` and is loosely based on\n     * [`Object.assign`](https://mdn.io/Object/assign).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.10.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.assignIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * function Bar() {\n     *   this.c = 3;\n     * }\n     *\n     * Foo.prototype.b = 2;\n     * Bar.prototype.d = 4;\n     *\n     * _.assign({ 'a': 0 }, new Foo, new Bar);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    var assign = createAssigner(function(object, source) {\n      if (isPrototype(source) || isArrayLike(source)) {\n        copyObject(source, keys(source), object);\n        return;\n      }\n      for (var key in source) {\n        if (hasOwnProperty.call(source, key)) {\n          assignValue(object, key, source[key]);\n        }\n      }\n    });\n\n    /**\n     * This method is like `_.assign` except that it iterates over own and\n     * inherited source properties.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias extend\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.assign\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * function Bar() {\n     *   this.c = 3;\n     * }\n     *\n     * Foo.prototype.b = 2;\n     * Bar.prototype.d = 4;\n     *\n     * _.assignIn({ 'a': 0 }, new Foo, new Bar);\n     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\n     */\n    var assignIn = createAssigner(function(object, source) {\n      copyObject(source, keysIn(source), object);\n    });\n\n    /**\n     * This method is like `_.assignIn` except that it accepts `customizer`\n     * which is invoked to produce the assigned values. If `customizer` returns\n     * `undefined`, assignment is handled by the method instead. The `customizer`\n     * is invoked with five arguments: (objValue, srcValue, key, object, source).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias extendWith\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @see _.assignWith\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   return _.isUndefined(objValue) ? srcValue : objValue;\n     * }\n     *\n     * var defaults = _.partialRight(_.assignInWith, customizer);\n     *\n     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {\n      copyObject(source, keysIn(source), object, customizer);\n    });\n\n    /**\n     * This method is like `_.assign` except that it accepts `customizer`\n     * which is invoked to produce the assigned values. If `customizer` returns\n     * `undefined`, assignment is handled by the method instead. The `customizer`\n     * is invoked with five arguments: (objValue, srcValue, key, object, source).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @see _.assignInWith\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   return _.isUndefined(objValue) ? srcValue : objValue;\n     * }\n     *\n     * var defaults = _.partialRight(_.assignWith, customizer);\n     *\n     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {\n      copyObject(source, keys(source), object, customizer);\n    });\n\n    /**\n     * Creates an array of values corresponding to `paths` of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Array} Returns the picked values.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n     *\n     * _.at(object, ['a[0].b.c', 'a[1]']);\n     * // => [3, 4]\n     */\n    var at = flatRest(baseAt);\n\n    /**\n     * Creates an object that inherits from the `prototype` object. If a\n     * `properties` object is given, its own enumerable string keyed properties\n     * are assigned to the created object.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.3.0\n     * @category Object\n     * @param {Object} prototype The object to inherit from.\n     * @param {Object} [properties] The properties to assign to the object.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * function Shape() {\n     *   this.x = 0;\n     *   this.y = 0;\n     * }\n     *\n     * function Circle() {\n     *   Shape.call(this);\n     * }\n     *\n     * Circle.prototype = _.create(Shape.prototype, {\n     *   'constructor': Circle\n     * });\n     *\n     * var circle = new Circle;\n     * circle instanceof Circle;\n     * // => true\n     *\n     * circle instanceof Shape;\n     * // => true\n     */\n    function create(prototype, properties) {\n      var result = baseCreate(prototype);\n      return properties == null ? result : baseAssign(result, properties);\n    }\n\n    /**\n     * Assigns own and inherited enumerable string keyed properties of source\n     * objects to the destination object for all destination properties that\n     * resolve to `undefined`. Source objects are applied from left to right.\n     * Once a property is set, additional values of the same property are ignored.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.defaultsDeep\n     * @example\n     *\n     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var defaults = baseRest(function(args) {\n      args.push(undefined, customDefaultsAssignIn);\n      return apply(assignInWith, undefined, args);\n    });\n\n    /**\n     * This method is like `_.defaults` except that it recursively assigns\n     * default properties.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.defaults\n     * @example\n     *\n     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n     * // => { 'a': { 'b': 2, 'c': 3 } }\n     */\n    var defaultsDeep = baseRest(function(args) {\n      args.push(undefined, customDefaultsMerge);\n      return apply(mergeWith, undefined, args);\n    });\n\n    /**\n     * This method is like `_.find` except that it returns the key of the first\n     * element `predicate` returns truthy for instead of the element itself.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {string|undefined} Returns the key of the matched element,\n     *  else `undefined`.\n     * @example\n     *\n     * var users = {\n     *   'barney':  { 'age': 36, 'active': true },\n     *   'fred':    { 'age': 40, 'active': false },\n     *   'pebbles': { 'age': 1,  'active': true }\n     * };\n     *\n     * _.findKey(users, function(o) { return o.age < 40; });\n     * // => 'barney' (iteration order is not guaranteed)\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findKey(users, { 'age': 1, 'active': true });\n     * // => 'pebbles'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findKey(users, ['active', false]);\n     * // => 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findKey(users, 'active');\n     * // => 'barney'\n     */\n    function findKey(object, predicate) {\n      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);\n    }\n\n    /**\n     * This method is like `_.findKey` except that it iterates over elements of\n     * a collection in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {string|undefined} Returns the key of the matched element,\n     *  else `undefined`.\n     * @example\n     *\n     * var users = {\n     *   'barney':  { 'age': 36, 'active': true },\n     *   'fred':    { 'age': 40, 'active': false },\n     *   'pebbles': { 'age': 1,  'active': true }\n     * };\n     *\n     * _.findLastKey(users, function(o) { return o.age < 40; });\n     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findLastKey(users, { 'age': 36, 'active': true });\n     * // => 'barney'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findLastKey(users, ['active', false]);\n     * // => 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findLastKey(users, 'active');\n     * // => 'pebbles'\n     */\n    function findLastKey(object, predicate) {\n      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);\n    }\n\n    /**\n     * Iterates over own and inherited enumerable string keyed properties of an\n     * object and invokes `iteratee` for each property. The iteratee is invoked\n     * with three arguments: (value, key, object). Iteratee functions may exit\n     * iteration early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forInRight\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forIn(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).\n     */\n    function forIn(object, iteratee) {\n      return object == null\n        ? object\n        : baseFor(object, getIteratee(iteratee, 3), keysIn);\n    }\n\n    /**\n     * This method is like `_.forIn` except that it iterates over properties of\n     * `object` in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forInRight(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.\n     */\n    function forInRight(object, iteratee) {\n      return object == null\n        ? object\n        : baseForRight(object, getIteratee(iteratee, 3), keysIn);\n    }\n\n    /**\n     * Iterates over own enumerable string keyed properties of an object and\n     * invokes `iteratee` for each property. The iteratee is invoked with three\n     * arguments: (value, key, object). Iteratee functions may exit iteration\n     * early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forOwnRight\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forOwn(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n     */\n    function forOwn(object, iteratee) {\n      return object && baseForOwn(object, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.forOwn` except that it iterates over properties of\n     * `object` in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forOwn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forOwnRight(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.\n     */\n    function forOwnRight(object, iteratee) {\n      return object && baseForOwnRight(object, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * Creates an array of function property names from own enumerable properties\n     * of `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @returns {Array} Returns the function names.\n     * @see _.functionsIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = _.constant('a');\n     *   this.b = _.constant('b');\n     * }\n     *\n     * Foo.prototype.c = _.constant('c');\n     *\n     * _.functions(new Foo);\n     * // => ['a', 'b']\n     */\n    function functions(object) {\n      return object == null ? [] : baseFunctions(object, keys(object));\n    }\n\n    /**\n     * Creates an array of function property names from own and inherited\n     * enumerable properties of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @returns {Array} Returns the function names.\n     * @see _.functions\n     * @example\n     *\n     * function Foo() {\n     *   this.a = _.constant('a');\n     *   this.b = _.constant('b');\n     * }\n     *\n     * Foo.prototype.c = _.constant('c');\n     *\n     * _.functionsIn(new Foo);\n     * // => ['a', 'b', 'c']\n     */\n    function functionsIn(object) {\n      return object == null ? [] : baseFunctions(object, keysIn(object));\n    }\n\n    /**\n     * Gets the value at `path` of `object`. If the resolved value is\n     * `undefined`, the `defaultValue` is returned in its place.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to get.\n     * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.get(object, 'a[0].b.c');\n     * // => 3\n     *\n     * _.get(object, ['a', '0', 'b', 'c']);\n     * // => 3\n     *\n     * _.get(object, 'a.b.c', 'default');\n     * // => 'default'\n     */\n    function get(object, path, defaultValue) {\n      var result = object == null ? undefined : baseGet(object, path);\n      return result === undefined ? defaultValue : result;\n    }\n\n    /**\n     * Checks if `path` is a direct property of `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     * @example\n     *\n     * var object = { 'a': { 'b': 2 } };\n     * var other = _.create({ 'a': _.create({ 'b': 2 }) });\n     *\n     * _.has(object, 'a');\n     * // => true\n     *\n     * _.has(object, 'a.b');\n     * // => true\n     *\n     * _.has(object, ['a', 'b']);\n     * // => true\n     *\n     * _.has(other, 'a');\n     * // => false\n     */\n    function has(object, path) {\n      return object != null && hasPath(object, path, baseHas);\n    }\n\n    /**\n     * Checks if `path` is a direct or inherited property of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     * @example\n     *\n     * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n     *\n     * _.hasIn(object, 'a');\n     * // => true\n     *\n     * _.hasIn(object, 'a.b');\n     * // => true\n     *\n     * _.hasIn(object, ['a', 'b']);\n     * // => true\n     *\n     * _.hasIn(object, 'b');\n     * // => false\n     */\n    function hasIn(object, path) {\n      return object != null && hasPath(object, path, baseHasIn);\n    }\n\n    /**\n     * Creates an object composed of the inverted keys and values of `object`.\n     * If `object` contains duplicate values, subsequent values overwrite\n     * property assignments of previous values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.7.0\n     * @category Object\n     * @param {Object} object The object to invert.\n     * @returns {Object} Returns the new inverted object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2, 'c': 1 };\n     *\n     * _.invert(object);\n     * // => { '1': 'c', '2': 'b' }\n     */\n    var invert = createInverter(function(result, value, key) {\n      result[value] = key;\n    }, constant(identity));\n\n    /**\n     * This method is like `_.invert` except that the inverted object is generated\n     * from the results of running each element of `object` thru `iteratee`. The\n     * corresponding inverted value of each inverted key is an array of keys\n     * responsible for generating the inverted value. The iteratee is invoked\n     * with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.1.0\n     * @category Object\n     * @param {Object} object The object to invert.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Object} Returns the new inverted object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2, 'c': 1 };\n     *\n     * _.invertBy(object);\n     * // => { '1': ['a', 'c'], '2': ['b'] }\n     *\n     * _.invertBy(object, function(value) {\n     *   return 'group' + value;\n     * });\n     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }\n     */\n    var invertBy = createInverter(function(result, value, key) {\n      if (hasOwnProperty.call(result, value)) {\n        result[value].push(key);\n      } else {\n        result[value] = [key];\n      }\n    }, getIteratee);\n\n    /**\n     * Invokes the method at `path` of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {*} Returns the result of the invoked method.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };\n     *\n     * _.invoke(object, 'a[0].b.c.slice', 1, 3);\n     * // => [2, 3]\n     */\n    var invoke = baseRest(baseInvoke);\n\n    /**\n     * Creates an array of the own enumerable property names of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects. See the\n     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n     * for more details.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.keys(new Foo);\n     * // => ['a', 'b'] (iteration order is not guaranteed)\n     *\n     * _.keys('hi');\n     * // => ['0', '1']\n     */\n    function keys(object) {\n      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n    }\n\n    /**\n     * Creates an array of the own and inherited enumerable property names of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.keysIn(new Foo);\n     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n     */\n    function keysIn(object) {\n      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n    }\n\n    /**\n     * The opposite of `_.mapValues`; this method creates an object with the\n     * same values as `object` and keys generated by running each own enumerable\n     * string keyed property of `object` thru `iteratee`. The iteratee is invoked\n     * with three arguments: (value, key, object).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns the new mapped object.\n     * @see _.mapValues\n     * @example\n     *\n     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {\n     *   return key + value;\n     * });\n     * // => { 'a1': 1, 'b2': 2 }\n     */\n    function mapKeys(object, iteratee) {\n      var result = {};\n      iteratee = getIteratee(iteratee, 3);\n\n      baseForOwn(object, function(value, key, object) {\n        baseAssignValue(result, iteratee(value, key, object), value);\n      });\n      return result;\n    }\n\n    /**\n     * Creates an object with the same keys as `object` and values generated\n     * by running each own enumerable string keyed property of `object` thru\n     * `iteratee`. The iteratee is invoked with three arguments:\n     * (value, key, object).\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns the new mapped object.\n     * @see _.mapKeys\n     * @example\n     *\n     * var users = {\n     *   'fred':    { 'user': 'fred',    'age': 40 },\n     *   'pebbles': { 'user': 'pebbles', 'age': 1 }\n     * };\n     *\n     * _.mapValues(users, function(o) { return o.age; });\n     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.mapValues(users, 'age');\n     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n     */\n    function mapValues(object, iteratee) {\n      var result = {};\n      iteratee = getIteratee(iteratee, 3);\n\n      baseForOwn(object, function(value, key, object) {\n        baseAssignValue(result, key, iteratee(value, key, object));\n      });\n      return result;\n    }\n\n    /**\n     * This method is like `_.assign` except that it recursively merges own and\n     * inherited enumerable string keyed properties of source objects into the\n     * destination object. Source properties that resolve to `undefined` are\n     * skipped if a destination value exists. Array and plain object properties\n     * are merged recursively. Other objects and value types are overridden by\n     * assignment. Source objects are applied from left to right. Subsequent\n     * sources overwrite property assignments of previous sources.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {\n     *   'a': [{ 'b': 2 }, { 'd': 4 }]\n     * };\n     *\n     * var other = {\n     *   'a': [{ 'c': 3 }, { 'e': 5 }]\n     * };\n     *\n     * _.merge(object, other);\n     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n     */\n    var merge = createAssigner(function(object, source, srcIndex) {\n      baseMerge(object, source, srcIndex);\n    });\n\n    /**\n     * This method is like `_.merge` except that it accepts `customizer` which\n     * is invoked to produce the merged values of the destination and source\n     * properties. If `customizer` returns `undefined`, merging is handled by the\n     * method instead. The `customizer` is invoked with six arguments:\n     * (objValue, srcValue, key, object, source, stack).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} customizer The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   if (_.isArray(objValue)) {\n     *     return objValue.concat(srcValue);\n     *   }\n     * }\n     *\n     * var object = { 'a': [1], 'b': [2] };\n     * var other = { 'a': [3], 'b': [4] };\n     *\n     * _.mergeWith(object, other, customizer);\n     * // => { 'a': [1, 3], 'b': [2, 4] }\n     */\n    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n      baseMerge(object, source, srcIndex, customizer);\n    });\n\n    /**\n     * The opposite of `_.pick`; this method creates an object composed of the\n     * own and inherited enumerable property paths of `object` that are not omitted.\n     *\n     * **Note:** This method is considerably slower than `_.pick`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {...(string|string[])} [paths] The property paths to omit.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.omit(object, ['a', 'c']);\n     * // => { 'b': '2' }\n     */\n    var omit = flatRest(function(object, paths) {\n      var result = {};\n      if (object == null) {\n        return result;\n      }\n      var isDeep = false;\n      paths = arrayMap(paths, function(path) {\n        path = castPath(path, object);\n        isDeep || (isDeep = path.length > 1);\n        return path;\n      });\n      copyObject(object, getAllKeysIn(object), result);\n      if (isDeep) {\n        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n      }\n      var length = paths.length;\n      while (length--) {\n        baseUnset(result, paths[length]);\n      }\n      return result;\n    });\n\n    /**\n     * The opposite of `_.pickBy`; this method creates an object composed of\n     * the own and inherited enumerable string keyed properties of `object` that\n     * `predicate` doesn't return truthy for. The predicate is invoked with two\n     * arguments: (value, key).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {Function} [predicate=_.identity] The function invoked per property.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.omitBy(object, _.isNumber);\n     * // => { 'b': '2' }\n     */\n    function omitBy(object, predicate) {\n      return pickBy(object, negate(getIteratee(predicate)));\n    }\n\n    /**\n     * Creates an object composed of the picked `object` properties.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.pick(object, ['a', 'c']);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    var pick = flatRest(function(object, paths) {\n      return object == null ? {} : basePick(object, paths);\n    });\n\n    /**\n     * Creates an object composed of the `object` properties `predicate` returns\n     * truthy for. The predicate is invoked with two arguments: (value, key).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {Function} [predicate=_.identity] The function invoked per property.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.pickBy(object, _.isNumber);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    function pickBy(object, predicate) {\n      if (object == null) {\n        return {};\n      }\n      var props = arrayMap(getAllKeysIn(object), function(prop) {\n        return [prop];\n      });\n      predicate = getIteratee(predicate);\n      return basePickBy(object, props, function(value, path) {\n        return predicate(value, path[0]);\n      });\n    }\n\n    /**\n     * This method is like `_.get` except that if the resolved value is a\n     * function it's invoked with the `this` binding of its parent object and\n     * its result is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to resolve.\n     * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };\n     *\n     * _.result(object, 'a[0].b.c1');\n     * // => 3\n     *\n     * _.result(object, 'a[0].b.c2');\n     * // => 4\n     *\n     * _.result(object, 'a[0].b.c3', 'default');\n     * // => 'default'\n     *\n     * _.result(object, 'a[0].b.c3', _.constant('default'));\n     * // => 'default'\n     */\n    function result(object, path, defaultValue) {\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length;\n\n      // Ensure the loop is entered when path is empty.\n      if (!length) {\n        length = 1;\n        object = undefined;\n      }\n      while (++index < length) {\n        var value = object == null ? undefined : object[toKey(path[index])];\n        if (value === undefined) {\n          index = length;\n          value = defaultValue;\n        }\n        object = isFunction(value) ? value.call(object) : value;\n      }\n      return object;\n    }\n\n    /**\n     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n     * it's created. Arrays are created for missing index properties while objects\n     * are created for all other missing properties. Use `_.setWith` to customize\n     * `path` creation.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.set(object, 'a[0].b.c', 4);\n     * console.log(object.a[0].b.c);\n     * // => 4\n     *\n     * _.set(object, ['x', '0', 'y', 'z'], 5);\n     * console.log(object.x[0].y.z);\n     * // => 5\n     */\n    function set(object, path, value) {\n      return object == null ? object : baseSet(object, path, value);\n    }\n\n    /**\n     * This method is like `_.set` except that it accepts `customizer` which is\n     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`\n     * path creation is handled by the method instead. The `customizer` is invoked\n     * with three arguments: (nsValue, key, nsObject).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {};\n     *\n     * _.setWith(object, '[0][1]', 'a', Object);\n     * // => { '0': { '1': 'a' } }\n     */\n    function setWith(object, path, value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return object == null ? object : baseSet(object, path, value, customizer);\n    }\n\n    /**\n     * Creates an array of own enumerable string keyed-value pairs for `object`\n     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its\n     * entries are returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias entries\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the key-value pairs.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.toPairs(new Foo);\n     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)\n     */\n    var toPairs = createToPairs(keys);\n\n    /**\n     * Creates an array of own and inherited enumerable string keyed-value pairs\n     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map\n     * or set, its entries are returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias entriesIn\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the key-value pairs.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.toPairsIn(new Foo);\n     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)\n     */\n    var toPairsIn = createToPairs(keysIn);\n\n    /**\n     * An alternative to `_.reduce`; this method transforms `object` to a new\n     * `accumulator` object which is the result of running each of its own\n     * enumerable string keyed properties thru `iteratee`, with each invocation\n     * potentially mutating the `accumulator` object. If `accumulator` is not\n     * provided, a new object with the same `[[Prototype]]` will be used. The\n     * iteratee is invoked with four arguments: (accumulator, value, key, object).\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The custom accumulator value.\n     * @returns {*} Returns the accumulated value.\n     * @example\n     *\n     * _.transform([2, 3, 4], function(result, n) {\n     *   result.push(n *= n);\n     *   return n % 2 == 0;\n     * }, []);\n     * // => [4, 9]\n     *\n     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n     *   (result[value] || (result[value] = [])).push(key);\n     * }, {});\n     * // => { '1': ['a', 'c'], '2': ['b'] }\n     */\n    function transform(object, iteratee, accumulator) {\n      var isArr = isArray(object),\n          isArrLike = isArr || isBuffer(object) || isTypedArray(object);\n\n      iteratee = getIteratee(iteratee, 4);\n      if (accumulator == null) {\n        var Ctor = object && object.constructor;\n        if (isArrLike) {\n          accumulator = isArr ? new Ctor : [];\n        }\n        else if (isObject(object)) {\n          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};\n        }\n        else {\n          accumulator = {};\n        }\n      }\n      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {\n        return iteratee(accumulator, value, index, object);\n      });\n      return accumulator;\n    }\n\n    /**\n     * Removes the property at `path` of `object`.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to unset.\n     * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 7 } }] };\n     * _.unset(object, 'a[0].b.c');\n     * // => true\n     *\n     * console.log(object);\n     * // => { 'a': [{ 'b': {} }] };\n     *\n     * _.unset(object, ['a', '0', 'b', 'c']);\n     * // => true\n     *\n     * console.log(object);\n     * // => { 'a': [{ 'b': {} }] };\n     */\n    function unset(object, path) {\n      return object == null ? true : baseUnset(object, path);\n    }\n\n    /**\n     * This method is like `_.set` except that accepts `updater` to produce the\n     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`\n     * is invoked with one argument: (value).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {Function} updater The function to produce the updated value.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.update(object, 'a[0].b.c', function(n) { return n * n; });\n     * console.log(object.a[0].b.c);\n     * // => 9\n     *\n     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });\n     * console.log(object.x[0].y.z);\n     * // => 0\n     */\n    function update(object, path, updater) {\n      return object == null ? object : baseUpdate(object, path, castFunction(updater));\n    }\n\n    /**\n     * This method is like `_.update` except that it accepts `customizer` which is\n     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`\n     * path creation is handled by the method instead. The `customizer` is invoked\n     * with three arguments: (nsValue, key, nsObject).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {Function} updater The function to produce the updated value.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {};\n     *\n     * _.updateWith(object, '[0][1]', _.constant('a'), Object);\n     * // => { '0': { '1': 'a' } }\n     */\n    function updateWith(object, path, updater, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);\n    }\n\n    /**\n     * Creates an array of the own enumerable string keyed property values of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property values.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.values(new Foo);\n     * // => [1, 2] (iteration order is not guaranteed)\n     *\n     * _.values('hi');\n     * // => ['h', 'i']\n     */\n    function values(object) {\n      return object == null ? [] : baseValues(object, keys(object));\n    }\n\n    /**\n     * Creates an array of the own and inherited enumerable string keyed property\n     * values of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property values.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.valuesIn(new Foo);\n     * // => [1, 2, 3] (iteration order is not guaranteed)\n     */\n    function valuesIn(object) {\n      return object == null ? [] : baseValues(object, keysIn(object));\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Clamps `number` within the inclusive `lower` and `upper` bounds.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Number\n     * @param {number} number The number to clamp.\n     * @param {number} [lower] The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the clamped number.\n     * @example\n     *\n     * _.clamp(-10, -5, 5);\n     * // => -5\n     *\n     * _.clamp(10, -5, 5);\n     * // => 5\n     */\n    function clamp(number, lower, upper) {\n      if (upper === undefined) {\n        upper = lower;\n        lower = undefined;\n      }\n      if (upper !== undefined) {\n        upper = toNumber(upper);\n        upper = upper === upper ? upper : 0;\n      }\n      if (lower !== undefined) {\n        lower = toNumber(lower);\n        lower = lower === lower ? lower : 0;\n      }\n      return baseClamp(toNumber(number), lower, upper);\n    }\n\n    /**\n     * Checks if `n` is between `start` and up to, but not including, `end`. If\n     * `end` is not specified, it's set to `start` with `start` then set to `0`.\n     * If `start` is greater than `end` the params are swapped to support\n     * negative ranges.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.3.0\n     * @category Number\n     * @param {number} number The number to check.\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n     * @see _.range, _.rangeRight\n     * @example\n     *\n     * _.inRange(3, 2, 4);\n     * // => true\n     *\n     * _.inRange(4, 8);\n     * // => true\n     *\n     * _.inRange(4, 2);\n     * // => false\n     *\n     * _.inRange(2, 2);\n     * // => false\n     *\n     * _.inRange(1.2, 2);\n     * // => true\n     *\n     * _.inRange(5.2, 4);\n     * // => false\n     *\n     * _.inRange(-3, -2, -6);\n     * // => true\n     */\n    function inRange(number, start, end) {\n      start = toFinite(start);\n      if (end === undefined) {\n        end = start;\n        start = 0;\n      } else {\n        end = toFinite(end);\n      }\n      number = toNumber(number);\n      return baseInRange(number, start, end);\n    }\n\n    /**\n     * Produces a random number between the inclusive `lower` and `upper` bounds.\n     * If only one argument is provided a number between `0` and the given number\n     * is returned. If `floating` is `true`, or either `lower` or `upper` are\n     * floats, a floating-point number is returned instead of an integer.\n     *\n     * **Note:** JavaScript follows the IEEE-754 standard for resolving\n     * floating-point values which can produce unexpected results.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.7.0\n     * @category Number\n     * @param {number} [lower=0] The lower bound.\n     * @param {number} [upper=1] The upper bound.\n     * @param {boolean} [floating] Specify returning a floating-point number.\n     * @returns {number} Returns the random number.\n     * @example\n     *\n     * _.random(0, 5);\n     * // => an integer between 0 and 5\n     *\n     * _.random(5);\n     * // => also an integer between 0 and 5\n     *\n     * _.random(5, true);\n     * // => a floating-point number between 0 and 5\n     *\n     * _.random(1.2, 5.2);\n     * // => a floating-point number between 1.2 and 5.2\n     */\n    function random(lower, upper, floating) {\n      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {\n        upper = floating = undefined;\n      }\n      if (floating === undefined) {\n        if (typeof upper == 'boolean') {\n          floating = upper;\n          upper = undefined;\n        }\n        else if (typeof lower == 'boolean') {\n          floating = lower;\n          lower = undefined;\n        }\n      }\n      if (lower === undefined && upper === undefined) {\n        lower = 0;\n        upper = 1;\n      }\n      else {\n        lower = toFinite(lower);\n        if (upper === undefined) {\n          upper = lower;\n          lower = 0;\n        } else {\n          upper = toFinite(upper);\n        }\n      }\n      if (lower > upper) {\n        var temp = lower;\n        lower = upper;\n        upper = temp;\n      }\n      if (floating || lower % 1 || upper % 1) {\n        var rand = nativeRandom();\n        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);\n      }\n      return baseRandom(lower, upper);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the camel cased string.\n     * @example\n     *\n     * _.camelCase('Foo Bar');\n     * // => 'fooBar'\n     *\n     * _.camelCase('--foo-bar--');\n     * // => 'fooBar'\n     *\n     * _.camelCase('__FOO_BAR__');\n     * // => 'fooBar'\n     */\n    var camelCase = createCompounder(function(result, word, index) {\n      word = word.toLowerCase();\n      return result + (index ? capitalize(word) : word);\n    });\n\n    /**\n     * Converts the first character of `string` to upper case and the remaining\n     * to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to capitalize.\n     * @returns {string} Returns the capitalized string.\n     * @example\n     *\n     * _.capitalize('FRED');\n     * // => 'Fred'\n     */\n    function capitalize(string) {\n      return upperFirst(toString(string).toLowerCase());\n    }\n\n    /**\n     * Deburrs `string` by converting\n     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n     * letters to basic Latin letters and removing\n     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to deburr.\n     * @returns {string} Returns the deburred string.\n     * @example\n     *\n     * _.deburr('déjà vu');\n     * // => 'deja vu'\n     */\n    function deburr(string) {\n      string = toString(string);\n      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n    }\n\n    /**\n     * Checks if `string` ends with the given target string.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {string} [target] The string to search for.\n     * @param {number} [position=string.length] The position to search up to.\n     * @returns {boolean} Returns `true` if `string` ends with `target`,\n     *  else `false`.\n     * @example\n     *\n     * _.endsWith('abc', 'c');\n     * // => true\n     *\n     * _.endsWith('abc', 'b');\n     * // => false\n     *\n     * _.endsWith('abc', 'b', 2);\n     * // => true\n     */\n    function endsWith(string, target, position) {\n      string = toString(string);\n      target = baseToString(target);\n\n      var length = string.length;\n      position = position === undefined\n        ? length\n        : baseClamp(toInteger(position), 0, length);\n\n      var end = position;\n      position -= target.length;\n      return position >= 0 && string.slice(position, end) == target;\n    }\n\n    /**\n     * Converts the characters \"&\", \"<\", \">\", '\"', and \"'\" in `string` to their\n     * corresponding HTML entities.\n     *\n     * **Note:** No other characters are escaped. To escape additional\n     * characters use a third-party library like [_he_](https://mths.be/he).\n     *\n     * Though the \">\" character is escaped for symmetry, characters like\n     * \">\" and \"/\" don't need escaping in HTML and have no special meaning\n     * unless they're part of a tag or unquoted attribute value. See\n     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)\n     * (under \"semi-related fun fact\") for more details.\n     *\n     * When working with HTML you should always\n     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce\n     * XSS vectors.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to escape.\n     * @returns {string} Returns the escaped string.\n     * @example\n     *\n     * _.escape('fred, barney, & pebbles');\n     * // => 'fred, barney, &amp; pebbles'\n     */\n    function escape(string) {\n      string = toString(string);\n      return (string && reHasUnescapedHtml.test(string))\n        ? string.replace(reUnescapedHtml, escapeHtmlChar)\n        : string;\n    }\n\n    /**\n     * Escapes the `RegExp` special characters \"^\", \"$\", \"\\\", \".\", \"*\", \"+\",\n     * \"?\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", and \"|\" in `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to escape.\n     * @returns {string} Returns the escaped string.\n     * @example\n     *\n     * _.escapeRegExp('[lodash](https://lodash.com/)');\n     * // => '\\[lodash\\]\\(https://lodash\\.com/\\)'\n     */\n    function escapeRegExp(string) {\n      string = toString(string);\n      return (string && reHasRegExpChar.test(string))\n        ? string.replace(reRegExpChar, '\\\\$&')\n        : string;\n    }\n\n    /**\n     * Converts `string` to\n     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the kebab cased string.\n     * @example\n     *\n     * _.kebabCase('Foo Bar');\n     * // => 'foo-bar'\n     *\n     * _.kebabCase('fooBar');\n     * // => 'foo-bar'\n     *\n     * _.kebabCase('__FOO_BAR__');\n     * // => 'foo-bar'\n     */\n    var kebabCase = createCompounder(function(result, word, index) {\n      return result + (index ? '-' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Converts `string`, as space separated words, to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the lower cased string.\n     * @example\n     *\n     * _.lowerCase('--Foo-Bar--');\n     * // => 'foo bar'\n     *\n     * _.lowerCase('fooBar');\n     * // => 'foo bar'\n     *\n     * _.lowerCase('__FOO_BAR__');\n     * // => 'foo bar'\n     */\n    var lowerCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Converts the first character of `string` to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.lowerFirst('Fred');\n     * // => 'fred'\n     *\n     * _.lowerFirst('FRED');\n     * // => 'fRED'\n     */\n    var lowerFirst = createCaseFirst('toLowerCase');\n\n    /**\n     * Pads `string` on the left and right sides if it's shorter than `length`.\n     * Padding characters are truncated if they can't be evenly divided by `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.pad('abc', 8);\n     * // => '  abc   '\n     *\n     * _.pad('abc', 8, '_-');\n     * // => '_-abc_-_'\n     *\n     * _.pad('abc', 3);\n     * // => 'abc'\n     */\n    function pad(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      if (!length || strLength >= length) {\n        return string;\n      }\n      var mid = (length - strLength) / 2;\n      return (\n        createPadding(nativeFloor(mid), chars) +\n        string +\n        createPadding(nativeCeil(mid), chars)\n      );\n    }\n\n    /**\n     * Pads `string` on the right side if it's shorter than `length`. Padding\n     * characters are truncated if they exceed `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.padEnd('abc', 6);\n     * // => 'abc   '\n     *\n     * _.padEnd('abc', 6, '_-');\n     * // => 'abc_-_'\n     *\n     * _.padEnd('abc', 3);\n     * // => 'abc'\n     */\n    function padEnd(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      return (length && strLength < length)\n        ? (string + createPadding(length - strLength, chars))\n        : string;\n    }\n\n    /**\n     * Pads `string` on the left side if it's shorter than `length`. Padding\n     * characters are truncated if they exceed `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.padStart('abc', 6);\n     * // => '   abc'\n     *\n     * _.padStart('abc', 6, '_-');\n     * // => '_-_abc'\n     *\n     * _.padStart('abc', 3);\n     * // => 'abc'\n     */\n    function padStart(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      return (length && strLength < length)\n        ? (createPadding(length - strLength, chars) + string)\n        : string;\n    }\n\n    /**\n     * Converts `string` to an integer of the specified radix. If `radix` is\n     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a\n     * hexadecimal, in which case a `radix` of `16` is used.\n     *\n     * **Note:** This method aligns with the\n     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category String\n     * @param {string} string The string to convert.\n     * @param {number} [radix=10] The radix to interpret `value` by.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.parseInt('08');\n     * // => 8\n     *\n     * _.map(['6', '08', '10'], _.parseInt);\n     * // => [6, 8, 10]\n     */\n    function parseInt(string, radix, guard) {\n      if (guard || radix == null) {\n        radix = 0;\n      } else if (radix) {\n        radix = +radix;\n      }\n      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);\n    }\n\n    /**\n     * Repeats the given string `n` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to repeat.\n     * @param {number} [n=1] The number of times to repeat the string.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the repeated string.\n     * @example\n     *\n     * _.repeat('*', 3);\n     * // => '***'\n     *\n     * _.repeat('abc', 2);\n     * // => 'abcabc'\n     *\n     * _.repeat('abc', 0);\n     * // => ''\n     */\n    function repeat(string, n, guard) {\n      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {\n        n = 1;\n      } else {\n        n = toInteger(n);\n      }\n      return baseRepeat(toString(string), n);\n    }\n\n    /**\n     * Replaces matches for `pattern` in `string` with `replacement`.\n     *\n     * **Note:** This method is based on\n     * [`String#replace`](https://mdn.io/String/replace).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to modify.\n     * @param {RegExp|string} pattern The pattern to replace.\n     * @param {Function|string} replacement The match replacement.\n     * @returns {string} Returns the modified string.\n     * @example\n     *\n     * _.replace('Hi Fred', 'Fred', 'Barney');\n     * // => 'Hi Barney'\n     */\n    function replace() {\n      var args = arguments,\n          string = toString(args[0]);\n\n      return args.length < 3 ? string : string.replace(args[1], args[2]);\n    }\n\n    /**\n     * Converts `string` to\n     * [snake case](https://en.wikipedia.org/wiki/Snake_case).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the snake cased string.\n     * @example\n     *\n     * _.snakeCase('Foo Bar');\n     * // => 'foo_bar'\n     *\n     * _.snakeCase('fooBar');\n     * // => 'foo_bar'\n     *\n     * _.snakeCase('--FOO-BAR--');\n     * // => 'foo_bar'\n     */\n    var snakeCase = createCompounder(function(result, word, index) {\n      return result + (index ? '_' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Splits `string` by `separator`.\n     *\n     * **Note:** This method is based on\n     * [`String#split`](https://mdn.io/String/split).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to split.\n     * @param {RegExp|string} separator The separator pattern to split by.\n     * @param {number} [limit] The length to truncate results to.\n     * @returns {Array} Returns the string segments.\n     * @example\n     *\n     * _.split('a-b-c', '-', 2);\n     * // => ['a', 'b']\n     */\n    function split(string, separator, limit) {\n      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {\n        separator = limit = undefined;\n      }\n      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;\n      if (!limit) {\n        return [];\n      }\n      string = toString(string);\n      if (string && (\n            typeof separator == 'string' ||\n            (separator != null && !isRegExp(separator))\n          )) {\n        separator = baseToString(separator);\n        if (!separator && hasUnicode(string)) {\n          return castSlice(stringToArray(string), 0, limit);\n        }\n      }\n      return string.split(separator, limit);\n    }\n\n    /**\n     * Converts `string` to\n     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.1.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the start cased string.\n     * @example\n     *\n     * _.startCase('--foo-bar--');\n     * // => 'Foo Bar'\n     *\n     * _.startCase('fooBar');\n     * // => 'Foo Bar'\n     *\n     * _.startCase('__FOO_BAR__');\n     * // => 'FOO BAR'\n     */\n    var startCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + upperFirst(word);\n    });\n\n    /**\n     * Checks if `string` starts with the given target string.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {string} [target] The string to search for.\n     * @param {number} [position=0] The position to search from.\n     * @returns {boolean} Returns `true` if `string` starts with `target`,\n     *  else `false`.\n     * @example\n     *\n     * _.startsWith('abc', 'a');\n     * // => true\n     *\n     * _.startsWith('abc', 'b');\n     * // => false\n     *\n     * _.startsWith('abc', 'b', 1);\n     * // => true\n     */\n    function startsWith(string, target, position) {\n      string = toString(string);\n      position = position == null\n        ? 0\n        : baseClamp(toInteger(position), 0, string.length);\n\n      target = baseToString(target);\n      return string.slice(position, position + target.length) == target;\n    }\n\n    /**\n     * Creates a compiled template function that can interpolate data properties\n     * in \"interpolate\" delimiters, HTML-escape interpolated data properties in\n     * \"escape\" delimiters, and execute JavaScript in \"evaluate\" delimiters. Data\n     * properties may be accessed as free variables in the template. If a setting\n     * object is given, it takes precedence over `_.templateSettings` values.\n     *\n     * **Note:** In the development build `_.template` utilizes\n     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)\n     * for easier debugging.\n     *\n     * For more information on precompiling templates see\n     * [lodash's custom builds documentation](https://lodash.com/custom-builds).\n     *\n     * For more information on Chrome extension sandboxes see\n     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The template string.\n     * @param {Object} [options={}] The options object.\n     * @param {RegExp} [options.escape=_.templateSettings.escape]\n     *  The HTML \"escape\" delimiter.\n     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]\n     *  The \"evaluate\" delimiter.\n     * @param {Object} [options.imports=_.templateSettings.imports]\n     *  An object to import into the template as free variables.\n     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]\n     *  The \"interpolate\" delimiter.\n     * @param {string} [options.sourceURL='lodash.templateSources[n]']\n     *  The sourceURL of the compiled template.\n     * @param {string} [options.variable='obj']\n     *  The data object variable name.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the compiled template function.\n     * @example\n     *\n     * // Use the \"interpolate\" delimiter to create a compiled template.\n     * var compiled = _.template('hello <%= user %>!');\n     * compiled({ 'user': 'fred' });\n     * // => 'hello fred!'\n     *\n     * // Use the HTML \"escape\" delimiter to escape data property values.\n     * var compiled = _.template('<b><%- value %></b>');\n     * compiled({ 'value': '<script>' });\n     * // => '<b>&lt;script&gt;</b>'\n     *\n     * // Use the \"evaluate\" delimiter to execute JavaScript and generate HTML.\n     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');\n     * compiled({ 'users': ['fred', 'barney'] });\n     * // => '<li>fred</li><li>barney</li>'\n     *\n     * // Use the internal `print` function in \"evaluate\" delimiters.\n     * var compiled = _.template('<% print(\"hello \" + user); %>!');\n     * compiled({ 'user': 'barney' });\n     * // => 'hello barney!'\n     *\n     * // Use the ES template literal delimiter as an \"interpolate\" delimiter.\n     * // Disable support by replacing the \"interpolate\" delimiter.\n     * var compiled = _.template('hello ${ user }!');\n     * compiled({ 'user': 'pebbles' });\n     * // => 'hello pebbles!'\n     *\n     * // Use backslashes to treat delimiters as plain text.\n     * var compiled = _.template('<%= \"\\\\<%- value %\\\\>\" %>');\n     * compiled({ 'value': 'ignored' });\n     * // => '<%- value %>'\n     *\n     * // Use the `imports` option to import `jQuery` as `jq`.\n     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';\n     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });\n     * compiled({ 'users': ['fred', 'barney'] });\n     * // => '<li>fred</li><li>barney</li>'\n     *\n     * // Use the `sourceURL` option to specify a custom sourceURL for the template.\n     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });\n     * compiled(data);\n     * // => Find the source of \"greeting.jst\" under the Sources tab or Resources panel of the web inspector.\n     *\n     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.\n     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });\n     * compiled.source;\n     * // => function(data) {\n     * //   var __t, __p = '';\n     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';\n     * //   return __p;\n     * // }\n     *\n     * // Use custom template delimiters.\n     * _.templateSettings.interpolate = /{{([\\s\\S]+?)}}/g;\n     * var compiled = _.template('hello {{ user }}!');\n     * compiled({ 'user': 'mustache' });\n     * // => 'hello mustache!'\n     *\n     * // Use the `source` property to inline compiled templates for meaningful\n     * // line numbers in error messages and stack traces.\n     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\\\n     *   var JST = {\\\n     *     \"main\": ' + _.template(mainText).source + '\\\n     *   };\\\n     * ');\n     */\n    function template(string, options, guard) {\n      // Based on John Resig's `tmpl` implementation\n      // (http://ejohn.org/blog/javascript-micro-templating/)\n      // and Laura Doktorova's doT.js (https://github.com/olado/doT).\n      var settings = lodash.templateSettings;\n\n      if (guard && isIterateeCall(string, options, guard)) {\n        options = undefined;\n      }\n      string = toString(string);\n      options = assignInWith({}, options, settings, customDefaultsAssignIn);\n\n      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),\n          importsKeys = keys(imports),\n          importsValues = baseValues(imports, importsKeys);\n\n      var isEscaping,\n          isEvaluating,\n          index = 0,\n          interpolate = options.interpolate || reNoMatch,\n          source = \"__p += '\";\n\n      // Compile the regexp to match each delimiter.\n      var reDelimiters = RegExp(\n        (options.escape || reNoMatch).source + '|' +\n        interpolate.source + '|' +\n        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +\n        (options.evaluate || reNoMatch).source + '|$'\n      , 'g');\n\n      // Use a sourceURL for easier debugging.\n      var sourceURL = '//# sourceURL=' +\n        ('sourceURL' in options\n          ? options.sourceURL\n          : ('lodash.templateSources[' + (++templateCounter) + ']')\n        ) + '\\n';\n\n      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {\n        interpolateValue || (interpolateValue = esTemplateValue);\n\n        // Escape characters that can't be included in string literals.\n        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);\n\n        // Replace delimiters with snippets.\n        if (escapeValue) {\n          isEscaping = true;\n          source += \"' +\\n__e(\" + escapeValue + \") +\\n'\";\n        }\n        if (evaluateValue) {\n          isEvaluating = true;\n          source += \"';\\n\" + evaluateValue + \";\\n__p += '\";\n        }\n        if (interpolateValue) {\n          source += \"' +\\n((__t = (\" + interpolateValue + \")) == null ? '' : __t) +\\n'\";\n        }\n        index = offset + match.length;\n\n        // The JS engine embedded in Adobe products needs `match` returned in\n        // order to produce the correct `offset` value.\n        return match;\n      });\n\n      source += \"';\\n\";\n\n      // If `variable` is not specified wrap a with-statement around the generated\n      // code to add the data object to the top of the scope chain.\n      var variable = options.variable;\n      if (!variable) {\n        source = 'with (obj) {\\n' + source + '\\n}\\n';\n      }\n      // Cleanup code by stripping empty strings.\n      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)\n        .replace(reEmptyStringMiddle, '$1')\n        .replace(reEmptyStringTrailing, '$1;');\n\n      // Frame code as the function body.\n      source = 'function(' + (variable || 'obj') + ') {\\n' +\n        (variable\n          ? ''\n          : 'obj || (obj = {});\\n'\n        ) +\n        \"var __t, __p = ''\" +\n        (isEscaping\n           ? ', __e = _.escape'\n           : ''\n        ) +\n        (isEvaluating\n          ? ', __j = Array.prototype.join;\\n' +\n            \"function print() { __p += __j.call(arguments, '') }\\n\"\n          : ';\\n'\n        ) +\n        source +\n        'return __p\\n}';\n\n      var result = attempt(function() {\n        return Function(importsKeys, sourceURL + 'return ' + source)\n          .apply(undefined, importsValues);\n      });\n\n      // Provide the compiled function's source by its `toString` method or\n      // the `source` property as a convenience for inlining compiled templates.\n      result.source = source;\n      if (isError(result)) {\n        throw result;\n      }\n      return result;\n    }\n\n    /**\n     * Converts `string`, as a whole, to lower case just like\n     * [String#toLowerCase](https://mdn.io/toLowerCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the lower cased string.\n     * @example\n     *\n     * _.toLower('--Foo-Bar--');\n     * // => '--foo-bar--'\n     *\n     * _.toLower('fooBar');\n     * // => 'foobar'\n     *\n     * _.toLower('__FOO_BAR__');\n     * // => '__foo_bar__'\n     */\n    function toLower(value) {\n      return toString(value).toLowerCase();\n    }\n\n    /**\n     * Converts `string`, as a whole, to upper case just like\n     * [String#toUpperCase](https://mdn.io/toUpperCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the upper cased string.\n     * @example\n     *\n     * _.toUpper('--foo-bar--');\n     * // => '--FOO-BAR--'\n     *\n     * _.toUpper('fooBar');\n     * // => 'FOOBAR'\n     *\n     * _.toUpper('__foo_bar__');\n     * // => '__FOO_BAR__'\n     */\n    function toUpper(value) {\n      return toString(value).toUpperCase();\n    }\n\n    /**\n     * Removes leading and trailing whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trim('  abc  ');\n     * // => 'abc'\n     *\n     * _.trim('-_-abc-_-', '_-');\n     * // => 'abc'\n     *\n     * _.map(['  foo  ', '  bar  '], _.trim);\n     * // => ['foo', 'bar']\n     */\n    function trim(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrim, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          chrSymbols = stringToArray(chars),\n          start = charsStartIndex(strSymbols, chrSymbols),\n          end = charsEndIndex(strSymbols, chrSymbols) + 1;\n\n      return castSlice(strSymbols, start, end).join('');\n    }\n\n    /**\n     * Removes trailing whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trimEnd('  abc  ');\n     * // => '  abc'\n     *\n     * _.trimEnd('-_-abc-_-', '_-');\n     * // => '-_-abc'\n     */\n    function trimEnd(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrimEnd, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;\n\n      return castSlice(strSymbols, 0, end).join('');\n    }\n\n    /**\n     * Removes leading whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trimStart('  abc  ');\n     * // => 'abc  '\n     *\n     * _.trimStart('-_-abc-_-', '_-');\n     * // => 'abc-_-'\n     */\n    function trimStart(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrimStart, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          start = charsStartIndex(strSymbols, stringToArray(chars));\n\n      return castSlice(strSymbols, start).join('');\n    }\n\n    /**\n     * Truncates `string` if it's longer than the given maximum string length.\n     * The last characters of the truncated string are replaced with the omission\n     * string which defaults to \"...\".\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to truncate.\n     * @param {Object} [options={}] The options object.\n     * @param {number} [options.length=30] The maximum string length.\n     * @param {string} [options.omission='...'] The string to indicate text is omitted.\n     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.\n     * @returns {string} Returns the truncated string.\n     * @example\n     *\n     * _.truncate('hi-diddly-ho there, neighborino');\n     * // => 'hi-diddly-ho there, neighbo...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'length': 24,\n     *   'separator': ' '\n     * });\n     * // => 'hi-diddly-ho there,...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'length': 24,\n     *   'separator': /,? +/\n     * });\n     * // => 'hi-diddly-ho there...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'omission': ' [...]'\n     * });\n     * // => 'hi-diddly-ho there, neig [...]'\n     */\n    function truncate(string, options) {\n      var length = DEFAULT_TRUNC_LENGTH,\n          omission = DEFAULT_TRUNC_OMISSION;\n\n      if (isObject(options)) {\n        var separator = 'separator' in options ? options.separator : separator;\n        length = 'length' in options ? toInteger(options.length) : length;\n        omission = 'omission' in options ? baseToString(options.omission) : omission;\n      }\n      string = toString(string);\n\n      var strLength = string.length;\n      if (hasUnicode(string)) {\n        var strSymbols = stringToArray(string);\n        strLength = strSymbols.length;\n      }\n      if (length >= strLength) {\n        return string;\n      }\n      var end = length - stringSize(omission);\n      if (end < 1) {\n        return omission;\n      }\n      var result = strSymbols\n        ? castSlice(strSymbols, 0, end).join('')\n        : string.slice(0, end);\n\n      if (separator === undefined) {\n        return result + omission;\n      }\n      if (strSymbols) {\n        end += (result.length - end);\n      }\n      if (isRegExp(separator)) {\n        if (string.slice(end).search(separator)) {\n          var match,\n              substring = result;\n\n          if (!separator.global) {\n            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');\n          }\n          separator.lastIndex = 0;\n          while ((match = separator.exec(substring))) {\n            var newEnd = match.index;\n          }\n          result = result.slice(0, newEnd === undefined ? end : newEnd);\n        }\n      } else if (string.indexOf(baseToString(separator), end) != end) {\n        var index = result.lastIndexOf(separator);\n        if (index > -1) {\n          result = result.slice(0, index);\n        }\n      }\n      return result + omission;\n    }\n\n    /**\n     * The inverse of `_.escape`; this method converts the HTML entities\n     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to\n     * their corresponding characters.\n     *\n     * **Note:** No other HTML entities are unescaped. To unescape additional\n     * HTML entities use a third-party library like [_he_](https://mths.be/he).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.6.0\n     * @category String\n     * @param {string} [string=''] The string to unescape.\n     * @returns {string} Returns the unescaped string.\n     * @example\n     *\n     * _.unescape('fred, barney, &amp; pebbles');\n     * // => 'fred, barney, & pebbles'\n     */\n    function unescape(string) {\n      string = toString(string);\n      return (string && reHasEscapedHtml.test(string))\n        ? string.replace(reEscapedHtml, unescapeHtmlChar)\n        : string;\n    }\n\n    /**\n     * Converts `string`, as space separated words, to upper case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the upper cased string.\n     * @example\n     *\n     * _.upperCase('--foo-bar');\n     * // => 'FOO BAR'\n     *\n     * _.upperCase('fooBar');\n     * // => 'FOO BAR'\n     *\n     * _.upperCase('__foo_bar__');\n     * // => 'FOO BAR'\n     */\n    var upperCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + word.toUpperCase();\n    });\n\n    /**\n     * Converts the first character of `string` to upper case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.upperFirst('fred');\n     * // => 'Fred'\n     *\n     * _.upperFirst('FRED');\n     * // => 'FRED'\n     */\n    var upperFirst = createCaseFirst('toUpperCase');\n\n    /**\n     * Splits `string` into an array of its words.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {RegExp|string} [pattern] The pattern to match words.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the words of `string`.\n     * @example\n     *\n     * _.words('fred, barney, & pebbles');\n     * // => ['fred', 'barney', 'pebbles']\n     *\n     * _.words('fred, barney, & pebbles', /[^, ]+/g);\n     * // => ['fred', 'barney', '&', 'pebbles']\n     */\n    function words(string, pattern, guard) {\n      string = toString(string);\n      pattern = guard ? undefined : pattern;\n\n      if (pattern === undefined) {\n        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);\n      }\n      return string.match(pattern) || [];\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Attempts to invoke `func`, returning either the result or the caught error\n     * object. Any additional arguments are provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Function} func The function to attempt.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {*} Returns the `func` result or error object.\n     * @example\n     *\n     * // Avoid throwing errors for invalid selectors.\n     * var elements = _.attempt(function(selector) {\n     *   return document.querySelectorAll(selector);\n     * }, '>_>');\n     *\n     * if (_.isError(elements)) {\n     *   elements = [];\n     * }\n     */\n    var attempt = baseRest(function(func, args) {\n      try {\n        return apply(func, undefined, args);\n      } catch (e) {\n        return isError(e) ? e : new Error(e);\n      }\n    });\n\n    /**\n     * Binds methods of an object to the object itself, overwriting the existing\n     * method.\n     *\n     * **Note:** This method doesn't set the \"length\" property of bound functions.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {Object} object The object to bind and assign the bound methods to.\n     * @param {...(string|string[])} methodNames The object method names to bind.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var view = {\n     *   'label': 'docs',\n     *   'click': function() {\n     *     console.log('clicked ' + this.label);\n     *   }\n     * };\n     *\n     * _.bindAll(view, ['click']);\n     * jQuery(element).on('click', view.click);\n     * // => Logs 'clicked docs' when clicked.\n     */\n    var bindAll = flatRest(function(object, methodNames) {\n      arrayEach(methodNames, function(key) {\n        key = toKey(key);\n        baseAssignValue(object, key, bind(object[key], object));\n      });\n      return object;\n    });\n\n    /**\n     * Creates a function that iterates over `pairs` and invokes the corresponding\n     * function of the first predicate to return truthy. The predicate-function\n     * pairs are invoked with the `this` binding and arguments of the created\n     * function.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {Array} pairs The predicate-function pairs.\n     * @returns {Function} Returns the new composite function.\n     * @example\n     *\n     * var func = _.cond([\n     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],\n     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],\n     *   [_.stubTrue,                      _.constant('no match')]\n     * ]);\n     *\n     * func({ 'a': 1, 'b': 2 });\n     * // => 'matches A'\n     *\n     * func({ 'a': 0, 'b': 1 });\n     * // => 'matches B'\n     *\n     * func({ 'a': '1', 'b': '2' });\n     * // => 'no match'\n     */\n    function cond(pairs) {\n      var length = pairs == null ? 0 : pairs.length,\n          toIteratee = getIteratee();\n\n      pairs = !length ? [] : arrayMap(pairs, function(pair) {\n        if (typeof pair[1] != 'function') {\n          throw new TypeError(FUNC_ERROR_TEXT);\n        }\n        return [toIteratee(pair[0]), pair[1]];\n      });\n\n      return baseRest(function(args) {\n        var index = -1;\n        while (++index < length) {\n          var pair = pairs[index];\n          if (apply(pair[0], this, args)) {\n            return apply(pair[1], this, args);\n          }\n        }\n      });\n    }\n\n    /**\n     * Creates a function that invokes the predicate properties of `source` with\n     * the corresponding property values of a given object, returning `true` if\n     * all predicates return truthy, else `false`.\n     *\n     * **Note:** The created function is equivalent to `_.conformsTo` with\n     * `source` partially applied.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 2, 'b': 1 },\n     *   { 'a': 1, 'b': 2 }\n     * ];\n     *\n     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));\n     * // => [{ 'a': 1, 'b': 2 }]\n     */\n    function conforms(source) {\n      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that returns `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Util\n     * @param {*} value The value to return from the new function.\n     * @returns {Function} Returns the new constant function.\n     * @example\n     *\n     * var objects = _.times(2, _.constant({ 'a': 1 }));\n     *\n     * console.log(objects);\n     * // => [{ 'a': 1 }, { 'a': 1 }]\n     *\n     * console.log(objects[0] === objects[1]);\n     * // => true\n     */\n    function constant(value) {\n      return function() {\n        return value;\n      };\n    }\n\n    /**\n     * Checks `value` to determine whether a default value should be returned in\n     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,\n     * or `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.14.0\n     * @category Util\n     * @param {*} value The value to check.\n     * @param {*} defaultValue The default value.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * _.defaultTo(1, 10);\n     * // => 1\n     *\n     * _.defaultTo(undefined, 10);\n     * // => 10\n     */\n    function defaultTo(value, defaultValue) {\n      return (value == null || value !== value) ? defaultValue : value;\n    }\n\n    /**\n     * Creates a function that returns the result of invoking the given functions\n     * with the `this` binding of the created function, where each successive\n     * invocation is supplied the return value of the previous.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [funcs] The functions to invoke.\n     * @returns {Function} Returns the new composite function.\n     * @see _.flowRight\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var addSquare = _.flow([_.add, square]);\n     * addSquare(1, 2);\n     * // => 9\n     */\n    var flow = createFlow();\n\n    /**\n     * This method is like `_.flow` except that it creates a function that\n     * invokes the given functions from right to left.\n     *\n     * @static\n     * @since 3.0.0\n     * @memberOf _\n     * @category Util\n     * @param {...(Function|Function[])} [funcs] The functions to invoke.\n     * @returns {Function} Returns the new composite function.\n     * @see _.flow\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var addSquare = _.flowRight([square, _.add]);\n     * addSquare(1, 2);\n     * // => 9\n     */\n    var flowRight = createFlow(true);\n\n    /**\n     * This method returns the first argument it receives.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {*} value Any value.\n     * @returns {*} Returns `value`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     *\n     * console.log(_.identity(object) === object);\n     * // => true\n     */\n    function identity(value) {\n      return value;\n    }\n\n    /**\n     * Creates a function that invokes `func` with the arguments of the created\n     * function. If `func` is a property name, the created function returns the\n     * property value for a given element. If `func` is an array or object, the\n     * created function returns `true` for elements that contain the equivalent\n     * source properties, otherwise it returns `false`.\n     *\n     * @static\n     * @since 4.0.0\n     * @memberOf _\n     * @category Util\n     * @param {*} [func=_.identity] The value to convert to a callback.\n     * @returns {Function} Returns the callback.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));\n     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.filter(users, _.iteratee(['user', 'fred']));\n     * // => [{ 'user': 'fred', 'age': 40 }]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.map(users, _.iteratee('user'));\n     * // => ['barney', 'fred']\n     *\n     * // Create custom iteratee shorthands.\n     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {\n     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {\n     *     return func.test(string);\n     *   };\n     * });\n     *\n     * _.filter(['abc', 'def'], /ef/);\n     * // => ['def']\n     */\n    function iteratee(func) {\n      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that performs a partial deep comparison between a given\n     * object and `source`, returning `true` if the given object has equivalent\n     * property values, else `false`.\n     *\n     * **Note:** The created function is equivalent to `_.isMatch` with `source`\n     * partially applied.\n     *\n     * Partial comparisons will match empty array and empty object `source`\n     * values against any array or object value, respectively. See `_.isEqual`\n     * for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Object} source The object of property values to match.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 1, 'b': 2, 'c': 3 },\n     *   { 'a': 4, 'b': 5, 'c': 6 }\n     * ];\n     *\n     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));\n     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]\n     */\n    function matches(source) {\n      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that performs a partial deep comparison between the\n     * value at `path` of a given object to `srcValue`, returning `true` if the\n     * object value is equivalent, else `false`.\n     *\n     * **Note:** Partial comparisons will match empty array and empty object\n     * `srcValue` values against any array or object value, respectively. See\n     * `_.isEqual` for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Util\n     * @param {Array|string} path The path of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 1, 'b': 2, 'c': 3 },\n     *   { 'a': 4, 'b': 5, 'c': 6 }\n     * ];\n     *\n     * _.find(objects, _.matchesProperty('a', 4));\n     * // => { 'a': 4, 'b': 5, 'c': 6 }\n     */\n    function matchesProperty(path, srcValue) {\n      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that invokes the method at `path` of a given object.\n     * Any additional arguments are provided to the invoked method.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Util\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Function} Returns the new invoker function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': { 'b': _.constant(2) } },\n     *   { 'a': { 'b': _.constant(1) } }\n     * ];\n     *\n     * _.map(objects, _.method('a.b'));\n     * // => [2, 1]\n     *\n     * _.map(objects, _.method(['a', 'b']));\n     * // => [2, 1]\n     */\n    var method = baseRest(function(path, args) {\n      return function(object) {\n        return baseInvoke(object, path, args);\n      };\n    });\n\n    /**\n     * The opposite of `_.method`; this method creates a function that invokes\n     * the method at a given path of `object`. Any additional arguments are\n     * provided to the invoked method.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Util\n     * @param {Object} object The object to query.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Function} Returns the new invoker function.\n     * @example\n     *\n     * var array = _.times(3, _.constant),\n     *     object = { 'a': array, 'b': array, 'c': array };\n     *\n     * _.map(['a[2]', 'c[0]'], _.methodOf(object));\n     * // => [2, 0]\n     *\n     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));\n     * // => [2, 0]\n     */\n    var methodOf = baseRest(function(object, args) {\n      return function(path) {\n        return baseInvoke(object, path, args);\n      };\n    });\n\n    /**\n     * Adds all own enumerable string keyed function properties of a source\n     * object to the destination object. If `object` is a function, then methods\n     * are added to its prototype as well.\n     *\n     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to\n     * avoid conflicts caused by modifying the original.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {Function|Object} [object=lodash] The destination object.\n     * @param {Object} source The object of functions to add.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.\n     * @returns {Function|Object} Returns `object`.\n     * @example\n     *\n     * function vowels(string) {\n     *   return _.filter(string, function(v) {\n     *     return /[aeiou]/i.test(v);\n     *   });\n     * }\n     *\n     * _.mixin({ 'vowels': vowels });\n     * _.vowels('fred');\n     * // => ['e']\n     *\n     * _('fred').vowels().value();\n     * // => ['e']\n     *\n     * _.mixin({ 'vowels': vowels }, { 'chain': false });\n     * _('fred').vowels();\n     * // => ['e']\n     */\n    function mixin(object, source, options) {\n      var props = keys(source),\n          methodNames = baseFunctions(source, props);\n\n      if (options == null &&\n          !(isObject(source) && (methodNames.length || !props.length))) {\n        options = source;\n        source = object;\n        object = this;\n        methodNames = baseFunctions(source, keys(source));\n      }\n      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,\n          isFunc = isFunction(object);\n\n      arrayEach(methodNames, function(methodName) {\n        var func = source[methodName];\n        object[methodName] = func;\n        if (isFunc) {\n          object.prototype[methodName] = function() {\n            var chainAll = this.__chain__;\n            if (chain || chainAll) {\n              var result = object(this.__wrapped__),\n                  actions = result.__actions__ = copyArray(this.__actions__);\n\n              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });\n              result.__chain__ = chainAll;\n              return result;\n            }\n            return func.apply(object, arrayPush([this.value()], arguments));\n          };\n        }\n      });\n\n      return object;\n    }\n\n    /**\n     * Reverts the `_` variable to its previous value and returns a reference to\n     * the `lodash` function.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @returns {Function} Returns the `lodash` function.\n     * @example\n     *\n     * var lodash = _.noConflict();\n     */\n    function noConflict() {\n      if (root._ === this) {\n        root._ = oldDash;\n      }\n      return this;\n    }\n\n    /**\n     * This method returns `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.3.0\n     * @category Util\n     * @example\n     *\n     * _.times(2, _.noop);\n     * // => [undefined, undefined]\n     */\n    function noop() {\n      // No operation performed.\n    }\n\n    /**\n     * Creates a function that gets the argument at index `n`. If `n` is negative,\n     * the nth argument from the end is returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {number} [n=0] The index of the argument to return.\n     * @returns {Function} Returns the new pass-thru function.\n     * @example\n     *\n     * var func = _.nthArg(1);\n     * func('a', 'b', 'c', 'd');\n     * // => 'b'\n     *\n     * var func = _.nthArg(-2);\n     * func('a', 'b', 'c', 'd');\n     * // => 'c'\n     */\n    function nthArg(n) {\n      n = toInteger(n);\n      return baseRest(function(args) {\n        return baseNth(args, n);\n      });\n    }\n\n    /**\n     * Creates a function that invokes `iteratees` with the arguments it receives\n     * and returns their results.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [iteratees=[_.identity]]\n     *  The iteratees to invoke.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.over([Math.max, Math.min]);\n     *\n     * func(1, 2, 3, 4);\n     * // => [4, 1]\n     */\n    var over = createOver(arrayMap);\n\n    /**\n     * Creates a function that checks if **all** of the `predicates` return\n     * truthy when invoked with the arguments it receives.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [predicates=[_.identity]]\n     *  The predicates to check.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.overEvery([Boolean, isFinite]);\n     *\n     * func('1');\n     * // => true\n     *\n     * func(null);\n     * // => false\n     *\n     * func(NaN);\n     * // => false\n     */\n    var overEvery = createOver(arrayEvery);\n\n    /**\n     * Creates a function that checks if **any** of the `predicates` return\n     * truthy when invoked with the arguments it receives.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [predicates=[_.identity]]\n     *  The predicates to check.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.overSome([Boolean, isFinite]);\n     *\n     * func('1');\n     * // => true\n     *\n     * func(null);\n     * // => true\n     *\n     * func(NaN);\n     * // => false\n     */\n    var overSome = createOver(arraySome);\n\n    /**\n     * Creates a function that returns the value at `path` of a given object.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Util\n     * @param {Array|string} path The path of the property to get.\n     * @returns {Function} Returns the new accessor function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': { 'b': 2 } },\n     *   { 'a': { 'b': 1 } }\n     * ];\n     *\n     * _.map(objects, _.property('a.b'));\n     * // => [2, 1]\n     *\n     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n     * // => [1, 2]\n     */\n    function property(path) {\n      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n    }\n\n    /**\n     * The opposite of `_.property`; this method creates a function that returns\n     * the value at a given path of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Object} object The object to query.\n     * @returns {Function} Returns the new accessor function.\n     * @example\n     *\n     * var array = [0, 1, 2],\n     *     object = { 'a': array, 'b': array, 'c': array };\n     *\n     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));\n     * // => [2, 0]\n     *\n     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));\n     * // => [2, 0]\n     */\n    function propertyOf(object) {\n      return function(path) {\n        return object == null ? undefined : baseGet(object, path);\n      };\n    }\n\n    /**\n     * Creates an array of numbers (positive and/or negative) progressing from\n     * `start` up to, but not including, `end`. A step of `-1` is used if a negative\n     * `start` is specified without an `end` or `step`. If `end` is not specified,\n     * it's set to `start` with `start` then set to `0`.\n     *\n     * **Note:** JavaScript follows the IEEE-754 standard for resolving\n     * floating-point values which can produce unexpected results.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} [step=1] The value to increment or decrement by.\n     * @returns {Array} Returns the range of numbers.\n     * @see _.inRange, _.rangeRight\n     * @example\n     *\n     * _.range(4);\n     * // => [0, 1, 2, 3]\n     *\n     * _.range(-4);\n     * // => [0, -1, -2, -3]\n     *\n     * _.range(1, 5);\n     * // => [1, 2, 3, 4]\n     *\n     * _.range(0, 20, 5);\n     * // => [0, 5, 10, 15]\n     *\n     * _.range(0, -4, -1);\n     * // => [0, -1, -2, -3]\n     *\n     * _.range(1, 4, 0);\n     * // => [1, 1, 1]\n     *\n     * _.range(0);\n     * // => []\n     */\n    var range = createRange();\n\n    /**\n     * This method is like `_.range` except that it populates values in\n     * descending order.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} [step=1] The value to increment or decrement by.\n     * @returns {Array} Returns the range of numbers.\n     * @see _.inRange, _.range\n     * @example\n     *\n     * _.rangeRight(4);\n     * // => [3, 2, 1, 0]\n     *\n     * _.rangeRight(-4);\n     * // => [-3, -2, -1, 0]\n     *\n     * _.rangeRight(1, 5);\n     * // => [4, 3, 2, 1]\n     *\n     * _.rangeRight(0, 20, 5);\n     * // => [15, 10, 5, 0]\n     *\n     * _.rangeRight(0, -4, -1);\n     * // => [-3, -2, -1, 0]\n     *\n     * _.rangeRight(1, 4, 0);\n     * // => [1, 1, 1]\n     *\n     * _.rangeRight(0);\n     * // => []\n     */\n    var rangeRight = createRange(true);\n\n    /**\n     * This method returns a new empty array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {Array} Returns the new empty array.\n     * @example\n     *\n     * var arrays = _.times(2, _.stubArray);\n     *\n     * console.log(arrays);\n     * // => [[], []]\n     *\n     * console.log(arrays[0] === arrays[1]);\n     * // => false\n     */\n    function stubArray() {\n      return [];\n    }\n\n    /**\n     * This method returns `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {boolean} Returns `false`.\n     * @example\n     *\n     * _.times(2, _.stubFalse);\n     * // => [false, false]\n     */\n    function stubFalse() {\n      return false;\n    }\n\n    /**\n     * This method returns a new empty object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {Object} Returns the new empty object.\n     * @example\n     *\n     * var objects = _.times(2, _.stubObject);\n     *\n     * console.log(objects);\n     * // => [{}, {}]\n     *\n     * console.log(objects[0] === objects[1]);\n     * // => false\n     */\n    function stubObject() {\n      return {};\n    }\n\n    /**\n     * This method returns an empty string.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {string} Returns the empty string.\n     * @example\n     *\n     * _.times(2, _.stubString);\n     * // => ['', '']\n     */\n    function stubString() {\n      return '';\n    }\n\n    /**\n     * This method returns `true`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {boolean} Returns `true`.\n     * @example\n     *\n     * _.times(2, _.stubTrue);\n     * // => [true, true]\n     */\n    function stubTrue() {\n      return true;\n    }\n\n    /**\n     * Invokes the iteratee `n` times, returning an array of the results of\n     * each invocation. The iteratee is invoked with one argument; (index).\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {number} n The number of times to invoke `iteratee`.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the array of results.\n     * @example\n     *\n     * _.times(3, String);\n     * // => ['0', '1', '2']\n     *\n     *  _.times(4, _.constant(0));\n     * // => [0, 0, 0, 0]\n     */\n    function times(n, iteratee) {\n      n = toInteger(n);\n      if (n < 1 || n > MAX_SAFE_INTEGER) {\n        return [];\n      }\n      var index = MAX_ARRAY_LENGTH,\n          length = nativeMin(n, MAX_ARRAY_LENGTH);\n\n      iteratee = getIteratee(iteratee);\n      n -= MAX_ARRAY_LENGTH;\n\n      var result = baseTimes(length, iteratee);\n      while (++index < n) {\n        iteratee(index);\n      }\n      return result;\n    }\n\n    /**\n     * Converts `value` to a property path array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {*} value The value to convert.\n     * @returns {Array} Returns the new property path array.\n     * @example\n     *\n     * _.toPath('a.b.c');\n     * // => ['a', 'b', 'c']\n     *\n     * _.toPath('a[0].b.c');\n     * // => ['a', '0', 'b', 'c']\n     */\n    function toPath(value) {\n      if (isArray(value)) {\n        return arrayMap(value, toKey);\n      }\n      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));\n    }\n\n    /**\n     * Generates a unique ID. If `prefix` is given, the ID is appended to it.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {string} [prefix=''] The value to prefix the ID with.\n     * @returns {string} Returns the unique ID.\n     * @example\n     *\n     * _.uniqueId('contact_');\n     * // => 'contact_104'\n     *\n     * _.uniqueId();\n     * // => '105'\n     */\n    function uniqueId(prefix) {\n      var id = ++idCounter;\n      return toString(prefix) + id;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Adds two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.4.0\n     * @category Math\n     * @param {number} augend The first number in an addition.\n     * @param {number} addend The second number in an addition.\n     * @returns {number} Returns the total.\n     * @example\n     *\n     * _.add(6, 4);\n     * // => 10\n     */\n    var add = createMathOperation(function(augend, addend) {\n      return augend + addend;\n    }, 0);\n\n    /**\n     * Computes `number` rounded up to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round up.\n     * @param {number} [precision=0] The precision to round up to.\n     * @returns {number} Returns the rounded up number.\n     * @example\n     *\n     * _.ceil(4.006);\n     * // => 5\n     *\n     * _.ceil(6.004, 2);\n     * // => 6.01\n     *\n     * _.ceil(6040, -2);\n     * // => 6100\n     */\n    var ceil = createRound('ceil');\n\n    /**\n     * Divide two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {number} dividend The first number in a division.\n     * @param {number} divisor The second number in a division.\n     * @returns {number} Returns the quotient.\n     * @example\n     *\n     * _.divide(6, 4);\n     * // => 1.5\n     */\n    var divide = createMathOperation(function(dividend, divisor) {\n      return dividend / divisor;\n    }, 1);\n\n    /**\n     * Computes `number` rounded down to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round down.\n     * @param {number} [precision=0] The precision to round down to.\n     * @returns {number} Returns the rounded down number.\n     * @example\n     *\n     * _.floor(4.006);\n     * // => 4\n     *\n     * _.floor(0.046, 2);\n     * // => 0.04\n     *\n     * _.floor(4060, -2);\n     * // => 4000\n     */\n    var floor = createRound('floor');\n\n    /**\n     * Computes the maximum value of `array`. If `array` is empty or falsey,\n     * `undefined` is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {*} Returns the maximum value.\n     * @example\n     *\n     * _.max([4, 2, 8, 6]);\n     * // => 8\n     *\n     * _.max([]);\n     * // => undefined\n     */\n    function max(array) {\n      return (array && array.length)\n        ? baseExtremum(array, identity, baseGt)\n        : undefined;\n    }\n\n    /**\n     * This method is like `_.max` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * the value is ranked. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {*} Returns the maximum value.\n     * @example\n     *\n     * var objects = [{ 'n': 1 }, { 'n': 2 }];\n     *\n     * _.maxBy(objects, function(o) { return o.n; });\n     * // => { 'n': 2 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.maxBy(objects, 'n');\n     * // => { 'n': 2 }\n     */\n    function maxBy(array, iteratee) {\n      return (array && array.length)\n        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)\n        : undefined;\n    }\n\n    /**\n     * Computes the mean of the values in `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {number} Returns the mean.\n     * @example\n     *\n     * _.mean([4, 2, 8, 6]);\n     * // => 5\n     */\n    function mean(array) {\n      return baseMean(array, identity);\n    }\n\n    /**\n     * This method is like `_.mean` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the value to be averaged.\n     * The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the mean.\n     * @example\n     *\n     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];\n     *\n     * _.meanBy(objects, function(o) { return o.n; });\n     * // => 5\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.meanBy(objects, 'n');\n     * // => 5\n     */\n    function meanBy(array, iteratee) {\n      return baseMean(array, getIteratee(iteratee, 2));\n    }\n\n    /**\n     * Computes the minimum value of `array`. If `array` is empty or falsey,\n     * `undefined` is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {*} Returns the minimum value.\n     * @example\n     *\n     * _.min([4, 2, 8, 6]);\n     * // => 2\n     *\n     * _.min([]);\n     * // => undefined\n     */\n    function min(array) {\n      return (array && array.length)\n        ? baseExtremum(array, identity, baseLt)\n        : undefined;\n    }\n\n    /**\n     * This method is like `_.min` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * the value is ranked. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {*} Returns the minimum value.\n     * @example\n     *\n     * var objects = [{ 'n': 1 }, { 'n': 2 }];\n     *\n     * _.minBy(objects, function(o) { return o.n; });\n     * // => { 'n': 1 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.minBy(objects, 'n');\n     * // => { 'n': 1 }\n     */\n    function minBy(array, iteratee) {\n      return (array && array.length)\n        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)\n        : undefined;\n    }\n\n    /**\n     * Multiply two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {number} multiplier The first number in a multiplication.\n     * @param {number} multiplicand The second number in a multiplication.\n     * @returns {number} Returns the product.\n     * @example\n     *\n     * _.multiply(6, 4);\n     * // => 24\n     */\n    var multiply = createMathOperation(function(multiplier, multiplicand) {\n      return multiplier * multiplicand;\n    }, 1);\n\n    /**\n     * Computes `number` rounded to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round.\n     * @param {number} [precision=0] The precision to round to.\n     * @returns {number} Returns the rounded number.\n     * @example\n     *\n     * _.round(4.006);\n     * // => 4\n     *\n     * _.round(4.006, 2);\n     * // => 4.01\n     *\n     * _.round(4060, -2);\n     * // => 4100\n     */\n    var round = createRound('round');\n\n    /**\n     * Subtract two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {number} minuend The first number in a subtraction.\n     * @param {number} subtrahend The second number in a subtraction.\n     * @returns {number} Returns the difference.\n     * @example\n     *\n     * _.subtract(6, 4);\n     * // => 2\n     */\n    var subtract = createMathOperation(function(minuend, subtrahend) {\n      return minuend - subtrahend;\n    }, 0);\n\n    /**\n     * Computes the sum of the values in `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.4.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {number} Returns the sum.\n     * @example\n     *\n     * _.sum([4, 2, 8, 6]);\n     * // => 20\n     */\n    function sum(array) {\n      return (array && array.length)\n        ? baseSum(array, identity)\n        : 0;\n    }\n\n    /**\n     * This method is like `_.sum` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the value to be summed.\n     * The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the sum.\n     * @example\n     *\n     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];\n     *\n     * _.sumBy(objects, function(o) { return o.n; });\n     * // => 20\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sumBy(objects, 'n');\n     * // => 20\n     */\n    function sumBy(array, iteratee) {\n      return (array && array.length)\n        ? baseSum(array, getIteratee(iteratee, 2))\n        : 0;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    // Add methods that return wrapped values in chain sequences.\n    lodash.after = after;\n    lodash.ary = ary;\n    lodash.assign = assign;\n    lodash.assignIn = assignIn;\n    lodash.assignInWith = assignInWith;\n    lodash.assignWith = assignWith;\n    lodash.at = at;\n    lodash.before = before;\n    lodash.bind = bind;\n    lodash.bindAll = bindAll;\n    lodash.bindKey = bindKey;\n    lodash.castArray = castArray;\n    lodash.chain = chain;\n    lodash.chunk = chunk;\n    lodash.compact = compact;\n    lodash.concat = concat;\n    lodash.cond = cond;\n    lodash.conforms = conforms;\n    lodash.constant = constant;\n    lodash.countBy = countBy;\n    lodash.create = create;\n    lodash.curry = curry;\n    lodash.curryRight = curryRight;\n    lodash.debounce = debounce;\n    lodash.defaults = defaults;\n    lodash.defaultsDeep = defaultsDeep;\n    lodash.defer = defer;\n    lodash.delay = delay;\n    lodash.difference = difference;\n    lodash.differenceBy = differenceBy;\n    lodash.differenceWith = differenceWith;\n    lodash.drop = drop;\n    lodash.dropRight = dropRight;\n    lodash.dropRightWhile = dropRightWhile;\n    lodash.dropWhile = dropWhile;\n    lodash.fill = fill;\n    lodash.filter = filter;\n    lodash.flatMap = flatMap;\n    lodash.flatMapDeep = flatMapDeep;\n    lodash.flatMapDepth = flatMapDepth;\n    lodash.flatten = flatten;\n    lodash.flattenDeep = flattenDeep;\n    lodash.flattenDepth = flattenDepth;\n    lodash.flip = flip;\n    lodash.flow = flow;\n    lodash.flowRight = flowRight;\n    lodash.fromPairs = fromPairs;\n    lodash.functions = functions;\n    lodash.functionsIn = functionsIn;\n    lodash.groupBy = groupBy;\n    lodash.initial = initial;\n    lodash.intersection = intersection;\n    lodash.intersectionBy = intersectionBy;\n    lodash.intersectionWith = intersectionWith;\n    lodash.invert = invert;\n    lodash.invertBy = invertBy;\n    lodash.invokeMap = invokeMap;\n    lodash.iteratee = iteratee;\n    lodash.keyBy = keyBy;\n    lodash.keys = keys;\n    lodash.keysIn = keysIn;\n    lodash.map = map;\n    lodash.mapKeys = mapKeys;\n    lodash.mapValues = mapValues;\n    lodash.matches = matches;\n    lodash.matchesProperty = matchesProperty;\n    lodash.memoize = memoize;\n    lodash.merge = merge;\n    lodash.mergeWith = mergeWith;\n    lodash.method = method;\n    lodash.methodOf = methodOf;\n    lodash.mixin = mixin;\n    lodash.negate = negate;\n    lodash.nthArg = nthArg;\n    lodash.omit = omit;\n    lodash.omitBy = omitBy;\n    lodash.once = once;\n    lodash.orderBy = orderBy;\n    lodash.over = over;\n    lodash.overArgs = overArgs;\n    lodash.overEvery = overEvery;\n    lodash.overSome = overSome;\n    lodash.partial = partial;\n    lodash.partialRight = partialRight;\n    lodash.partition = partition;\n    lodash.pick = pick;\n    lodash.pickBy = pickBy;\n    lodash.property = property;\n    lodash.propertyOf = propertyOf;\n    lodash.pull = pull;\n    lodash.pullAll = pullAll;\n    lodash.pullAllBy = pullAllBy;\n    lodash.pullAllWith = pullAllWith;\n    lodash.pullAt = pullAt;\n    lodash.range = range;\n    lodash.rangeRight = rangeRight;\n    lodash.rearg = rearg;\n    lodash.reject = reject;\n    lodash.remove = remove;\n    lodash.rest = rest;\n    lodash.reverse = reverse;\n    lodash.sampleSize = sampleSize;\n    lodash.set = set;\n    lodash.setWith = setWith;\n    lodash.shuffle = shuffle;\n    lodash.slice = slice;\n    lodash.sortBy = sortBy;\n    lodash.sortedUniq = sortedUniq;\n    lodash.sortedUniqBy = sortedUniqBy;\n    lodash.split = split;\n    lodash.spread = spread;\n    lodash.tail = tail;\n    lodash.take = take;\n    lodash.takeRight = takeRight;\n    lodash.takeRightWhile = takeRightWhile;\n    lodash.takeWhile = takeWhile;\n    lodash.tap = tap;\n    lodash.throttle = throttle;\n    lodash.thru = thru;\n    lodash.toArray = toArray;\n    lodash.toPairs = toPairs;\n    lodash.toPairsIn = toPairsIn;\n    lodash.toPath = toPath;\n    lodash.toPlainObject = toPlainObject;\n    lodash.transform = transform;\n    lodash.unary = unary;\n    lodash.union = union;\n    lodash.unionBy = unionBy;\n    lodash.unionWith = unionWith;\n    lodash.uniq = uniq;\n    lodash.uniqBy = uniqBy;\n    lodash.uniqWith = uniqWith;\n    lodash.unset = unset;\n    lodash.unzip = unzip;\n    lodash.unzipWith = unzipWith;\n    lodash.update = update;\n    lodash.updateWith = updateWith;\n    lodash.values = values;\n    lodash.valuesIn = valuesIn;\n    lodash.without = without;\n    lodash.words = words;\n    lodash.wrap = wrap;\n    lodash.xor = xor;\n    lodash.xorBy = xorBy;\n    lodash.xorWith = xorWith;\n    lodash.zip = zip;\n    lodash.zipObject = zipObject;\n    lodash.zipObjectDeep = zipObjectDeep;\n    lodash.zipWith = zipWith;\n\n    // Add aliases.\n    lodash.entries = toPairs;\n    lodash.entriesIn = toPairsIn;\n    lodash.extend = assignIn;\n    lodash.extendWith = assignInWith;\n\n    // Add methods to `lodash.prototype`.\n    mixin(lodash, lodash);\n\n    /*------------------------------------------------------------------------*/\n\n    // Add methods that return unwrapped values in chain sequences.\n    lodash.add = add;\n    lodash.attempt = attempt;\n    lodash.camelCase = camelCase;\n    lodash.capitalize = capitalize;\n    lodash.ceil = ceil;\n    lodash.clamp = clamp;\n    lodash.clone = clone;\n    lodash.cloneDeep = cloneDeep;\n    lodash.cloneDeepWith = cloneDeepWith;\n    lodash.cloneWith = cloneWith;\n    lodash.conformsTo = conformsTo;\n    lodash.deburr = deburr;\n    lodash.defaultTo = defaultTo;\n    lodash.divide = divide;\n    lodash.endsWith = endsWith;\n    lodash.eq = eq;\n    lodash.escape = escape;\n    lodash.escapeRegExp = escapeRegExp;\n    lodash.every = every;\n    lodash.find = find;\n    lodash.findIndex = findIndex;\n    lodash.findKey = findKey;\n    lodash.findLast = findLast;\n    lodash.findLastIndex = findLastIndex;\n    lodash.findLastKey = findLastKey;\n    lodash.floor = floor;\n    lodash.forEach = forEach;\n    lodash.forEachRight = forEachRight;\n    lodash.forIn = forIn;\n    lodash.forInRight = forInRight;\n    lodash.forOwn = forOwn;\n    lodash.forOwnRight = forOwnRight;\n    lodash.get = get;\n    lodash.gt = gt;\n    lodash.gte = gte;\n    lodash.has = has;\n    lodash.hasIn = hasIn;\n    lodash.head = head;\n    lodash.identity = identity;\n    lodash.includes = includes;\n    lodash.indexOf = indexOf;\n    lodash.inRange = inRange;\n    lodash.invoke = invoke;\n    lodash.isArguments = isArguments;\n    lodash.isArray = isArray;\n    lodash.isArrayBuffer = isArrayBuffer;\n    lodash.isArrayLike = isArrayLike;\n    lodash.isArrayLikeObject = isArrayLikeObject;\n    lodash.isBoolean = isBoolean;\n    lodash.isBuffer = isBuffer;\n    lodash.isDate = isDate;\n    lodash.isElement = isElement;\n    lodash.isEmpty = isEmpty;\n    lodash.isEqual = isEqual;\n    lodash.isEqualWith = isEqualWith;\n    lodash.isError = isError;\n    lodash.isFinite = isFinite;\n    lodash.isFunction = isFunction;\n    lodash.isInteger = isInteger;\n    lodash.isLength = isLength;\n    lodash.isMap = isMap;\n    lodash.isMatch = isMatch;\n    lodash.isMatchWith = isMatchWith;\n    lodash.isNaN = isNaN;\n    lodash.isNative = isNative;\n    lodash.isNil = isNil;\n    lodash.isNull = isNull;\n    lodash.isNumber = isNumber;\n    lodash.isObject = isObject;\n    lodash.isObjectLike = isObjectLike;\n    lodash.isPlainObject = isPlainObject;\n    lodash.isRegExp = isRegExp;\n    lodash.isSafeInteger = isSafeInteger;\n    lodash.isSet = isSet;\n    lodash.isString = isString;\n    lodash.isSymbol = isSymbol;\n    lodash.isTypedArray = isTypedArray;\n    lodash.isUndefined = isUndefined;\n    lodash.isWeakMap = isWeakMap;\n    lodash.isWeakSet = isWeakSet;\n    lodash.join = join;\n    lodash.kebabCase = kebabCase;\n    lodash.last = last;\n    lodash.lastIndexOf = lastIndexOf;\n    lodash.lowerCase = lowerCase;\n    lodash.lowerFirst = lowerFirst;\n    lodash.lt = lt;\n    lodash.lte = lte;\n    lodash.max = max;\n    lodash.maxBy = maxBy;\n    lodash.mean = mean;\n    lodash.meanBy = meanBy;\n    lodash.min = min;\n    lodash.minBy = minBy;\n    lodash.stubArray = stubArray;\n    lodash.stubFalse = stubFalse;\n    lodash.stubObject = stubObject;\n    lodash.stubString = stubString;\n    lodash.stubTrue = stubTrue;\n    lodash.multiply = multiply;\n    lodash.nth = nth;\n    lodash.noConflict = noConflict;\n    lodash.noop = noop;\n    lodash.now = now;\n    lodash.pad = pad;\n    lodash.padEnd = padEnd;\n    lodash.padStart = padStart;\n    lodash.parseInt = parseInt;\n    lodash.random = random;\n    lodash.reduce = reduce;\n    lodash.reduceRight = reduceRight;\n    lodash.repeat = repeat;\n    lodash.replace = replace;\n    lodash.result = result;\n    lodash.round = round;\n    lodash.runInContext = runInContext;\n    lodash.sample = sample;\n    lodash.size = size;\n    lodash.snakeCase = snakeCase;\n    lodash.some = some;\n    lodash.sortedIndex = sortedIndex;\n    lodash.sortedIndexBy = sortedIndexBy;\n    lodash.sortedIndexOf = sortedIndexOf;\n    lodash.sortedLastIndex = sortedLastIndex;\n    lodash.sortedLastIndexBy = sortedLastIndexBy;\n    lodash.sortedLastIndexOf = sortedLastIndexOf;\n    lodash.startCase = startCase;\n    lodash.startsWith = startsWith;\n    lodash.subtract = subtract;\n    lodash.sum = sum;\n    lodash.sumBy = sumBy;\n    lodash.template = template;\n    lodash.times = times;\n    lodash.toFinite = toFinite;\n    lodash.toInteger = toInteger;\n    lodash.toLength = toLength;\n    lodash.toLower = toLower;\n    lodash.toNumber = toNumber;\n    lodash.toSafeInteger = toSafeInteger;\n    lodash.toString = toString;\n    lodash.toUpper = toUpper;\n    lodash.trim = trim;\n    lodash.trimEnd = trimEnd;\n    lodash.trimStart = trimStart;\n    lodash.truncate = truncate;\n    lodash.unescape = unescape;\n    lodash.uniqueId = uniqueId;\n    lodash.upperCase = upperCase;\n    lodash.upperFirst = upperFirst;\n\n    // Add aliases.\n    lodash.each = forEach;\n    lodash.eachRight = forEachRight;\n    lodash.first = head;\n\n    mixin(lodash, (function() {\n      var source = {};\n      baseForOwn(lodash, function(func, methodName) {\n        if (!hasOwnProperty.call(lodash.prototype, methodName)) {\n          source[methodName] = func;\n        }\n      });\n      return source;\n    }()), { 'chain': false });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * The semantic version number.\n     *\n     * @static\n     * @memberOf _\n     * @type {string}\n     */\n    lodash.VERSION = VERSION;\n\n    // Assign default placeholders.\n    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {\n      lodash[methodName].placeholder = lodash;\n    });\n\n    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.\n    arrayEach(['drop', 'take'], function(methodName, index) {\n      LazyWrapper.prototype[methodName] = function(n) {\n        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);\n\n        var result = (this.__filtered__ && !index)\n          ? new LazyWrapper(this)\n          : this.clone();\n\n        if (result.__filtered__) {\n          result.__takeCount__ = nativeMin(n, result.__takeCount__);\n        } else {\n          result.__views__.push({\n            'size': nativeMin(n, MAX_ARRAY_LENGTH),\n            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')\n          });\n        }\n        return result;\n      };\n\n      LazyWrapper.prototype[methodName + 'Right'] = function(n) {\n        return this.reverse()[methodName](n).reverse();\n      };\n    });\n\n    // Add `LazyWrapper` methods that accept an `iteratee` value.\n    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {\n      var type = index + 1,\n          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;\n\n      LazyWrapper.prototype[methodName] = function(iteratee) {\n        var result = this.clone();\n        result.__iteratees__.push({\n          'iteratee': getIteratee(iteratee, 3),\n          'type': type\n        });\n        result.__filtered__ = result.__filtered__ || isFilter;\n        return result;\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.head` and `_.last`.\n    arrayEach(['head', 'last'], function(methodName, index) {\n      var takeName = 'take' + (index ? 'Right' : '');\n\n      LazyWrapper.prototype[methodName] = function() {\n        return this[takeName](1).value()[0];\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.\n    arrayEach(['initial', 'tail'], function(methodName, index) {\n      var dropName = 'drop' + (index ? '' : 'Right');\n\n      LazyWrapper.prototype[methodName] = function() {\n        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);\n      };\n    });\n\n    LazyWrapper.prototype.compact = function() {\n      return this.filter(identity);\n    };\n\n    LazyWrapper.prototype.find = function(predicate) {\n      return this.filter(predicate).head();\n    };\n\n    LazyWrapper.prototype.findLast = function(predicate) {\n      return this.reverse().find(predicate);\n    };\n\n    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {\n      if (typeof path == 'function') {\n        return new LazyWrapper(this);\n      }\n      return this.map(function(value) {\n        return baseInvoke(value, path, args);\n      });\n    });\n\n    LazyWrapper.prototype.reject = function(predicate) {\n      return this.filter(negate(getIteratee(predicate)));\n    };\n\n    LazyWrapper.prototype.slice = function(start, end) {\n      start = toInteger(start);\n\n      var result = this;\n      if (result.__filtered__ && (start > 0 || end < 0)) {\n        return new LazyWrapper(result);\n      }\n      if (start < 0) {\n        result = result.takeRight(-start);\n      } else if (start) {\n        result = result.drop(start);\n      }\n      if (end !== undefined) {\n        end = toInteger(end);\n        result = end < 0 ? result.dropRight(-end) : result.take(end - start);\n      }\n      return result;\n    };\n\n    LazyWrapper.prototype.takeRightWhile = function(predicate) {\n      return this.reverse().takeWhile(predicate).reverse();\n    };\n\n    LazyWrapper.prototype.toArray = function() {\n      return this.take(MAX_ARRAY_LENGTH);\n    };\n\n    // Add `LazyWrapper` methods to `lodash.prototype`.\n    baseForOwn(LazyWrapper.prototype, function(func, methodName) {\n      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),\n          isTaker = /^(?:head|last)$/.test(methodName),\n          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],\n          retUnwrapped = isTaker || /^find/.test(methodName);\n\n      if (!lodashFunc) {\n        return;\n      }\n      lodash.prototype[methodName] = function() {\n        var value = this.__wrapped__,\n            args = isTaker ? [1] : arguments,\n            isLazy = value instanceof LazyWrapper,\n            iteratee = args[0],\n            useLazy = isLazy || isArray(value);\n\n        var interceptor = function(value) {\n          var result = lodashFunc.apply(lodash, arrayPush([value], args));\n          return (isTaker && chainAll) ? result[0] : result;\n        };\n\n        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {\n          // Avoid lazy use if the iteratee has a \"length\" value other than `1`.\n          isLazy = useLazy = false;\n        }\n        var chainAll = this.__chain__,\n            isHybrid = !!this.__actions__.length,\n            isUnwrapped = retUnwrapped && !chainAll,\n            onlyLazy = isLazy && !isHybrid;\n\n        if (!retUnwrapped && useLazy) {\n          value = onlyLazy ? value : new LazyWrapper(this);\n          var result = func.apply(value, args);\n          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });\n          return new LodashWrapper(result, chainAll);\n        }\n        if (isUnwrapped && onlyLazy) {\n          return func.apply(this, args);\n        }\n        result = this.thru(interceptor);\n        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;\n      };\n    });\n\n    // Add `Array` methods to `lodash.prototype`.\n    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {\n      var func = arrayProto[methodName],\n          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',\n          retUnwrapped = /^(?:pop|shift)$/.test(methodName);\n\n      lodash.prototype[methodName] = function() {\n        var args = arguments;\n        if (retUnwrapped && !this.__chain__) {\n          var value = this.value();\n          return func.apply(isArray(value) ? value : [], args);\n        }\n        return this[chainName](function(value) {\n          return func.apply(isArray(value) ? value : [], args);\n        });\n      };\n    });\n\n    // Map minified method names to their real names.\n    baseForOwn(LazyWrapper.prototype, function(func, methodName) {\n      var lodashFunc = lodash[methodName];\n      if (lodashFunc) {\n        var key = (lodashFunc.name + ''),\n            names = realNames[key] || (realNames[key] = []);\n\n        names.push({ 'name': methodName, 'func': lodashFunc });\n      }\n    });\n\n    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{\n      'name': 'wrapper',\n      'func': undefined\n    }];\n\n    // Add methods to `LazyWrapper`.\n    LazyWrapper.prototype.clone = lazyClone;\n    LazyWrapper.prototype.reverse = lazyReverse;\n    LazyWrapper.prototype.value = lazyValue;\n\n    // Add chain sequence methods to the `lodash` wrapper.\n    lodash.prototype.at = wrapperAt;\n    lodash.prototype.chain = wrapperChain;\n    lodash.prototype.commit = wrapperCommit;\n    lodash.prototype.next = wrapperNext;\n    lodash.prototype.plant = wrapperPlant;\n    lodash.prototype.reverse = wrapperReverse;\n    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;\n\n    // Add lazy aliases.\n    lodash.prototype.first = lodash.prototype.head;\n\n    if (symIterator) {\n      lodash.prototype[symIterator] = wrapperToIterator;\n    }\n    return lodash;\n  });\n\n  /*--------------------------------------------------------------------------*/\n\n  // Export lodash.\n  var _ = runInContext();\n\n  // Some AMD build optimizers, like r.js, check for condition patterns like:\n  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {\n    // Expose Lodash on the global object to prevent errors when Lodash is\n    // loaded by a script tag in the presence of an AMD loader.\n    // See http://requirejs.org/docs/errors.html#mismatch for more details.\n    // Use `_.noConflict` to remove Lodash from the global object.\n    root._ = _;\n\n    // Define as an anonymous module so, through path mapping, it can be\n    // referenced as the \"underscore\" module.\n    define(function() {\n      return _;\n    });\n  }\n  // Check for `exports` after `define` in case a build optimizer adds it.\n  else if (freeModule) {\n    // Export for Node.js.\n    (freeModule.exports = _)._ = _;\n    // Export for CommonJS support.\n    freeExports._ = _;\n  }\n  else {\n    // Export to the global object.\n    root._ = _;\n  }\n}.call(this));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/lodash.js\n// module id = 13\n// module chunks = 0","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() { return this; })();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 14\n// module chunks = 0","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tif(!module.children) module.children = [];\r\n\t\tObject.defineProperty(module, \"loaded\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tconfigurable: false,\r\n\t\t\tget: function() { return module.l; }\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"id\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tconfigurable: false,\r\n\t\t\tget: function() { return module.i; }\r\n\t\t});\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/module.js\n// module id = 15\n// module chunks = 0","\n/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/// <reference path=\"../typings/index.d.ts\" />\nimport * as angular from 'angular';\n\nimport 'angular-ui-router';\nimport 'angular-resource';\nimport 'angular-cookies';\n\nimport 'ngmap';\n\nimport routesConfig from './routes';\nimport {engMap} from './app/components/engMap.component';\nimport {elineSide} from './app/components/eline-side.component';\n\nangular.module('vnaasgui', [\n    'ui.router',\n    'app',\n    'ngMap'\n  ])\n  .config(routesConfig)\n  .component('engMap', engMap)\n  .component('elineSide', elineSide)\n  .run(function(\n    $log: ng.ILogService,\n    $state: ng.ui.IStateService,\n    XosNavigationService: any,\n    XosComponentInjector: any) {\n    $log.info('[vnaasgui] App is running');\n\n    XosNavigationService.add({\n      label: 'vNaaS GUI',\n      state: 'xos.vnaasgui',\n    });\n\n  });\n\n\n\n// WEBPACK FOOTER //\n// ./~/tslint-loader!./src/index.ts","/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\"use strict\";\nexports.__esModule = true;\n/// <reference path=\"../typings/index.d.ts\" />\nvar angular = require(\"angular\");\nrequire(\"angular-ui-router\");\nrequire(\"angular-resource\");\nrequire(\"angular-cookies\");\nrequire(\"ngmap\");\nvar routes_1 = require(\"./routes\");\nvar engMap_component_1 = require(\"./app/components/engMap.component\");\nvar eline_side_component_1 = require(\"./app/components/eline-side.component\");\nangular.module('vnaasgui', [\n    'ui.router',\n    'app',\n    'ngMap'\n])\n    .config(routes_1[\"default\"])\n    .component('engMap', engMap_component_1.engMap)\n    .component('elineSide', eline_side_component_1.elineSide)\n    .run(function ($log, $state, XosNavigationService, XosComponentInjector) {\n    $log.info('[vnaasgui] App is running');\n    XosNavigationService.add({\n        label: 'vNaaS GUI',\n        state: 'xos.vnaasgui'\n    });\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.ts"],"sourceRoot":""}
\ No newline at end of file
diff --git a/xos/gui/.tmp/mapconstants.js b/xos/gui/.tmp/mapconstants.js
deleted file mode 100755
index 217b8c0..0000000
--- a/xos/gui/.tmp/mapconstants.js
+++ /dev/null
@@ -1,22 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-angular.module('app')
-  .constant('MapConfig', {
-    marker: './xos/extensions/vnaasgui/app/img/co.png',
-  });
diff --git a/xos/gui/.tmp/style.config.js b/xos/gui/.tmp/style.config.js
deleted file mode 100755
index 022938b..0000000
--- a/xos/gui/.tmp/style.config.js
+++ /dev/null
@@ -1,40 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-angular.module('app')
-  .constant('StyleConfig', {
-    projectName: 'CORD',
-    favicon: 'cord-favicon.png',
-    background: 'cord-bg.jpg',
-    payoff: 'Your VNF orchestrator',
-    logo: 'cord-logo.png',
-    routes: [
-        {
-            label: 'Slices',
-            state: 'xos.core.slices'
-        },
-        {
-            label: 'Instances',
-            state: 'xos.core.instances'
-        },
-        {
-            label: 'Nodes',
-            state: 'xos.core.nodes'
-        }
-    ]
-});
diff --git a/xos/gui/_DS_Store b/xos/gui/_DS_Store
deleted file mode 100755
index 4894909..0000000
--- a/xos/gui/_DS_Store
+++ /dev/null
Binary files differ
diff --git a/xos/gui/src/app/components/eline-side.component.html b/xos/gui/src/app/components/eline-side.component.html
index e0c19f0..733f022 100755
--- a/xos/gui/src/app/components/eline-side.component.html
+++ b/xos/gui/src/app/components/eline-side.component.html
@@ -7,7 +7,7 @@
 You may obtain a copy of the License at
 
 http://www.apache.org/licenses/LICENSE-2.0
-
+xz
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,50 +15,54 @@
 limitations under the License.
 -->
 
-<div class = "elinepanel">
+<div class="elinepanel">
+  <div class="text-right">
+    <a href ng-click="vm.vng.elinePanel({}, vm.vng.eline, false)">
+      <i class="fa fa-remove" style="color:#fff;"></i>
+    </a>
+  </div>
   <h1>ELine Overview</h1>
-  <form ng-submit="vm.saveEline(vm.eng.eline)">
-    <div class="form-group" ng-hide="vm.eng.createMode">
+  <form ng-submit="vm.saveEline(vm.vng.eline)">
+    <div class="form-group" ng-hide="vm.vng.createMode">
       <label>ID</label><br/>
-      <p>{{vm.eng.eline.id}}</p>
+      <p>{{vm.vng.eline.id}}</p>
     </div>
     <div class="form-group">
       <label for="name">Name</label>
-      <input required class="form-control" id="name" type="text" ng-value="vm.eng.eline.name" ng-model="vm.eng.eline.name">
+      <input required class="form-control" id="name" type="text" ng-value="vm.vng.eline.name" ng-model="vm.vng.eline.name">
     </div>
-    <div class="form-group" ng-hide="vm.eng.createMode">
+    <div class="form-group" ng-hide="vm.vng.createMode">
       <label>Backend Status</label><br/>
-      <p>{{vm.eng.eline.backend_status}}</p>
+      <p>{{vm.vng.eline.backend_status}}</p>
     </div>
     <div class="form-group">
       <label for="cpi1">Connect point 1 ID</label>
-      <input required class="form-control" id="cpi1" type="text" ng-value="vm.eng.eline.connect_point_1_id" ng-model="vm.eng.eline.connect_point_1_id">
+      <input required class="form-control" id="cpi1" type="text" ng-value="vm.vng.eline.connect_point_1_id" ng-model="vm.vng.eline.connect_point_1_id">
     </div>
     <div class="form-group">
       <label for="cpi2">Connect point 2 ID</label>
-      <input required class="form-control" id="cpi2" type="text" ng-value="vm.eng.eline.connect_point_2_id" ng-model="vm.eng.eline.connect_point_2_id">
+      <input required class="form-control" id="cpi2" type="text" ng-value="vm.vng.eline.connect_point_2_id" ng-model="vm.vng.eline.connect_point_2_id">
     </div>
     <div class="form-group">
       <label for="bwps">Bandwidth Profile</label>
       <select required class="form-control"
               id="bwps"
-              ng-model="vm.eng.eline.bwp"
-              ng-options="bwp.name as bwp.name for bwp in vm.eng.bwps | orderBy:'name'"
+              ng-model="vm.vng.eline.bwp"
+              ng-options="bwp.name as bwp.name for bwp in vm.vng.bwps | orderBy:'name'"
       >
       </select>
     </div>
     <div class="form-group">
       <label for="sitename">CORD Site Name</label>
-      <input required class="form-control" id="sitename" type="text" ng-value="vm.eng.eline.cord_site_name" ng-model="vm.eng.eline.cord_site_name">
+      <input required class="form-control" id="sitename" type="text" ng-value="vm.vng.eline.cord_site_name" ng-model="vm.vng.eline.cord_site_name">
     </div>
     <div class="form-group">
       <label for="vlanids">Vlan IDs</label>
-      <input required class="form-control" id="vlanids" type="text" ng-value="vm.eng.eline.vlanids" ng-model="vm.eng.eline.vlanids">
+      <input required class="form-control" id="vlanids" type="text" ng-value="vm.vng.eline.vlanids" ng-model="vm.vng.eline.vlanids">
     </div>
     <div class="form-group" style="text-align: center">
       <button type="submit" class="btn btn-success btn-block">Save Changes</button>
     </div>
   </form>
-  <button type="button" class="btn btn-danger btn-block" ng-click="vm.eng.elinePanel({}, vm.eng.eline, false)">Close</button>
-  <button type="button" class="btn btn-danger delete-eline" ng-click="vm.deleteEline(vm.eng.eline)">Delete Eline</button>
+  <button type="button" class="btn btn-danger btn-block" ng-click="vm.deleteEline(vm.vng.eline)" ng-hide="vm.vng.createMode">Delete Eline</button>
 </div>
\ No newline at end of file
diff --git a/xos/gui/src/app/components/eline-side.component.ts b/xos/gui/src/app/components/eline-side.component.ts
index fb8a2f1..e8613e7 100755
--- a/xos/gui/src/app/components/eline-side.component.ts
+++ b/xos/gui/src/app/components/eline-side.component.ts
@@ -2,14 +2,14 @@
 /*
  * Copyright 2017-present Open Networking Foundation
 
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Apache License, Version 2.0 (the 'License');
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
 
  * http://www.apache.org/licenses/LICENSE-2.0
 
  * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
+ * distributed under the License is distributed on an 'AS IS' BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
@@ -20,7 +20,7 @@
 
 class ElineSide {
 
-  static $inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];
+  static $inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr', 'XosConfirm'];
 
   constructor(
     private XosSidePanel: any,
@@ -28,6 +28,7 @@
     private $http: any,
     private $log: any,
     private toastr: any,
+    private XosConfirm: any,
   ) {
     self = this;
   }
@@ -46,12 +47,23 @@
 
   public deleteEline(item: any) {
     let name = item.name;
-    item.$delete().then((res) => {
-      this.toastr.success(`${name} successfully deleted!`);
-    })
-    .catch((error) => {
-        this.toastr.error(`Error while deleting ${name}: ${error.specific_error}`);
-      });
+    this.XosConfirm.open({
+      header: 'Confirm deletion',
+      text: 'Are you sure you want to delete this? This action cannot be undone.',
+      actions: [{
+        label: 'Delete',
+        class: 'btn-danger',
+        cb: () => {
+          item.$delete().then((res) => {
+            this.toastr.success(`${name} successfully deleted!`);
+          })
+            .catch((error) => {
+              this.toastr.error(`Error while deleting ${name}: ${error.specific_error}`);
+            });
+        }
+      }]
+    });
+
   }
 
 
@@ -62,6 +74,6 @@
   controllerAs: 'vm',
   controller: ElineSide,
   bindings: {
-    eng: '='
+    vng: '='
   }
 };
diff --git a/xos/gui/src/app/components/engMap.component.html b/xos/gui/src/app/components/vnaasMap.component.html
similarity index 92%
rename from xos/gui/src/app/components/engMap.component.html
rename to xos/gui/src/app/components/vnaasMap.component.html
index cf85835..65dff42 100755
--- a/xos/gui/src/app/components/engMap.component.html
+++ b/xos/gui/src/app/components/vnaasMap.component.html
@@ -30,7 +30,7 @@
         min-zoom="2"
         styles="{{vm.mapStyles}}"
       >
-        <!--Markers-->
+
         <marker
           ng-repeat="uni in vm.unis"
           id="marker-{{uni.id}}"
@@ -40,8 +40,6 @@
         >
         </marker>
 
-        <!--Marker Info Window-->
-
         <info-window id = "uni-info">
           <div class = "marker-info">
             <h4>{{vm.current_uni.name}}</h4>
@@ -55,8 +53,6 @@
           </div>
         </info-window>
 
-        <!--Connections-->
-
         <shape
           ng-repeat="eline in vm.elines"
           name="polyline"
@@ -75,4 +71,3 @@
     Changes may not display until page refresh.
   </div>
 </div>
-<!--"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4"-->
\ No newline at end of file
diff --git a/xos/gui/src/app/components/engMap.component.ts b/xos/gui/src/app/components/vnaasMap.component.ts
similarity index 94%
rename from xos/gui/src/app/components/engMap.component.ts
rename to xos/gui/src/app/components/vnaasMap.component.ts
index 1f726c8..4e50194 100755
--- a/xos/gui/src/app/components/engMap.component.ts
+++ b/xos/gui/src/app/components/vnaasMap.component.ts
@@ -24,7 +24,7 @@
 
 let self;
 
-export class EngMap {
+export class VnaasMap {
 
   static $inject = [
     'NgMap',
@@ -140,14 +140,14 @@
     self.map.showInfoWindow('uni-info', this);
   }
 
-  // do not display backend status or ID in create mode
-
+  // fix this function!
   public elinePanel(e: any, eline: any, exists: boolean) {
+
     self.panelOpen = !self.panelOpen;
     if (exists) {
       self.eline = _.find(self.elines, {id: eline.id});
     }
-    self.XosSidePanel.toggleComponent('elineSide', {eline: self.eline, bwplist: self.bwps, eng: self}, false);
+    self.XosSidePanel.toggleComponent('elineSide', {vng: self}, false);
     if (!self.panelOpen && self.createMode) {
       self.createMode = false;
       self.canCreateEline = true;
@@ -191,8 +191,8 @@
 
 }
 
-export const engMap: angular.IComponentOptions = {
-  template: require('./engMap.component.html'),
+export const vnaasMap: angular.IComponentOptions = {
+  template: require('./vnaasMap.component.html'),
   controllerAs: 'vm',
-  controller: EngMap,
+  controller: VnaasMap,
 };
diff --git a/xos/gui/src/app/style/style.css b/xos/gui/src/app/style/style.css
index 44f2f1b..2f2018f 100755
--- a/xos/gui/src/app/style/style.css
+++ b/xos/gui/src/app/style/style.css
@@ -25,17 +25,10 @@
     color: #000000;
 }
 
-body > ui-view > xos > div > xos-side-panel > section > div:nth-child(1) {
-    display: none;
-}
-
 .elinepanel{
     height: 100%;
 }
 
-.delete-eline{
-    position: absolute;
-    right: 0;
-    bottom: 0;
-    margin: 10px;
+section.xos-side-panel > div.row:nth-child(1){
+    display: none;
 }
\ No newline at end of file
diff --git a/xos/gui/src/index.ts b/xos/gui/src/index.ts
index 5dd1151..0461183 100755
--- a/xos/gui/src/index.ts
+++ b/xos/gui/src/index.ts
@@ -26,16 +26,16 @@
 import 'ngmap';
 
 import routesConfig from './routes';
-import {engMap} from './app/components/engMap.component';
+import {vnaasMap} from './app/components/vnaasMap.component';
 import {elineSide} from './app/components/eline-side.component';
 
 angular.module('vnaasgui', [
-    'ui.router',
-    'app',
-    'ngMap'
-  ])
+  'ui.router',
+  'app',
+  'ngMap'
+])
   .config(routesConfig)
-  .component('engMap', engMap)
+  .component('vnaasMap', vnaasMap)
   .component('elineSide', elineSide)
   .run(function(
     $log: ng.ILogService,
@@ -45,7 +45,7 @@
     $log.info('[vnaasgui] App is running');
 
     XosNavigationService.add({
-      label: 'vNaaS GUI',
+      label: 'VNaaS GUI',
       state: 'xos.vnaasgui',
     });
 
diff --git a/xos/gui/src/routes.ts b/xos/gui/src/routes.ts
index eb1f5ad..b36dad1 100755
--- a/xos/gui/src/routes.ts
+++ b/xos/gui/src/routes.ts
@@ -25,6 +25,6 @@
     .state('xos.vnaasgui', {
       url: 'vnaasgui',
       parent: 'xos',
-      component: 'engMap'
+      component: 'vnaasMap'
     });
 }
