From 1ee78ab657264250a577d60b67942014fda11d83 Mon Sep 17 00:00:00 2001 From: Andreas Baldeau Date: Sun, 10 Aug 2014 12:02:48 +0200 Subject: [PATCH] Bower modules updated. --- .../angular-mocks/.bower.json | 12 +- .../angular-mocks/angular-mocks.js | 26 +- app/bower_components/angular-mocks/bower.json | 4 +- .../angular-route/.bower.json | 12 +- .../angular-route/angular-route.js | 10 +- .../angular-route/angular-route.min.js | 18 +- .../angular-route/angular-route.min.js.map | 4 +- app/bower_components/angular-route/bower.json | 4 +- .../angular-sanitize/.bower.json | 12 +- .../angular-sanitize/angular-sanitize.js | 80 +- .../angular-sanitize/angular-sanitize.min.js | 19 +- .../angular-sanitize.min.js.map | 6 +- .../angular-sanitize/bower.json | 4 +- .../angular-scenario/.bower.json | 12 +- .../angular-scenario/angular-scenario.js | 3027 ++++++++++------- .../angular-scenario/bower.json | 4 +- app/bower_components/angular/.bower.json | 10 +- app/bower_components/angular/angular-csp.css | 6 + app/bower_components/angular/angular.js | 3017 +++++++++------- app/bower_components/angular/angular.min.js | 414 +-- .../angular/angular.min.js.gzip | Bin 39258 -> 39367 bytes .../angular/angular.min.js.map | 6 +- app/bower_components/angular/bower.json | 2 +- .../bootstrap-sass-official/.bower.json | 47 +- .../bootstrap-sass-official/CHANGELOG.md | 11 + .../bootstrap-sass-official/README.md | 180 +- .../glyphicons-halflings-regular.eot | Bin .../glyphicons-halflings-regular.svg | 0 .../glyphicons-halflings-regular.ttf | Bin .../glyphicons-halflings-regular.woff | Bin .../assets/javascripts/bootstrap-sprockets.js | 12 + .../assets/javascripts/bootstrap.js | 2107 ++++++++++++ .../assets/javascripts/bootstrap/affix.js | 29 +- .../assets/javascripts/bootstrap/alert.js | 16 +- .../assets/javascripts/bootstrap/button.js | 17 +- .../assets/javascripts/bootstrap/carousel.js | 80 +- .../assets/javascripts/bootstrap/collapse.js | 41 +- .../assets/javascripts/bootstrap/dropdown.js | 13 +- .../assets/javascripts/bootstrap/modal.js | 35 +- .../assets/javascripts/bootstrap/popover.js | 15 +- .../assets/javascripts/bootstrap/scrollspy.js | 60 +- .../assets/javascripts/bootstrap/tab.js | 19 +- .../assets/javascripts/bootstrap/tooltip.js | 69 +- .../javascripts/bootstrap/transition.js | 17 +- .../stylesheets/_bootstrap-compass.scss | 7 + .../assets/stylesheets/_bootstrap-mincer.scss | 0 .../stylesheets/_bootstrap-sprockets.scss | 7 + .../assets/stylesheets/bootstrap.scss | 0 .../assets/stylesheets/bootstrap/_alerts.scss | 7 +- .../assets/stylesheets/bootstrap/_badges.scss | 0 .../stylesheets/bootstrap/_breadcrumbs.scss | 0 .../stylesheets/bootstrap/_button-groups.scss | 6 +- .../stylesheets/bootstrap/_buttons.scss | 2 - .../stylesheets/bootstrap/_carousel.scss | 4 +- .../assets/stylesheets/bootstrap/_close.scss | 0 .../assets/stylesheets/bootstrap/_code.scss | 6 + .../bootstrap/_component-animations.scss | 0 .../stylesheets/bootstrap/_dropdowns.scss | 1 + .../assets/stylesheets/bootstrap/_forms.scss | 106 +- .../stylesheets/bootstrap/_glyphicons.scss | 8 +- .../assets/stylesheets/bootstrap/_grid.scss | 0 .../stylesheets/bootstrap/_input-groups.scss | 8 +- .../stylesheets/bootstrap/_jumbotron.scss | 0 .../assets/stylesheets/bootstrap/_labels.scss | 0 .../stylesheets/bootstrap/_list-group.scss | 7 +- .../assets/stylesheets/bootstrap/_media.scss | 0 .../assets/stylesheets/bootstrap/_mixins.scss | 0 .../assets/stylesheets/bootstrap/_modals.scss | 11 +- .../assets/stylesheets/bootstrap/_navbar.scss | 1 + .../assets/stylesheets/bootstrap/_navs.scss | 2 +- .../stylesheets/bootstrap/_normalize.scss | 0 .../assets/stylesheets/bootstrap/_pager.scss | 0 .../stylesheets/bootstrap/_pagination.scss | 0 .../assets/stylesheets/bootstrap/_panels.scss | 9 +- .../stylesheets/bootstrap/_popovers.scss | 0 .../assets/stylesheets/bootstrap/_print.scss | 0 .../stylesheets/bootstrap/_progress-bars.scss | 20 +- .../bootstrap/_responsive-embed.scss | 0 .../bootstrap/_responsive-utilities.scss | 3 +- .../stylesheets/bootstrap/_scaffolding.scss | 2 +- .../assets/stylesheets/bootstrap/_tables.scss | 4 +- .../assets/stylesheets/bootstrap/_theme.scss | 11 + .../stylesheets/bootstrap/_thumbnails.scss | 0 .../stylesheets/bootstrap/_tooltip.scss | 0 .../assets/stylesheets/bootstrap/_type.scss | 22 +- .../stylesheets/bootstrap/_utilities.scss | 1 + .../stylesheets/bootstrap/_variables.scss | 29 +- .../assets/stylesheets/bootstrap/_wells.scss | 0 .../stylesheets/bootstrap/bootstrap.scss | 0 .../stylesheets/bootstrap/mixins/_alerts.scss | 0 .../bootstrap/mixins/_background-variant.scss | 0 .../bootstrap/mixins/_border-radius.scss | 0 .../bootstrap/mixins/_buttons.scss | 0 .../bootstrap/mixins/_center-block.scss | 0 .../bootstrap/mixins/_clearfix.scss | 0 .../stylesheets/bootstrap/mixins/_forms.scss | 0 .../bootstrap/mixins/_gradients.scss | 2 +- .../bootstrap/mixins/_grid-framework.scss | 10 +- .../stylesheets/bootstrap/mixins/_grid.scss | 6 +- .../bootstrap/mixins/_hide-text.scss | 0 .../stylesheets/bootstrap/mixins/_image.scss | 1 + .../stylesheets/bootstrap/mixins/_labels.scss | 0 .../bootstrap/mixins/_list-group.scss | 0 .../bootstrap/mixins/_nav-divider.scss | 0 .../bootstrap/mixins/_nav-vertical-align.scss | 0 .../bootstrap/mixins/_opacity.scss | 0 .../bootstrap/mixins/_pagination.scss | 0 .../stylesheets/bootstrap/mixins/_panels.scss | 4 + .../bootstrap/mixins/_progress-bar.scss | 2 + .../bootstrap/mixins/_reset-filter.scss | 0 .../stylesheets/bootstrap/mixins/_resize.scss | 2 +- .../mixins/_responsive-visibility.scss | 0 .../stylesheets/bootstrap/mixins/_size.scss | 0 .../bootstrap/mixins/_tab-focus.scss | 0 .../bootstrap/mixins/_table-row.scss | 0 .../bootstrap/mixins/_text-emphasis.scss | 0 .../bootstrap/mixins/_text-overflow.scss | 0 .../bootstrap/mixins/_vendor-prefixes.scss | 15 +- .../bootstrap-sass-official/bower.json | 41 +- .../bootstrap-sass-official/composer.json | 2 +- .../bootstrap-sass-official/package.json | 2 +- .../bootstrap-sass-official/sache.json | 5 + .../vendor/assets/javascripts/bootstrap.js | 12 - app/bower_components/es5-shim/.bower.json | 10 +- app/bower_components/es5-shim/CHANGES | 9 + app/bower_components/es5-shim/bower.json | 2 +- app/bower_components/es5-shim/component.json | 2 +- app/bower_components/es5-shim/es5-shim.js | 774 +++-- app/bower_components/es5-shim/es5-shim.map | 2 +- app/bower_components/es5-shim/es5-shim.min.js | 2 +- app/bower_components/es5-shim/package.json | 11 +- app/bower_components/es5-shim/shims.json | 2 +- app/bower_components/json3/.bower.json | 28 +- app/bower_components/json3/CHANGELOG.md | 44 + app/bower_components/json3/CONTRIBUTING.md | 3 + app/bower_components/json3/README.md | 10 +- app/bower_components/json3/bower.json | 25 +- app/bower_components/json3/lib/json3.js | 4 +- app/bower_components/json3/lib/json3.min.js | 4 +- bower.json | 14 +- 140 files changed, 7098 insertions(+), 3713 deletions(-) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/fonts/bootstrap/glyphicons-halflings-regular.eot (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/fonts/bootstrap/glyphicons-halflings-regular.svg (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/fonts/bootstrap/glyphicons-halflings-regular.woff (100%) create mode 100644 app/bower_components/bootstrap-sass-official/assets/javascripts/bootstrap-sprockets.js create mode 100644 app/bower_components/bootstrap-sass-official/assets/javascripts/bootstrap.js rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/affix.js (88%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/alert.js (87%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/button.js (90%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/carousel.js (71%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/collapse.js (85%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/dropdown.js (95%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/modal.js (89%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/popover.js (89%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/scrollspy.js (71%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/tab.js (91%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/tooltip.js (87%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/javascripts/bootstrap/transition.js (76%) create mode 100644 app/bower_components/bootstrap-sass-official/assets/stylesheets/_bootstrap-compass.scss rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/_bootstrap-mincer.scss (100%) create mode 100644 app/bower_components/bootstrap-sass-official/assets/stylesheets/_bootstrap-sprockets.scss rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_alerts.scss (89%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_badges.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_breadcrumbs.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_button-groups.scss (98%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_buttons.scss (98%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_carousel.scss (99%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_close.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_code.scss (94%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_component-animations.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_dropdowns.scss (99%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_forms.scss (86%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_glyphicons.scss (98%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_grid.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_input-groups.scss (96%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_jumbotron.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_labels.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_list-group.scss (95%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_media.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_mixins.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_modals.scss (95%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_navbar.scss (99%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_navs.scss (99%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_normalize.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_pager.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_pagination.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_panels.scss (97%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_popovers.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_print.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_progress-bars.scss (75%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_responsive-embed.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_responsive-utilities.scss (96%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_scaffolding.scss (99%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_tables.scss (99%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_theme.scss (95%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_thumbnails.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_tooltip.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_type.scss (91%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_utilities.scss (96%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_variables.scss (97%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/_wells.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/bootstrap.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_alerts.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_background-variant.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_border-radius.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_buttons.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_center-block.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_clearfix.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_forms.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_gradients.scss (96%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_grid-framework.scss (91%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_grid.scss (96%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_hide-text.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_image.scss (94%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_labels.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_list-group.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_nav-divider.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_opacity.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_pagination.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_panels.scss (82%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_progress-bar.scss (72%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_reset-filter.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_resize.scss (56%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_size.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_tab-focus.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_table-row.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_text-overflow.scss (100%) rename app/bower_components/bootstrap-sass-official/{vendor => }/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss (93%) create mode 100644 app/bower_components/bootstrap-sass-official/sache.json delete mode 100644 app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap.js create mode 100644 app/bower_components/json3/CHANGELOG.md create mode 100644 app/bower_components/json3/CONTRIBUTING.md diff --git a/app/bower_components/angular-mocks/.bower.json b/app/bower_components/angular-mocks/.bower.json index ce38275..d7ca1a0 100644 --- a/app/bower_components/angular-mocks/.bower.json +++ b/app/bower_components/angular-mocks/.bower.json @@ -1,18 +1,18 @@ { "name": "angular-mocks", - "version": "1.2.16", + "version": "1.2.21", "main": "./angular-mocks.js", "dependencies": { - "angular": "1.2.16" + "angular": "1.2.21" }, "homepage": "https://github.com/angular/bower-angular-mocks", - "_release": "1.2.16", + "_release": "1.2.21", "_resolution": { "type": "version", - "tag": "v1.2.16", - "commit": "e429a011d88c402430329449500f352751d1a137" + "tag": "v1.2.21", + "commit": "ab33e90eaec5bb2c96126e808ae9f44cf59b7205" }, "_source": "git://github.com/angular/bower-angular-mocks.git", - "_target": "1.2.16", + "_target": "1.2.21", "_originalSource": "angular-mocks" } \ No newline at end of file diff --git a/app/bower_components/angular-mocks/angular-mocks.js b/app/bower_components/angular-mocks/angular-mocks.js index da804b4..c2f9cec 100644 --- a/app/bower_components/angular-mocks/angular-mocks.js +++ b/app/bower_components/angular-mocks/angular-mocks.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.2.16 + * @license AngularJS v1.2.21 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -462,7 +462,7 @@ angular.mock.$IntervalProvider = function() { iteration = 0, skipApply = (angular.isDefined(invokeApply) && !invokeApply); - count = (angular.isDefined(count)) ? count : 0, + count = (angular.isDefined(count)) ? count : 0; promise.then(null, null, fn); promise.$$intervalId = nextRepeatId; @@ -900,7 +900,7 @@ angular.mock.dump = function(object) { * When an Angular application needs some data from a server, it calls the $http service, which * sends the request to a real server using $httpBackend service. With dependency injection, it is * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify - * the requests and respond with some testing data without sending a request to real server. + * the requests and respond with some testing data without sending a request to a real server. * * There are two ways to specify what test data should be returned as http responses by the mock * backend when the code under test makes http requests: @@ -1722,11 +1722,12 @@ angular.mock.$RootElementProvider = function() { /** * @ngdoc module * @name ngMock + * @packageName angular-mocks * @description * * # ngMock * - * The `ngMock` module providers support to inject and mock Angular services into unit tests. + * The `ngMock` module provides support to inject and mock Angular services into unit tests. * In addition, ngMock also extends various core ng services such that they can be * inspected and controlled in a synchronous manner within test code. * @@ -1751,6 +1752,7 @@ angular.module('ngMock', ['ng']).provider({ * @ngdoc module * @name ngMockE2E * @module ngMockE2E + * @packageName angular-mocks * @description * * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing. @@ -1800,7 +1802,9 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * * // adds a new phone to the phones array * $httpBackend.whenPOST('/phones').respond(function(method, url, data) { - * phones.push(angular.fromJson(data)); + * var phone = angular.fromJson(data); + * phones.push(phone); + * return [200, phone, {}]; * }); * $httpBackend.whenGET(/^\/templates\//).passThrough(); * //... @@ -1956,13 +1960,19 @@ if(window.jasmine || window.mocha) { }; - beforeEach(function() { + (window.beforeEach || window.setup)(function() { currentSpec = this; }); - afterEach(function() { + (window.afterEach || window.teardown)(function() { var injector = currentSpec.$injector; + angular.forEach(currentSpec.$modules, function(module) { + if (module && module.$$hashKey) { + module.$$hashKey = undefined; + } + }); + currentSpec.$injector = null; currentSpec.$modules = null; currentSpec = null; @@ -2002,7 +2012,7 @@ if(window.jasmine || window.mocha) { * @param {...(string|Function|Object)} fns any number of modules which are represented as string * aliases or as anonymous module initialization functions. The modules are used to * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an - * object literal is passed they will be register as values in the module, the key being + * object literal is passed they will be registered as values in the module, the key being * the module name and the value being what is returned. */ window.module = angular.mock.module = function() { diff --git a/app/bower_components/angular-mocks/bower.json b/app/bower_components/angular-mocks/bower.json index 09d2e7c..5ad409f 100644 --- a/app/bower_components/angular-mocks/bower.json +++ b/app/bower_components/angular-mocks/bower.json @@ -1,8 +1,8 @@ { "name": "angular-mocks", - "version": "1.2.16", + "version": "1.2.21", "main": "./angular-mocks.js", "dependencies": { - "angular": "1.2.16" + "angular": "1.2.21" } } diff --git a/app/bower_components/angular-route/.bower.json b/app/bower_components/angular-route/.bower.json index 4bacfc5..10cb905 100644 --- a/app/bower_components/angular-route/.bower.json +++ b/app/bower_components/angular-route/.bower.json @@ -1,18 +1,18 @@ { "name": "angular-route", - "version": "1.2.16", + "version": "1.2.21", "main": "./angular-route.js", "dependencies": { - "angular": "1.2.16" + "angular": "1.2.21" }, "homepage": "https://github.com/angular/bower-angular-route", - "_release": "1.2.16", + "_release": "1.2.21", "_resolution": { "type": "version", - "tag": "v1.2.16", - "commit": "ed0e2b796077d953f518cb81cc7af981cf695a45" + "tag": "v1.2.21", + "commit": "a3f4ff7700330ef8e1e84b31177fa1b2206884c8" }, "_source": "git://github.com/angular/bower-angular-route.git", - "_target": "1.2.16", + "_target": "~1.2.21", "_originalSource": "angular-route" } \ No newline at end of file diff --git a/app/bower_components/angular-route/angular-route.js b/app/bower_components/angular-route/angular-route.js index f7ebda8..a589753 100644 --- a/app/bower_components/angular-route/angular-route.js +++ b/app/bower_components/angular-route/angular-route.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.2.16 + * @license AngularJS v1.2.21 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -27,7 +27,7 @@ var ngRouteModule = angular.module('ngRoute', ['ng']). /** * @ngdoc provider * @name $routeProvider - * @function + * @kind function * * @description * @@ -473,9 +473,7 @@ function $RouteProvider(){ for (var i = 1, len = m.length; i < len; ++i) { var key = keys[i - 1]; - var val = 'string' == typeof m[i] - ? decodeURIComponent(m[i]) - : m[i]; + var val = m[i]; if (key && val) { params[key.name] = val; @@ -632,7 +630,7 @@ ngRouteModule.provider('$routeParams', $RouteParamsProvider); * // Route: /Chapter/:chapterId/Section/:sectionId * // * // Then - * $routeParams ==> {chapterId:1, sectionId:2, search:'moby'} + * $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'} * ``` */ function $RouteParamsProvider() { diff --git a/app/bower_components/angular-route/angular-route.min.js b/app/bower_components/angular-route/angular-route.min.js index aef1fd6..54e7dc9 100644 --- a/app/bower_components/angular-route/angular-route.min.js +++ b/app/bower_components/angular-route/angular-route.min.js @@ -1,14 +1,14 @@ /* - AngularJS v1.2.16 + AngularJS v1.2.21 (c) 2010-2014 Google, Inc. http://angularjs.org License: MIT */ -(function(n,e,A){'use strict';function x(s,g,k){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,w){function y(){p&&(p.remove(),p=null);h&&(h.$destroy(),h=null);l&&(k.leave(l,function(){p=null}),p=l,l=null)}function v(){var b=s.current&&s.current.locals;if(e.isDefined(b&&b.$template)){var b=a.$new(),d=s.current;l=w(b,function(d){k.enter(d,null,l||c,function(){!e.isDefined(t)||t&&!a.$eval(t)||g()});y()});h=d.scope=b;h.$emit("$viewContentLoaded");h.$eval(u)}else y()} -var h,l,p,t=b.autoscroll,u=b.onload||"";a.$on("$routeChangeSuccess",v);v()}}}function z(e,g,k){return{restrict:"ECA",priority:-400,link:function(a,c){var b=k.current,f=b.locals;c.html(f.$template);var w=e(c.contents());b.controller&&(f.$scope=a,f=g(b.controller,f),b.controllerAs&&(a[b.controllerAs]=f),c.data("$ngControllerController",f),c.children().data("$ngControllerController",f));w(a)}}}n=e.module("ngRoute",["ng"]).provider("$route",function(){function s(a,c){return e.extend(new (e.extend(function(){}, -{prototype:a})),c)}function g(a,e){var b=e.caseInsensitiveMatch,f={originalPath:a,regexp:a},k=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,e,b,c){a="?"===c?c:null;c="*"===c?c:null;k.push({name:b,optional:!!a});e=e||"";return""+(a?"":e)+"(?:"+(a?e:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=RegExp("^"+a+"$",b?"i":"");return f}var k={};this.when=function(a,c){k[a]=e.extend({reloadOnSearch:!0},c,a&&g(a,c));if(a){var b= -"/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";k[b]=e.extend({redirectTo:a},g(b,c))}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,c,b,f,g,n,v,h){function l(){var d=p(),m=r.current;if(d&&m&&d.$$route===m.$$route&&e.equals(d.pathParams,m.pathParams)&&!d.reloadOnSearch&&!u)m.params=d.params,e.copy(m.params,b),a.$broadcast("$routeUpdate",m);else if(d||m)u=!1,a.$broadcast("$routeChangeStart", -d,m),(r.current=d)&&d.redirectTo&&(e.isString(d.redirectTo)?c.path(t(d.redirectTo,d.params)).search(d.params).replace():c.url(d.redirectTo(d.pathParams,c.path(),c.search())).replace()),f.when(d).then(function(){if(d){var a=e.extend({},d.resolve),c,b;e.forEach(a,function(d,c){a[c]=e.isString(d)?g.get(d):g.invoke(d)});e.isDefined(c=d.template)?e.isFunction(c)&&(c=c(d.params)):e.isDefined(b=d.templateUrl)&&(e.isFunction(b)&&(b=b(d.params)),b=h.getTrustedResourceUrl(b),e.isDefined(b)&&(d.loadedTemplateUrl= -b,c=n.get(b,{cache:v}).then(function(a){return a.data})));e.isDefined(c)&&(a.$template=c);return f.all(a)}}).then(function(c){d==r.current&&(d&&(d.locals=c,e.copy(d.params,b)),a.$broadcast("$routeChangeSuccess",d,m))},function(c){d==r.current&&a.$broadcast("$routeChangeError",d,m,c)})}function p(){var a,b;e.forEach(k,function(f,k){var q;if(q=!b){var g=c.path();q=f.keys;var l={};if(f.regexp)if(g=f.regexp.exec(g)){for(var h=1,p=g.length;h + -
+
Snippet: @@ -158,14 +159,15 @@ function sanitizeText(chars) { // Regular Expressions for parsing tags and attributes var START_TAG_REGEXP = - /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, - END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/, + /^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/, + END_TAG_REGEXP = /^<\/\s*([\w:-]+)[^>]*>/, ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, BEGIN_TAG_REGEXP = /^/g, DOCTYPE_REGEXP = /]*?)>/i, CDATA_REGEXP = //g, + SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, // Match everything outside of normal chars and " (quote character) NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; @@ -235,10 +237,11 @@ function makeMap(str) { * @param {object} handler */ function htmlParser( html, handler ) { - var index, chars, match, stack = [], last = html; + var index, chars, match, stack = [], last = html, text; stack.last = function() { return stack[ stack.length - 1 ]; }; while ( html ) { + text = ''; chars = true; // Make sure we're not in a script or style element @@ -277,16 +280,23 @@ function htmlParser( html, handler ) { match = html.match( START_TAG_REGEXP ); if ( match ) { - html = html.substring( match[0].length ); - match[0].replace( START_TAG_REGEXP, parseStartTag ); + // We only have a valid start-tag if there is a '>'. + if ( match[4] ) { + html = html.substring( match[0].length ); + match[0].replace( START_TAG_REGEXP, parseStartTag ); + } chars = false; + } else { + // no ending tag found --- this piece should be encoded as an entity. + text += '<'; + html = html.substring(1); } } if ( chars ) { index = html.indexOf("<"); - var text = index < 0 ? html : html.substring( 0, index ); + text += index < 0 ? html : html.substring( 0, index ); html = index < 0 ? "" : html.substring( index ); if (handler.chars) handler.chars( decodeEntities(text) ); @@ -404,6 +414,11 @@ function decodeEntities(value) { function encodeEntities(value) { return value. replace(/&/g, '&'). + replace(SURROGATE_PAIR_REGEXP, function (value) { + var hi = value.charCodeAt(0); + var low = value.charCodeAt(1); + return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';'; + }). replace(NON_ALPHANUMERIC_REGEXP, function(value){ return '&#' + value.charCodeAt(0) + ';'; }). @@ -476,7 +491,7 @@ angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider); /** * @ngdoc filter * @name linky - * @function + * @kind function * * @description * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and @@ -492,20 +507,21 @@ angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider); * * @example - + -
+
Snippet:
diff --git a/app/bower_components/angular-sanitize/angular-sanitize.min.js b/app/bower_components/angular-sanitize/angular-sanitize.min.js index 0896471..b7f8105 100644 --- a/app/bower_components/angular-sanitize/angular-sanitize.min.js +++ b/app/bower_components/angular-sanitize/angular-sanitize.min.js @@ -1,14 +1,15 @@ /* - AngularJS v1.2.16 + AngularJS v1.2.21 (c) 2010-2014 Google, Inc. http://angularjs.org License: MIT */ -(function(p,h,q){'use strict';function E(a){var e=[];s(e,h.noop).chars(a);return e.join("")}function k(a){var e={};a=a.split(",");var d;for(d=0;d=c;d--)e.end&&e.end(f[d]);f.length=c}}var b,g,f=[],l=a;for(f.last=function(){return f[f.length-1]};a;){g=!0;if(f.last()&&x[f.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(b,a){a=a.replace(H,"$1").replace(I,"$1");e.chars&&e.chars(r(a));return""}),c("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(e.comment&&e.comment(a.substring(4,b)),a=a.substring(b+3),g=!1);else if(y.test(a)){if(b=a.match(y))a= -a.replace(b[0],""),g=!1}else if(J.test(a)){if(b=a.match(z))a=a.substring(b[0].length),b[0].replace(z,c),g=!1}else K.test(a)&&(b=a.match(A))&&(a=a.substring(b[0].length),b[0].replace(A,d),g=!1);g&&(b=a.indexOf("<"),g=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),e.chars&&e.chars(r(g)))}if(a==l)throw L("badparse",a);l=a}c()}function r(a){if(!a)return"";var e=M.exec(a);a=e[1];var d=e[3];if(e=e[2])n.innerHTML=e.replace(//g,">")}function s(a,e){var d=!1,c=h.bind(a,a.push);return{start:function(a,g,f){a=h.lowercase(a);!d&&x[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(g,function(d,f){var g=h.lowercase(f),k="img"===a&&"src"===g||"background"===g;!0!==O[g]||!0===D[g]&&!e(d,k)||(c(" "),c(f),c('="'),c(B(d)),c('"'))}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c(""));a==d&&(d=!1)},chars:function(a){d|| -c(B(a))}}}var L=h.$$minErr("$sanitize"),A=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,z=/^<\s*\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^]*?)>/i,I=/]/,d=/^mailto:/;return function(c,b){function g(a){a&&m.push(E(a))}function f(a,c){m.push("');g(c);m.push("")}if(!c)return c;for(var l,k=c,m=[],n,p;l=k.match(e);)n=l[0],l[2]==l[3]&&(n="mailto:"+n),p=l.index,g(k.substr(0,p)),f(n,l[0].replace(d,"")),k=k.substring(p+l[0].length);g(k);return a(m.join(""))}}])})(window,window.angular); +(function(q,g,r){'use strict';function F(a){var d=[];t(d,g.noop).chars(a);return d.join("")}function m(a){var d={};a=a.split(",");var b;for(b=0;b=b;e--)d.end&&d.end(f[e]);f.length=b}}var c,l,f=[],n=a,h;for(f.last=function(){return f[f.length-1]};a;){h="";l=!0;if(f.last()&&y[f.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(c,a){a=a.replace(I,"$1").replace(J,"$1");d.chars&&d.chars(s(a));return""}),e("",f.last());else{if(0===a.indexOf("\x3c!--"))c=a.indexOf("--",4),0<=c&&a.lastIndexOf("--\x3e",c)===c&&(d.comment&&d.comment(a.substring(4,c)),a=a.substring(c+3),l=!1);else if(z.test(a)){if(c= +a.match(z))a=a.replace(c[0],""),l=!1}else if(K.test(a)){if(c=a.match(A))a=a.substring(c[0].length),c[0].replace(A,e),l=!1}else L.test(a)&&((c=a.match(B))?(c[4]&&(a=a.substring(c[0].length),c[0].replace(B,b)),l=!1):(h+="<",a=a.substring(1)));l&&(c=a.indexOf("<"),h+=0>c?a:a.substring(0,c),a=0>c?"":a.substring(c),d.chars&&d.chars(s(h)))}if(a==n)throw M("badparse",a);n=a}e()}function s(a){if(!a)return"";var d=N.exec(a);a=d[1];var b=d[3];if(d=d[2])p.innerHTML=d.replace(//g,">")}function t(a,d){var b=!1,e=g.bind(a,a.push);return{start:function(a,l,f){a=g.lowercase(a);!b&&y[a]&&(b=a);b||!0!==D[a]||(e("<"),e(a),g.forEach(l,function(b,f){var k=g.lowercase(f),l="img"===a&&"src"===k||"background"=== +k;!0!==Q[k]||!0===E[k]&&!d(b,l)||(e(" "),e(f),e('="'),e(C(b)),e('"'))}),e(f?"/>":">"))},end:function(a){a=g.lowercase(a);b||!0!==D[a]||(e(""));a==b&&(b=!1)},chars:function(a){b||e(C(a))}}}var M=g.$$minErr("$sanitize"),B=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,A=/^<\/\s*([\w:-]+)[^>]*>/,H=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,L=/^]*?)>/i, +J=/]/,b=/^mailto:/;return function(e,c){function l(a){a&&k.push(F(a))}function f(a,b){k.push("');l(b);k.push("")} +if(!e)return e;for(var n,h=e,k=[],m,p;n=h.match(d);)m=n[0],n[2]==n[3]&&(m="mailto:"+m),p=n.index,l(h.substr(0,p)),f(m,n[0].replace(b,"")),h=h.substring(p+n[0].length);l(h);return a(k.join(""))}}])})(window,window.angular); //# sourceMappingURL=angular-sanitize.min.js.map diff --git a/app/bower_components/angular-sanitize/angular-sanitize.min.js.map b/app/bower_components/angular-sanitize/angular-sanitize.min.js.map index dbf6b25..1b4a750 100644 --- a/app/bower_components/angular-sanitize/angular-sanitize.min.js.map +++ b/app/bower_components/angular-sanitize/angular-sanitize.min.js.map @@ -1,8 +1,8 @@ { "version":3, "file":"angular-sanitize.min.js", -"lineCount":13, -"mappings":"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", +"lineCount":14, +"mappings":"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", "sources":["angular-sanitize.js"], -"names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","makeMap","str","obj","items","split","i","length","htmlParser","html","handler","parseStartTag","tag","tagName","rest","unary","lowercase","blockElements","stack","last","inlineElements","parseEndTag","optionalEndTagElements","voidElements","push","attrs","replace","ATTR_REGEXP","match","name","doubleQuotedValue","singleQuotedValue","unquotedValue","decodeEntities","start","pos","end","index","stack.last","specialElements","RegExp","all","text","COMMENT_REGEXP","CDATA_REGEXP","indexOf","lastIndexOf","comment","substring","DOCTYPE_REGEXP","test","BEGING_END_TAGE_REGEXP","END_TAG_REGEXP","BEGIN_TAG_REGEXP","START_TAG_REGEXP","$sanitizeMinErr","value","parts","spaceRe","exec","spaceBefore","spaceAfter","content","hiddenPre","innerHTML","textContent","innerText","encodeEntities","NON_ALPHANUMERIC_REGEXP","charCodeAt","uriValidator","ignore","out","bind","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","extend","document","createElement","module","provider","$SanitizeProvider","$get","$$sanitizeUri","uri","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","target","addText","addLink","url","isDefined","raw","substr"] +"names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","makeMap","str","obj","items","split","i","length","htmlParser","html","handler","parseStartTag","tag","tagName","rest","unary","lowercase","blockElements","stack","last","inlineElements","parseEndTag","optionalEndTagElements","voidElements","push","attrs","replace","ATTR_REGEXP","match","name","doubleQuotedValue","singleQuotedValue","unquotedValue","decodeEntities","start","pos","end","index","text","stack.last","specialElements","RegExp","all","COMMENT_REGEXP","CDATA_REGEXP","indexOf","lastIndexOf","comment","substring","DOCTYPE_REGEXP","test","BEGING_END_TAGE_REGEXP","END_TAG_REGEXP","BEGIN_TAG_REGEXP","START_TAG_REGEXP","$sanitizeMinErr","value","parts","spaceRe","exec","spaceBefore","spaceAfter","content","hiddenPre","innerHTML","textContent","innerText","encodeEntities","SURROGATE_PAIR_REGEXP","hi","charCodeAt","low","NON_ALPHANUMERIC_REGEXP","uriValidator","ignore","out","bind","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","extend","document","createElement","module","provider","$SanitizeProvider","$get","$$sanitizeUri","uri","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","target","addText","addLink","url","isDefined","raw","substr"] } diff --git a/app/bower_components/angular-sanitize/bower.json b/app/bower_components/angular-sanitize/bower.json index 1160f22..7daf7d9 100644 --- a/app/bower_components/angular-sanitize/bower.json +++ b/app/bower_components/angular-sanitize/bower.json @@ -1,8 +1,8 @@ { "name": "angular-sanitize", - "version": "1.2.16", + "version": "1.2.21", "main": "./angular-sanitize.js", "dependencies": { - "angular": "1.2.16" + "angular": "1.2.21" } } diff --git a/app/bower_components/angular-scenario/.bower.json b/app/bower_components/angular-scenario/.bower.json index f33be68..89f1aa4 100644 --- a/app/bower_components/angular-scenario/.bower.json +++ b/app/bower_components/angular-scenario/.bower.json @@ -1,18 +1,18 @@ { "name": "angular-scenario", - "version": "1.2.16", + "version": "1.2.21", "main": "./angular-scenario.js", "dependencies": { - "angular": "1.2.16" + "angular": "1.2.21" }, "homepage": "https://github.com/angular/bower-angular-scenario", - "_release": "1.2.16", + "_release": "1.2.21", "_resolution": { "type": "version", - "tag": "v1.2.16", - "commit": "387bd67cc4863655aed0f889956cdeb4acdb03ae" + "tag": "v1.2.21", + "commit": "1e442f99fe1531084a8c502b0acb097f7f65988b" }, "_source": "git://github.com/angular/bower-angular-scenario.git", - "_target": "1.2.16", + "_target": "1.2.21", "_originalSource": "angular-scenario" } \ No newline at end of file diff --git a/app/bower_components/angular-scenario/angular-scenario.js b/app/bower_components/angular-scenario/angular-scenario.js index 81491c5..5a6ac19 100644 --- a/app/bower_components/angular-scenario/angular-scenario.js +++ b/app/bower_components/angular-scenario/angular-scenario.js @@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object" })( window ); /** - * @license AngularJS v1.2.16 + * @license AngularJS v1.2.21 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -9860,7 +9860,7 @@ function minErr(module) { return match; }); - message = message + '\nhttp://errors.angularjs.org/1.2.16/' + + message = message + '\nhttp://errors.angularjs.org/1.2.21/' + (module ? module + '/' : '') + code; for (i = 2; i < arguments.length; i++) { message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + @@ -9872,89 +9872,88 @@ function minErr(module) { } /* We need to tell jshint what variables are being exported */ -/* global - -angular, - -msie, - -jqLite, - -jQuery, - -slice, - -push, - -toString, - -ngMinErr, - -_angular, - -angularModule, - -nodeName_, - -uid, - - -lowercase, - -uppercase, - -manualLowercase, - -manualUppercase, - -nodeName_, - -isArrayLike, - -forEach, - -sortedKeys, - -forEachSorted, - -reverseParams, - -nextUid, - -setHashKey, - -extend, - -int, - -inherit, - -noop, - -identity, - -valueFn, - -isUndefined, - -isDefined, - -isObject, - -isString, - -isNumber, - -isDate, - -isArray, - -isFunction, - -isRegExp, - -isWindow, - -isScope, - -isFile, - -isBlob, - -isBoolean, - -trim, - -isElement, - -makeMap, - -map, - -size, - -includes, - -indexOf, - -arrayRemove, - -isLeafNode, - -copy, - -shallowCopy, - -equals, - -csp, - -concat, - -sliceArgs, - -bind, - -toJsonReplacer, - -toJson, - -fromJson, - -toBoolean, - -startingTag, - -tryDecodeURIComponent, - -parseKeyValue, - -toKeyValue, - -encodeUriSegment, - -encodeUriQuery, - -angularInit, - -bootstrap, - -snake_case, - -bindJQuery, - -assertArg, - -assertArgFn, - -assertNotHasOwnProperty, - -getter, - -getBlockElements, - -hasOwnProperty, +/* global angular: true, + msie: true, + jqLite: true, + jQuery: true, + slice: true, + push: true, + toString: true, + ngMinErr: true, + angularModule: true, + nodeName_: true, + uid: true, + VALIDITY_STATE_PROPERTY: true, + lowercase: true, + uppercase: true, + manualLowercase: true, + manualUppercase: true, + nodeName_: true, + isArrayLike: true, + forEach: true, + sortedKeys: true, + forEachSorted: true, + reverseParams: true, + nextUid: true, + setHashKey: true, + extend: true, + int: true, + inherit: true, + noop: true, + identity: true, + valueFn: true, + isUndefined: true, + isDefined: true, + isObject: true, + isString: true, + isNumber: true, + isDate: true, + isArray: true, + isFunction: true, + isRegExp: true, + isWindow: true, + isScope: true, + isFile: true, + isBlob: true, + isBoolean: true, + isPromiseLike: true, + trim: true, + isElement: true, + makeMap: true, + map: true, + size: true, + includes: true, + indexOf: true, + arrayRemove: true, + isLeafNode: true, + copy: true, + shallowCopy: true, + equals: true, + csp: true, + concat: true, + sliceArgs: true, + bind: true, + toJsonReplacer: true, + toJson: true, + fromJson: true, + toBoolean: true, + startingTag: true, + tryDecodeURIComponent: true, + parseKeyValue: true, + toKeyValue: true, + encodeUriSegment: true, + encodeUriQuery: true, + angularInit: true, + bootstrap: true, + snake_case: true, + bindJQuery: true, + assertArg: true, + assertArgFn: true, + assertNotHasOwnProperty: true, + getter: true, + getBlockElements: true, + hasOwnProperty: true, */ //////////////////////////////////// @@ -9974,11 +9973,15 @@ function minErr(module) { *
*/ +// 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'; + /** * @ngdoc function * @name angular.lowercase * @module ng - * @function + * @kind function * * @description Converts the specified string to lowercase. * @param {string} string String to be converted to lowercase. @@ -9991,7 +9994,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; * @ngdoc function * @name angular.uppercase * @module ng - * @function + * @kind function * * @description Converts the specified string to uppercase. * @param {string} string String to be converted to uppercase. @@ -10032,8 +10035,6 @@ var /** holds major version number for IE or NaN for real browsers */ toString = Object.prototype.toString, ngMinErr = minErr('ng'), - - _angular = window.angular, /** @name angular */ angular = window.angular || (window.angular = {}), angularModule, @@ -10075,7 +10076,7 @@ function isArrayLike(obj) { * @ngdoc function * @name angular.forEach * @module ng - * @function + * @kind function * * @description * Invokes the `iterator` function once for each item in `obj` collection, which can be either an @@ -10089,7 +10090,7 @@ function isArrayLike(obj) { ```js var values = {name: 'misko', gender: 'male'}; var log = []; - angular.forEach(values, function(value, key){ + angular.forEach(values, function(value, key) { this.push(key + ': ' + value); }, log); expect(log).toEqual(['name: misko', 'gender: male']); @@ -10103,7 +10104,7 @@ function isArrayLike(obj) { function forEach(obj, iterator, context) { var key; if (obj) { - if (isFunction(obj)){ + if (isFunction(obj)) { for (key in obj) { // Need to check if hasOwnProperty exists, // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function @@ -10111,11 +10112,12 @@ function forEach(obj, iterator, context) { iterator.call(context, obj[key], key); } } - } else if (obj.forEach && obj.forEach !== forEach) { - obj.forEach(iterator, context); - } else if (isArrayLike(obj)) { - for (key = 0; key < obj.length; key++) + } else if (isArray(obj) || isArrayLike(obj)) { + for (key = 0; key < obj.length; key++) { iterator.call(context, obj[key], key); + } + } else if (obj.forEach && obj.forEach !== forEach) { + obj.forEach(iterator, context); } else { for (key in obj) { if (obj.hasOwnProperty(key)) { @@ -10204,7 +10206,7 @@ function setHashKey(obj, h) { * @ngdoc function * @name angular.extend * @module ng - * @function + * @kind function * * @description * Extends the destination object `dst` by copying all of the properties from the `src` object(s) @@ -10216,9 +10218,9 @@ function setHashKey(obj, h) { */ function extend(dst) { var h = dst.$$hashKey; - forEach(arguments, function(obj){ + forEach(arguments, function(obj) { if (obj !== dst) { - forEach(obj, function(value, key){ + forEach(obj, function(value, key) { dst[key] = value; }); } @@ -10241,7 +10243,7 @@ function inherit(parent, extra) { * @ngdoc function * @name angular.noop * @module ng - * @function + * @kind function * * @description * A function that performs no operations. This function can be useful when writing code in the @@ -10261,7 +10263,7 @@ noop.$inject = []; * @ngdoc function * @name angular.identity * @module ng - * @function + * @kind function * * @description * A function that returns its first argument. This function is useful when writing code in the @@ -10283,7 +10285,7 @@ function valueFn(value) {return function() {return value;};} * @ngdoc function * @name angular.isUndefined * @module ng - * @function + * @kind function * * @description * Determines if a reference is undefined. @@ -10298,7 +10300,7 @@ function isUndefined(value){return typeof value === 'undefined';} * @ngdoc function * @name angular.isDefined * @module ng - * @function + * @kind function * * @description * Determines if a reference is defined. @@ -10313,7 +10315,7 @@ function isDefined(value){return typeof value !== 'undefined';} * @ngdoc function * @name angular.isObject * @module ng - * @function + * @kind function * * @description * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not @@ -10329,7 +10331,7 @@ function isObject(value){return value != null && typeof value === 'object';} * @ngdoc function * @name angular.isString * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `String`. @@ -10344,7 +10346,7 @@ function isString(value){return typeof value === 'string';} * @ngdoc function * @name angular.isNumber * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `Number`. @@ -10359,7 +10361,7 @@ function isNumber(value){return typeof value === 'number';} * @ngdoc function * @name angular.isDate * @module ng - * @function + * @kind function * * @description * Determines if a value is a date. @@ -10367,7 +10369,7 @@ function isNumber(value){return typeof value === 'number';} * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Date`. */ -function isDate(value){ +function isDate(value) { return toString.call(value) === '[object Date]'; } @@ -10376,7 +10378,7 @@ function isDate(value){ * @ngdoc function * @name angular.isArray * @module ng - * @function + * @kind function * * @description * Determines if a reference is an `Array`. @@ -10384,16 +10386,20 @@ function isDate(value){ * @param {*} value Reference to check. * @returns {boolean} True if `value` is an `Array`. */ -function isArray(value) { - return toString.call(value) === '[object Array]'; -} - +var isArray = (function() { + if (!isFunction(Array.isArray)) { + return function(value) { + return toString.call(value) === '[object Array]'; + }; + } + return Array.isArray; +})(); /** * @ngdoc function * @name angular.isFunction * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `Function`. @@ -10448,6 +10454,11 @@ function isBoolean(value) { } +function isPromiseLike(obj) { + return obj && isFunction(obj.then); +} + + var trim = (function() { // native trim is way faster: http://jsperf.com/angular-trim-test // but IE doesn't have it... :-( @@ -10467,7 +10478,7 @@ var trim = (function() { * @ngdoc function * @name angular.isElement * @module ng - * @function + * @kind function * * @description * Determines if a reference is a DOM element (or wrapped jQuery element). @@ -10485,7 +10496,7 @@ function isElement(node) { * @param str 'key1,key2,...' * @returns {object} in the form of {key1:true, key2:true, ...} */ -function makeMap(str){ +function makeMap(str) { var obj = {}, items = str.split(","), i; for ( i = 0; i < items.length; i++ ) obj[ items[i] ] = true; @@ -10532,7 +10543,7 @@ function size(obj, ownPropsOnly) { if (isArray(obj) || isString(obj)) { return obj.length; - } else if (isObject(obj)){ + } else if (isObject(obj)) { for (key in obj) if (!ownPropsOnly || obj.hasOwnProperty(key)) count++; @@ -10578,7 +10589,7 @@ function isLeafNode (node) { * @ngdoc function * @name angular.copy * @module ng - * @function + * @kind function * * @description * Creates a deep copy of `source`, which should be an object or an array. @@ -10596,9 +10607,9 @@ function isLeafNode (node) { * @returns {*} The copy or updated `destination`, if `destination` was specified. * * @example - + -
+
Name:
E-mail:
@@ -10612,26 +10623,27 @@ function isLeafNode (node) {
*/ -function copy(source, destination){ +function copy(source, destination, stackSource, stackDest) { if (isWindow(source) || isScope(source)) { throw ngMinErr('cpws', "Can't copy! Making copies of Window or Scope instances is not supported."); @@ -10641,52 +10653,83 @@ function copy(source, destination){ destination = source; if (source) { if (isArray(source)) { - destination = copy(source, []); + destination = copy(source, [], stackSource, stackDest); } else if (isDate(source)) { destination = new Date(source.getTime()); } else if (isRegExp(source)) { - destination = new RegExp(source.source); + destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]); + destination.lastIndex = source.lastIndex; } else if (isObject(source)) { - destination = copy(source, {}); + destination = copy(source, {}, stackSource, stackDest); } } } else { if (source === destination) throw ngMinErr('cpi', "Can't copy! Source and destination are identical."); + + stackSource = stackSource || []; + stackDest = stackDest || []; + + if (isObject(source)) { + var index = indexOf(stackSource, source); + if (index !== -1) return stackDest[index]; + + stackSource.push(source); + stackDest.push(destination); + } + + var result; if (isArray(source)) { destination.length = 0; for ( var i = 0; i < source.length; i++) { - destination.push(copy(source[i])); + result = copy(source[i], null, stackSource, stackDest); + if (isObject(source[i])) { + stackSource.push(source[i]); + stackDest.push(result); + } + destination.push(result); } } else { var h = destination.$$hashKey; - forEach(destination, function(value, key){ + forEach(destination, function(value, key) { delete destination[key]; }); for ( var key in source) { - destination[key] = copy(source[key]); + result = copy(source[key], null, stackSource, stackDest); + if (isObject(source[key])) { + stackSource.push(source[key]); + stackDest.push(result); + } + destination[key] = result; } setHashKey(destination,h); } + } return destination; } /** - * Create a shallow copy of an object + * Creates a shallow copy of an object, an array or a primitive */ function shallowCopy(src, dst) { - dst = dst || {}; + if (isArray(src)) { + dst = dst || []; - for(var key in src) { - // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src - // so we don't need to worry about using our custom hasOwnProperty here - if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { - dst[key] = src[key]; + for ( var i = 0; i < src.length; i++) { + dst[i] = src[i]; + } + } else if (isObject(src)) { + dst = dst || {}; + + for (var key in src) { + if (hasOwnProperty.call(src, key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { + dst[key] = src[key]; + } } } - return dst; + return dst || src; } @@ -10694,7 +10737,7 @@ function shallowCopy(src, dst) { * @ngdoc function * @name angular.equals * @module ng - * @function + * @kind function * * @description * Determines if two objects or two values are equivalent. Supports value types, regular @@ -10706,7 +10749,7 @@ function shallowCopy(src, dst) { * * Both objects or values are of the same type and all of their properties are equal by * comparing them with `angular.equals`. * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal) - * * Both values represent the same regular expression (In JavasScript, + * * 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). * @@ -10759,12 +10802,25 @@ function equals(o1, o2) { return false; } +var csp = function() { + if (isDefined(csp.isActive_)) return csp.isActive_; + + var active = !!(document.querySelector('[ng-csp]') || + document.querySelector('[data-ng-csp]')); + + if (!active) { + try { + /* jshint -W031, -W054 */ + new Function(''); + /* jshint +W031, +W054 */ + } catch (e) { + active = true; + } + } + + return (csp.isActive_ = active); +}; -function csp() { - return (document.securityPolicy && document.securityPolicy.isActive) || - (document.querySelector && - !!(document.querySelector('[ng-csp]') || document.querySelector('[data-ng-csp]'))); -} function concat(array1, array2, index) { @@ -10781,7 +10837,7 @@ function sliceArgs(args, startIndex) { * @ngdoc function * @name angular.bind * @module ng - * @function + * @kind function * * @description * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for @@ -10837,7 +10893,7 @@ function toJsonReplacer(key, value) { * @ngdoc function * @name angular.toJson * @module ng - * @function + * @kind function * * @description * Serializes input into a JSON-formatted string. Properties with leading $ characters will be @@ -10857,7 +10913,7 @@ function toJson(obj, pretty) { * @ngdoc function * @name angular.fromJson * @module ng - * @function + * @kind function * * @description * Deserializes a JSON string. @@ -10934,13 +10990,13 @@ function tryDecodeURIComponent(value) { */ function parseKeyValue(/**string*/keyValue) { var obj = {}, key_value, key; - forEach((keyValue || "").split('&'), function(keyValue){ + forEach((keyValue || "").split('&'), function(keyValue) { if ( keyValue ) { - key_value = keyValue.split('='); + key_value = keyValue.replace(/\+/g,'%20').split('='); key = tryDecodeURIComponent(key_value[0]); if ( isDefined(key) ) { var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true; - if (!obj[key]) { + if (!hasOwnProperty.call(obj, key)) { obj[key] = val; } else if(isArray(obj[key])) { obj[key].push(val); @@ -11114,7 +11170,7 @@ function angularInit(element, bootstrap) { * * 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 + * each of the subsequent scripts. This prevents strange results in applications, where otherwise * multiple instances of Angular try to work on the DOM. * * @@ -11196,7 +11252,7 @@ function bootstrap(element, modules) { } var SNAKE_CASE_REGEXP = /[A-Z]/g; -function snake_case(name, separator){ +function snake_case(name, separator) { separator = separator || '_'; return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) { return (pos ? separator : '') + letter.toLowerCase(); @@ -11206,8 +11262,9 @@ function snake_case(name, separator){ function bindJQuery() { // bind to jQuery if present; jQuery = window.jQuery; - // reset to jQuery or default to us. - if (jQuery) { + // Use jQuery if it exists with proper functionality, otherwise default to us. + // Angular 1.2+ requires jQuery 1.7.1+ for on()/off() support. + if (jQuery && jQuery.fn.on) { jqLite = jQuery; extend(jQuery.fn, { scope: JQLitePrototype.scope, @@ -11243,7 +11300,7 @@ function assertArgFn(arg, name, acceptArrayAnnotation) { } assertArg(isFunction(arg), name, 'not a function, got ' + - (arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg)); + (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg)); return arg; } @@ -11353,7 +11410,7 @@ function setupModuleLoader(window) { * * # Module * - * A module is a collection of services, directives, filters, and configuration information. + * 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 @@ -11381,9 +11438,9 @@ function setupModuleLoader(window) { * {@link angular.bootstrap} to simplify this process for you. * * @param {!string} name The name of the module to create or retrieve. -<<<<<* @param {!Array.=} 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 + * @param {!Array.=} 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 {module} new module with the {@link angular.Module} api. */ @@ -11575,6 +11632,8 @@ function setupModuleLoader(window) { * 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#providers_provider-recipe Provider Recipe}. */ config: config, @@ -11618,12 +11677,11 @@ function setupModuleLoader(window) { } -/* global - angularModule: true, - version: true, +/* global angularModule: true, + version: true, - $LocaleProvider, - $CompileProvider, + $LocaleProvider, + $CompileProvider, htmlAnchorDirective, inputDirective, @@ -11711,11 +11769,11 @@ function setupModuleLoader(window) { * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". */ var version = { - full: '1.2.16', // all of these placeholder strings will be replaced by grunt's + full: '1.2.21', // all of these placeholder strings will be replaced by grunt's major: 1, // package task minor: 2, - dot: 16, - codeName: 'badger-enumeration' + dot: 21, + codeName: 'wizard-props' }; @@ -11839,12 +11897,10 @@ function publishExternalAPI(angular){ ]); } -/* global - - -JQLitePrototype, - -addEventListenerFn, - -removeEventListenerFn, - -BOOLEAN_ATTR +/* global JQLitePrototype: true, + addEventListenerFn: true, + removeEventListenerFn: true, + BOOLEAN_ATTR: true */ ////////////////////////////////// @@ -11855,7 +11911,7 @@ function publishExternalAPI(angular){ * @ngdoc function * @name angular.element * @module ng - * @function + * @kind function * * @description * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. @@ -11937,8 +11993,9 @@ function publishExternalAPI(angular){ * @returns {Object} jQuery object. */ +JQLite.expando = 'ng339'; + var jqCache = JQLite.cache = {}, - jqName = JQLite.expando = 'ng-' + new Date().getTime(), jqId = 1, addEventListenerFn = (window.document.addEventListener ? function(element, type, fn) {element.addEventListener(type, fn, false);} @@ -12148,7 +12205,7 @@ function jqLiteOff(element, type, fn, unsupported) { } function jqLiteRemoveData(element, name) { - var expandoId = element[jqName], + var expandoId = element.ng339, expandoStore = jqCache[expandoId]; if (expandoStore) { @@ -12162,17 +12219,17 @@ function jqLiteRemoveData(element, name) { jqLiteOff(element); } delete jqCache[expandoId]; - element[jqName] = undefined; // ie does not allow deletion of attributes on elements. + element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it } } function jqLiteExpandoStore(element, key, value) { - var expandoId = element[jqName], + var expandoId = element.ng339, expandoStore = jqCache[expandoId || -1]; if (isDefined(value)) { if (!expandoStore) { - element[jqName] = expandoId = jqNextId(); + element.ng339 = expandoId = jqNextId(); expandoStore = jqCache[expandoId] = {}; } expandoStore[key] = value; @@ -12257,25 +12314,22 @@ function jqLiteController(element, name) { } function jqLiteInheritedData(element, name, value) { - element = jqLite(element); - // if element is the document object work with the html element instead // this makes $(document).scope() possible - if(element[0].nodeType == 9) { - element = element.find('html'); + if(element.nodeType == 9) { + element = element.documentElement; } var names = isArray(name) ? name : [name]; - while (element.length) { - var node = element[0]; + while (element) { for (var i = 0, ii = names.length; i < ii; i++) { - if ((value = element.data(names[i])) !== undefined) return value; + if ((value = jqLite.data(element, names[i])) !== undefined) 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 = jqLite(node.parentNode || (node.nodeType === 11 && node.host)); + element = element.parentNode || (element.nodeType === 11 && element.host); } } @@ -12350,18 +12404,25 @@ function getBooleanAttrName(element, name) { return booleanAttr && BOOLEAN_ELEMENTS[element.nodeName] && booleanAttr; } +forEach({ + data: jqLiteData, + removeData: jqLiteRemoveData +}, 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(element).data('$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']); + 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(element).data('$isolateScope') || jqLite(element).data('$isolateScopeNoTemplate'); + return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate'); }, controller: jqLiteController, @@ -12491,6 +12552,7 @@ forEach({ */ 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. @@ -12500,7 +12562,7 @@ forEach({ if (isObject(arg1)) { // we are a write, but the object properties are the key/values - for (i = 0; i < this.length; i++) { + for (i = 0; i < nodeCount; i++) { if (fn === jqLiteData) { // data() takes the whole object in jQuery fn(this[i], arg1); @@ -12514,9 +12576,10 @@ forEach({ 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 = (value === undefined) ? Math.min(this.length, 1) : this.length; + var jj = (value === undefined) ? Math.min(nodeCount, 1) : nodeCount; for (var j = 0; j < jj; j++) { var nodeValue = fn(this[j], arg1, arg2); value = value ? value + nodeValue : nodeValue; @@ -12525,7 +12588,7 @@ forEach({ } } else { // we are a write, so apply to all children - for (i = 0; i < this.length; i++) { + for (i = 0; i < nodeCount; i++) { fn(this[i], arg1, arg2); } // return self for chaining @@ -12787,7 +12850,9 @@ forEach({ clone: jqLiteClone, triggerHandler: function(element, eventName, eventData) { - var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName]; + // Copy event handlers in case event handlers array is modified during execution. + var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName], + eventFnsCopy = shallowCopy(eventFns || []); eventData = eventData || []; @@ -12796,7 +12861,7 @@ forEach({ stopPropagation: noop }]; - forEach(eventFns, function(fn) { + forEach(eventFnsCopy, function(fn) { fn.apply(element, event.concat(eventData)); }); } @@ -12837,16 +12902,16 @@ forEach({ * @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) { +function hashKey(obj, nextUidFn) { var objType = typeof obj, key; - if (objType == 'object' && obj !== null) { + if (objType == 'function' || (objType == 'object' && obj !== null)) { if (typeof (key = obj.$$hashKey) == 'function') { // must invoke on object to keep the right this key = obj.$$hashKey(); } else if (key === undefined) { - key = obj.$$hashKey = nextUid(); + key = obj.$$hashKey = (nextUidFn || nextUid)(); } } else { key = obj; @@ -12858,7 +12923,13 @@ function hashKey(obj) { /** * HashMap which can use objects as keys */ -function HashMap(array){ +function HashMap(array, isolatedUid) { + if (isolatedUid) { + var uid = 0; + this.nextUid = function() { + return ++uid; + }; + } forEach(array, this.put, this); } HashMap.prototype = { @@ -12868,7 +12939,7 @@ HashMap.prototype = { * @param value value to store can be any type */ put: function(key, value) { - this[hashKey(key)] = value; + this[hashKey(key, this.nextUid)] = value; }, /** @@ -12876,7 +12947,7 @@ HashMap.prototype = { * @returns {Object} the value for the key */ get: function(key) { - return this[hashKey(key)]; + return this[hashKey(key, this.nextUid)]; }, /** @@ -12884,7 +12955,7 @@ HashMap.prototype = { * @param key */ remove: function(key) { - var value = this[key = hashKey(key)]; + var value = this[key = hashKey(key, this.nextUid)]; delete this[key]; return value; } @@ -12894,7 +12965,7 @@ HashMap.prototype = { * @ngdoc function * @module ng * @name angular.injector - * @function + * @kind function * * @description * Creates an injector function that can be used for retrieving services as well as for @@ -12921,7 +12992,7 @@ HashMap.prototype = { * * 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 extra `injector()` added + * 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 @@ -12962,7 +13033,7 @@ function annotate(fn) { argDecl, last; - if (typeof fn == 'function') { + if (typeof fn === 'function') { if (!($inject = fn.$inject)) { $inject = []; if (fn.length) { @@ -12991,7 +13062,7 @@ function annotate(fn) { /** * @ngdoc service * @name $injector - * @function + * @kind function * * @description * @@ -13034,7 +13105,7 @@ function annotate(fn) { * minification, and obfuscation tools since these tools change the argument names. * * ## `$inject` Annotation - * By adding a `$inject` property onto a function the injection parameters can be specified. + * 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. @@ -13071,7 +13142,7 @@ function annotate(fn) { * @name $injector#has * * @description - * Allows the user to query if the particular service exist. + * Allows the user to query if the particular service exists. * * @param {string} Name of the service to query. * @returns {boolean} returns true if injector has given service. @@ -13081,8 +13152,8 @@ function annotate(fn) { * @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 + * 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. @@ -13175,7 +13246,7 @@ function annotate(fn) { /** - * @ngdoc object + * @ngdoc service * @name $provide * * @description @@ -13481,7 +13552,7 @@ function createInjector(modulesToLoad) { var INSTANTIATING = {}, providerSuffix = 'Provider', path = [], - loadedModules = new HashMap(), + loadedModules = new HashMap([], true), providerCache = { $provide: { provider: supportObject(provider), @@ -13614,7 +13685,8 @@ function createInjector(modulesToLoad) { function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { - throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); + throw $injectorMinErr('cdep', 'Circular dependency found: {0}', + serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { @@ -13651,8 +13723,7 @@ function createInjector(modulesToLoad) { : getService(key) ); } - if (!fn.$inject) { - // this means that we must be an array. + if (isArray(fn)) { fn = fn[length]; } @@ -13695,7 +13766,7 @@ function createInjector(modulesToLoad) { * @requires $rootScope * * @description - * When called, it checks current value of `$location.hash()` and scroll to related element, + * When called, it checks current value of `$location.hash()` and scrolls to the related element, * according to rules specified in * [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document). * @@ -13897,7 +13968,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#enter - * @function + * @kind function * @description Inserts the element into the DOM either after the `after` element or within * the `parent` element. Once complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will be inserted into the DOM @@ -13924,7 +13995,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#leave - * @function + * @kind function * @description Removes the element from the DOM. Once complete, the done() callback will be * fired (if provided). * @param {DOMElement} element the element which will be removed from the DOM @@ -13940,7 +14011,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#move - * @function + * @kind function * @description Moves the position of the provided element within the DOM to be placed * either after the `after` element or inside of the `parent` element. Once complete, the * done() callback will be fired (if provided). @@ -13964,7 +14035,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#addClass - * @function + * @kind function * @description Adds the provided className CSS class value to the provided element. Once * complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will have the className value @@ -13987,7 +14058,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#removeClass - * @function + * @kind function * @description Removes the provided className CSS class value from the provided element. * Once complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will have the className value @@ -14010,10 +14081,10 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#setClass - * @function + * @kind function * @description Adds and/or removes the given CSS classes to and from the element. * Once complete, the done() callback will be fired (if provided). - * @param {DOMElement} element the element which will it's CSS classes changed + * @param {DOMElement} element the element which will have its CSS classes changed * removed from it * @param {string} add the CSS classes which will be added to the element * @param {string} remove the CSS class which will be removed from the element @@ -14567,7 +14638,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#put - * @function + * @kind function * * @description * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be @@ -14603,7 +14674,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#get - * @function + * @kind function * * @description * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object. @@ -14627,7 +14698,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#remove - * @function + * @kind function * * @description * Removes an entry from the {@link $cacheFactory.Cache Cache} object. @@ -14655,7 +14726,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#removeAll - * @function + * @kind function * * @description * Clears the cache object of any entries. @@ -14671,7 +14742,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#destroy - * @function + * @kind function * * @description * Destroys the {@link $cacheFactory.Cache Cache} object entirely, @@ -14688,7 +14759,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#info - * @function + * @kind function * * @description * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}. @@ -14743,7 +14814,7 @@ function $CacheFactoryProvider() { * @name $cacheFactory#info * * @description - * Get information about all the of the caches that have been created + * Get information about all the caches that have been created * * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info` */ @@ -14844,7 +14915,7 @@ function $TemplateCacheProvider() { /** * @ngdoc service * @name $compile - * @function + * @kind function * * @description * Compiles an HTML string or DOM into a template and produces a template function, which @@ -14882,7 +14953,6 @@ function $TemplateCacheProvider() { * template: '
', // or // function(tElement, tAttrs) { ... }, * // or * // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, - * replace: false, * transclude: false, * restrict: 'A', * scope: false, @@ -14986,7 +15056,7 @@ function $TemplateCacheProvider() { * local name. Given `` and widget definition of * `scope: { localFn:'&myAttr' }`, then 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 and to the parent scope, this can be + * 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})`. @@ -15037,14 +15107,16 @@ function $TemplateCacheProvider() { * * * #### `template` - * replace the current element with the contents of the HTML. The replacement process - * migrates all of the attributes / classes from the old element to the new one. See the - * {@link guide/directive#creating-custom-directives_creating-directives_template-expanding-directive - * Directives Guide} for an example. + * HTML markup that may: + * * Replace the contents of the directive's element (defualt). + * * Replace the directive's element itself (if `replace` is true - DEPRECATED). + * * Wrap the contents of the directive's element (if `transclude` is true). * - * You can specify `template` as a string representing the template 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 template. + * Value may be: + * + * * A string. For example `
{{delete_str}}
`. + * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile` + * function api below) and returns a string value. * * * #### `templateUrl` @@ -15058,12 +15130,15 @@ function $TemplateCacheProvider() { * api/ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}. * * - * #### `replace` - * specify where the template should be inserted. Defaults to `false`. + * #### `replace` ([*DEPRECATED*!], will be removed in next major release) + * specify what the template should replace. Defaults to `false`. * - * * `true` - the template will replace the current element. - * * `false` - the template will replace the contents of the current element. + * * `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#creating-custom-directives_creating-directives_template-expanding-directive + * Directives Guide} for an example. * * #### `transclude` * compile the content of the element and make it available to the directive. @@ -15077,6 +15152,11 @@ function $TemplateCacheProvider() { * * `true` - transclude the content of the directive. * * `'element'` - transclude the whole element including any directives defined at lower priority. * + *
+ * **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}. + *
* * #### `compile` * @@ -15085,11 +15165,7 @@ function $TemplateCacheProvider() { * ``` * * The compile function deals with transforming the template DOM. Since most directives do not do - * template transformation, it is not used often. Examples that require compile functions are - * directives that transform template DOM, such as {@link - * api/ng.directive:ngRepeat ngRepeat}, or load the contents - * asynchronously, such as {@link ngRoute.directive:ngView ngView}. The - * compile function takes the following arguments. + * 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. @@ -15217,10 +15293,10 @@ function $TemplateCacheProvider() { * to illustrate how `$compile` works. *
* - + -
+


@@ -15327,7 +15402,7 @@ var $compileMinErr = minErr('$compile'); /** * @ngdoc provider * @name $compileProvider - * @function + * @kind function * * @description */ @@ -15335,8 +15410,8 @@ $CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider']; function $CompileProvider($provide, $$sanitizeUriProvider) { var hasDirectives = {}, Suffix = 'Directive', - COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/, - CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/; + COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/, + CLASS_DIRECTIVE_REGEXP = /(([\d\w_\-]+)(?:\:([^;]+))?;?)/; // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes // The assumption is that future DOM event attribute names will begin with @@ -15346,7 +15421,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#directive - * @function + * @kind function * * @description * Register a new directive with the compiler. @@ -15399,7 +15474,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#aHrefSanitizationWhitelist - * @function + * @kind function * * @description * Retrieves or overrides the default regular expression that is used for whitelisting of safe @@ -15429,7 +15504,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#imgSrcSanitizationWhitelist - * @function + * @kind function * * @description * Retrieves or overrides the default regular expression that is used for whitelisting of safe @@ -15473,7 +15548,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$addClass - * @function + * @kind function * * @description * Adds the CSS class value specified by the classVal parameter to the element. If animations @@ -15490,7 +15565,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$removeClass - * @function + * @kind function * * @description * Removes the CSS class value specified by the classVal parameter from the element. If @@ -15507,7 +15582,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$updateClass - * @function + * @kind function * * @description * Adds and removes the appropriate CSS class values to the element based on the difference @@ -15595,7 +15670,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$observe - * @function + * @kind function * * @description * Observes an interpolated attribute. @@ -15658,7 +15733,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext); safeAddClass($compileNodes, 'ng-scope'); - return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){ + return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn){ assertArg(scope, 'scope'); // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart // and sometimes changes the structure of the DOM. @@ -15680,7 +15755,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (cloneConnectFn) cloneConnectFn($linkNode, scope); - if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode); + if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn); return $linkNode; }; } @@ -15727,7 +15802,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { : null; if (nodeLinkFn && nodeLinkFn.scope) { - safeAddClass(jqLite(nodeList[i]), 'ng-scope'); + safeAddClass(attrs.$$element, 'ng-scope'); } childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || @@ -15735,7 +15810,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { !childNodes.length) ? null : compileNodes(childNodes, - nodeLinkFn ? nodeLinkFn.transclude : transcludeFn); + nodeLinkFn ? ( + (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement) + && nodeLinkFn.transclude) : transcludeFn); linkFns.push(nodeLinkFn, childLinkFn); linkFnFound = linkFnFound || nodeLinkFn || childLinkFn; @@ -15746,8 +15823,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // return a linking function if we have found anything, null otherwise return linkFnFound ? compositeLinkFn : null; - function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) { - var nodeLinkFn, childLinkFn, node, $node, childScope, childTranscludeFn, i, ii, n; + function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) { + var nodeLinkFn, childLinkFn, node, childScope, i, ii, n, childBoundTranscludeFn; // copy nodeList so that linking doesn't break due to live list updates. var nodeListLength = nodeList.length, @@ -15760,32 +15837,40 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { node = stableNodeList[n]; nodeLinkFn = linkFns[i++]; childLinkFn = linkFns[i++]; - $node = jqLite(node); if (nodeLinkFn) { if (nodeLinkFn.scope) { childScope = scope.$new(); - $node.data('$scope', childScope); + jqLite.data(node, '$scope', childScope); } else { childScope = scope; } - childTranscludeFn = nodeLinkFn.transclude; - if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) { - nodeLinkFn(childLinkFn, childScope, node, $rootElement, - createBoundTranscludeFn(scope, childTranscludeFn || transcludeFn) - ); + + 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 { - nodeLinkFn(childLinkFn, childScope, node, $rootElement, boundTranscludeFn); + childBoundTranscludeFn = null; } + + nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn); + } else if (childLinkFn) { - childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn); + childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn); } } } } - function createBoundTranscludeFn(scope, transcludeFn) { - return function boundTranscludeFn(transcludedScope, cloneFn, controllers) { + function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) { + + var boundTranscludeFn = function(transcludedScope, cloneFn, controllers) { var scopeCreated = false; if (!transcludedScope) { @@ -15794,12 +15879,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { scopeCreated = true; } - var clone = transcludeFn(transcludedScope, cloneFn, controllers); + var clone = transcludeFn(transcludedScope, cloneFn, controllers, previousBoundTranscludeFn); if (scopeCreated) { - clone.on('$destroy', bind(transcludedScope, transcludedScope.$destroy)); + clone.on('$destroy', function() { transcludedScope.$destroy(); }); } return clone; }; + + return boundTranscludeFn; } /** @@ -15825,7 +15912,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority, ignoreDirective); // iterate over the attributes - for (var attr, name, nName, ngAttrName, value, nAttrs = node.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; @@ -15833,9 +15920,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { attr = nAttrs[j]; if (!msie || msie >= 8 || attr.specified) { name = attr.name; + value = trim(attr.value); + // support ngAttr attribute binding ngAttrName = directiveNormalize(name); - if (NG_ATTR_BINDING.test(ngAttrName)) { + if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) { name = snake_case(ngAttrName.substr(6), '-'); } @@ -15848,9 +15937,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { nName = directiveNormalize(name.toLowerCase()); attrsMap[nName] = name; - attrs[nName] = value = trim(attr.value); - if (getBooleanAttrName(node, nName)) { - attrs[nName] = true; // presence means true + if (isNgAttr || !attrs.hasOwnProperty(nName)) { + attrs[nName] = value; + if (getBooleanAttrName(node, nName)) { + attrs[nName] = true; // presence means true + } } addAttrInterpolateDirective(node, directives, value, nName); addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, @@ -15977,6 +16068,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { templateDirective = previousCompileContext.templateDirective, nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective, hasTranscludeDirective = false, + hasTemplate = false, hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective, $compileNode = templateAttrs.$$element = jqLite(compileNode), directive, @@ -16041,12 +16133,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (directiveValue == 'element') { hasElementTranscludeDirective = true; terminalPriority = directive.priority; - $template = groupScan(compileNode, attrStart, attrEnd); + $template = $compileNode; $compileNode = templateAttrs.$$element = jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' ')); compileNode = $compileNode[0]; - replaceWith(jqCollection, jqLite(sliceArgs($template)), compileNode); + replaceWith(jqCollection, sliceArgs($template), compileNode); childTranscludeFn = compile($template, transcludeFn, terminalPriority, replaceDirective && replaceDirective.name, { @@ -16067,6 +16159,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (directive.template) { + hasTemplate = true; assertNoDuplicate('template', templateDirective, directive, $compileNode); templateDirective = directive; @@ -16081,7 +16174,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (jqLiteIsTextNode(directiveValue)) { $template = []; } else { - $template = jqLite(directiveValue); + $template = jqLite(trim(directiveValue)); } compileNode = $template[0]; @@ -16116,6 +16209,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (directive.templateUrl) { + hasTemplate = true; assertNoDuplicate('template', templateDirective, directive, $compileNode); templateDirective = directive; @@ -16124,7 +16218,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, - templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, { + templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, { controllerDirectives: controllerDirectives, newIsolateScopeDirective: newIsolateScopeDirective, templateDirective: templateDirective, @@ -16152,7 +16246,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true; - nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn; + nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective; + nodeLinkFn.templateOnThisElement = hasTemplate; + nodeLinkFn.transclude = childTranscludeFn; + previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective; // might be normal or delayed nodeLinkFn depending on if templateUrl is present @@ -16164,6 +16261,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { 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}); } @@ -16172,6 +16270,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { 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}); } @@ -16180,7 +16279,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } - function getControllers(require, $element, elementControllers) { + function getControllers(directiveName, require, $element, elementControllers) { var value, retrievalMethod = 'data', optional = false; if (isString(require)) { while((value = require.charAt(0)) == '^' || value == '?') { @@ -16206,7 +16305,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } else if (isArray(require)) { value = []; forEach(require, function(require) { - value.push(getControllers(require, $element, elementControllers)); + value.push(getControllers(directiveName, require, $element, elementControllers)); }); } return value; @@ -16216,28 +16315,26 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) { var attrs, $element, i, ii, linkFn, controller, isolateScope, elementControllers = {}, transcludeFn; - if (compileNode === linkNode) { - attrs = templateAttrs; - } else { - attrs = shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr)); - } + attrs = (compileNode === linkNode) + ? templateAttrs + : shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr)); $element = attrs.$$element; if (newIsolateScopeDirective) { var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/; - var $linkNode = jqLite(linkNode); isolateScope = scope.$new(true); - if (templateDirective && (templateDirective === newIsolateScopeDirective.$$originalDirective)) { - $linkNode.data('$isolateScope', isolateScope) ; + if (templateDirective && (templateDirective === newIsolateScopeDirective || + templateDirective === newIsolateScopeDirective.$$originalDirective)) { + $element.data('$isolateScope', isolateScope); } else { - $linkNode.data('$isolateScopeNoTemplate', isolateScope); + $element.data('$isolateScopeNoTemplate', isolateScope); } - safeAddClass($linkNode, 'ng-isolate-scope'); + safeAddClass($element, 'ng-isolate-scope'); forEach(newIsolateScopeDirective.scope, function(definition, scopeName) { var match = definition.match(LOCAL_REGEXP) || [], @@ -16349,7 +16446,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { try { linkFn = preLinkFns[i]; linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, - linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn); + linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn); } catch (e) { $exceptionHandler(e, startingTag($element)); } @@ -16369,7 +16466,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { try { linkFn = postLinkFns[i]; linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, - linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn); + linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn); } catch (e) { $exceptionHandler(e, startingTag($element)); } @@ -16455,7 +16552,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // reapply the old attributes to the new element forEach(dst, function(value, key) { if (key.charAt(0) != '$') { - if (src[key]) { + if (src[key] && src[key] !== value) { value += (key === 'style' ? ';' : ' ') + src[key]; } dst.$set(key, value, true, srcAttr[key]); @@ -16508,7 +16605,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (jqLiteIsTextNode(content)) { $template = []; } else { - $template = jqLite(content); + $template = jqLite(trim(content)); } compileNode = $template[0]; @@ -16544,7 +16641,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }); afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn); - while(linkQueue.length) { var scope = linkQueue.shift(), beforeTemplateLinkNode = linkQueue.shift(), @@ -16566,8 +16662,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // Copy in CSS classes from original node safeAddClass(jqLite(linkNode), oldClasses); } - if (afterTemplateNodeLinkFn.transclude) { - childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude); + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); } else { childBoundTranscludeFn = boundTranscludeFn; } @@ -16581,13 +16677,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }); return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) { + var childBoundTranscludeFn = boundTranscludeFn; if (linkQueue) { linkQueue.push(scope); linkQueue.push(node); linkQueue.push(rootElement); - linkQueue.push(boundTranscludeFn); + linkQueue.push(childBoundTranscludeFn); } else { - afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, boundTranscludeFn); + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); + } + afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn); } }; } @@ -16612,23 +16712,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } - function addTextInterpolateDirective(directives, text) { - var interpolateFn = $interpolate(text, true); - if (interpolateFn) { - directives.push({ - priority: 0, - compile: valueFn(function textInterpolateLinkFn(scope, node) { - var parent = node.parent(), - bindings = parent.data('$binding') || []; - bindings.push(interpolateFn); - safeAddClass(parent.data('$binding', bindings), 'ng-binding'); - scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { - node[0].nodeValue = value; - }); - }) - }); + function addTextInterpolateDirective(directives, text) { + var interpolateFn = $interpolate(text, true); + if (interpolateFn) { + directives.push({ + priority: 0, + compile: function textInterpolateCompileFn(templateNode) { + // when transcluding a template that has bindings in the root + // then we don't have a parent and should do this in the linkFn + var parent = templateNode.parent(), hasCompileParent = parent.length; + if (hasCompileParent) safeAddClass(templateNode.parent(), 'ng-binding'); + + return function textInterpolateLinkFn(scope, node) { + var parent = node.parent(), + bindings = parent.data('$binding') || []; + bindings.push(interpolateFn); + parent.data('$binding', bindings); + if (!hasCompileParent) safeAddClass(parent, 'ng-binding'); + scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { + node[0].nodeValue = value; + }); + }; + } + }); + } } - } function getTrustedContext(node, attrNormalizedName) { @@ -16789,7 +16897,9 @@ function directiveNormalize(name) { * element attributes. The values reflect current binding state `{{ }}`. The normalization is * needed since all of these are treated as equivalent in Angular: * + * ``` * + * ``` */ /** @@ -16803,7 +16913,7 @@ function directiveNormalize(name) { /** * @ngdoc method * @name $compile.directive.Attributes#$set - * @function + * @kind function * * @description * Set DOM element attribute value. @@ -16926,7 +17036,7 @@ function $ControllerProvider() { instance = $injector.instantiate(expression, locals); if (identifier) { - if (!(locals && typeof locals.$scope == 'object')) { + if (!(locals && typeof locals.$scope === 'object')) { throw minErr('$controller')('noscp', "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", constructor || expression.name, identifier); @@ -16949,18 +17059,19 @@ function $ControllerProvider() { * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object. * * @example - + -
+

$document title:

window.document title:

- function MainCtrl($scope, $document) { - $scope.title = $document[0].title; - $scope.windowTitle = angular.element(window.document)[0].title; - } + angular.module('documentExample', []) + .controller('ExampleController', ['$scope', '$document', function($scope, $document) { + $scope.title = $document[0].title; + $scope.windowTitle = angular.element(window.document)[0].title; + }]); */ @@ -17027,11 +17138,7 @@ function parseHeaders(headers) { val = trim(line.substr(i + 1)); if (key) { - if (parsed[key]) { - parsed[key] += ', ' + val; - } else { - parsed[key] = val; - } + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; } }); @@ -17093,12 +17200,39 @@ function isSuccess(status) { } +/** + * @ngdoc provider + * @name $httpProvider + * @description + * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service. + * */ function $HttpProvider() { var JSON_START = /^\s*(\[|\{[^\{])/, JSON_END = /[\}\]]\s*$/, PROTECTION_PREFIX = /^\)\]\}',?\n/, CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'}; + /** + * @ngdoc property + * @name $httpProvider#defaults + * @description + * + * Object containing default values for all {@link ng.$http $http} requests. + * + * - **`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`** + **/ var defaults = this.defaults = { // transform incoming response data transformResponse: [function(data) { @@ -17121,9 +17255,9 @@ function $HttpProvider() { common: { 'Accept': 'application/json, text/plain, */*' }, - post: copy(CONTENT_TYPE_APPLICATION_JSON), - put: copy(CONTENT_TYPE_APPLICATION_JSON), - patch: copy(CONTENT_TYPE_APPLICATION_JSON) + post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), + put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), + patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON) }, xsrfCookieName: 'XSRF-TOKEN', @@ -17365,14 +17499,14 @@ function $HttpProvider() { * * There are two kinds of interceptors (and two kinds of rejection interceptors): * - * * `request`: interceptors get called with http `config` object. The function is free to - * modify the `config` or create a new one. The function needs to return the `config` - * directly or as a promise. + * * `request`: interceptors get called with a http `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` or create a new one. The function needs to return the `response` - * directly or as a promise. + * 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. * @@ -17384,7 +17518,7 @@ function $HttpProvider() { * // optional method * 'request': function(config) { * // do something on success - * return config || $q.when(config); + * return config; * }, * * // optional method @@ -17401,7 +17535,7 @@ function $HttpProvider() { * // optional method * 'response': function(response) { * // do something on success - * return response || $q.when(response); + * return response; * }, * * // optional method @@ -17562,7 +17696,7 @@ function $HttpProvider() { * caching. * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} * that should abort the request when resolved. - * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the + * - **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 @@ -17588,9 +17722,9 @@ function $HttpProvider() { * * * @example - + -
+

- * Current time is: - *
- * Blood 1 : {{blood_1}} - * Blood 2 : {{blood_2}} - * - * - * - *
+ *
+ *
+ * Date format:
+ * Current time is: + *
+ * Blood 1 : {{blood_1}} + * Blood 2 : {{blood_2}} + * + * + * *
+ *
* - * + * * */ function interval(fn, delay, count, invokeApply) { @@ -18646,7 +18820,7 @@ function $IntervalProvider() { interval.cancel = function(promise) { if (promise && promise.$$intervalId in intervals) { intervals[promise.$$intervalId].reject('canceled'); - clearInterval(promise.$$intervalId); + $window.clearInterval(promise.$$intervalId); delete intervals[promise.$$intervalId]; return true; } @@ -18929,7 +19103,7 @@ function LocationHashbangUrl(appBase, hashPrefix) { Matches paths for file protocol on windows, such as /C:/foo/bar, and captures only /foo/bar. */ - var windowsFilePathExp = /^\/?.*?:(\/.*)/; + var windowsFilePathExp = /^\/[A-Z]:(\/.*)/; var firstPathSegmentMatch; @@ -18938,10 +19112,7 @@ function LocationHashbangUrl(appBase, hashPrefix) { url = url.replace(base, ''); } - /* - * The input URL intentionally contains a - * first path segment that ends with a colon. - */ + // The input URL intentionally contains a first path segment that ends with a colon. if (windowsFilePathExp.exec(url)) { return path; } @@ -18997,6 +19168,16 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) { return appBaseNoFile; } }; + + 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 IE8 & 9 do not reload page because of removal of '#' + this.$$absUrl = appBase + hashPrefix + this.$$url; + }; + } @@ -19128,15 +19309,40 @@ LocationHashbangInHtml5Url.prototype = * * 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 + * ``` + * * @param {string|Object.|Object.>} search New search params - string or - * hash object. Hash object may contain an array of values, which will be decoded as duplicates in - * the url. + * hash object. * - * @param {(string|Array)=} paramValue If `search` is a string, then `paramValue` will override only a - * single search parameter. If `paramValue` is an array, it will set the parameter as a - * comma-separated value. If `paramValue` is `null`, the parameter will be deleted. + * When called with a single argument the method acts as a setter, setting the `search` component + * of `$location` to the specified value. * - * @return {string} search + * 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|Array|boolean)=} paramValue If `search` is a string, 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) { @@ -19146,6 +19352,11 @@ LocationHashbangInHtml5Url.prototype = if (isString(search)) { this.$$search = parseKeyValue(search); } else if (isObject(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', @@ -19251,7 +19462,7 @@ function $LocationProvider(){ html5Mode = false; /** - * @ngdoc property + * @ngdoc method * @name $locationProvider#hashPrefix * @description * @param {string=} prefix Prefix for hash part (containing path and search) @@ -19267,7 +19478,7 @@ function $LocationProvider(){ }; /** - * @ngdoc property + * @ngdoc method * @name $locationProvider#html5Mode * @description * @param {boolean=} mode Use HTML5 strategy if available. @@ -19349,6 +19560,39 @@ function $LocationProvider(){ absHref = urlResolve(absHref.animVal).href; } + // Make relative links work in HTML5 mode for legacy browsers (or at least IE8 & 9) + // The href should be a regular url e.g. /link/somewhere or link/somewhere or ../somewhere or + // somewhere#anchor or http://example.com/somewhere + if (LocationMode === LocationHashbangInHtml5Url) { + // get the actual href attribute - see + // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx + var href = elm.attr('href') || elm.attr('xlink:href'); + + if (href.indexOf('://') < 0) { // Ignore absolute URLs + var prefix = '#' + hashPrefix; + if (href[0] == '/') { + // absolute path - replace old path + absHref = appBase + prefix + href; + } else if (href[0] == '#') { + // local anchor + absHref = appBase + prefix + ($location.path() || '/') + href; + } else { + // relative path - join with current path + var stack = $location.path().split("/"), + parts = href.split("/"); + for (var i=0; i + - function LogCtrl($scope, $log) { - $scope.$log = $log; - $scope.message = 'Hello World!'; - } + angular.module('logExample', []) + .controller('LogController', ['$scope', '$log', function($scope, $log) { + $scope.$log = $log; + $scope.message = 'Hello World!'; + }]); -
+

Reload this page with open console, enter text and hit the log button...

Message: @@ -19466,7 +19711,7 @@ function $LogProvider(){ self = this; /** - * @ngdoc property + * @ngdoc method * @name $logProvider#debugEnabled * @description * @param {boolean=} flag enable or disable debug level messages @@ -19592,14 +19837,7 @@ var promiseWarning; // // As an example, consider the following Angular expression: // -// {}.toString.constructor(alert("evil JS code")) -// -// We want to prevent this type of access. For the sake of performance, during the lexing phase we -// disallow any "dotted" access to any member named "constructor". -// -// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor -// while evaluating the expression, which is a stronger but more expensive test. Since reflective -// calls are expensive anyway, this is not such a big deal compared to static dereferencing. +// {}.toString.constructor('alert("evil JS code")') // // This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits // against the expression language, but not to prevent exploits that were enabled by exposing @@ -19607,17 +19845,19 @@ var promiseWarning; // practice and therefore we are not even trying to protect against interaction with an object // explicitly exposed in this way. // -// A developer could foil the name check by aliasing the Function constructor under a different -// name on the scope. -// // In general, it is not possible to access a Window object from an angular expression unless a // window or some DOM object that has a reference to window is published onto a Scope. +// Similarly we prevent invocations of function known to be dangerous, as well as assignments to +// native objects. + function ensureSafeMemberName(name, fullExpression) { - if (name === "constructor") { + if (name === "__defineGetter__" || name === "__defineSetter__" + || name === "__lookupGetter__" || name === "__lookupSetter__" + || name === "__proto__") { throw $parseMinErr('isecfld', - 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', - fullExpression); + 'Attempting to access a disallowed field in Angular expressions! ' + +'Expression: {0}', fullExpression); } return name; } @@ -19639,11 +19879,34 @@ function ensureSafeObject(obj, fullExpression) { throw $parseMinErr('isecdom', 'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}', fullExpression); + } else if (// block Object so that we can't get hold of dangerous Object.* methods + obj === Object) { + throw $parseMinErr('isecobj', + 'Referencing Object in Angular expressions is disallowed! Expression: {0}', + fullExpression); } } return obj; } +var CALL = Function.prototype.call; +var APPLY = Function.prototype.apply; +var BIND = Function.prototype.bind; + +function ensureSafeFunction(obj, fullExpression) { + if (obj) { + if (obj.constructor === obj) { + throw $parseMinErr('isecfn', + 'Referencing Function in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } else if (obj === CALL || obj === APPLY || (BIND && obj === BIND)) { + throw $parseMinErr('isecff', + 'Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } + } +} + var OPERATORS = { /* jshint bitwise : false */ 'null':function(){return null;}, @@ -19709,9 +19972,6 @@ Lexer.prototype = { this.tokens = []; - var token; - var json = []; - while (this.index < this.text.length) { this.ch = this.text.charAt(this.index); if (this.is('"\'')) { @@ -19720,19 +19980,11 @@ Lexer.prototype = { this.readNumber(); } else if (this.isIdent(this.ch)) { this.readIdent(); - // identifiers can only be if the preceding char was a { or , - if (this.was('{,') && json[0] === '{' && - (token = this.tokens[this.tokens.length - 1])) { - token.json = token.text.indexOf('.') === -1; - } } else if (this.is('(){}[].,;:?')) { this.tokens.push({ index: this.index, - text: this.ch, - json: (this.was(':[,') && this.is('{[')) || this.is('}]:,') + text: this.ch }); - if (this.is('{[')) json.unshift(this.ch); - if (this.is('}]')) json.shift(); this.index++; } else if (this.isWhitespace(this.ch)) { this.index++; @@ -19753,8 +20005,7 @@ Lexer.prototype = { this.tokens.push({ index: this.index, text: this.ch, - fn: fn, - json: (this.was('[,:') && this.is('+-')) + fn: fn }); this.index += 1; } else { @@ -19837,7 +20088,8 @@ Lexer.prototype = { this.tokens.push({ index: start, text: number, - json: true, + literal: true, + constant: true, fn: function() { return number; } }); }, @@ -19889,7 +20141,8 @@ Lexer.prototype = { // OPERATORS is our own object so we don't need to use special hasOwnPropertyFn if (OPERATORS.hasOwnProperty(ident)) { token.fn = OPERATORS[ident]; - token.json = OPERATORS[ident]; + token.literal = true; + token.constant = true; } else { var getter = getterFn(ident, this.options, this.text); token.fn = extend(function(self, locals) { @@ -19906,13 +20159,11 @@ Lexer.prototype = { if (methodName) { this.tokens.push({ index:lastDot, - text: '.', - json: false + text: '.' }); this.tokens.push({ index: lastDot + 1, - text: methodName, - json: false + text: methodName }); } }, @@ -19935,11 +20186,7 @@ Lexer.prototype = { string += String.fromCharCode(parseInt(hex, 16)); } else { var rep = ESCAPE[ch]; - if (rep) { - string += rep; - } else { - string += ch; - } + string = string + (rep || ch); } escape = false; } else if (ch === '\\') { @@ -19950,7 +20197,8 @@ Lexer.prototype = { index: start, text: rawString, string: string, - json: true, + literal: true, + constant: true, fn: function() { return string; } }); return; @@ -19982,28 +20230,12 @@ Parser.ZERO = extend(function () { Parser.prototype = { constructor: Parser, - parse: function (text, json) { + parse: function (text) { this.text = text; - //TODO(i): strip all the obsolte json stuff from this file - this.json = json; - this.tokens = this.lexer.lex(text); - if (json) { - // The extra level of aliasing is here, just in case the lexer misses something, so that - // we prevent any accidental execution in JSON. - this.assignment = this.logicalOR; - - this.functionCall = - this.fieldAccess = - this.objectIndex = - this.filterChain = function() { - this.throwError('is not valid json', {text: text, index: 0}); - }; - } - - var value = json ? this.primary() : this.statements(); + var value = this.statements(); if (this.tokens.length !== 0) { this.throwError('is an unexpected token', this.tokens[0]); @@ -20030,10 +20262,8 @@ Parser.prototype = { if (!primary) { this.throwError('not a primary expression', token); } - if (token.json) { - primary.constant = true; - primary.literal = true; - } + primary.literal = !!token.literal; + primary.constant = !!token.constant; } var next, context; @@ -20081,9 +20311,6 @@ Parser.prototype = { expect: function(e1, e2, e3, e4){ var token = this.peek(e1, e2, e3, e4); if (token) { - if (this.json && !token.json) { - this.throwError('is not valid json', token); - } this.tokens.shift(); return token; } @@ -20310,6 +20537,7 @@ Parser.prototype = { i = indexFn(self, locals), v, p; + ensureSafeMemberName(i, parser.text); if (!o) return undefined; v = ensureSafeObject(o[i], parser.text); if (v && v.then && parser.options.unwrapPromises) { @@ -20352,7 +20580,7 @@ Parser.prototype = { var fnPtr = fn(scope, locals, context) || noop; ensureSafeObject(context, parser.text); - ensureSafeObject(fnPtr, parser.text); + ensureSafeFunction(fnPtr, parser.text); // IE stupidity! (IE doesn't have apply for some native functions) var v = fnPtr.apply @@ -20461,6 +20689,8 @@ function setter(obj, path, setValue, fullExp, options) { } } key = ensureSafeMemberName(element.shift(), fullExp); + ensureSafeObject(obj, fullExp); + ensureSafeObject(obj[key], fullExp); obj[key] = setValue; return setValue; } @@ -20576,26 +20806,6 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { }; } -function simpleGetterFn1(key0, fullExp) { - ensureSafeMemberName(key0, fullExp); - - return function simpleGetterFn1(scope, locals) { - if (scope == null) return undefined; - return ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0]; - }; -} - -function simpleGetterFn2(key0, key1, fullExp) { - ensureSafeMemberName(key0, fullExp); - ensureSafeMemberName(key1, fullExp); - - return function simpleGetterFn2(scope, locals) { - if (scope == null) return undefined; - scope = ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0]; - return scope == null ? undefined : scope[key1]; - }; -} - function getterFn(path, options, fullExp) { // Check whether the cache has this getter already. // We can use hasOwnProperty directly on the cache because we ensure, @@ -20608,13 +20818,8 @@ function getterFn(path, options, fullExp) { pathKeysLength = pathKeys.length, fn; - // When we have only 1 or 2 tokens, use optimized special case closures. // http://jsperf.com/angularjs-parse-getter/6 - if (!options.unwrapPromises && pathKeysLength === 1) { - fn = simpleGetterFn1(pathKeys[0], fullExp); - } else if (!options.unwrapPromises && pathKeysLength === 2) { - fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp); - } else if (options.csp) { + if (options.csp) { if (pathKeysLength < 6) { fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, options); @@ -20718,7 +20923,7 @@ function getterFn(path, options, fullExp) { /** * @ngdoc provider * @name $parseProvider - * @function + * @kind function * * @description * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse} @@ -20837,7 +21042,7 @@ function $ParseProvider() { var lexer = new Lexer($parseOptions); var parser = new Parser(lexer, $filter, $parseOptions); - parsedExpression = parser.parse(exp, false); + parsedExpression = parser.parse(exp); if (exp !== 'hasOwnProperty') { // Only cache the value if it's not going to mess up the cache object @@ -20880,17 +21085,13 @@ function $ParseProvider() { * var deferred = $q.defer(); * * setTimeout(function() { - * // since this fn executes async in a future turn of the event loop, we need to wrap - * // our code into an $apply call so that the model changes are properly observed. - * scope.$apply(function() { - * deferred.notify('About to greet ' + name + '.'); + * deferred.notify('About to greet ' + name + '.'); * - * if (okToGreet(name)) { - * deferred.resolve('Hello, ' + name + '!'); - * } else { - * deferred.reject('Greeting ' + name + ' is not allowed.'); - * } - * }); + * if (okToGreet(name)) { + * deferred.resolve('Hello, ' + name + '!'); + * } else { + * deferred.reject('Greeting ' + name + ' is not allowed.'); + * } * }, 1000); * * return deferred.promise; @@ -21048,7 +21249,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#defer - * @function + * @kind function * * @description * Creates a `Deferred` object which represents a task which will finish in the future. @@ -21164,7 +21365,7 @@ function qFactory(nextTick, exceptionHandler) { } catch(e) { return makePromise(e, false); } - if (callbackOutput && isFunction(callbackOutput.then)) { + if (isPromiseLike(callbackOutput)) { return callbackOutput.then(function() { return makePromise(value, isResolved); }, function(error) { @@ -21189,7 +21390,7 @@ function qFactory(nextTick, exceptionHandler) { var ref = function(value) { - if (value && isFunction(value.then)) return value; + if (isPromiseLike(value)) return value; return { then: function(callback) { var result = defer(); @@ -21205,7 +21406,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#reject - * @function + * @kind function * * @description * Creates a promise that is resolved as rejected with the specified `reason`. This api should be @@ -21265,7 +21466,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#when - * @function + * @kind function * * @description * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. @@ -21337,7 +21538,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#all - * @function + * @kind function * * @description * Combines multiple promises into a single promise that is resolved when all of the input @@ -21428,7 +21629,7 @@ function $$RAFProvider(){ //rAF * * 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 (shift) instead of at the end (push) + * 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 middle are expensive so we use linked list @@ -21562,7 +21763,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$new - * @function + * @kind function * * @description * Creates a new child {@link ng.$rootScope.Scope scope}. @@ -21594,18 +21795,23 @@ function $RootScopeProvider(){ child.$$asyncQueue = this.$$asyncQueue; child.$$postDigestQueue = this.$$postDigestQueue; } else { - ChildScope = function() {}; // should be anonymous; This is so that when the minifier munges - // the name it does not become random set of chars. This will then show up as class - // name in the web inspector. - ChildScope.prototype = this; - child = new ChildScope(); - child.$id = nextUid(); + // Only create a child scope class if somebody asks for one, + // but cache it to allow the VM to optimize lookups. + if (!this.$$childScopeClass) { + this.$$childScopeClass = function() { + this.$$watchers = this.$$nextSibling = + this.$$childHead = this.$$childTail = null; + this.$$listeners = {}; + this.$$listenerCount = {}; + this.$id = nextUid(); + this.$$childScopeClass = null; + }; + this.$$childScopeClass.prototype = this; + } + child = new this.$$childScopeClass(); } child['this'] = child; - child.$$listeners = {}; - child.$$listenerCount = {}; child.$parent = this; - child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null; child.$$prevSibling = this.$$childTail; if (this.$$childHead) { this.$$childTail.$$nextSibling = child; @@ -21619,7 +21825,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$watch - * @function + * @kind function * * @description * Registers a `listener` callback to be executed whenever the `watchExpression` changes. @@ -21631,10 +21837,14 @@ function $RootScopeProvider(){ * {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.) * - 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). The inequality is determined according to - * {@link angular.equals} function. To save the value of the object for later comparison, - * the {@link angular.copy} function is used. It also means that watching complex options - * will have adverse memory and performance implications. + * 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. * - 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. @@ -21669,12 +21879,16 @@ function $RootScopeProvider(){ expect(scope.counter).toEqual(0); scope.$digest(); - // no variable change - expect(scope.counter).toEqual(0); + // 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(1); + expect(scope.counter).toEqual(2); @@ -21761,7 +21975,7 @@ function $RootScopeProvider(){ // the while loop reads in reverse order. array.unshift(watcher); - return function() { + return function deregisterWatch() { arrayRemove(array, watcher); lastDirtyWatch = null; }; @@ -21771,7 +21985,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$watchCollection - * @function + * @kind function * * @description * Shallow watches the properties of an object and fires whenever any of the properties change @@ -21843,7 +22057,7 @@ function $RootScopeProvider(){ function $watchCollectionWatch() { newValue = objGetter(self); - var newLength, key; + var newLength, key, bothNaN; if (!isObject(newValue)) { // if primitive if (oldValue !== newValue) { @@ -21867,7 +22081,7 @@ function $RootScopeProvider(){ } // copy the items to oldValue and look for changes. for (var i = 0; i < newLength; i++) { - var bothNaN = (oldValue[i] !== oldValue[i]) && + bothNaN = (oldValue[i] !== oldValue[i]) && (newValue[i] !== newValue[i]); if (!bothNaN && (oldValue[i] !== newValue[i])) { changeDetected++; @@ -21887,7 +22101,9 @@ function $RootScopeProvider(){ if (newValue.hasOwnProperty(key)) { newLength++; if (oldValue.hasOwnProperty(key)) { - if (oldValue[key] !== newValue[key]) { + bothNaN = (oldValue[key] !== oldValue[key]) && + (newValue[key] !== newValue[key]); + if (!bothNaN && (oldValue[key] !== newValue[key])) { changeDetected++; oldValue[key] = newValue[key]; } @@ -21947,7 +22163,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$digest - * @function + * @kind function * * @description * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and @@ -21982,12 +22198,16 @@ function $RootScopeProvider(){ expect(scope.counter).toEqual(0); scope.$digest(); - // no variable change - expect(scope.counter).toEqual(0); + // 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(1); + expect(scope.counter).toEqual(2); * ``` * */ @@ -22035,11 +22255,11 @@ function $RootScopeProvider(){ if ((value = watch.get(current)) !== (last = watch.last) && !(watch.eq ? equals(value, last) - : (typeof value == 'number' && typeof last == 'number' + : (typeof value === 'number' && typeof last === 'number' && isNaN(value) && isNaN(last)))) { dirty = true; lastDirtyWatch = watch; - watch.last = watch.eq ? copy(value) : value; + watch.last = watch.eq ? copy(value, null) : value; watch.fn(value, ((last === initWatchVal) ? value : last), current); if (ttl < 5) { logIdx = 4 - ttl; @@ -22114,7 +22334,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$destroy - * @function + * @kind function * * @description * Removes the current scope (and all of its children) from the parent scope. Removal implies @@ -22175,7 +22395,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$eval - * @function + * @kind function * * @description * Executes the `expression` on the current scope and returns the result. Any exceptions in @@ -22207,7 +22427,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$evalAsync - * @function + * @kind function * * @description * Executes the expression on the current scope at a later point in time. @@ -22254,7 +22474,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$apply - * @function + * @kind function * * @description * `$apply()` is used to execute an expression in angular from outside of the angular @@ -22316,7 +22536,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$on - * @function + * @kind function * * @description * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for @@ -22365,7 +22585,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$emit - * @function + * @kind function * * @description * Dispatches an event `name` upwards through the scope hierarchy notifying the @@ -22433,7 +22653,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$broadcast - * @function + * @kind function * * @description * Dispatches an event `name` downwards to all child scopes (and their children) notifying the @@ -22681,7 +22901,7 @@ function adjustMatchers(matchers) { /** * @ngdoc service * @name $sceDelegate - * @function + * @kind function * * @description * @@ -22728,19 +22948,21 @@ function adjustMatchers(matchers) { * * 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/**']);
+ * ```
+ *  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**']);
- *      });
- * 
+ * // The blacklist overrides the whitelist so the open redirect here is blocked. + * $sceDelegateProvider.resourceUrlBlacklist([ + * 'http://myapp.example.com/clickThru**' + * ]); + * }); + * ``` */ function $SceDelegateProvider() { @@ -22753,7 +22975,7 @@ function $SceDelegateProvider() { /** * @ngdoc method * @name $sceDelegateProvider#resourceUrlWhitelist - * @function + * @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 @@ -22782,7 +23004,7 @@ function $SceDelegateProvider() { /** * @ngdoc method * @name $sceDelegateProvider#resourceUrlBlacklist - * @function + * @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 @@ -23009,7 +23231,7 @@ function $SceDelegateProvider() { /** * @ngdoc service * @name $sce - * @function + * @kind function * * @description * @@ -23035,10 +23257,10 @@ function $SceDelegateProvider() { * * Here's an example of a binding in a privileged context: * - *
- *     
- *     
- *
+ * ``` + * + *
+ * ``` * * 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. @@ -23078,15 +23300,15 @@ function $SceDelegateProvider() { * 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 || '');
- *       });
- *     };
- *   }];
- * 
+ * ``` + * 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 * @@ -23135,7 +23357,7 @@ function $SceDelegateProvider() { * * | 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. | + * | `$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 (`
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. | @@ -23159,7 +23381,7 @@ function $SceDelegateProvider() { * - `**`: matches zero or more occurrences of *any* character. As such, it's not * not appropriate to use in for 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.) It's usage at the very end of the path is ok. (e.g. + * 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 @@ -23190,66 +23412,65 @@ function $SceDelegateProvider() { * * ## Show me an example using SCE. * - * @example - - -
-

- User comments
- 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. -
-
- {{userComment.name}}: - -
-
-
-
-
- - - var mySceApp = angular.module('mySceApp', ['ngSanitize']); - - mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { - var self = this; - $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { - self.userComments = userComments; - }); - self.explicitlyTrustedHtml = $sce.trustAsHtml( - 'Hover over this text.'); - }); - - - -[ - { "name": "Alice", - "htmlComment": - "Is anyone reading this?" - }, - { "name": "Bob", - "htmlComment": "Yes! Am I the only other one?" - } -] - - - - describe('SCE doc demo', function() { - it('should sanitize untrusted values', function() { - expect(element(by.css('.htmlComment')).getInnerHtml()) - .toBe('Is anyone reading this?'); - }); - - it('should NOT sanitize explicitly trusted values', function() { - expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe( - 'Hover over this text.'); - }); - }); - -
+ * + * + *
+ *

+ * User comments
+ * 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. + *
+ *
+ * {{userComment.name}}: + * + *
+ *
+ *
+ *
+ *
+ * + * + * var mySceApp = angular.module('mySceApp', ['ngSanitize']); + * + * mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { + * var self = this; + * $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { + * self.userComments = userComments; + * }); + * self.explicitlyTrustedHtml = $sce.trustAsHtml( + * 'Hover over this text.'); + * }); + * + * + * + * [ + * { "name": "Alice", + * "htmlComment": + * "Is anyone reading this?" + * }, + * { "name": "Bob", + * "htmlComment": "Yes! Am I the only other one?" + * } + * ] + * + * + * + * describe('SCE doc demo', function() { + * it('should sanitize untrusted values', function() { + * expect(element.all(by.css('.htmlComment')).first().getInnerHtml()) + * .toBe('Is anyone reading this?'); + * }); + * + * it('should NOT sanitize explicitly trusted values', function() { + * expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe( + * 'Hover over this text.'); + * }); + * }); + * + *
* * * @@ -23263,13 +23484,13 @@ function $SceDelegateProvider() { * * 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);
- *   });
- * 
+ * ``` + * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) { + * // Completely disable SCE. For demonstration purposes only! + * // Do not use in new projects. + * $sceProvider.enabled(false); + * }); + * ``` * */ /* jshint maxlen: 100 */ @@ -23280,7 +23501,7 @@ function $SceProvider() { /** * @ngdoc method * @name $sceProvider#enabled - * @function + * @kind function * * @param {boolean=} value If provided, then enables/disables SCE. * @return {boolean} true if SCE is enabled, false otherwise. @@ -23353,12 +23574,12 @@ function $SceProvider() { 'document. See http://docs.angularjs.org/api/ng.$sce for more information.'); } - var sce = copy(SCE_CONTEXTS); + var sce = shallowCopy(SCE_CONTEXTS); /** * @ngdoc method * @name $sce#isEnabled - * @function + * @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}. @@ -23380,7 +23601,7 @@ function $SceProvider() { /** * @ngdoc method - * @name $sce#parse + * @name $sce#parseAs * * @description * Converts Angular {@link guide/expression expression} into a function. This is like {@link @@ -23893,7 +24114,7 @@ var originUrl = urlResolve(window.location.href, true); * https://github.com/angular/angular.js/pull/2902 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/ * - * @function + * @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. @@ -23966,17 +24187,18 @@ function urlIsSameOrigin(requestUrl) { * expression. * * @example - + -
+
@@ -23994,6 +24216,17 @@ function $WindowProvider(){ this.$get = valueFn(window); } +/* global currencyFilter: true, + dateFilter: true, + filterFilter: true, + jsonFilter: true, + limitToFilter: true, + lowercaseFilter: true, + numberFilter: true, + orderByFilter: true, + uppercaseFilter: true, + */ + /** * @ngdoc provider * @name $filterProvider @@ -24057,7 +24290,7 @@ function $WindowProvider(){ /** * @ngdoc service * @name $filter - * @function + * @kind function * @description * Filters are used for formatting data displayed to the user. * @@ -24067,7 +24300,24 @@ function $WindowProvider(){ * * @param {String} name Name of the filter function to retrieve * @return {Function} the filter function - */ + * @example + + +
+

{{ originalText }}

+

{{ filteredText }}

+
+
+ + + angular.module('filterExample', []) + .controller('MainCtrl', function($scope, $filter) { + $scope.originalText = 'hello'; + $scope.filteredText = $filter('uppercase')($scope.originalText); + }); + +
+ */ $FilterProvider.$inject = ['$provide']; function $FilterProvider($provide) { var suffix = 'Filter'; @@ -24127,7 +24377,7 @@ function $FilterProvider($provide) { /** * @ngdoc filter * @name filter - * @function + * @kind function * * @description * Selects a subset of items from `array` and returns it as a new array. @@ -24159,15 +24409,15 @@ function $FilterProvider($provide) { * * 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 the item should be included in filtered result. + * - `function(actual, expected)`: + * The function will be given the object value and the predicate value to compare and + * should return true if the item should be included in filtered result. * - * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`. - * this is essentially strict comparison of expected and actual. + * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`. + * this is essentially strict comparison of expected and actual. * - * - `false|undefined`: A short hand for a function which will look for a substring match in case - * insensitive way. + * - `false|undefined`: A short hand for a function which will look for a substring match in case + * insensitive way. * * @example @@ -24319,7 +24569,7 @@ function filterFilter() { // jshint +W086 for (var key in expression) { (function(path) { - if (typeof expression[path] == 'undefined') return; + if (typeof expression[path] === 'undefined') return; predicates.push(function(value) { return search(path == '$' ? value : (value && value[path]), expression[path]); }); @@ -24346,7 +24596,7 @@ function filterFilter() { /** * @ngdoc filter * @name currency - * @function + * @kind function * * @description * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default @@ -24358,14 +24608,15 @@ function filterFilter() { * * * @example - + -
+

default currency symbol ($): {{amount | currency}}
custom currency identifier (USD$): {{amount | currency:"USD$"}} @@ -24403,7 +24654,7 @@ function currencyFilter($locale) { /** * @ngdoc filter * @name number - * @function + * @kind function * * @description * Formats a number as text. @@ -24417,14 +24668,15 @@ function currencyFilter($locale) { * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit. * * @example - + -
+
Enter number:
Default formatting: {{val | number}}
No fractions: {{val | number:0}}
@@ -24474,6 +24726,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { var match = numStr.match(/([\d\.]+)e(-?)(\d+)/); if (match && match[2] == '-' && match[3] > fractionSize + 1) { numStr = '0'; + number = 0; } else { formatedText = numStr; hasExponent = true; @@ -24488,8 +24741,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac); } - var pow = Math.pow(10, fractionSize); - number = Math.round(number * pow) / pow; + // safely round numbers in JS without hitting imprecisions of floating-point arithmetics + // inspired by: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round + number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize); + var fraction = ('' + number).split(DECIMAL_SEP); var whole = fraction[0]; fraction = fraction[1] || ''; @@ -24615,7 +24871,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+ /** * @ngdoc filter * @name date - * @function + * @kind function * * @description * Formats `date` to a string based on the requested `format`. @@ -24732,11 +24988,7 @@ function dateFilter($locale) { format = format || 'mediumDate'; format = $locale.DATETIME_FORMATS[format] || format; if (isString(date)) { - if (NUMBER_STRING.test(date)) { - date = int(date); - } else { - date = jsonStringToDate(date); - } + date = NUMBER_STRING.test(date) ? int(date) : jsonStringToDate(date); } if (isNumber(date)) { @@ -24772,7 +25024,7 @@ function dateFilter($locale) { /** * @ngdoc filter * @name json - * @function + * @kind function * * @description * Allows you to convert a JavaScript object into JSON string. @@ -24807,7 +25059,7 @@ function jsonFilter() { /** * @ngdoc filter * @name lowercase - * @function + * @kind function * @description * Converts string to lowercase. * @see angular.lowercase @@ -24818,7 +25070,7 @@ var lowercaseFilter = valueFn(lowercase); /** * @ngdoc filter * @name uppercase - * @function + * @kind function * @description * Converts string to uppercase. * @see angular.uppercase @@ -24828,7 +25080,7 @@ var uppercaseFilter = valueFn(uppercase); /** * @ngdoc filter * @name limitTo - * @function + * @kind function * * @description * Creates a new array or string containing only a specified number of elements. The elements @@ -24844,17 +25096,18 @@ var uppercaseFilter = valueFn(uppercase); * had less than `limit` elements. * * @example - + -
+
Limit {{numbers}} to:

Output numbers: {{ numbers | limitTo:numLimit }}

Limit {{letters}} to: @@ -24898,7 +25151,11 @@ function limitToFilter(){ return function(input, limit) { if (!isArray(input) && !isString(input)) return input; - limit = int(limit); + if (Math.abs(Number(limit)) === Infinity) { + limit = Number(limit); + } else { + limit = int(limit); + } if (isString(input)) { //NaN check on limit @@ -24937,10 +25194,12 @@ function limitToFilter(){ /** * @ngdoc filter * @name orderBy - * @function + * @kind function * * @description - * Orders a specified `array` by the `expression` predicate. + * Orders a specified `array` by the `expression` predicate. It is ordered alphabetically + * for strings and numerically for numbers. Note: if you notice numbers are not being sorted + * correctly, make sure they are actually being saved as numbers and not strings. * * @param {Array} array The array to sort. * @param {function(*)|string|Array.<(function(*)|string)>} expression A predicate to be @@ -24960,20 +25219,21 @@ function limitToFilter(){ * @returns {Array} Sorted copy of the source array. * * @example - + -
+ + + + + + + + + + +
Name + (^)Phone NumberAge
{{friend.name}}{{friend.phone}}{{friend.age}}
+
+ + + + angular.module('orderByExample', []) + .controller('ExampleController', ['$scope', '$filter', function($scope, $filter) { + var orderBy = $filter('orderBy'); + $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 } + ]; + $scope.order = function(predicate, reverse) { + $scope.friends = orderBy($scope.friends, predicate, reverse); + }; + $scope.order('-age',false); + }]); + + */ orderByFilter.$inject = ['$parse']; function orderByFilter($parse){ @@ -25039,6 +25344,10 @@ function orderByFilter($parse){ var t1 = typeof v1; var t2 = typeof v2; if (t1 == t2) { + if (isDate(v1) && isDate(v2)) { + v1 = v1.valueOf(); + v2 = v2.valueOf(); + } if (t1 == "string") { v1 = v1.toLowerCase(); v2 = v2.toLowerCase(); @@ -25176,7 +25485,7 @@ var htmlAnchorDirective = valueFn({ return browser.driver.getCurrentUrl().then(function(url) { return url.match(/\/123$/); }); - }, 1000, 'page should navigate to /123'); + }, 5000, 'page should navigate to /123'); }); xit('should execute ng-click but not reload when href empty string and name specified', function() { @@ -25204,7 +25513,7 @@ var htmlAnchorDirective = valueFn({ return browser.driver.getCurrentUrl().then(function(url) { return url.match(/\/6$/); }); - }, 1000, 'page should navigate to /6'); + }, 5000, 'page should navigate to /6'); }); @@ -25544,7 +25853,7 @@ var nullFormCtrl = { * - `url` * * @description - * `FormController` keeps track of all its controls and nested forms as well as state of them, + * `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 @@ -25820,12 +26129,13 @@ function FormController(element, attrs, $scope, $animate) { * * * @example - + - + userType: Required!
userType = {{userType}}
@@ -25931,16 +26241,14 @@ var formDirectiveFactory = function(isNgForm) { var formDirective = formDirectiveFactory(); var ngFormDirective = formDirectiveFactory(true); -/* global - - -VALID_CLASS, - -INVALID_CLASS, - -PRISTINE_CLASS, - -DIRTY_CLASS +/* global VALID_CLASS: true, + INVALID_CLASS: true, + PRISTINE_CLASS: true, + DIRTY_CLASS: true */ var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/; -var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i; +var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i; var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/; var inputType = { @@ -25970,15 +26278,16 @@ var inputType = { * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. * * @example - + - + Single word: @@ -26050,14 +26359,15 @@ var inputType = { * interaction with the input element. * * @example - + - + Number: @@ -26125,14 +26435,15 @@ var inputType = { * interaction with the input element. * * @example - + - + URL: Required! @@ -26201,14 +26512,15 @@ var inputType = { * interaction with the input element. * * @example - + - + Email: Required! @@ -26267,18 +26579,19 @@ var inputType = { * be set when selected. * * @example - + - + Red
Green
Blue
@@ -26317,15 +26630,16 @@ var inputType = { * interaction with the input element. * * @example - + - + Value1:
Value2:
@@ -26366,15 +26680,29 @@ function validate(ctrl, validatorName, validity, value){ return validity ? value : undefined; } +function testFlags(validity, flags) { + var i, flag; + if (flags) { + for (i=0; i @@ -26413,11 +26753,11 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { value = trim(value); } - if (ctrl.$viewValue !== value || - // If the value is still empty/falsy, and there is no `required` error, run validators - // again. This enables HTML5 constraint validation errors to affect Angular validation - // even when the first character entered causes an error. - (validity && value === '' && !validity.valueMissing)) { + // If a control is suffering from bad input, browsers discard its value, so it may be + // necessary to revalidate even if the control's value is the same empty value twice in + // a row. + var revalidate = validity && ctrl.$$hasNativeValidators; + if (ctrl.$viewValue !== value || (value === '' && revalidate)) { if (scope.$$phase) { ctrl.$setViewValue(value); } else { @@ -26523,6 +26863,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { } } +var numberBadFlags = ['badInput']; + function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { textInputType(scope, element, attr, ctrl, $sniffer, $browser); @@ -26537,7 +26879,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { } }); - addNativeHtml5Validators(ctrl, 'number', element); + addNativeHtml5Validators(ctrl, 'number', numberBadFlags, null, ctrl.$$validityState); ctrl.$formatters.push(function(value) { return ctrl.$isEmpty(value) ? '' : '' + value; @@ -26669,6 +27011,7 @@ function checkboxInputType(scope, element, attr, ctrl) { * patterns defined as scope expressions. * @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. */ @@ -26696,14 +27039,15 @@ function checkboxInputType(scope, element, attr, ctrl) { * interaction with the input element. * * @example - + -
+
User name: @@ -26818,14 +27162,14 @@ var VALID_CLASS = 'ng-valid', * @property {Array.} $formatters Array of functions to execute, as a pipeline, whenever the model value changes. Each function is called, in turn, passing the value through to the next. Used to format / convert values for display in the control and validation. - * ```js - * function formatter(value) { - * if (value) { - * return value.toUpperCase(); - * } - * } - * ngModel.$formatters.push(formatter); - * ``` + * ```js + * function formatter(value) { + * if (value) { + * return value.toUpperCase(); + * } + * } + * ngModel.$formatters.push(formatter); + * ``` * * @property {Array.} $viewChangeListeners Array of functions to execute whenever the * view value has changed. It is called with no arguments, and its return value is ignored. @@ -26854,7 +27198,12 @@ var VALID_CLASS = 'ng-valid', * Note that `contenteditable` is an HTML5 attribute, which tells the browser to let the element * contents be edited in place by the user. This will not work on older browsers. * - * + * 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. ``). + * However, as we are using `$sce` the model can still decide to to provide unsafe content if it marks + * that content using the `$sce` service. + * + * [contenteditable] { border: 1px solid black; @@ -26868,8 +27217,8 @@ var VALID_CLASS = 'ng-valid', - angular.module('customControl', []). - directive('contenteditable', function() { + angular.module('customControl', ['ngSanitize']). + directive('contenteditable', ['$sce', function($sce) { return { restrict: 'A', // only activate on element attribute require: '?ngModel', // get a hold of NgModelController @@ -26878,7 +27227,7 @@ var VALID_CLASS = 'ng-valid', // Specify how UI should be updated ngModel.$render = function() { - element.html(ngModel.$viewValue || ''); + element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); }; // Listen for change events to enable binding @@ -26899,7 +27248,7 @@ var VALID_CLASS = 'ng-valid', } } }; - }); + }]); @@ -27013,7 +27362,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * This method should be called by validators - i.e. the parser or formatter functions. * * @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign - * to `$error[validationErrorKey]=isValid` so that it is available for data-binding. + * to `$error[validationErrorKey]=!isValid` 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}}` . @@ -27216,12 +27565,13 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * * * @example - * + * Update input to see transitions when valid/invalid. Integer is a valid value. - + @@ -27280,17 +27630,18 @@ var ngModelDirective = function() { * in input value. * * @example - * + * * * - *
+ *
* * *
@@ -27371,14 +27722,15 @@ var requiredDirective = function() { * specified in form `/something/` then the value will be converted into a regular expression. * * @example - + -
+ List: Required! @@ -27470,15 +27822,16 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/; * of the `input` element * * @example - + - +

Which is your favorite?

+
Enter name:
Hello !
@@ -27573,14 +27927,19 @@ var ngValueDirective = function() { */ -var ngBindDirective = ngDirective(function(scope, element, attr) { - element.addClass('ng-binding').data('$binding', attr.ngBind); - scope.$watch(attr.ngBind, function ngBindWatchAction(value) { - // We are purposefully using == here rather than === because we want to - // catch when value is "null or undefined" - // jshint -W041 - element.text(value == undefined ? '' : value); - }); +var ngBindDirective = ngDirective({ + compile: function(templateElement) { + templateElement.addClass('ng-binding'); + return function (scope, element, attr) { + element.data('$binding', attr.ngBind); + scope.$watch(attr.ngBind, function ngBindWatchAction(value) { + // We are purposefully using == here rather than === because we want to + // catch when value is "null or undefined" + // jshint -W041 + element.text(value == undefined ? '' : value); + }); + }; + } }); @@ -27602,15 +27961,16 @@ var ngBindDirective = ngDirective(function(scope, element, attr) { * * @example * Try it here: enter text in text box and watch the greeting change. - + -
+
Salutation:
Name:

@@ -27668,20 +28028,20 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
  * @example
    Try it here: enter text in text box and watch the greeting change.
 
-   
+   
      
-       
+

- angular.module('ngBindHtmlExample', ['ngSanitize']) - - .controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) { - $scope.myHTML = - 'I am an HTMLstring with links! and other stuff'; - }]); + angular.module('bindHtmlExample', ['ngSanitize']) + .controller('ExampleController', ['$scope', function($scope) { + $scope.myHTML = + 'I am an HTMLstring with ' + + '
links! and other stuff'; + }]); @@ -27693,15 +28053,24 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) { */ var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) { - return function(scope, element, attr) { - element.addClass('ng-binding').data('$binding', attr.ngBindHtml); + return { + compile: function (tElement) { + tElement.addClass('ng-binding'); - var parsed = $parse(attr.ngBindHtml); - function getStringValue() { return (parsed(scope) || '').toString(); } + return function (scope, element, attr) { + element.data('$binding', attr.ngBindHtml); - scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) { - element.html($sce.getTrustedHtml(parsed(scope)) || ''); - }); + var parsed = $parse(attr.ngBindHtml); + + function getStringValue() { + return (parsed(scope) || '').toString(); + } + + scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) { + element.html($sce.getTrustedHtml(parsed(scope)) || ''); + }); + }; + } }; }]; @@ -27724,7 +28093,7 @@ function classDirective(name, selector) { scope.$watch('$index', function($index, old$index) { // jshint bitwise: false var mod = $index & 1; - if (mod !== old$index & 1) { + if (mod !== (old$index & 1)) { var classes = arrayClasses(scope.$eval(attr[name])); mod === selector ? addClasses(classes) : @@ -27783,7 +28152,7 @@ function classDirective(name, selector) { updateClasses(oldClasses, newClasses); } } - oldVal = copy(newVal); + oldVal = shallowCopy(newVal); } } }; @@ -27811,7 +28180,7 @@ function classDirective(name, selector) { var classes = [], i = 0; forEach(classVal, function(v, k) { if (v) { - classes.push(k); + classes = classes.concat(k.split(' ')); } }); return classes; @@ -28136,7 +28505,7 @@ var ngCloakDirective = ngDirective({ * * MVC components in angular: * - * * Model — The Model is scope properties; scopes are attached to the DOM where scope properties + * * 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 @@ -28157,165 +28526,192 @@ var ngCloakDirective = ngDirective({ * @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. Notice that the scope becomes the `this` for the - * controller's instance. This allows for easy access to the view data from the controller. Also - * notice that any changes to the data are automatically reflected in the View without the need - * for a manual update. The example is shown in two different declaration styles you may use - * according to preference. - - - -
- Name: - [ greet ]
- Contact: -
    -
  • - - - [ clear - | X ] -
  • -
  • [ add ]
  • -
-
-
- - it('should check controller as', function() { - var container = element(by.id('ctrl-as-exmpl')); - - expect(container.findElement(by.model('settings.name')) - .getAttribute('value')).toBe('John Smith'); - - var firstRepeat = - container.findElement(by.repeater('contact in settings.contacts').row(0)); - var secondRepeat = - container.findElement(by.repeater('contact in settings.contacts').row(1)); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('408 555 1212'); - expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('john.smith@example.org'); - - firstRepeat.findElement(by.linkText('clear')).click(); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe(''); - - container.findElement(by.linkText('add')).click(); - - expect(container.findElement(by.repeater('contact in settings.contacts').row(2)) - .findElement(by.model('contact.value')) - .getAttribute('value')) - .toBe('yourname@example.org'); - }); - -
- - - -
- Name: - [ greet ]
- Contact: -
    -
  • - - - [ clear - | X ] -
  • -
  • [ add ]
  • -
-
-
- - it('should check controller', function() { - var container = element(by.id('ctrl-exmpl')); - - expect(container.findElement(by.model('name')) - .getAttribute('value')).toBe('John Smith'); - - var firstRepeat = - container.findElement(by.repeater('contact in contacts').row(0)); - var secondRepeat = - container.findElement(by.repeater('contact in contacts').row(1)); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('408 555 1212'); - expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('john.smith@example.org'); - - firstRepeat.findElement(by.linkText('clear')).click(); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe(''); - - container.findElement(by.linkText('add')).click(); - - expect(container.findElement(by.repeater('contact in contacts').row(2)) - .findElement(by.model('contact.value')) - .getAttribute('value')) - .toBe('yourname@example.org'); - }); - -
+ * 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. + * + * + * + *
+ * Name: + * [ greet ]
+ * Contact: + *
    + *
  • + * + * + * [ clear + * | X ] + *
  • + *
  • [ add ]
  • + *
+ *
+ *
+ * + * 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 = ''; + * }; + * + * + * 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.linkText('clear')).click(); + * + * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe(''); + * + * container.element(by.linkText('add')).click(); + * + * expect(container.element(by.repeater('contact in settings.contacts').row(2)) + * .element(by.model('contact.value')) + * .getAttribute('value')) + * .toBe('yourname@example.org'); + * }); + * + *
+ * + * This example demonstrates the "attach to `$scope`" style of controller. + * + * + * + *
+ * Name: + * [ greet ]
+ * Contact: + *
    + *
  • + * + * + * [ clear + * | X ] + *
  • + *
  • [ add ]
  • + *
+ *
+ *
+ * + * 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 = ''; + * }; + * } + * + * + * 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.linkText('clear')).click(); + * + * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe(''); + * + * container.element(by.linkText('add')).click(); + * + * expect(container.element(by.repeater('contact in contacts').row(2)) + * .element(by.model('contact.value')) + * .getAttribute('value')) + * .toBe('yourname@example.org'); + * }); + * + *
*/ var ngControllerDirective = [function() { @@ -28337,8 +28733,10 @@ var ngControllerDirective = [function() { * This is necessary when developing things like Google Chrome Extensions. * * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things). - * For us to be compatible, we just need to implement the "getterFn" in $parse without violating - * any of these restrictions. + * For Angular to be CSP compatible there are only two things that we need to do differently: + * + * - don't use `Function` constructor to generate optimized value getters + * - don't inject custom stylesheet into the document * * AngularJS uses `Function(string)` generated functions as a speed optimization. Applying the `ngCsp` * directive will cause Angular to use CSP compatibility mode. When this mode is on AngularJS will @@ -28349,7 +28747,18 @@ var ngControllerDirective = [function() { * includes some CSS rules (e.g. {@link ng.directive:ngCloak ngCloak}). * To make those directives work in CSP mode, include the `angular-csp.css` manually. * - * In order to use this feature put the `ngCsp` directive on the root element of the application. + * Angular tries to autodetect if CSP is active and automatically turn on the CSP-safe mode. 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 the root element of the application or on the `angular.js` script tag, whichever + * appears first in the html document. * * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.* * @@ -28364,9 +28773,9 @@ var ngControllerDirective = [function() { ``` */ -// ngCsp is not implemented as a proper directive any more, because we need it be processed while we bootstrap -// the system (before $parse is instantiated), for this reason we just have a csp() fn that looks for ng-csp attribute -// anywhere in the current doc +// ngCsp is not implemented as a proper directive any more, because we need it be processed while we +// bootstrap the system (before $parse is instantiated), for this reason we just have +// the csp.isActive() fn that looks for ng-csp attribute anywhere in the current doc /** * @ngdoc directive @@ -28413,7 +28822,7 @@ forEach( return { compile: function($element, attr) { var fn = $parse(attr[directiveName]); - return function(scope, element, attr) { + return function ngEventHandler(scope, element) { element.on(lowercase(name), function(event) { scope.$apply(function() { fn(scope, {$event:event}); @@ -28630,8 +29039,13 @@ forEach( * @example - - key up count: {{count}} +

Typing in the input box below updates the key count

+ key up count: {{count}} + +

Typing in the input box below updates the keycode

+ +

event keyCode: {{ event.keyCode }}

+

event altKey: {{ event.altKey }}

*/ @@ -28676,21 +29090,22 @@ forEach( * ({@link guide/expression#-event- Event object is available as `$event`}) * * @example - + - + Enter text and hit enter: @@ -28702,7 +29117,7 @@ forEach( expect(element(by.binding('list')).getText()).toBe('list=[]'); element(by.css('#submit')).click(); expect(element(by.binding('list')).getText()).toContain('hello'); - expect(element(by.input('text')).getAttribute('value')).toBe(''); + expect(element(by.model('text')).getAttribute('value')).toBe(''); }); it('should ignore empty strings', function() { expect(element(by.binding('list')).getText()).toBe('list=[]'); @@ -28903,7 +29318,7 @@ var ngIfDirective = ['$animate', function($animate) { clone[clone.length++] = document.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 it's template arrives. + // by a directive with templateUrl when its template arrives. block = { clone: clone }; @@ -28975,9 +29390,9 @@ var ngIfDirective = ['$animate', function($animate) { * - Otherwise enable scrolling only if the expression evaluates to truthy value. * * @example - + -
+
@@ -28989,12 +29404,13 @@ var ngIfDirective = ['$animate', function($animate) {
- function Ctrl($scope) { - $scope.templates = - [ { name: 'template1.html', url: 'template1.html'}, - { name: 'template2.html', url: 'template2.html'} ]; - $scope.template = $scope.templates[0]; - } + 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]; + }]); Content of template1.html @@ -29057,7 +29473,7 @@ var ngIfDirective = ['$animate', function($animate) { return; } templateSelect.click(); - templateSelect.element.all(by.css('option')).get(2).click(); + templateSelect.all(by.css('option')).get(2).click(); expect(includeElem.getText()).toMatch(/Content of template2.html/); }); @@ -29067,7 +29483,7 @@ var ngIfDirective = ['$animate', function($animate) { return; } templateSelect.click(); - templateSelect.element.all(by.css('option')).get(0).click(); + templateSelect.all(by.css('option')).get(0).click(); expect(includeElem.isPresent()).toBe(false); }); @@ -29219,14 +29635,15 @@ var ngIncludeFillContentDirective = ['$compile', * @param {expression} ngInit {@link guide/expression Expression} to eval. * * @example - + -
+
list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}}; @@ -29366,7 +29783,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); * 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, Marry and one other person are viewing" + * 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 @@ -29379,16 +29796,17 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); * @param {number=} offset Offset to deduct from the total number. * * @example - + -
+
Person 1:
Person 2:
Number of People:
@@ -29602,7 +30020,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp * mapped to the same DOM element, which is not possible.) Filters should be applied to the expression, * before specifying a tracking expression. * - * For example: `item in items` is equivalent to `item in items track by $id(item)'. This implies that the DOM elements + * 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 @@ -29880,7 +30298,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { block.scope = childScope; // 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 it's template arrives. + // by a directive with templateUrl when its template arrives. block.clone = clone; nextBlockMap[block.id] = block; }); @@ -29923,6 +30341,11 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * on the element causing it to become hidden. When true, the ng-hide CSS class is removed * from the element causing the element not to appear hidden. * + *
+ * **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):
+ * "f" / "0" / "false" / "no" / "n" / "[]" + *
+ * * ## 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 @@ -29936,26 +30359,21 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * * ### Overriding .ng-hide * - * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by - * restating the styles for the .ng-hide class in CSS: + * 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 then this can be achieved by restating the styles for the `.ng-hide` + * class in CSS: + * * ```css * .ng-hide { - * //!annotate CSS Specificity|Not to worry, this will override the AngularJS default... - * display:block!important; - * * //this is just another form of hiding an element + * display:block!important; * position:absolute; * top:-9999px; * left:-9999px; * } * ``` * - * Just remember to include the important flag so the CSS override will function. - * - *
- * **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):
- * "f" / "0" / "false" / "no" / "n" / "[]" - *
+ * 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 ngShow * @@ -29970,7 +30388,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * // * .my-element.ng-hide-add, .my-element.ng-hide-remove { * transition:0.5s linear all; - * display:block!important; * } * * .my-element.ng-hide-add { ... } @@ -29979,6 +30396,9 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * .my-element.ng-hide-remove.ng-hide-remove-active { ... } * ``` * + * Keep in mind that, as of AngularJS version 1.2.17 (and 1.3.0-beta.11), there is no need to change the display + * property to block during animation states--ngAnimate will handle the style toggling automatically for you. + * * @animations * addClass: .ng-hide - happens after the ngShow expression evaluates to a truthy value and the just before contents are set to visible * removeClass: .ng-hide - happens after the ngShow expression evaluates to a non truthy value and just before the contents are set to hidden @@ -30018,11 +30438,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { background:white; } - .animate-show.ng-hide-add, - .animate-show.ng-hide-remove { - display:block!important; - } - .animate-show.ng-hide { line-height:0; opacity:0; @@ -30073,16 +30488,21 @@ var ngShowDirective = ['$animate', function($animate) { * * ```html * - *
+ *
* * - *
+ *
* ``` * * When the ngHide expression evaluates to true then the .ng-hide CSS class is added to the class attribute * on the element causing it to become hidden. When false, the ng-hide CSS class is removed * from the element causing the element not to appear hidden. * + *
+ * **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):
+ * "f" / "0" / "false" / "no" / "n" / "[]" + *
+ * * ## 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 @@ -30096,33 +30516,27 @@ var ngShowDirective = ['$animate', function($animate) { * * ### Overriding .ng-hide * - * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by - * restating the styles for the .ng-hide class in CSS: + * 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 then this can be achieved by restating the styles for the `.ng-hide` + * class in CSS: + * * ```css * .ng-hide { - * //!annotate CSS Specificity|Not to worry, this will override the AngularJS default... - * display:block!important; - * * //this is just another form of hiding an element + * display:block!important; * position:absolute; * top:-9999px; * left:-9999px; * } * ``` * - * Just remember to include the important flag so the CSS override will function. - * - *
- * **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):
- * "f" / "0" / "false" / "no" / "n" / "[]" - *
+ * 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 you can perform an animation when the element is hidden during the time of the animation. + * is true and false. This system works like the animation system present with ngClass, except that the `.ng-hide` + * CSS class is added and removed for you instead of your own CSS class. * * ```css * // @@ -30130,7 +30544,6 @@ var ngShowDirective = ['$animate', function($animate) { * // * .my-element.ng-hide-add, .my-element.ng-hide-remove { * transition:0.5s linear all; - * display:block!important; * } * * .my-element.ng-hide-add { ... } @@ -30139,6 +30552,9 @@ var ngShowDirective = ['$animate', function($animate) { * .my-element.ng-hide-remove.ng-hide-remove-active { ... } * ``` * + * Keep in mind that, as of AngularJS version 1.2.17 (and 1.3.0-beta.11), there is no need to change the display + * property to block during animation states--ngAnimate will handle the style toggling automatically for you. + * * @animations * removeClass: .ng-hide - happens after the ngHide expression evaluates to a truthy value and just before the contents are set to hidden * addClass: .ng-hide - happens after the ngHide expression evaluates to a non truthy value and just before the contents are set to visible @@ -30178,11 +30594,6 @@ var ngShowDirective = ['$animate', function($animate) { background:white; } - .animate-hide.ng-hide-add, - .animate-hide.ng-hide-remove { - display:block!important; - } - .animate-hide.ng-hide { line-height:0; opacity:0; @@ -30228,14 +30639,20 @@ var ngHideDirective = ['$animate', function($animate) { * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally. * * @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. + * @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 - + +
Sample Text @@ -30251,7 +30668,7 @@ var ngHideDirective = ['$animate', function($animate) { it('should check ng-style', function() { expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)'); - element(by.css('input[value=set]')).click(); + 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)'); @@ -30299,11 +30716,14 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { * leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM * * @usage + * + * ``` * * ... * ... * ... * + * ``` * * * @scope @@ -30320,9 +30740,9 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { * * * @example - + -
+
selection={{selection}} @@ -30336,10 +30756,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
- function Ctrl($scope) { - $scope.items = ['settings', 'home', 'other']; - $scope.selection = $scope.items[0]; - } + angular.module('switchExample', ['ngAnimate']) + .controller('ExampleController', ['$scope', function($scope) { + $scope.items = ['settings', 'home', 'other']; + $scope.selection = $scope.items[0]; + }]); .animate-switch-container { @@ -30382,11 +30803,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { expect(switchElem.getText()).toMatch(/Settings Div/); }); it('should change to home', function() { - select.element.all(by.css('option')).get(1).click(); + select.all(by.css('option')).get(1).click(); expect(switchElem.getText()).toMatch(/Home Span/); }); it('should select default', function() { - select.element.all(by.css('option')).get(2).click(); + select.all(by.css('option')).get(2).click(); expect(switchElem.getText()).toMatch(/default/); }); @@ -30403,37 +30824,29 @@ var ngSwitchDirective = ['$animate', function($animate) { }], link: function(scope, element, attr, ngSwitchController) { var watchExpr = attr.ngSwitch || attr.on, - selectedTranscludes, - selectedElements, - previousElements, + selectedTranscludes = [], + selectedElements = [], + previousElements = [], selectedScopes = []; scope.$watch(watchExpr, function ngSwitchWatchAction(value) { - var i, ii = selectedScopes.length; - if(ii > 0) { - if(previousElements) { - for (i = 0; i < ii; i++) { - previousElements[i].remove(); - } - previousElements = null; - } + var i, ii; + for (i = 0, ii = previousElements.length; i < ii; ++i) { + previousElements[i].remove(); + } + previousElements.length = 0; - previousElements = []; - for (i= 0; i + -
+


{{text}} @@ -30666,21 +31078,22 @@ var ngOptionsMinErr = minErr('ngOptions'); * `value` variable (e.g. `value.propertyName`). * * @example - + -
+
  • Name: @@ -30692,37 +31105,37 @@ var ngOptionsMinErr = minErr('ngOptions');

Color (null not allowed): -
+
Color (null allowed): -
Color grouped by shade: -
- Select bogus.
+ Select bogus.

- Currently selected: {{ {selected_color:color} }} + Currently selected: {{ {selected_color:myColor} }}
+ ng-style="{'background-color':myColor.name}">
it('should check ng-options', function() { - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red'); - element.all(by.select('color')).first().click(); - element.all(by.css('select[ng-model="color"] option')).first().click(); - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black'); - element(by.css('.nullable select[ng-model="color"]')).click(); - element.all(by.css('.nullable select[ng-model="color"] option')).first().click(); - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null'); + 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'); }); @@ -30877,7 +31290,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // we need to work of an array, so we need to see if anything was inserted/removed scope.$watch(function selectMultipleWatch() { if (!equals(lastView, ctrl.$viewValue)) { - lastView = copy(ctrl.$viewValue); + lastView = shallowCopy(ctrl.$viewValue); ctrl.$render(); } }); @@ -31133,6 +31546,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // lastElement.prop('selected') provided by jQuery has side-effects if (existingOption.selected !== option.selected) { lastElement.prop('selected', (existingOption.selected = option.selected)); + if (msie) { + // See #7692 + // The selected item wouldn't visually update on IE without this. + // Tested on Win7: IE9, IE10 and IE11. Future IEs should be tested as well + lastElement.prop('selected', existingOption.selected); + } } } else { // grow elements @@ -31147,7 +31566,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // rather then the element. (element = optionTemplate.clone()) .val(option.id) - .attr('selected', option.selected) + .prop('selected', option.selected) .text(option.label); } @@ -31528,7 +31947,7 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) { function push(value) { if (value === undefined) { value = ''; - } else if (typeof value != 'string') { + } else if (typeof value !== 'string') { value = angular.toJson(value); } result.push('' + value); @@ -32036,7 +32455,7 @@ angular.scenario.Future.prototype.execute = function(doneFn) { }; /** - * Configures the future to convert it's final with a function fn(value) + * Configures the future to convert its final with a function fn(value) * * @param {function()} fn function(value) that returns the parsed value */ @@ -32046,7 +32465,7 @@ angular.scenario.Future.prototype.parsedWith = function(fn) { }; /** - * Configures the future to parse it's final value from JSON + * Configures the future to parse its final value from JSON * into objects. */ angular.scenario.Future.prototype.fromJson = function() { @@ -32054,7 +32473,7 @@ angular.scenario.Future.prototype.fromJson = function() { }; /** - * Configures the future to convert it's final value from objects + * Configures the future to convert its final value from objects * into JSON. */ angular.scenario.Future.prototype.toJson = function() { @@ -33460,5 +33879,5 @@ if (config.autotest) { })(window, document); -!angular.$$csp() && angular.element(document).find('head').prepend(''); -!angular.$$csp() && angular.element(document).find('head').prepend(''); \ No newline at end of file +!window.angular.$$csp() && window.angular.element(document).find('head').prepend(''); +!window.angular.$$csp() && window.angular.element(document).find('head').prepend(''); \ No newline at end of file diff --git a/app/bower_components/angular-scenario/bower.json b/app/bower_components/angular-scenario/bower.json index 0949da7..50b8b00 100644 --- a/app/bower_components/angular-scenario/bower.json +++ b/app/bower_components/angular-scenario/bower.json @@ -1,8 +1,8 @@ { "name": "angular-scenario", - "version": "1.2.16", + "version": "1.2.21", "main": "./angular-scenario.js", "dependencies": { - "angular": "1.2.16" + "angular": "1.2.21" } } diff --git a/app/bower_components/angular/.bower.json b/app/bower_components/angular/.bower.json index 8c16649..2602743 100644 --- a/app/bower_components/angular/.bower.json +++ b/app/bower_components/angular/.bower.json @@ -1,16 +1,16 @@ { "name": "angular", - "version": "1.2.16", + "version": "1.2.21", "main": "./angular.js", "dependencies": {}, "homepage": "https://github.com/angular/bower-angular", - "_release": "1.2.16", + "_release": "1.2.21", "_resolution": { "type": "version", - "tag": "v1.2.16", - "commit": "7ae38b4a0cfced157e3486a0d6e2d299601723bb" + "tag": "v1.2.21", + "commit": "162c9a2dbffe36e0b583d78a87fc2ccb2a3abf20" }, "_source": "git://github.com/angular/bower-angular.git", - "_target": "1.2.16", + "_target": "~1.2.21", "_originalSource": "angular" } \ No newline at end of file diff --git a/app/bower_components/angular/angular-csp.css b/app/bower_components/angular/angular-csp.css index 0d3d3a9..3abb3a0 100644 --- a/app/bower_components/angular/angular-csp.css +++ b/app/bower_components/angular/angular-csp.css @@ -16,3 +16,9 @@ ng\:form { transition:0s all!important; -webkit-transition:0s all!important; } + +/* show the element during a show/hide animation when the + * animation is ongoing, but the .ng-hide class is active */ +.ng-hide-add-active, .ng-hide-remove { + display: block!important; +} diff --git a/app/bower_components/angular/angular.js b/app/bower_components/angular/angular.js index 2f26bee..5121ba5 100644 --- a/app/bower_components/angular/angular.js +++ b/app/bower_components/angular/angular.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.2.16 + * @license AngularJS v1.2.21 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -68,7 +68,7 @@ function minErr(module) { return match; }); - message = message + '\nhttp://errors.angularjs.org/1.2.16/' + + message = message + '\nhttp://errors.angularjs.org/1.2.21/' + (module ? module + '/' : '') + code; for (i = 2; i < arguments.length; i++) { message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + @@ -80,89 +80,88 @@ function minErr(module) { } /* We need to tell jshint what variables are being exported */ -/* global - -angular, - -msie, - -jqLite, - -jQuery, - -slice, - -push, - -toString, - -ngMinErr, - -_angular, - -angularModule, - -nodeName_, - -uid, - - -lowercase, - -uppercase, - -manualLowercase, - -manualUppercase, - -nodeName_, - -isArrayLike, - -forEach, - -sortedKeys, - -forEachSorted, - -reverseParams, - -nextUid, - -setHashKey, - -extend, - -int, - -inherit, - -noop, - -identity, - -valueFn, - -isUndefined, - -isDefined, - -isObject, - -isString, - -isNumber, - -isDate, - -isArray, - -isFunction, - -isRegExp, - -isWindow, - -isScope, - -isFile, - -isBlob, - -isBoolean, - -trim, - -isElement, - -makeMap, - -map, - -size, - -includes, - -indexOf, - -arrayRemove, - -isLeafNode, - -copy, - -shallowCopy, - -equals, - -csp, - -concat, - -sliceArgs, - -bind, - -toJsonReplacer, - -toJson, - -fromJson, - -toBoolean, - -startingTag, - -tryDecodeURIComponent, - -parseKeyValue, - -toKeyValue, - -encodeUriSegment, - -encodeUriQuery, - -angularInit, - -bootstrap, - -snake_case, - -bindJQuery, - -assertArg, - -assertArgFn, - -assertNotHasOwnProperty, - -getter, - -getBlockElements, - -hasOwnProperty, +/* global angular: true, + msie: true, + jqLite: true, + jQuery: true, + slice: true, + push: true, + toString: true, + ngMinErr: true, + angularModule: true, + nodeName_: true, + uid: true, + VALIDITY_STATE_PROPERTY: true, + lowercase: true, + uppercase: true, + manualLowercase: true, + manualUppercase: true, + nodeName_: true, + isArrayLike: true, + forEach: true, + sortedKeys: true, + forEachSorted: true, + reverseParams: true, + nextUid: true, + setHashKey: true, + extend: true, + int: true, + inherit: true, + noop: true, + identity: true, + valueFn: true, + isUndefined: true, + isDefined: true, + isObject: true, + isString: true, + isNumber: true, + isDate: true, + isArray: true, + isFunction: true, + isRegExp: true, + isWindow: true, + isScope: true, + isFile: true, + isBlob: true, + isBoolean: true, + isPromiseLike: true, + trim: true, + isElement: true, + makeMap: true, + map: true, + size: true, + includes: true, + indexOf: true, + arrayRemove: true, + isLeafNode: true, + copy: true, + shallowCopy: true, + equals: true, + csp: true, + concat: true, + sliceArgs: true, + bind: true, + toJsonReplacer: true, + toJson: true, + fromJson: true, + toBoolean: true, + startingTag: true, + tryDecodeURIComponent: true, + parseKeyValue: true, + toKeyValue: true, + encodeUriSegment: true, + encodeUriQuery: true, + angularInit: true, + bootstrap: true, + snake_case: true, + bindJQuery: true, + assertArg: true, + assertArgFn: true, + assertNotHasOwnProperty: true, + getter: true, + getBlockElements: true, + hasOwnProperty: true, */ //////////////////////////////////// @@ -182,11 +181,15 @@ function minErr(module) { *
*/ +// 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'; + /** * @ngdoc function * @name angular.lowercase * @module ng - * @function + * @kind function * * @description Converts the specified string to lowercase. * @param {string} string String to be converted to lowercase. @@ -199,7 +202,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; * @ngdoc function * @name angular.uppercase * @module ng - * @function + * @kind function * * @description Converts the specified string to uppercase. * @param {string} string String to be converted to uppercase. @@ -240,8 +243,6 @@ var /** holds major version number for IE or NaN for real browsers */ toString = Object.prototype.toString, ngMinErr = minErr('ng'), - - _angular = window.angular, /** @name angular */ angular = window.angular || (window.angular = {}), angularModule, @@ -283,7 +284,7 @@ function isArrayLike(obj) { * @ngdoc function * @name angular.forEach * @module ng - * @function + * @kind function * * @description * Invokes the `iterator` function once for each item in `obj` collection, which can be either an @@ -297,7 +298,7 @@ function isArrayLike(obj) { ```js var values = {name: 'misko', gender: 'male'}; var log = []; - angular.forEach(values, function(value, key){ + angular.forEach(values, function(value, key) { this.push(key + ': ' + value); }, log); expect(log).toEqual(['name: misko', 'gender: male']); @@ -311,7 +312,7 @@ function isArrayLike(obj) { function forEach(obj, iterator, context) { var key; if (obj) { - if (isFunction(obj)){ + if (isFunction(obj)) { for (key in obj) { // Need to check if hasOwnProperty exists, // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function @@ -319,11 +320,12 @@ function forEach(obj, iterator, context) { iterator.call(context, obj[key], key); } } - } else if (obj.forEach && obj.forEach !== forEach) { - obj.forEach(iterator, context); - } else if (isArrayLike(obj)) { - for (key = 0; key < obj.length; key++) + } else if (isArray(obj) || isArrayLike(obj)) { + for (key = 0; key < obj.length; key++) { iterator.call(context, obj[key], key); + } + } else if (obj.forEach && obj.forEach !== forEach) { + obj.forEach(iterator, context); } else { for (key in obj) { if (obj.hasOwnProperty(key)) { @@ -412,7 +414,7 @@ function setHashKey(obj, h) { * @ngdoc function * @name angular.extend * @module ng - * @function + * @kind function * * @description * Extends the destination object `dst` by copying all of the properties from the `src` object(s) @@ -424,9 +426,9 @@ function setHashKey(obj, h) { */ function extend(dst) { var h = dst.$$hashKey; - forEach(arguments, function(obj){ + forEach(arguments, function(obj) { if (obj !== dst) { - forEach(obj, function(value, key){ + forEach(obj, function(value, key) { dst[key] = value; }); } @@ -449,7 +451,7 @@ function inherit(parent, extra) { * @ngdoc function * @name angular.noop * @module ng - * @function + * @kind function * * @description * A function that performs no operations. This function can be useful when writing code in the @@ -469,7 +471,7 @@ noop.$inject = []; * @ngdoc function * @name angular.identity * @module ng - * @function + * @kind function * * @description * A function that returns its first argument. This function is useful when writing code in the @@ -491,7 +493,7 @@ function valueFn(value) {return function() {return value;};} * @ngdoc function * @name angular.isUndefined * @module ng - * @function + * @kind function * * @description * Determines if a reference is undefined. @@ -506,7 +508,7 @@ function isUndefined(value){return typeof value === 'undefined';} * @ngdoc function * @name angular.isDefined * @module ng - * @function + * @kind function * * @description * Determines if a reference is defined. @@ -521,7 +523,7 @@ function isDefined(value){return typeof value !== 'undefined';} * @ngdoc function * @name angular.isObject * @module ng - * @function + * @kind function * * @description * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not @@ -537,7 +539,7 @@ function isObject(value){return value != null && typeof value === 'object';} * @ngdoc function * @name angular.isString * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `String`. @@ -552,7 +554,7 @@ function isString(value){return typeof value === 'string';} * @ngdoc function * @name angular.isNumber * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `Number`. @@ -567,7 +569,7 @@ function isNumber(value){return typeof value === 'number';} * @ngdoc function * @name angular.isDate * @module ng - * @function + * @kind function * * @description * Determines if a value is a date. @@ -575,7 +577,7 @@ function isNumber(value){return typeof value === 'number';} * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Date`. */ -function isDate(value){ +function isDate(value) { return toString.call(value) === '[object Date]'; } @@ -584,7 +586,7 @@ function isDate(value){ * @ngdoc function * @name angular.isArray * @module ng - * @function + * @kind function * * @description * Determines if a reference is an `Array`. @@ -592,16 +594,20 @@ function isDate(value){ * @param {*} value Reference to check. * @returns {boolean} True if `value` is an `Array`. */ -function isArray(value) { - return toString.call(value) === '[object Array]'; -} - +var isArray = (function() { + if (!isFunction(Array.isArray)) { + return function(value) { + return toString.call(value) === '[object Array]'; + }; + } + return Array.isArray; +})(); /** * @ngdoc function * @name angular.isFunction * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `Function`. @@ -656,6 +662,11 @@ function isBoolean(value) { } +function isPromiseLike(obj) { + return obj && isFunction(obj.then); +} + + var trim = (function() { // native trim is way faster: http://jsperf.com/angular-trim-test // but IE doesn't have it... :-( @@ -675,7 +686,7 @@ var trim = (function() { * @ngdoc function * @name angular.isElement * @module ng - * @function + * @kind function * * @description * Determines if a reference is a DOM element (or wrapped jQuery element). @@ -693,7 +704,7 @@ function isElement(node) { * @param str 'key1,key2,...' * @returns {object} in the form of {key1:true, key2:true, ...} */ -function makeMap(str){ +function makeMap(str) { var obj = {}, items = str.split(","), i; for ( i = 0; i < items.length; i++ ) obj[ items[i] ] = true; @@ -740,7 +751,7 @@ function size(obj, ownPropsOnly) { if (isArray(obj) || isString(obj)) { return obj.length; - } else if (isObject(obj)){ + } else if (isObject(obj)) { for (key in obj) if (!ownPropsOnly || obj.hasOwnProperty(key)) count++; @@ -786,7 +797,7 @@ function isLeafNode (node) { * @ngdoc function * @name angular.copy * @module ng - * @function + * @kind function * * @description * Creates a deep copy of `source`, which should be an object or an array. @@ -804,9 +815,9 @@ function isLeafNode (node) { * @returns {*} The copy or updated `destination`, if `destination` was specified. * * @example - + -
+
Name:
E-mail:
@@ -820,26 +831,27 @@ function isLeafNode (node) {
*/ -function copy(source, destination){ +function copy(source, destination, stackSource, stackDest) { if (isWindow(source) || isScope(source)) { throw ngMinErr('cpws', "Can't copy! Making copies of Window or Scope instances is not supported."); @@ -849,52 +861,83 @@ function copy(source, destination){ destination = source; if (source) { if (isArray(source)) { - destination = copy(source, []); + destination = copy(source, [], stackSource, stackDest); } else if (isDate(source)) { destination = new Date(source.getTime()); } else if (isRegExp(source)) { - destination = new RegExp(source.source); + destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]); + destination.lastIndex = source.lastIndex; } else if (isObject(source)) { - destination = copy(source, {}); + destination = copy(source, {}, stackSource, stackDest); } } } else { if (source === destination) throw ngMinErr('cpi', "Can't copy! Source and destination are identical."); + + stackSource = stackSource || []; + stackDest = stackDest || []; + + if (isObject(source)) { + var index = indexOf(stackSource, source); + if (index !== -1) return stackDest[index]; + + stackSource.push(source); + stackDest.push(destination); + } + + var result; if (isArray(source)) { destination.length = 0; for ( var i = 0; i < source.length; i++) { - destination.push(copy(source[i])); + result = copy(source[i], null, stackSource, stackDest); + if (isObject(source[i])) { + stackSource.push(source[i]); + stackDest.push(result); + } + destination.push(result); } } else { var h = destination.$$hashKey; - forEach(destination, function(value, key){ + forEach(destination, function(value, key) { delete destination[key]; }); for ( var key in source) { - destination[key] = copy(source[key]); + result = copy(source[key], null, stackSource, stackDest); + if (isObject(source[key])) { + stackSource.push(source[key]); + stackDest.push(result); + } + destination[key] = result; } setHashKey(destination,h); } + } return destination; } /** - * Create a shallow copy of an object + * Creates a shallow copy of an object, an array or a primitive */ function shallowCopy(src, dst) { - dst = dst || {}; + if (isArray(src)) { + dst = dst || []; - for(var key in src) { - // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src - // so we don't need to worry about using our custom hasOwnProperty here - if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { - dst[key] = src[key]; + for ( var i = 0; i < src.length; i++) { + dst[i] = src[i]; + } + } else if (isObject(src)) { + dst = dst || {}; + + for (var key in src) { + if (hasOwnProperty.call(src, key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { + dst[key] = src[key]; + } } } - return dst; + return dst || src; } @@ -902,7 +945,7 @@ function shallowCopy(src, dst) { * @ngdoc function * @name angular.equals * @module ng - * @function + * @kind function * * @description * Determines if two objects or two values are equivalent. Supports value types, regular @@ -914,7 +957,7 @@ function shallowCopy(src, dst) { * * Both objects or values are of the same type and all of their properties are equal by * comparing them with `angular.equals`. * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal) - * * Both values represent the same regular expression (In JavasScript, + * * 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). * @@ -967,12 +1010,25 @@ function equals(o1, o2) { return false; } +var csp = function() { + if (isDefined(csp.isActive_)) return csp.isActive_; + + var active = !!(document.querySelector('[ng-csp]') || + document.querySelector('[data-ng-csp]')); + + if (!active) { + try { + /* jshint -W031, -W054 */ + new Function(''); + /* jshint +W031, +W054 */ + } catch (e) { + active = true; + } + } + + return (csp.isActive_ = active); +}; -function csp() { - return (document.securityPolicy && document.securityPolicy.isActive) || - (document.querySelector && - !!(document.querySelector('[ng-csp]') || document.querySelector('[data-ng-csp]'))); -} function concat(array1, array2, index) { @@ -989,7 +1045,7 @@ function sliceArgs(args, startIndex) { * @ngdoc function * @name angular.bind * @module ng - * @function + * @kind function * * @description * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for @@ -1045,7 +1101,7 @@ function toJsonReplacer(key, value) { * @ngdoc function * @name angular.toJson * @module ng - * @function + * @kind function * * @description * Serializes input into a JSON-formatted string. Properties with leading $ characters will be @@ -1065,7 +1121,7 @@ function toJson(obj, pretty) { * @ngdoc function * @name angular.fromJson * @module ng - * @function + * @kind function * * @description * Deserializes a JSON string. @@ -1142,13 +1198,13 @@ function tryDecodeURIComponent(value) { */ function parseKeyValue(/**string*/keyValue) { var obj = {}, key_value, key; - forEach((keyValue || "").split('&'), function(keyValue){ + forEach((keyValue || "").split('&'), function(keyValue) { if ( keyValue ) { - key_value = keyValue.split('='); + key_value = keyValue.replace(/\+/g,'%20').split('='); key = tryDecodeURIComponent(key_value[0]); if ( isDefined(key) ) { var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true; - if (!obj[key]) { + if (!hasOwnProperty.call(obj, key)) { obj[key] = val; } else if(isArray(obj[key])) { obj[key].push(val); @@ -1322,7 +1378,7 @@ function angularInit(element, bootstrap) { * * 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 + * each of the subsequent scripts. This prevents strange results in applications, where otherwise * multiple instances of Angular try to work on the DOM. * * @@ -1404,7 +1460,7 @@ function bootstrap(element, modules) { } var SNAKE_CASE_REGEXP = /[A-Z]/g; -function snake_case(name, separator){ +function snake_case(name, separator) { separator = separator || '_'; return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) { return (pos ? separator : '') + letter.toLowerCase(); @@ -1414,8 +1470,9 @@ function snake_case(name, separator){ function bindJQuery() { // bind to jQuery if present; jQuery = window.jQuery; - // reset to jQuery or default to us. - if (jQuery) { + // Use jQuery if it exists with proper functionality, otherwise default to us. + // Angular 1.2+ requires jQuery 1.7.1+ for on()/off() support. + if (jQuery && jQuery.fn.on) { jqLite = jQuery; extend(jQuery.fn, { scope: JQLitePrototype.scope, @@ -1451,7 +1508,7 @@ function assertArgFn(arg, name, acceptArrayAnnotation) { } assertArg(isFunction(arg), name, 'not a function, got ' + - (arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg)); + (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg)); return arg; } @@ -1561,7 +1618,7 @@ function setupModuleLoader(window) { * * # Module * - * A module is a collection of services, directives, filters, and configuration information. + * 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 @@ -1589,9 +1646,9 @@ function setupModuleLoader(window) { * {@link angular.bootstrap} to simplify this process for you. * * @param {!string} name The name of the module to create or retrieve. -<<<<<* @param {!Array.=} 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 + * @param {!Array.=} 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 {module} new module with the {@link angular.Module} api. */ @@ -1783,6 +1840,8 @@ function setupModuleLoader(window) { * 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#providers_provider-recipe Provider Recipe}. */ config: config, @@ -1826,12 +1885,11 @@ function setupModuleLoader(window) { } -/* global - angularModule: true, - version: true, +/* global angularModule: true, + version: true, - $LocaleProvider, - $CompileProvider, + $LocaleProvider, + $CompileProvider, htmlAnchorDirective, inputDirective, @@ -1919,11 +1977,11 @@ function setupModuleLoader(window) { * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". */ var version = { - full: '1.2.16', // all of these placeholder strings will be replaced by grunt's + full: '1.2.21', // all of these placeholder strings will be replaced by grunt's major: 1, // package task minor: 2, - dot: 16, - codeName: 'badger-enumeration' + dot: 21, + codeName: 'wizard-props' }; @@ -2047,12 +2105,10 @@ function publishExternalAPI(angular){ ]); } -/* global - - -JQLitePrototype, - -addEventListenerFn, - -removeEventListenerFn, - -BOOLEAN_ATTR +/* global JQLitePrototype: true, + addEventListenerFn: true, + removeEventListenerFn: true, + BOOLEAN_ATTR: true */ ////////////////////////////////// @@ -2063,7 +2119,7 @@ function publishExternalAPI(angular){ * @ngdoc function * @name angular.element * @module ng - * @function + * @kind function * * @description * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. @@ -2145,8 +2201,9 @@ function publishExternalAPI(angular){ * @returns {Object} jQuery object. */ +JQLite.expando = 'ng339'; + var jqCache = JQLite.cache = {}, - jqName = JQLite.expando = 'ng-' + new Date().getTime(), jqId = 1, addEventListenerFn = (window.document.addEventListener ? function(element, type, fn) {element.addEventListener(type, fn, false);} @@ -2356,7 +2413,7 @@ function jqLiteOff(element, type, fn, unsupported) { } function jqLiteRemoveData(element, name) { - var expandoId = element[jqName], + var expandoId = element.ng339, expandoStore = jqCache[expandoId]; if (expandoStore) { @@ -2370,17 +2427,17 @@ function jqLiteRemoveData(element, name) { jqLiteOff(element); } delete jqCache[expandoId]; - element[jqName] = undefined; // ie does not allow deletion of attributes on elements. + element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it } } function jqLiteExpandoStore(element, key, value) { - var expandoId = element[jqName], + var expandoId = element.ng339, expandoStore = jqCache[expandoId || -1]; if (isDefined(value)) { if (!expandoStore) { - element[jqName] = expandoId = jqNextId(); + element.ng339 = expandoId = jqNextId(); expandoStore = jqCache[expandoId] = {}; } expandoStore[key] = value; @@ -2465,25 +2522,22 @@ function jqLiteController(element, name) { } function jqLiteInheritedData(element, name, value) { - element = jqLite(element); - // if element is the document object work with the html element instead // this makes $(document).scope() possible - if(element[0].nodeType == 9) { - element = element.find('html'); + if(element.nodeType == 9) { + element = element.documentElement; } var names = isArray(name) ? name : [name]; - while (element.length) { - var node = element[0]; + while (element) { for (var i = 0, ii = names.length; i < ii; i++) { - if ((value = element.data(names[i])) !== undefined) return value; + if ((value = jqLite.data(element, names[i])) !== undefined) 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 = jqLite(node.parentNode || (node.nodeType === 11 && node.host)); + element = element.parentNode || (element.nodeType === 11 && element.host); } } @@ -2558,18 +2612,25 @@ function getBooleanAttrName(element, name) { return booleanAttr && BOOLEAN_ELEMENTS[element.nodeName] && booleanAttr; } +forEach({ + data: jqLiteData, + removeData: jqLiteRemoveData +}, 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(element).data('$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']); + 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(element).data('$isolateScope') || jqLite(element).data('$isolateScopeNoTemplate'); + return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate'); }, controller: jqLiteController, @@ -2699,6 +2760,7 @@ forEach({ */ 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. @@ -2708,7 +2770,7 @@ forEach({ if (isObject(arg1)) { // we are a write, but the object properties are the key/values - for (i = 0; i < this.length; i++) { + for (i = 0; i < nodeCount; i++) { if (fn === jqLiteData) { // data() takes the whole object in jQuery fn(this[i], arg1); @@ -2722,9 +2784,10 @@ forEach({ 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 = (value === undefined) ? Math.min(this.length, 1) : this.length; + var jj = (value === undefined) ? Math.min(nodeCount, 1) : nodeCount; for (var j = 0; j < jj; j++) { var nodeValue = fn(this[j], arg1, arg2); value = value ? value + nodeValue : nodeValue; @@ -2733,7 +2796,7 @@ forEach({ } } else { // we are a write, so apply to all children - for (i = 0; i < this.length; i++) { + for (i = 0; i < nodeCount; i++) { fn(this[i], arg1, arg2); } // return self for chaining @@ -2995,7 +3058,9 @@ forEach({ clone: jqLiteClone, triggerHandler: function(element, eventName, eventData) { - var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName]; + // Copy event handlers in case event handlers array is modified during execution. + var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName], + eventFnsCopy = shallowCopy(eventFns || []); eventData = eventData || []; @@ -3004,7 +3069,7 @@ forEach({ stopPropagation: noop }]; - forEach(eventFns, function(fn) { + forEach(eventFnsCopy, function(fn) { fn.apply(element, event.concat(eventData)); }); } @@ -3045,16 +3110,16 @@ forEach({ * @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) { +function hashKey(obj, nextUidFn) { var objType = typeof obj, key; - if (objType == 'object' && obj !== null) { + if (objType == 'function' || (objType == 'object' && obj !== null)) { if (typeof (key = obj.$$hashKey) == 'function') { // must invoke on object to keep the right this key = obj.$$hashKey(); } else if (key === undefined) { - key = obj.$$hashKey = nextUid(); + key = obj.$$hashKey = (nextUidFn || nextUid)(); } } else { key = obj; @@ -3066,7 +3131,13 @@ function hashKey(obj) { /** * HashMap which can use objects as keys */ -function HashMap(array){ +function HashMap(array, isolatedUid) { + if (isolatedUid) { + var uid = 0; + this.nextUid = function() { + return ++uid; + }; + } forEach(array, this.put, this); } HashMap.prototype = { @@ -3076,7 +3147,7 @@ HashMap.prototype = { * @param value value to store can be any type */ put: function(key, value) { - this[hashKey(key)] = value; + this[hashKey(key, this.nextUid)] = value; }, /** @@ -3084,7 +3155,7 @@ HashMap.prototype = { * @returns {Object} the value for the key */ get: function(key) { - return this[hashKey(key)]; + return this[hashKey(key, this.nextUid)]; }, /** @@ -3092,7 +3163,7 @@ HashMap.prototype = { * @param key */ remove: function(key) { - var value = this[key = hashKey(key)]; + var value = this[key = hashKey(key, this.nextUid)]; delete this[key]; return value; } @@ -3102,7 +3173,7 @@ HashMap.prototype = { * @ngdoc function * @module ng * @name angular.injector - * @function + * @kind function * * @description * Creates an injector function that can be used for retrieving services as well as for @@ -3129,7 +3200,7 @@ HashMap.prototype = { * * 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 extra `injector()` added + * 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 @@ -3170,7 +3241,7 @@ function annotate(fn) { argDecl, last; - if (typeof fn == 'function') { + if (typeof fn === 'function') { if (!($inject = fn.$inject)) { $inject = []; if (fn.length) { @@ -3199,7 +3270,7 @@ function annotate(fn) { /** * @ngdoc service * @name $injector - * @function + * @kind function * * @description * @@ -3242,7 +3313,7 @@ function annotate(fn) { * minification, and obfuscation tools since these tools change the argument names. * * ## `$inject` Annotation - * By adding a `$inject` property onto a function the injection parameters can be specified. + * 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. @@ -3279,7 +3350,7 @@ function annotate(fn) { * @name $injector#has * * @description - * Allows the user to query if the particular service exist. + * Allows the user to query if the particular service exists. * * @param {string} Name of the service to query. * @returns {boolean} returns true if injector has given service. @@ -3289,8 +3360,8 @@ function annotate(fn) { * @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 + * 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. @@ -3383,7 +3454,7 @@ function annotate(fn) { /** - * @ngdoc object + * @ngdoc service * @name $provide * * @description @@ -3689,7 +3760,7 @@ function createInjector(modulesToLoad) { var INSTANTIATING = {}, providerSuffix = 'Provider', path = [], - loadedModules = new HashMap(), + loadedModules = new HashMap([], true), providerCache = { $provide: { provider: supportObject(provider), @@ -3822,7 +3893,8 @@ function createInjector(modulesToLoad) { function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { - throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); + throw $injectorMinErr('cdep', 'Circular dependency found: {0}', + serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { @@ -3859,8 +3931,7 @@ function createInjector(modulesToLoad) { : getService(key) ); } - if (!fn.$inject) { - // this means that we must be an array. + if (isArray(fn)) { fn = fn[length]; } @@ -3903,7 +3974,7 @@ function createInjector(modulesToLoad) { * @requires $rootScope * * @description - * When called, it checks current value of `$location.hash()` and scroll to related element, + * When called, it checks current value of `$location.hash()` and scrolls to the related element, * according to rules specified in * [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document). * @@ -4105,7 +4176,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#enter - * @function + * @kind function * @description Inserts the element into the DOM either after the `after` element or within * the `parent` element. Once complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will be inserted into the DOM @@ -4132,7 +4203,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#leave - * @function + * @kind function * @description Removes the element from the DOM. Once complete, the done() callback will be * fired (if provided). * @param {DOMElement} element the element which will be removed from the DOM @@ -4148,7 +4219,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#move - * @function + * @kind function * @description Moves the position of the provided element within the DOM to be placed * either after the `after` element or inside of the `parent` element. Once complete, the * done() callback will be fired (if provided). @@ -4172,7 +4243,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#addClass - * @function + * @kind function * @description Adds the provided className CSS class value to the provided element. Once * complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will have the className value @@ -4195,7 +4266,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#removeClass - * @function + * @kind function * @description Removes the provided className CSS class value from the provided element. * Once complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will have the className value @@ -4218,10 +4289,10 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#setClass - * @function + * @kind function * @description Adds and/or removes the given CSS classes to and from the element. * Once complete, the done() callback will be fired (if provided). - * @param {DOMElement} element the element which will it's CSS classes changed + * @param {DOMElement} element the element which will have its CSS classes changed * removed from it * @param {string} add the CSS classes which will be added to the element * @param {string} remove the CSS class which will be removed from the element @@ -4775,7 +4846,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#put - * @function + * @kind function * * @description * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be @@ -4811,7 +4882,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#get - * @function + * @kind function * * @description * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object. @@ -4835,7 +4906,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#remove - * @function + * @kind function * * @description * Removes an entry from the {@link $cacheFactory.Cache Cache} object. @@ -4863,7 +4934,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#removeAll - * @function + * @kind function * * @description * Clears the cache object of any entries. @@ -4879,7 +4950,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#destroy - * @function + * @kind function * * @description * Destroys the {@link $cacheFactory.Cache Cache} object entirely, @@ -4896,7 +4967,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#info - * @function + * @kind function * * @description * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}. @@ -4951,7 +5022,7 @@ function $CacheFactoryProvider() { * @name $cacheFactory#info * * @description - * Get information about all the of the caches that have been created + * Get information about all the caches that have been created * * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info` */ @@ -5052,7 +5123,7 @@ function $TemplateCacheProvider() { /** * @ngdoc service * @name $compile - * @function + * @kind function * * @description * Compiles an HTML string or DOM into a template and produces a template function, which @@ -5090,7 +5161,6 @@ function $TemplateCacheProvider() { * template: '
', // or // function(tElement, tAttrs) { ... }, * // or * // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, - * replace: false, * transclude: false, * restrict: 'A', * scope: false, @@ -5194,7 +5264,7 @@ function $TemplateCacheProvider() { * local name. Given `` and widget definition of * `scope: { localFn:'&myAttr' }`, then 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 and to the parent scope, this can be + * 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})`. @@ -5245,14 +5315,16 @@ function $TemplateCacheProvider() { * * * #### `template` - * replace the current element with the contents of the HTML. The replacement process - * migrates all of the attributes / classes from the old element to the new one. See the - * {@link guide/directive#creating-custom-directives_creating-directives_template-expanding-directive - * Directives Guide} for an example. + * HTML markup that may: + * * Replace the contents of the directive's element (defualt). + * * Replace the directive's element itself (if `replace` is true - DEPRECATED). + * * Wrap the contents of the directive's element (if `transclude` is true). * - * You can specify `template` as a string representing the template 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 template. + * Value may be: + * + * * A string. For example `
{{delete_str}}
`. + * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile` + * function api below) and returns a string value. * * * #### `templateUrl` @@ -5266,12 +5338,15 @@ function $TemplateCacheProvider() { * api/ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}. * * - * #### `replace` - * specify where the template should be inserted. Defaults to `false`. + * #### `replace` ([*DEPRECATED*!], will be removed in next major release) + * specify what the template should replace. Defaults to `false`. * - * * `true` - the template will replace the current element. - * * `false` - the template will replace the contents of the current element. + * * `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#creating-custom-directives_creating-directives_template-expanding-directive + * Directives Guide} for an example. * * #### `transclude` * compile the content of the element and make it available to the directive. @@ -5285,6 +5360,11 @@ function $TemplateCacheProvider() { * * `true` - transclude the content of the directive. * * `'element'` - transclude the whole element including any directives defined at lower priority. * + *
+ * **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}. + *
* * #### `compile` * @@ -5293,11 +5373,7 @@ function $TemplateCacheProvider() { * ``` * * The compile function deals with transforming the template DOM. Since most directives do not do - * template transformation, it is not used often. Examples that require compile functions are - * directives that transform template DOM, such as {@link - * api/ng.directive:ngRepeat ngRepeat}, or load the contents - * asynchronously, such as {@link ngRoute.directive:ngView ngView}. The - * compile function takes the following arguments. + * 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. @@ -5425,10 +5501,10 @@ function $TemplateCacheProvider() { * to illustrate how `$compile` works. *
* - + -
+


@@ -5535,7 +5610,7 @@ var $compileMinErr = minErr('$compile'); /** * @ngdoc provider * @name $compileProvider - * @function + * @kind function * * @description */ @@ -5543,8 +5618,8 @@ $CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider']; function $CompileProvider($provide, $$sanitizeUriProvider) { var hasDirectives = {}, Suffix = 'Directive', - COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/, - CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/; + COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/, + CLASS_DIRECTIVE_REGEXP = /(([\d\w_\-]+)(?:\:([^;]+))?;?)/; // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes // The assumption is that future DOM event attribute names will begin with @@ -5554,7 +5629,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#directive - * @function + * @kind function * * @description * Register a new directive with the compiler. @@ -5607,7 +5682,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#aHrefSanitizationWhitelist - * @function + * @kind function * * @description * Retrieves or overrides the default regular expression that is used for whitelisting of safe @@ -5637,7 +5712,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#imgSrcSanitizationWhitelist - * @function + * @kind function * * @description * Retrieves or overrides the default regular expression that is used for whitelisting of safe @@ -5681,7 +5756,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$addClass - * @function + * @kind function * * @description * Adds the CSS class value specified by the classVal parameter to the element. If animations @@ -5698,7 +5773,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$removeClass - * @function + * @kind function * * @description * Removes the CSS class value specified by the classVal parameter from the element. If @@ -5715,7 +5790,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$updateClass - * @function + * @kind function * * @description * Adds and removes the appropriate CSS class values to the element based on the difference @@ -5803,7 +5878,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$observe - * @function + * @kind function * * @description * Observes an interpolated attribute. @@ -5866,7 +5941,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext); safeAddClass($compileNodes, 'ng-scope'); - return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){ + return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn){ assertArg(scope, 'scope'); // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart // and sometimes changes the structure of the DOM. @@ -5888,7 +5963,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (cloneConnectFn) cloneConnectFn($linkNode, scope); - if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode); + if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn); return $linkNode; }; } @@ -5935,7 +6010,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { : null; if (nodeLinkFn && nodeLinkFn.scope) { - safeAddClass(jqLite(nodeList[i]), 'ng-scope'); + safeAddClass(attrs.$$element, 'ng-scope'); } childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || @@ -5943,7 +6018,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { !childNodes.length) ? null : compileNodes(childNodes, - nodeLinkFn ? nodeLinkFn.transclude : transcludeFn); + nodeLinkFn ? ( + (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement) + && nodeLinkFn.transclude) : transcludeFn); linkFns.push(nodeLinkFn, childLinkFn); linkFnFound = linkFnFound || nodeLinkFn || childLinkFn; @@ -5954,8 +6031,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // return a linking function if we have found anything, null otherwise return linkFnFound ? compositeLinkFn : null; - function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) { - var nodeLinkFn, childLinkFn, node, $node, childScope, childTranscludeFn, i, ii, n; + function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) { + var nodeLinkFn, childLinkFn, node, childScope, i, ii, n, childBoundTranscludeFn; // copy nodeList so that linking doesn't break due to live list updates. var nodeListLength = nodeList.length, @@ -5968,32 +6045,40 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { node = stableNodeList[n]; nodeLinkFn = linkFns[i++]; childLinkFn = linkFns[i++]; - $node = jqLite(node); if (nodeLinkFn) { if (nodeLinkFn.scope) { childScope = scope.$new(); - $node.data('$scope', childScope); + jqLite.data(node, '$scope', childScope); } else { childScope = scope; } - childTranscludeFn = nodeLinkFn.transclude; - if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) { - nodeLinkFn(childLinkFn, childScope, node, $rootElement, - createBoundTranscludeFn(scope, childTranscludeFn || transcludeFn) - ); + + 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 { - nodeLinkFn(childLinkFn, childScope, node, $rootElement, boundTranscludeFn); + childBoundTranscludeFn = null; } + + nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn); + } else if (childLinkFn) { - childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn); + childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn); } } } } - function createBoundTranscludeFn(scope, transcludeFn) { - return function boundTranscludeFn(transcludedScope, cloneFn, controllers) { + function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) { + + var boundTranscludeFn = function(transcludedScope, cloneFn, controllers) { var scopeCreated = false; if (!transcludedScope) { @@ -6002,12 +6087,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { scopeCreated = true; } - var clone = transcludeFn(transcludedScope, cloneFn, controllers); + var clone = transcludeFn(transcludedScope, cloneFn, controllers, previousBoundTranscludeFn); if (scopeCreated) { - clone.on('$destroy', bind(transcludedScope, transcludedScope.$destroy)); + clone.on('$destroy', function() { transcludedScope.$destroy(); }); } return clone; }; + + return boundTranscludeFn; } /** @@ -6033,7 +6120,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority, ignoreDirective); // iterate over the attributes - for (var attr, name, nName, ngAttrName, value, nAttrs = node.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; @@ -6041,9 +6128,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { attr = nAttrs[j]; if (!msie || msie >= 8 || attr.specified) { name = attr.name; + value = trim(attr.value); + // support ngAttr attribute binding ngAttrName = directiveNormalize(name); - if (NG_ATTR_BINDING.test(ngAttrName)) { + if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) { name = snake_case(ngAttrName.substr(6), '-'); } @@ -6056,9 +6145,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { nName = directiveNormalize(name.toLowerCase()); attrsMap[nName] = name; - attrs[nName] = value = trim(attr.value); - if (getBooleanAttrName(node, nName)) { - attrs[nName] = true; // presence means true + if (isNgAttr || !attrs.hasOwnProperty(nName)) { + attrs[nName] = value; + if (getBooleanAttrName(node, nName)) { + attrs[nName] = true; // presence means true + } } addAttrInterpolateDirective(node, directives, value, nName); addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, @@ -6185,6 +6276,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { templateDirective = previousCompileContext.templateDirective, nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective, hasTranscludeDirective = false, + hasTemplate = false, hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective, $compileNode = templateAttrs.$$element = jqLite(compileNode), directive, @@ -6249,12 +6341,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (directiveValue == 'element') { hasElementTranscludeDirective = true; terminalPriority = directive.priority; - $template = groupScan(compileNode, attrStart, attrEnd); + $template = $compileNode; $compileNode = templateAttrs.$$element = jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' ')); compileNode = $compileNode[0]; - replaceWith(jqCollection, jqLite(sliceArgs($template)), compileNode); + replaceWith(jqCollection, sliceArgs($template), compileNode); childTranscludeFn = compile($template, transcludeFn, terminalPriority, replaceDirective && replaceDirective.name, { @@ -6275,6 +6367,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (directive.template) { + hasTemplate = true; assertNoDuplicate('template', templateDirective, directive, $compileNode); templateDirective = directive; @@ -6289,7 +6382,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (jqLiteIsTextNode(directiveValue)) { $template = []; } else { - $template = jqLite(directiveValue); + $template = jqLite(trim(directiveValue)); } compileNode = $template[0]; @@ -6324,6 +6417,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (directive.templateUrl) { + hasTemplate = true; assertNoDuplicate('template', templateDirective, directive, $compileNode); templateDirective = directive; @@ -6332,7 +6426,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, - templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, { + templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, { controllerDirectives: controllerDirectives, newIsolateScopeDirective: newIsolateScopeDirective, templateDirective: templateDirective, @@ -6360,7 +6454,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true; - nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn; + nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective; + nodeLinkFn.templateOnThisElement = hasTemplate; + nodeLinkFn.transclude = childTranscludeFn; + previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective; // might be normal or delayed nodeLinkFn depending on if templateUrl is present @@ -6372,6 +6469,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { 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}); } @@ -6380,6 +6478,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { 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}); } @@ -6388,7 +6487,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } - function getControllers(require, $element, elementControllers) { + function getControllers(directiveName, require, $element, elementControllers) { var value, retrievalMethod = 'data', optional = false; if (isString(require)) { while((value = require.charAt(0)) == '^' || value == '?') { @@ -6414,7 +6513,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } else if (isArray(require)) { value = []; forEach(require, function(require) { - value.push(getControllers(require, $element, elementControllers)); + value.push(getControllers(directiveName, require, $element, elementControllers)); }); } return value; @@ -6424,28 +6523,26 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) { var attrs, $element, i, ii, linkFn, controller, isolateScope, elementControllers = {}, transcludeFn; - if (compileNode === linkNode) { - attrs = templateAttrs; - } else { - attrs = shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr)); - } + attrs = (compileNode === linkNode) + ? templateAttrs + : shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr)); $element = attrs.$$element; if (newIsolateScopeDirective) { var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/; - var $linkNode = jqLite(linkNode); isolateScope = scope.$new(true); - if (templateDirective && (templateDirective === newIsolateScopeDirective.$$originalDirective)) { - $linkNode.data('$isolateScope', isolateScope) ; + if (templateDirective && (templateDirective === newIsolateScopeDirective || + templateDirective === newIsolateScopeDirective.$$originalDirective)) { + $element.data('$isolateScope', isolateScope); } else { - $linkNode.data('$isolateScopeNoTemplate', isolateScope); + $element.data('$isolateScopeNoTemplate', isolateScope); } - safeAddClass($linkNode, 'ng-isolate-scope'); + safeAddClass($element, 'ng-isolate-scope'); forEach(newIsolateScopeDirective.scope, function(definition, scopeName) { var match = definition.match(LOCAL_REGEXP) || [], @@ -6557,7 +6654,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { try { linkFn = preLinkFns[i]; linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, - linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn); + linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn); } catch (e) { $exceptionHandler(e, startingTag($element)); } @@ -6577,7 +6674,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { try { linkFn = postLinkFns[i]; linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, - linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn); + linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn); } catch (e) { $exceptionHandler(e, startingTag($element)); } @@ -6663,7 +6760,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // reapply the old attributes to the new element forEach(dst, function(value, key) { if (key.charAt(0) != '$') { - if (src[key]) { + if (src[key] && src[key] !== value) { value += (key === 'style' ? ';' : ' ') + src[key]; } dst.$set(key, value, true, srcAttr[key]); @@ -6716,7 +6813,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (jqLiteIsTextNode(content)) { $template = []; } else { - $template = jqLite(content); + $template = jqLite(trim(content)); } compileNode = $template[0]; @@ -6752,7 +6849,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }); afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn); - while(linkQueue.length) { var scope = linkQueue.shift(), beforeTemplateLinkNode = linkQueue.shift(), @@ -6774,8 +6870,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // Copy in CSS classes from original node safeAddClass(jqLite(linkNode), oldClasses); } - if (afterTemplateNodeLinkFn.transclude) { - childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude); + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); } else { childBoundTranscludeFn = boundTranscludeFn; } @@ -6789,13 +6885,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }); return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) { + var childBoundTranscludeFn = boundTranscludeFn; if (linkQueue) { linkQueue.push(scope); linkQueue.push(node); linkQueue.push(rootElement); - linkQueue.push(boundTranscludeFn); + linkQueue.push(childBoundTranscludeFn); } else { - afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, boundTranscludeFn); + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); + } + afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn); } }; } @@ -6820,23 +6920,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } - function addTextInterpolateDirective(directives, text) { - var interpolateFn = $interpolate(text, true); - if (interpolateFn) { - directives.push({ - priority: 0, - compile: valueFn(function textInterpolateLinkFn(scope, node) { - var parent = node.parent(), - bindings = parent.data('$binding') || []; - bindings.push(interpolateFn); - safeAddClass(parent.data('$binding', bindings), 'ng-binding'); - scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { - node[0].nodeValue = value; - }); - }) - }); + function addTextInterpolateDirective(directives, text) { + var interpolateFn = $interpolate(text, true); + if (interpolateFn) { + directives.push({ + priority: 0, + compile: function textInterpolateCompileFn(templateNode) { + // when transcluding a template that has bindings in the root + // then we don't have a parent and should do this in the linkFn + var parent = templateNode.parent(), hasCompileParent = parent.length; + if (hasCompileParent) safeAddClass(templateNode.parent(), 'ng-binding'); + + return function textInterpolateLinkFn(scope, node) { + var parent = node.parent(), + bindings = parent.data('$binding') || []; + bindings.push(interpolateFn); + parent.data('$binding', bindings); + if (!hasCompileParent) safeAddClass(parent, 'ng-binding'); + scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { + node[0].nodeValue = value; + }); + }; + } + }); + } } - } function getTrustedContext(node, attrNormalizedName) { @@ -6997,7 +7105,9 @@ function directiveNormalize(name) { * element attributes. The values reflect current binding state `{{ }}`. The normalization is * needed since all of these are treated as equivalent in Angular: * + * ``` * + * ``` */ /** @@ -7011,7 +7121,7 @@ function directiveNormalize(name) { /** * @ngdoc method * @name $compile.directive.Attributes#$set - * @function + * @kind function * * @description * Set DOM element attribute value. @@ -7134,7 +7244,7 @@ function $ControllerProvider() { instance = $injector.instantiate(expression, locals); if (identifier) { - if (!(locals && typeof locals.$scope == 'object')) { + if (!(locals && typeof locals.$scope === 'object')) { throw minErr('$controller')('noscp', "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", constructor || expression.name, identifier); @@ -7157,18 +7267,19 @@ function $ControllerProvider() { * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object. * * @example - + -
+

$document title:

window.document title:

- function MainCtrl($scope, $document) { - $scope.title = $document[0].title; - $scope.windowTitle = angular.element(window.document)[0].title; - } + angular.module('documentExample', []) + .controller('ExampleController', ['$scope', '$document', function($scope, $document) { + $scope.title = $document[0].title; + $scope.windowTitle = angular.element(window.document)[0].title; + }]); */ @@ -7235,11 +7346,7 @@ function parseHeaders(headers) { val = trim(line.substr(i + 1)); if (key) { - if (parsed[key]) { - parsed[key] += ', ' + val; - } else { - parsed[key] = val; - } + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; } }); @@ -7301,12 +7408,39 @@ function isSuccess(status) { } +/** + * @ngdoc provider + * @name $httpProvider + * @description + * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service. + * */ function $HttpProvider() { var JSON_START = /^\s*(\[|\{[^\{])/, JSON_END = /[\}\]]\s*$/, PROTECTION_PREFIX = /^\)\]\}',?\n/, CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'}; + /** + * @ngdoc property + * @name $httpProvider#defaults + * @description + * + * Object containing default values for all {@link ng.$http $http} requests. + * + * - **`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`** + **/ var defaults = this.defaults = { // transform incoming response data transformResponse: [function(data) { @@ -7329,9 +7463,9 @@ function $HttpProvider() { common: { 'Accept': 'application/json, text/plain, */*' }, - post: copy(CONTENT_TYPE_APPLICATION_JSON), - put: copy(CONTENT_TYPE_APPLICATION_JSON), - patch: copy(CONTENT_TYPE_APPLICATION_JSON) + post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), + put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), + patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON) }, xsrfCookieName: 'XSRF-TOKEN', @@ -7573,14 +7707,14 @@ function $HttpProvider() { * * There are two kinds of interceptors (and two kinds of rejection interceptors): * - * * `request`: interceptors get called with http `config` object. The function is free to - * modify the `config` or create a new one. The function needs to return the `config` - * directly or as a promise. + * * `request`: interceptors get called with a http `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` or create a new one. The function needs to return the `response` - * directly or as a promise. + * 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. * @@ -7592,7 +7726,7 @@ function $HttpProvider() { * // optional method * 'request': function(config) { * // do something on success - * return config || $q.when(config); + * return config; * }, * * // optional method @@ -7609,7 +7743,7 @@ function $HttpProvider() { * // optional method * 'response': function(response) { * // do something on success - * return response || $q.when(response); + * return response; * }, * * // optional method @@ -7770,7 +7904,7 @@ function $HttpProvider() { * caching. * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} * that should abort the request when resolved. - * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the + * - **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 @@ -7796,9 +7930,9 @@ function $HttpProvider() { * * * @example - + -
+

- * Current time is: - *
- * Blood 1 : {{blood_1}} - * Blood 2 : {{blood_2}} - * - * - * - *
+ *
+ *
+ * Date format:
+ * Current time is: + *
+ * Blood 1 : {{blood_1}} + * Blood 2 : {{blood_2}} + * + * + * *
+ *
* - * + * * */ function interval(fn, delay, count, invokeApply) { @@ -8854,7 +9028,7 @@ function $IntervalProvider() { interval.cancel = function(promise) { if (promise && promise.$$intervalId in intervals) { intervals[promise.$$intervalId].reject('canceled'); - clearInterval(promise.$$intervalId); + $window.clearInterval(promise.$$intervalId); delete intervals[promise.$$intervalId]; return true; } @@ -9137,7 +9311,7 @@ function LocationHashbangUrl(appBase, hashPrefix) { Matches paths for file protocol on windows, such as /C:/foo/bar, and captures only /foo/bar. */ - var windowsFilePathExp = /^\/?.*?:(\/.*)/; + var windowsFilePathExp = /^\/[A-Z]:(\/.*)/; var firstPathSegmentMatch; @@ -9146,10 +9320,7 @@ function LocationHashbangUrl(appBase, hashPrefix) { url = url.replace(base, ''); } - /* - * The input URL intentionally contains a - * first path segment that ends with a colon. - */ + // The input URL intentionally contains a first path segment that ends with a colon. if (windowsFilePathExp.exec(url)) { return path; } @@ -9205,6 +9376,16 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) { return appBaseNoFile; } }; + + 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 IE8 & 9 do not reload page because of removal of '#' + this.$$absUrl = appBase + hashPrefix + this.$$url; + }; + } @@ -9336,15 +9517,40 @@ LocationHashbangInHtml5Url.prototype = * * 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 + * ``` + * * @param {string|Object.|Object.>} search New search params - string or - * hash object. Hash object may contain an array of values, which will be decoded as duplicates in - * the url. + * hash object. * - * @param {(string|Array)=} paramValue If `search` is a string, then `paramValue` will override only a - * single search parameter. If `paramValue` is an array, it will set the parameter as a - * comma-separated value. If `paramValue` is `null`, the parameter will be deleted. + * When called with a single argument the method acts as a setter, setting the `search` component + * of `$location` to the specified value. * - * @return {string} search + * 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|Array|boolean)=} paramValue If `search` is a string, 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) { @@ -9354,6 +9560,11 @@ LocationHashbangInHtml5Url.prototype = if (isString(search)) { this.$$search = parseKeyValue(search); } else if (isObject(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', @@ -9459,7 +9670,7 @@ function $LocationProvider(){ html5Mode = false; /** - * @ngdoc property + * @ngdoc method * @name $locationProvider#hashPrefix * @description * @param {string=} prefix Prefix for hash part (containing path and search) @@ -9475,7 +9686,7 @@ function $LocationProvider(){ }; /** - * @ngdoc property + * @ngdoc method * @name $locationProvider#html5Mode * @description * @param {boolean=} mode Use HTML5 strategy if available. @@ -9557,6 +9768,39 @@ function $LocationProvider(){ absHref = urlResolve(absHref.animVal).href; } + // Make relative links work in HTML5 mode for legacy browsers (or at least IE8 & 9) + // The href should be a regular url e.g. /link/somewhere or link/somewhere or ../somewhere or + // somewhere#anchor or http://example.com/somewhere + if (LocationMode === LocationHashbangInHtml5Url) { + // get the actual href attribute - see + // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx + var href = elm.attr('href') || elm.attr('xlink:href'); + + if (href.indexOf('://') < 0) { // Ignore absolute URLs + var prefix = '#' + hashPrefix; + if (href[0] == '/') { + // absolute path - replace old path + absHref = appBase + prefix + href; + } else if (href[0] == '#') { + // local anchor + absHref = appBase + prefix + ($location.path() || '/') + href; + } else { + // relative path - join with current path + var stack = $location.path().split("/"), + parts = href.split("/"); + for (var i=0; i + - function LogCtrl($scope, $log) { - $scope.$log = $log; - $scope.message = 'Hello World!'; - } + angular.module('logExample', []) + .controller('LogController', ['$scope', '$log', function($scope, $log) { + $scope.$log = $log; + $scope.message = 'Hello World!'; + }]); -
+

Reload this page with open console, enter text and hit the log button...

Message: @@ -9674,7 +9919,7 @@ function $LogProvider(){ self = this; /** - * @ngdoc property + * @ngdoc method * @name $logProvider#debugEnabled * @description * @param {boolean=} flag enable or disable debug level messages @@ -9800,14 +10045,7 @@ var promiseWarning; // // As an example, consider the following Angular expression: // -// {}.toString.constructor(alert("evil JS code")) -// -// We want to prevent this type of access. For the sake of performance, during the lexing phase we -// disallow any "dotted" access to any member named "constructor". -// -// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor -// while evaluating the expression, which is a stronger but more expensive test. Since reflective -// calls are expensive anyway, this is not such a big deal compared to static dereferencing. +// {}.toString.constructor('alert("evil JS code")') // // This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits // against the expression language, but not to prevent exploits that were enabled by exposing @@ -9815,17 +10053,19 @@ var promiseWarning; // practice and therefore we are not even trying to protect against interaction with an object // explicitly exposed in this way. // -// A developer could foil the name check by aliasing the Function constructor under a different -// name on the scope. -// // In general, it is not possible to access a Window object from an angular expression unless a // window or some DOM object that has a reference to window is published onto a Scope. +// Similarly we prevent invocations of function known to be dangerous, as well as assignments to +// native objects. + function ensureSafeMemberName(name, fullExpression) { - if (name === "constructor") { + if (name === "__defineGetter__" || name === "__defineSetter__" + || name === "__lookupGetter__" || name === "__lookupSetter__" + || name === "__proto__") { throw $parseMinErr('isecfld', - 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', - fullExpression); + 'Attempting to access a disallowed field in Angular expressions! ' + +'Expression: {0}', fullExpression); } return name; } @@ -9847,11 +10087,34 @@ function ensureSafeObject(obj, fullExpression) { throw $parseMinErr('isecdom', 'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}', fullExpression); + } else if (// block Object so that we can't get hold of dangerous Object.* methods + obj === Object) { + throw $parseMinErr('isecobj', + 'Referencing Object in Angular expressions is disallowed! Expression: {0}', + fullExpression); } } return obj; } +var CALL = Function.prototype.call; +var APPLY = Function.prototype.apply; +var BIND = Function.prototype.bind; + +function ensureSafeFunction(obj, fullExpression) { + if (obj) { + if (obj.constructor === obj) { + throw $parseMinErr('isecfn', + 'Referencing Function in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } else if (obj === CALL || obj === APPLY || (BIND && obj === BIND)) { + throw $parseMinErr('isecff', + 'Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } + } +} + var OPERATORS = { /* jshint bitwise : false */ 'null':function(){return null;}, @@ -9917,9 +10180,6 @@ Lexer.prototype = { this.tokens = []; - var token; - var json = []; - while (this.index < this.text.length) { this.ch = this.text.charAt(this.index); if (this.is('"\'')) { @@ -9928,19 +10188,11 @@ Lexer.prototype = { this.readNumber(); } else if (this.isIdent(this.ch)) { this.readIdent(); - // identifiers can only be if the preceding char was a { or , - if (this.was('{,') && json[0] === '{' && - (token = this.tokens[this.tokens.length - 1])) { - token.json = token.text.indexOf('.') === -1; - } } else if (this.is('(){}[].,;:?')) { this.tokens.push({ index: this.index, - text: this.ch, - json: (this.was(':[,') && this.is('{[')) || this.is('}]:,') + text: this.ch }); - if (this.is('{[')) json.unshift(this.ch); - if (this.is('}]')) json.shift(); this.index++; } else if (this.isWhitespace(this.ch)) { this.index++; @@ -9961,8 +10213,7 @@ Lexer.prototype = { this.tokens.push({ index: this.index, text: this.ch, - fn: fn, - json: (this.was('[,:') && this.is('+-')) + fn: fn }); this.index += 1; } else { @@ -10045,7 +10296,8 @@ Lexer.prototype = { this.tokens.push({ index: start, text: number, - json: true, + literal: true, + constant: true, fn: function() { return number; } }); }, @@ -10097,7 +10349,8 @@ Lexer.prototype = { // OPERATORS is our own object so we don't need to use special hasOwnPropertyFn if (OPERATORS.hasOwnProperty(ident)) { token.fn = OPERATORS[ident]; - token.json = OPERATORS[ident]; + token.literal = true; + token.constant = true; } else { var getter = getterFn(ident, this.options, this.text); token.fn = extend(function(self, locals) { @@ -10114,13 +10367,11 @@ Lexer.prototype = { if (methodName) { this.tokens.push({ index:lastDot, - text: '.', - json: false + text: '.' }); this.tokens.push({ index: lastDot + 1, - text: methodName, - json: false + text: methodName }); } }, @@ -10143,11 +10394,7 @@ Lexer.prototype = { string += String.fromCharCode(parseInt(hex, 16)); } else { var rep = ESCAPE[ch]; - if (rep) { - string += rep; - } else { - string += ch; - } + string = string + (rep || ch); } escape = false; } else if (ch === '\\') { @@ -10158,7 +10405,8 @@ Lexer.prototype = { index: start, text: rawString, string: string, - json: true, + literal: true, + constant: true, fn: function() { return string; } }); return; @@ -10190,28 +10438,12 @@ Parser.ZERO = extend(function () { Parser.prototype = { constructor: Parser, - parse: function (text, json) { + parse: function (text) { this.text = text; - //TODO(i): strip all the obsolte json stuff from this file - this.json = json; - this.tokens = this.lexer.lex(text); - if (json) { - // The extra level of aliasing is here, just in case the lexer misses something, so that - // we prevent any accidental execution in JSON. - this.assignment = this.logicalOR; - - this.functionCall = - this.fieldAccess = - this.objectIndex = - this.filterChain = function() { - this.throwError('is not valid json', {text: text, index: 0}); - }; - } - - var value = json ? this.primary() : this.statements(); + var value = this.statements(); if (this.tokens.length !== 0) { this.throwError('is an unexpected token', this.tokens[0]); @@ -10238,10 +10470,8 @@ Parser.prototype = { if (!primary) { this.throwError('not a primary expression', token); } - if (token.json) { - primary.constant = true; - primary.literal = true; - } + primary.literal = !!token.literal; + primary.constant = !!token.constant; } var next, context; @@ -10289,9 +10519,6 @@ Parser.prototype = { expect: function(e1, e2, e3, e4){ var token = this.peek(e1, e2, e3, e4); if (token) { - if (this.json && !token.json) { - this.throwError('is not valid json', token); - } this.tokens.shift(); return token; } @@ -10518,6 +10745,7 @@ Parser.prototype = { i = indexFn(self, locals), v, p; + ensureSafeMemberName(i, parser.text); if (!o) return undefined; v = ensureSafeObject(o[i], parser.text); if (v && v.then && parser.options.unwrapPromises) { @@ -10560,7 +10788,7 @@ Parser.prototype = { var fnPtr = fn(scope, locals, context) || noop; ensureSafeObject(context, parser.text); - ensureSafeObject(fnPtr, parser.text); + ensureSafeFunction(fnPtr, parser.text); // IE stupidity! (IE doesn't have apply for some native functions) var v = fnPtr.apply @@ -10669,6 +10897,8 @@ function setter(obj, path, setValue, fullExp, options) { } } key = ensureSafeMemberName(element.shift(), fullExp); + ensureSafeObject(obj, fullExp); + ensureSafeObject(obj[key], fullExp); obj[key] = setValue; return setValue; } @@ -10784,26 +11014,6 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { }; } -function simpleGetterFn1(key0, fullExp) { - ensureSafeMemberName(key0, fullExp); - - return function simpleGetterFn1(scope, locals) { - if (scope == null) return undefined; - return ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0]; - }; -} - -function simpleGetterFn2(key0, key1, fullExp) { - ensureSafeMemberName(key0, fullExp); - ensureSafeMemberName(key1, fullExp); - - return function simpleGetterFn2(scope, locals) { - if (scope == null) return undefined; - scope = ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0]; - return scope == null ? undefined : scope[key1]; - }; -} - function getterFn(path, options, fullExp) { // Check whether the cache has this getter already. // We can use hasOwnProperty directly on the cache because we ensure, @@ -10816,13 +11026,8 @@ function getterFn(path, options, fullExp) { pathKeysLength = pathKeys.length, fn; - // When we have only 1 or 2 tokens, use optimized special case closures. // http://jsperf.com/angularjs-parse-getter/6 - if (!options.unwrapPromises && pathKeysLength === 1) { - fn = simpleGetterFn1(pathKeys[0], fullExp); - } else if (!options.unwrapPromises && pathKeysLength === 2) { - fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp); - } else if (options.csp) { + if (options.csp) { if (pathKeysLength < 6) { fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, options); @@ -10926,7 +11131,7 @@ function getterFn(path, options, fullExp) { /** * @ngdoc provider * @name $parseProvider - * @function + * @kind function * * @description * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse} @@ -11045,7 +11250,7 @@ function $ParseProvider() { var lexer = new Lexer($parseOptions); var parser = new Parser(lexer, $filter, $parseOptions); - parsedExpression = parser.parse(exp, false); + parsedExpression = parser.parse(exp); if (exp !== 'hasOwnProperty') { // Only cache the value if it's not going to mess up the cache object @@ -11088,17 +11293,13 @@ function $ParseProvider() { * var deferred = $q.defer(); * * setTimeout(function() { - * // since this fn executes async in a future turn of the event loop, we need to wrap - * // our code into an $apply call so that the model changes are properly observed. - * scope.$apply(function() { - * deferred.notify('About to greet ' + name + '.'); + * deferred.notify('About to greet ' + name + '.'); * - * if (okToGreet(name)) { - * deferred.resolve('Hello, ' + name + '!'); - * } else { - * deferred.reject('Greeting ' + name + ' is not allowed.'); - * } - * }); + * if (okToGreet(name)) { + * deferred.resolve('Hello, ' + name + '!'); + * } else { + * deferred.reject('Greeting ' + name + ' is not allowed.'); + * } * }, 1000); * * return deferred.promise; @@ -11256,7 +11457,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#defer - * @function + * @kind function * * @description * Creates a `Deferred` object which represents a task which will finish in the future. @@ -11372,7 +11573,7 @@ function qFactory(nextTick, exceptionHandler) { } catch(e) { return makePromise(e, false); } - if (callbackOutput && isFunction(callbackOutput.then)) { + if (isPromiseLike(callbackOutput)) { return callbackOutput.then(function() { return makePromise(value, isResolved); }, function(error) { @@ -11397,7 +11598,7 @@ function qFactory(nextTick, exceptionHandler) { var ref = function(value) { - if (value && isFunction(value.then)) return value; + if (isPromiseLike(value)) return value; return { then: function(callback) { var result = defer(); @@ -11413,7 +11614,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#reject - * @function + * @kind function * * @description * Creates a promise that is resolved as rejected with the specified `reason`. This api should be @@ -11473,7 +11674,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#when - * @function + * @kind function * * @description * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. @@ -11545,7 +11746,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#all - * @function + * @kind function * * @description * Combines multiple promises into a single promise that is resolved when all of the input @@ -11636,7 +11837,7 @@ function $$RAFProvider(){ //rAF * * 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 (shift) instead of at the end (push) + * 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 middle are expensive so we use linked list @@ -11770,7 +11971,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$new - * @function + * @kind function * * @description * Creates a new child {@link ng.$rootScope.Scope scope}. @@ -11802,18 +12003,23 @@ function $RootScopeProvider(){ child.$$asyncQueue = this.$$asyncQueue; child.$$postDigestQueue = this.$$postDigestQueue; } else { - ChildScope = function() {}; // should be anonymous; This is so that when the minifier munges - // the name it does not become random set of chars. This will then show up as class - // name in the web inspector. - ChildScope.prototype = this; - child = new ChildScope(); - child.$id = nextUid(); + // Only create a child scope class if somebody asks for one, + // but cache it to allow the VM to optimize lookups. + if (!this.$$childScopeClass) { + this.$$childScopeClass = function() { + this.$$watchers = this.$$nextSibling = + this.$$childHead = this.$$childTail = null; + this.$$listeners = {}; + this.$$listenerCount = {}; + this.$id = nextUid(); + this.$$childScopeClass = null; + }; + this.$$childScopeClass.prototype = this; + } + child = new this.$$childScopeClass(); } child['this'] = child; - child.$$listeners = {}; - child.$$listenerCount = {}; child.$parent = this; - child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null; child.$$prevSibling = this.$$childTail; if (this.$$childHead) { this.$$childTail.$$nextSibling = child; @@ -11827,7 +12033,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$watch - * @function + * @kind function * * @description * Registers a `listener` callback to be executed whenever the `watchExpression` changes. @@ -11839,10 +12045,14 @@ function $RootScopeProvider(){ * {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.) * - 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). The inequality is determined according to - * {@link angular.equals} function. To save the value of the object for later comparison, - * the {@link angular.copy} function is used. It also means that watching complex options - * will have adverse memory and performance implications. + * 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. * - 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. @@ -11877,12 +12087,16 @@ function $RootScopeProvider(){ expect(scope.counter).toEqual(0); scope.$digest(); - // no variable change - expect(scope.counter).toEqual(0); + // 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(1); + expect(scope.counter).toEqual(2); @@ -11969,7 +12183,7 @@ function $RootScopeProvider(){ // the while loop reads in reverse order. array.unshift(watcher); - return function() { + return function deregisterWatch() { arrayRemove(array, watcher); lastDirtyWatch = null; }; @@ -11979,7 +12193,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$watchCollection - * @function + * @kind function * * @description * Shallow watches the properties of an object and fires whenever any of the properties change @@ -12051,7 +12265,7 @@ function $RootScopeProvider(){ function $watchCollectionWatch() { newValue = objGetter(self); - var newLength, key; + var newLength, key, bothNaN; if (!isObject(newValue)) { // if primitive if (oldValue !== newValue) { @@ -12075,7 +12289,7 @@ function $RootScopeProvider(){ } // copy the items to oldValue and look for changes. for (var i = 0; i < newLength; i++) { - var bothNaN = (oldValue[i] !== oldValue[i]) && + bothNaN = (oldValue[i] !== oldValue[i]) && (newValue[i] !== newValue[i]); if (!bothNaN && (oldValue[i] !== newValue[i])) { changeDetected++; @@ -12095,7 +12309,9 @@ function $RootScopeProvider(){ if (newValue.hasOwnProperty(key)) { newLength++; if (oldValue.hasOwnProperty(key)) { - if (oldValue[key] !== newValue[key]) { + bothNaN = (oldValue[key] !== oldValue[key]) && + (newValue[key] !== newValue[key]); + if (!bothNaN && (oldValue[key] !== newValue[key])) { changeDetected++; oldValue[key] = newValue[key]; } @@ -12155,7 +12371,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$digest - * @function + * @kind function * * @description * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and @@ -12190,12 +12406,16 @@ function $RootScopeProvider(){ expect(scope.counter).toEqual(0); scope.$digest(); - // no variable change - expect(scope.counter).toEqual(0); + // 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(1); + expect(scope.counter).toEqual(2); * ``` * */ @@ -12243,11 +12463,11 @@ function $RootScopeProvider(){ if ((value = watch.get(current)) !== (last = watch.last) && !(watch.eq ? equals(value, last) - : (typeof value == 'number' && typeof last == 'number' + : (typeof value === 'number' && typeof last === 'number' && isNaN(value) && isNaN(last)))) { dirty = true; lastDirtyWatch = watch; - watch.last = watch.eq ? copy(value) : value; + watch.last = watch.eq ? copy(value, null) : value; watch.fn(value, ((last === initWatchVal) ? value : last), current); if (ttl < 5) { logIdx = 4 - ttl; @@ -12322,7 +12542,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$destroy - * @function + * @kind function * * @description * Removes the current scope (and all of its children) from the parent scope. Removal implies @@ -12383,7 +12603,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$eval - * @function + * @kind function * * @description * Executes the `expression` on the current scope and returns the result. Any exceptions in @@ -12415,7 +12635,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$evalAsync - * @function + * @kind function * * @description * Executes the expression on the current scope at a later point in time. @@ -12462,7 +12682,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$apply - * @function + * @kind function * * @description * `$apply()` is used to execute an expression in angular from outside of the angular @@ -12524,7 +12744,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$on - * @function + * @kind function * * @description * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for @@ -12573,7 +12793,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$emit - * @function + * @kind function * * @description * Dispatches an event `name` upwards through the scope hierarchy notifying the @@ -12641,7 +12861,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$broadcast - * @function + * @kind function * * @description * Dispatches an event `name` downwards to all child scopes (and their children) notifying the @@ -12889,7 +13109,7 @@ function adjustMatchers(matchers) { /** * @ngdoc service * @name $sceDelegate - * @function + * @kind function * * @description * @@ -12936,19 +13156,21 @@ function adjustMatchers(matchers) { * * 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/**']);
+ * ```
+ *  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**']);
- *      });
- * 
+ * // The blacklist overrides the whitelist so the open redirect here is blocked. + * $sceDelegateProvider.resourceUrlBlacklist([ + * 'http://myapp.example.com/clickThru**' + * ]); + * }); + * ``` */ function $SceDelegateProvider() { @@ -12961,7 +13183,7 @@ function $SceDelegateProvider() { /** * @ngdoc method * @name $sceDelegateProvider#resourceUrlWhitelist - * @function + * @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 @@ -12990,7 +13212,7 @@ function $SceDelegateProvider() { /** * @ngdoc method * @name $sceDelegateProvider#resourceUrlBlacklist - * @function + * @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 @@ -13217,7 +13439,7 @@ function $SceDelegateProvider() { /** * @ngdoc service * @name $sce - * @function + * @kind function * * @description * @@ -13243,10 +13465,10 @@ function $SceDelegateProvider() { * * Here's an example of a binding in a privileged context: * - *
- *     
- *     
- *
+ * ``` + * + *
+ * ``` * * 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. @@ -13286,15 +13508,15 @@ function $SceDelegateProvider() { * 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 || '');
- *       });
- *     };
- *   }];
- * 
+ * ``` + * 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 * @@ -13343,7 +13565,7 @@ function $SceDelegateProvider() { * * | 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. | + * | `$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 (`
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. | @@ -13367,7 +13589,7 @@ function $SceDelegateProvider() { * - `**`: matches zero or more occurrences of *any* character. As such, it's not * not appropriate to use in for 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.) It's usage at the very end of the path is ok. (e.g. + * 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 @@ -13398,66 +13620,65 @@ function $SceDelegateProvider() { * * ## Show me an example using SCE. * - * @example - - -
-

- User comments
- 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. -
-
- {{userComment.name}}: - -
-
-
-
-
- - - var mySceApp = angular.module('mySceApp', ['ngSanitize']); - - mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { - var self = this; - $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { - self.userComments = userComments; - }); - self.explicitlyTrustedHtml = $sce.trustAsHtml( - 'Hover over this text.'); - }); - - - -[ - { "name": "Alice", - "htmlComment": - "Is anyone reading this?" - }, - { "name": "Bob", - "htmlComment": "Yes! Am I the only other one?" - } -] - - - - describe('SCE doc demo', function() { - it('should sanitize untrusted values', function() { - expect(element(by.css('.htmlComment')).getInnerHtml()) - .toBe('Is anyone reading this?'); - }); - - it('should NOT sanitize explicitly trusted values', function() { - expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe( - 'Hover over this text.'); - }); - }); - -
+ * + * + *
+ *

+ * User comments
+ * 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. + *
+ *
+ * {{userComment.name}}: + * + *
+ *
+ *
+ *
+ *
+ * + * + * var mySceApp = angular.module('mySceApp', ['ngSanitize']); + * + * mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { + * var self = this; + * $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { + * self.userComments = userComments; + * }); + * self.explicitlyTrustedHtml = $sce.trustAsHtml( + * 'Hover over this text.'); + * }); + * + * + * + * [ + * { "name": "Alice", + * "htmlComment": + * "Is anyone reading this?" + * }, + * { "name": "Bob", + * "htmlComment": "Yes! Am I the only other one?" + * } + * ] + * + * + * + * describe('SCE doc demo', function() { + * it('should sanitize untrusted values', function() { + * expect(element.all(by.css('.htmlComment')).first().getInnerHtml()) + * .toBe('Is anyone reading this?'); + * }); + * + * it('should NOT sanitize explicitly trusted values', function() { + * expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe( + * 'Hover over this text.'); + * }); + * }); + * + *
* * * @@ -13471,13 +13692,13 @@ function $SceDelegateProvider() { * * 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);
- *   });
- * 
+ * ``` + * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) { + * // Completely disable SCE. For demonstration purposes only! + * // Do not use in new projects. + * $sceProvider.enabled(false); + * }); + * ``` * */ /* jshint maxlen: 100 */ @@ -13488,7 +13709,7 @@ function $SceProvider() { /** * @ngdoc method * @name $sceProvider#enabled - * @function + * @kind function * * @param {boolean=} value If provided, then enables/disables SCE. * @return {boolean} true if SCE is enabled, false otherwise. @@ -13561,12 +13782,12 @@ function $SceProvider() { 'document. See http://docs.angularjs.org/api/ng.$sce for more information.'); } - var sce = copy(SCE_CONTEXTS); + var sce = shallowCopy(SCE_CONTEXTS); /** * @ngdoc method * @name $sce#isEnabled - * @function + * @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}. @@ -13588,7 +13809,7 @@ function $SceProvider() { /** * @ngdoc method - * @name $sce#parse + * @name $sce#parseAs * * @description * Converts Angular {@link guide/expression expression} into a function. This is like {@link @@ -14101,7 +14322,7 @@ var originUrl = urlResolve(window.location.href, true); * https://github.com/angular/angular.js/pull/2902 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/ * - * @function + * @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. @@ -14174,17 +14395,18 @@ function urlIsSameOrigin(requestUrl) { * expression. * * @example - + -
+
@@ -14202,6 +14424,17 @@ function $WindowProvider(){ this.$get = valueFn(window); } +/* global currencyFilter: true, + dateFilter: true, + filterFilter: true, + jsonFilter: true, + limitToFilter: true, + lowercaseFilter: true, + numberFilter: true, + orderByFilter: true, + uppercaseFilter: true, + */ + /** * @ngdoc provider * @name $filterProvider @@ -14265,7 +14498,7 @@ function $WindowProvider(){ /** * @ngdoc service * @name $filter - * @function + * @kind function * @description * Filters are used for formatting data displayed to the user. * @@ -14275,7 +14508,24 @@ function $WindowProvider(){ * * @param {String} name Name of the filter function to retrieve * @return {Function} the filter function - */ + * @example + + +
+

{{ originalText }}

+

{{ filteredText }}

+
+
+ + + angular.module('filterExample', []) + .controller('MainCtrl', function($scope, $filter) { + $scope.originalText = 'hello'; + $scope.filteredText = $filter('uppercase')($scope.originalText); + }); + +
+ */ $FilterProvider.$inject = ['$provide']; function $FilterProvider($provide) { var suffix = 'Filter'; @@ -14335,7 +14585,7 @@ function $FilterProvider($provide) { /** * @ngdoc filter * @name filter - * @function + * @kind function * * @description * Selects a subset of items from `array` and returns it as a new array. @@ -14367,15 +14617,15 @@ function $FilterProvider($provide) { * * 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 the item should be included in filtered result. + * - `function(actual, expected)`: + * The function will be given the object value and the predicate value to compare and + * should return true if the item should be included in filtered result. * - * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`. - * this is essentially strict comparison of expected and actual. + * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`. + * this is essentially strict comparison of expected and actual. * - * - `false|undefined`: A short hand for a function which will look for a substring match in case - * insensitive way. + * - `false|undefined`: A short hand for a function which will look for a substring match in case + * insensitive way. * * @example @@ -14527,7 +14777,7 @@ function filterFilter() { // jshint +W086 for (var key in expression) { (function(path) { - if (typeof expression[path] == 'undefined') return; + if (typeof expression[path] === 'undefined') return; predicates.push(function(value) { return search(path == '$' ? value : (value && value[path]), expression[path]); }); @@ -14554,7 +14804,7 @@ function filterFilter() { /** * @ngdoc filter * @name currency - * @function + * @kind function * * @description * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default @@ -14566,14 +14816,15 @@ function filterFilter() { * * * @example - + -
+

default currency symbol ($): {{amount | currency}}
custom currency identifier (USD$): {{amount | currency:"USD$"}} @@ -14611,7 +14862,7 @@ function currencyFilter($locale) { /** * @ngdoc filter * @name number - * @function + * @kind function * * @description * Formats a number as text. @@ -14625,14 +14876,15 @@ function currencyFilter($locale) { * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit. * * @example - + -
+
Enter number:
Default formatting: {{val | number}}
No fractions: {{val | number:0}}
@@ -14682,6 +14934,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { var match = numStr.match(/([\d\.]+)e(-?)(\d+)/); if (match && match[2] == '-' && match[3] > fractionSize + 1) { numStr = '0'; + number = 0; } else { formatedText = numStr; hasExponent = true; @@ -14696,8 +14949,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac); } - var pow = Math.pow(10, fractionSize); - number = Math.round(number * pow) / pow; + // safely round numbers in JS without hitting imprecisions of floating-point arithmetics + // inspired by: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round + number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize); + var fraction = ('' + number).split(DECIMAL_SEP); var whole = fraction[0]; fraction = fraction[1] || ''; @@ -14823,7 +15079,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+ /** * @ngdoc filter * @name date - * @function + * @kind function * * @description * Formats `date` to a string based on the requested `format`. @@ -14940,11 +15196,7 @@ function dateFilter($locale) { format = format || 'mediumDate'; format = $locale.DATETIME_FORMATS[format] || format; if (isString(date)) { - if (NUMBER_STRING.test(date)) { - date = int(date); - } else { - date = jsonStringToDate(date); - } + date = NUMBER_STRING.test(date) ? int(date) : jsonStringToDate(date); } if (isNumber(date)) { @@ -14980,7 +15232,7 @@ function dateFilter($locale) { /** * @ngdoc filter * @name json - * @function + * @kind function * * @description * Allows you to convert a JavaScript object into JSON string. @@ -15015,7 +15267,7 @@ function jsonFilter() { /** * @ngdoc filter * @name lowercase - * @function + * @kind function * @description * Converts string to lowercase. * @see angular.lowercase @@ -15026,7 +15278,7 @@ var lowercaseFilter = valueFn(lowercase); /** * @ngdoc filter * @name uppercase - * @function + * @kind function * @description * Converts string to uppercase. * @see angular.uppercase @@ -15036,7 +15288,7 @@ var uppercaseFilter = valueFn(uppercase); /** * @ngdoc filter * @name limitTo - * @function + * @kind function * * @description * Creates a new array or string containing only a specified number of elements. The elements @@ -15052,17 +15304,18 @@ var uppercaseFilter = valueFn(uppercase); * had less than `limit` elements. * * @example - + -
+
Limit {{numbers}} to:

Output numbers: {{ numbers | limitTo:numLimit }}

Limit {{letters}} to: @@ -15106,7 +15359,11 @@ function limitToFilter(){ return function(input, limit) { if (!isArray(input) && !isString(input)) return input; - limit = int(limit); + if (Math.abs(Number(limit)) === Infinity) { + limit = Number(limit); + } else { + limit = int(limit); + } if (isString(input)) { //NaN check on limit @@ -15145,10 +15402,12 @@ function limitToFilter(){ /** * @ngdoc filter * @name orderBy - * @function + * @kind function * * @description - * Orders a specified `array` by the `expression` predicate. + * Orders a specified `array` by the `expression` predicate. It is ordered alphabetically + * for strings and numerically for numbers. Note: if you notice numbers are not being sorted + * correctly, make sure they are actually being saved as numbers and not strings. * * @param {Array} array The array to sort. * @param {function(*)|string|Array.<(function(*)|string)>} expression A predicate to be @@ -15168,20 +15427,21 @@ function limitToFilter(){ * @returns {Array} Sorted copy of the source array. * * @example - + -
+
Sorting predicate = {{predicate}}; reverse = {{reverse}}

[ unsorted ] @@ -15201,6 +15461,51 @@ function limitToFilter(){
+ * + * It's also possible to call the orderBy filter manually, by injecting `$filter`, retrieving the + * filter routine with `$filter('orderBy')`, and calling the returned filter routine with the + * desired parameters. + * + * Example: + * + * @example + + +
+ + + + + + + + + + + +
Name + (^)Phone NumberAge
{{friend.name}}{{friend.phone}}{{friend.age}}
+
+
+ + + angular.module('orderByExample', []) + .controller('ExampleController', ['$scope', '$filter', function($scope, $filter) { + var orderBy = $filter('orderBy'); + $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 } + ]; + $scope.order = function(predicate, reverse) { + $scope.friends = orderBy($scope.friends, predicate, reverse); + }; + $scope.order('-age',false); + }]); + +
*/ orderByFilter.$inject = ['$parse']; function orderByFilter($parse){ @@ -15247,6 +15552,10 @@ function orderByFilter($parse){ var t1 = typeof v1; var t2 = typeof v2; if (t1 == t2) { + if (isDate(v1) && isDate(v2)) { + v1 = v1.valueOf(); + v2 = v2.valueOf(); + } if (t1 == "string") { v1 = v1.toLowerCase(); v2 = v2.toLowerCase(); @@ -15384,7 +15693,7 @@ var htmlAnchorDirective = valueFn({ return browser.driver.getCurrentUrl().then(function(url) { return url.match(/\/123$/); }); - }, 1000, 'page should navigate to /123'); + }, 5000, 'page should navigate to /123'); }); xit('should execute ng-click but not reload when href empty string and name specified', function() { @@ -15412,7 +15721,7 @@ var htmlAnchorDirective = valueFn({ return browser.driver.getCurrentUrl().then(function(url) { return url.match(/\/6$/); }); - }, 1000, 'page should navigate to /6'); + }, 5000, 'page should navigate to /6'); }); @@ -15752,7 +16061,7 @@ var nullFormCtrl = { * - `url` * * @description - * `FormController` keeps track of all its controls and nested forms as well as state of them, + * `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 @@ -16028,12 +16337,13 @@ function FormController(element, attrs, $scope, $animate) { * * * @example - + - + userType: Required!
userType = {{userType}}
@@ -16139,16 +16449,14 @@ var formDirectiveFactory = function(isNgForm) { var formDirective = formDirectiveFactory(); var ngFormDirective = formDirectiveFactory(true); -/* global - - -VALID_CLASS, - -INVALID_CLASS, - -PRISTINE_CLASS, - -DIRTY_CLASS +/* global VALID_CLASS: true, + INVALID_CLASS: true, + PRISTINE_CLASS: true, + DIRTY_CLASS: true */ var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/; -var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i; +var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i; var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/; var inputType = { @@ -16178,15 +16486,16 @@ var inputType = { * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. * * @example - + - + Single word: @@ -16258,14 +16567,15 @@ var inputType = { * interaction with the input element. * * @example - + - + Number: @@ -16333,14 +16643,15 @@ var inputType = { * interaction with the input element. * * @example - + - + URL: Required! @@ -16409,14 +16720,15 @@ var inputType = { * interaction with the input element. * * @example - + - + Email: Required! @@ -16475,18 +16787,19 @@ var inputType = { * be set when selected. * * @example - + - + Red
Green
Blue
@@ -16525,15 +16838,16 @@ var inputType = { * interaction with the input element. * * @example - + - + Value1:
Value2:
@@ -16574,15 +16888,29 @@ function validate(ctrl, validatorName, validity, value){ return validity ? value : undefined; } +function testFlags(validity, flags) { + var i, flag; + if (flags) { + for (i=0; i @@ -16621,11 +16961,11 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { value = trim(value); } - if (ctrl.$viewValue !== value || - // If the value is still empty/falsy, and there is no `required` error, run validators - // again. This enables HTML5 constraint validation errors to affect Angular validation - // even when the first character entered causes an error. - (validity && value === '' && !validity.valueMissing)) { + // If a control is suffering from bad input, browsers discard its value, so it may be + // necessary to revalidate even if the control's value is the same empty value twice in + // a row. + var revalidate = validity && ctrl.$$hasNativeValidators; + if (ctrl.$viewValue !== value || (value === '' && revalidate)) { if (scope.$$phase) { ctrl.$setViewValue(value); } else { @@ -16731,6 +17071,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { } } +var numberBadFlags = ['badInput']; + function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { textInputType(scope, element, attr, ctrl, $sniffer, $browser); @@ -16745,7 +17087,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { } }); - addNativeHtml5Validators(ctrl, 'number', element); + addNativeHtml5Validators(ctrl, 'number', numberBadFlags, null, ctrl.$$validityState); ctrl.$formatters.push(function(value) { return ctrl.$isEmpty(value) ? '' : '' + value; @@ -16877,6 +17219,7 @@ function checkboxInputType(scope, element, attr, ctrl) { * patterns defined as scope expressions. * @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. */ @@ -16904,14 +17247,15 @@ function checkboxInputType(scope, element, attr, ctrl) { * interaction with the input element. * * @example - + -
+
User name: @@ -17026,14 +17370,14 @@ var VALID_CLASS = 'ng-valid', * @property {Array.} $formatters Array of functions to execute, as a pipeline, whenever the model value changes. Each function is called, in turn, passing the value through to the next. Used to format / convert values for display in the control and validation. - * ```js - * function formatter(value) { - * if (value) { - * return value.toUpperCase(); - * } - * } - * ngModel.$formatters.push(formatter); - * ``` + * ```js + * function formatter(value) { + * if (value) { + * return value.toUpperCase(); + * } + * } + * ngModel.$formatters.push(formatter); + * ``` * * @property {Array.} $viewChangeListeners Array of functions to execute whenever the * view value has changed. It is called with no arguments, and its return value is ignored. @@ -17062,7 +17406,12 @@ var VALID_CLASS = 'ng-valid', * Note that `contenteditable` is an HTML5 attribute, which tells the browser to let the element * contents be edited in place by the user. This will not work on older browsers. * - * + * 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. ``). + * However, as we are using `$sce` the model can still decide to to provide unsafe content if it marks + * that content using the `$sce` service. + * + * [contenteditable] { border: 1px solid black; @@ -17076,8 +17425,8 @@ var VALID_CLASS = 'ng-valid', - angular.module('customControl', []). - directive('contenteditable', function() { + angular.module('customControl', ['ngSanitize']). + directive('contenteditable', ['$sce', function($sce) { return { restrict: 'A', // only activate on element attribute require: '?ngModel', // get a hold of NgModelController @@ -17086,7 +17435,7 @@ var VALID_CLASS = 'ng-valid', // Specify how UI should be updated ngModel.$render = function() { - element.html(ngModel.$viewValue || ''); + element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); }; // Listen for change events to enable binding @@ -17107,7 +17456,7 @@ var VALID_CLASS = 'ng-valid', } } }; - }); + }]); @@ -17221,7 +17570,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * This method should be called by validators - i.e. the parser or formatter functions. * * @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign - * to `$error[validationErrorKey]=isValid` so that it is available for data-binding. + * to `$error[validationErrorKey]=!isValid` 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}}` . @@ -17424,12 +17773,13 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * * * @example - * + * Update input to see transitions when valid/invalid. Integer is a valid value. - + @@ -17488,17 +17838,18 @@ var ngModelDirective = function() { * in input value. * * @example - * + * * * - *
+ *
* * *
@@ -17579,14 +17930,15 @@ var requiredDirective = function() { * specified in form `/something/` then the value will be converted into a regular expression. * * @example - + -
+ List: Required! @@ -17678,15 +18030,16 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/; * of the `input` element * * @example - + - +

Which is your favorite?

+
Enter name:
Hello !
@@ -17781,14 +18135,19 @@ var ngValueDirective = function() { */ -var ngBindDirective = ngDirective(function(scope, element, attr) { - element.addClass('ng-binding').data('$binding', attr.ngBind); - scope.$watch(attr.ngBind, function ngBindWatchAction(value) { - // We are purposefully using == here rather than === because we want to - // catch when value is "null or undefined" - // jshint -W041 - element.text(value == undefined ? '' : value); - }); +var ngBindDirective = ngDirective({ + compile: function(templateElement) { + templateElement.addClass('ng-binding'); + return function (scope, element, attr) { + element.data('$binding', attr.ngBind); + scope.$watch(attr.ngBind, function ngBindWatchAction(value) { + // We are purposefully using == here rather than === because we want to + // catch when value is "null or undefined" + // jshint -W041 + element.text(value == undefined ? '' : value); + }); + }; + } }); @@ -17810,15 +18169,16 @@ var ngBindDirective = ngDirective(function(scope, element, attr) { * * @example * Try it here: enter text in text box and watch the greeting change. - + -
+
Salutation:
Name:

@@ -17876,20 +18236,20 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
  * @example
    Try it here: enter text in text box and watch the greeting change.
 
-   
+   
      
-       
+

- angular.module('ngBindHtmlExample', ['ngSanitize']) - - .controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) { - $scope.myHTML = - 'I am an HTMLstring with links! and other stuff'; - }]); + angular.module('bindHtmlExample', ['ngSanitize']) + .controller('ExampleController', ['$scope', function($scope) { + $scope.myHTML = + 'I am an HTMLstring with ' + + '
links! and other stuff'; + }]); @@ -17901,15 +18261,24 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) { */ var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) { - return function(scope, element, attr) { - element.addClass('ng-binding').data('$binding', attr.ngBindHtml); + return { + compile: function (tElement) { + tElement.addClass('ng-binding'); - var parsed = $parse(attr.ngBindHtml); - function getStringValue() { return (parsed(scope) || '').toString(); } + return function (scope, element, attr) { + element.data('$binding', attr.ngBindHtml); - scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) { - element.html($sce.getTrustedHtml(parsed(scope)) || ''); - }); + var parsed = $parse(attr.ngBindHtml); + + function getStringValue() { + return (parsed(scope) || '').toString(); + } + + scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) { + element.html($sce.getTrustedHtml(parsed(scope)) || ''); + }); + }; + } }; }]; @@ -17932,7 +18301,7 @@ function classDirective(name, selector) { scope.$watch('$index', function($index, old$index) { // jshint bitwise: false var mod = $index & 1; - if (mod !== old$index & 1) { + if (mod !== (old$index & 1)) { var classes = arrayClasses(scope.$eval(attr[name])); mod === selector ? addClasses(classes) : @@ -17991,7 +18360,7 @@ function classDirective(name, selector) { updateClasses(oldClasses, newClasses); } } - oldVal = copy(newVal); + oldVal = shallowCopy(newVal); } } }; @@ -18019,7 +18388,7 @@ function classDirective(name, selector) { var classes = [], i = 0; forEach(classVal, function(v, k) { if (v) { - classes.push(k); + classes = classes.concat(k.split(' ')); } }); return classes; @@ -18344,7 +18713,7 @@ var ngCloakDirective = ngDirective({ * * MVC components in angular: * - * * Model — The Model is scope properties; scopes are attached to the DOM where scope properties + * * 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 @@ -18365,165 +18734,192 @@ var ngCloakDirective = ngDirective({ * @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. Notice that the scope becomes the `this` for the - * controller's instance. This allows for easy access to the view data from the controller. Also - * notice that any changes to the data are automatically reflected in the View without the need - * for a manual update. The example is shown in two different declaration styles you may use - * according to preference. - - - -
- Name: - [ greet ]
- Contact: -
    -
  • - - - [ clear - | X ] -
  • -
  • [ add ]
  • -
-
-
- - it('should check controller as', function() { - var container = element(by.id('ctrl-as-exmpl')); - - expect(container.findElement(by.model('settings.name')) - .getAttribute('value')).toBe('John Smith'); - - var firstRepeat = - container.findElement(by.repeater('contact in settings.contacts').row(0)); - var secondRepeat = - container.findElement(by.repeater('contact in settings.contacts').row(1)); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('408 555 1212'); - expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('john.smith@example.org'); - - firstRepeat.findElement(by.linkText('clear')).click(); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe(''); - - container.findElement(by.linkText('add')).click(); - - expect(container.findElement(by.repeater('contact in settings.contacts').row(2)) - .findElement(by.model('contact.value')) - .getAttribute('value')) - .toBe('yourname@example.org'); - }); - -
- - - -
- Name: - [ greet ]
- Contact: -
    -
  • - - - [ clear - | X ] -
  • -
  • [ add ]
  • -
-
-
- - it('should check controller', function() { - var container = element(by.id('ctrl-exmpl')); - - expect(container.findElement(by.model('name')) - .getAttribute('value')).toBe('John Smith'); - - var firstRepeat = - container.findElement(by.repeater('contact in contacts').row(0)); - var secondRepeat = - container.findElement(by.repeater('contact in contacts').row(1)); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('408 555 1212'); - expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('john.smith@example.org'); - - firstRepeat.findElement(by.linkText('clear')).click(); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe(''); - - container.findElement(by.linkText('add')).click(); - - expect(container.findElement(by.repeater('contact in contacts').row(2)) - .findElement(by.model('contact.value')) - .getAttribute('value')) - .toBe('yourname@example.org'); - }); - -
+ * 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. + * + * + * + *
+ * Name: + * [ greet ]
+ * Contact: + *
    + *
  • + * + * + * [ clear + * | X ] + *
  • + *
  • [ add ]
  • + *
+ *
+ *
+ * + * 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 = ''; + * }; + * + * + * 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.linkText('clear')).click(); + * + * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe(''); + * + * container.element(by.linkText('add')).click(); + * + * expect(container.element(by.repeater('contact in settings.contacts').row(2)) + * .element(by.model('contact.value')) + * .getAttribute('value')) + * .toBe('yourname@example.org'); + * }); + * + *
+ * + * This example demonstrates the "attach to `$scope`" style of controller. + * + * + * + *
+ * Name: + * [ greet ]
+ * Contact: + *
    + *
  • + * + * + * [ clear + * | X ] + *
  • + *
  • [ add ]
  • + *
+ *
+ *
+ * + * 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 = ''; + * }; + * } + * + * + * 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.linkText('clear')).click(); + * + * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe(''); + * + * container.element(by.linkText('add')).click(); + * + * expect(container.element(by.repeater('contact in contacts').row(2)) + * .element(by.model('contact.value')) + * .getAttribute('value')) + * .toBe('yourname@example.org'); + * }); + * + *
*/ var ngControllerDirective = [function() { @@ -18545,8 +18941,10 @@ var ngControllerDirective = [function() { * This is necessary when developing things like Google Chrome Extensions. * * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things). - * For us to be compatible, we just need to implement the "getterFn" in $parse without violating - * any of these restrictions. + * For Angular to be CSP compatible there are only two things that we need to do differently: + * + * - don't use `Function` constructor to generate optimized value getters + * - don't inject custom stylesheet into the document * * AngularJS uses `Function(string)` generated functions as a speed optimization. Applying the `ngCsp` * directive will cause Angular to use CSP compatibility mode. When this mode is on AngularJS will @@ -18557,7 +18955,18 @@ var ngControllerDirective = [function() { * includes some CSS rules (e.g. {@link ng.directive:ngCloak ngCloak}). * To make those directives work in CSP mode, include the `angular-csp.css` manually. * - * In order to use this feature put the `ngCsp` directive on the root element of the application. + * Angular tries to autodetect if CSP is active and automatically turn on the CSP-safe mode. 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 the root element of the application or on the `angular.js` script tag, whichever + * appears first in the html document. * * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.* * @@ -18572,9 +18981,9 @@ var ngControllerDirective = [function() { ``` */ -// ngCsp is not implemented as a proper directive any more, because we need it be processed while we bootstrap -// the system (before $parse is instantiated), for this reason we just have a csp() fn that looks for ng-csp attribute -// anywhere in the current doc +// ngCsp is not implemented as a proper directive any more, because we need it be processed while we +// bootstrap the system (before $parse is instantiated), for this reason we just have +// the csp.isActive() fn that looks for ng-csp attribute anywhere in the current doc /** * @ngdoc directive @@ -18621,7 +19030,7 @@ forEach( return { compile: function($element, attr) { var fn = $parse(attr[directiveName]); - return function(scope, element, attr) { + return function ngEventHandler(scope, element) { element.on(lowercase(name), function(event) { scope.$apply(function() { fn(scope, {$event:event}); @@ -18838,8 +19247,13 @@ forEach( * @example - - key up count: {{count}} +

Typing in the input box below updates the key count

+ key up count: {{count}} + +

Typing in the input box below updates the keycode

+ +

event keyCode: {{ event.keyCode }}

+

event altKey: {{ event.altKey }}

*/ @@ -18884,21 +19298,22 @@ forEach( * ({@link guide/expression#-event- Event object is available as `$event`}) * * @example - + - + Enter text and hit enter: @@ -18910,7 +19325,7 @@ forEach( expect(element(by.binding('list')).getText()).toBe('list=[]'); element(by.css('#submit')).click(); expect(element(by.binding('list')).getText()).toContain('hello'); - expect(element(by.input('text')).getAttribute('value')).toBe(''); + expect(element(by.model('text')).getAttribute('value')).toBe(''); }); it('should ignore empty strings', function() { expect(element(by.binding('list')).getText()).toBe('list=[]'); @@ -19111,7 +19526,7 @@ var ngIfDirective = ['$animate', function($animate) { clone[clone.length++] = document.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 it's template arrives. + // by a directive with templateUrl when its template arrives. block = { clone: clone }; @@ -19183,9 +19598,9 @@ var ngIfDirective = ['$animate', function($animate) { * - Otherwise enable scrolling only if the expression evaluates to truthy value. * * @example - + -
+
@@ -19197,12 +19612,13 @@ var ngIfDirective = ['$animate', function($animate) {
- function Ctrl($scope) { - $scope.templates = - [ { name: 'template1.html', url: 'template1.html'}, - { name: 'template2.html', url: 'template2.html'} ]; - $scope.template = $scope.templates[0]; - } + 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]; + }]); Content of template1.html @@ -19265,7 +19681,7 @@ var ngIfDirective = ['$animate', function($animate) { return; } templateSelect.click(); - templateSelect.element.all(by.css('option')).get(2).click(); + templateSelect.all(by.css('option')).get(2).click(); expect(includeElem.getText()).toMatch(/Content of template2.html/); }); @@ -19275,7 +19691,7 @@ var ngIfDirective = ['$animate', function($animate) { return; } templateSelect.click(); - templateSelect.element.all(by.css('option')).get(0).click(); + templateSelect.all(by.css('option')).get(0).click(); expect(includeElem.isPresent()).toBe(false); }); @@ -19427,14 +19843,15 @@ var ngIncludeFillContentDirective = ['$compile', * @param {expression} ngInit {@link guide/expression Expression} to eval. * * @example - + -
+
list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}}; @@ -19574,7 +19991,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); * 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, Marry and one other person are viewing" + * 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 @@ -19587,16 +20004,17 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); * @param {number=} offset Offset to deduct from the total number. * * @example - + -
+
Person 1:
Person 2:
Number of People:
@@ -19810,7 +20228,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp * mapped to the same DOM element, which is not possible.) Filters should be applied to the expression, * before specifying a tracking expression. * - * For example: `item in items` is equivalent to `item in items track by $id(item)'. This implies that the DOM elements + * 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 @@ -20088,7 +20506,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { block.scope = childScope; // 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 it's template arrives. + // by a directive with templateUrl when its template arrives. block.clone = clone; nextBlockMap[block.id] = block; }); @@ -20131,6 +20549,11 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * on the element causing it to become hidden. When true, the ng-hide CSS class is removed * from the element causing the element not to appear hidden. * + *
+ * **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):
+ * "f" / "0" / "false" / "no" / "n" / "[]" + *
+ * * ## 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 @@ -20144,26 +20567,21 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * * ### Overriding .ng-hide * - * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by - * restating the styles for the .ng-hide class in CSS: + * 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 then this can be achieved by restating the styles for the `.ng-hide` + * class in CSS: + * * ```css * .ng-hide { - * //!annotate CSS Specificity|Not to worry, this will override the AngularJS default... - * display:block!important; - * * //this is just another form of hiding an element + * display:block!important; * position:absolute; * top:-9999px; * left:-9999px; * } * ``` * - * Just remember to include the important flag so the CSS override will function. - * - *
- * **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):
- * "f" / "0" / "false" / "no" / "n" / "[]" - *
+ * 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 ngShow * @@ -20178,7 +20596,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * // * .my-element.ng-hide-add, .my-element.ng-hide-remove { * transition:0.5s linear all; - * display:block!important; * } * * .my-element.ng-hide-add { ... } @@ -20187,6 +20604,9 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * .my-element.ng-hide-remove.ng-hide-remove-active { ... } * ``` * + * Keep in mind that, as of AngularJS version 1.2.17 (and 1.3.0-beta.11), there is no need to change the display + * property to block during animation states--ngAnimate will handle the style toggling automatically for you. + * * @animations * addClass: .ng-hide - happens after the ngShow expression evaluates to a truthy value and the just before contents are set to visible * removeClass: .ng-hide - happens after the ngShow expression evaluates to a non truthy value and just before the contents are set to hidden @@ -20226,11 +20646,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { background:white; } - .animate-show.ng-hide-add, - .animate-show.ng-hide-remove { - display:block!important; - } - .animate-show.ng-hide { line-height:0; opacity:0; @@ -20281,16 +20696,21 @@ var ngShowDirective = ['$animate', function($animate) { * * ```html * - *
+ *
* * - *
+ *
* ``` * * When the ngHide expression evaluates to true then the .ng-hide CSS class is added to the class attribute * on the element causing it to become hidden. When false, the ng-hide CSS class is removed * from the element causing the element not to appear hidden. * + *
+ * **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):
+ * "f" / "0" / "false" / "no" / "n" / "[]" + *
+ * * ## 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 @@ -20304,33 +20724,27 @@ var ngShowDirective = ['$animate', function($animate) { * * ### Overriding .ng-hide * - * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by - * restating the styles for the .ng-hide class in CSS: + * 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 then this can be achieved by restating the styles for the `.ng-hide` + * class in CSS: + * * ```css * .ng-hide { - * //!annotate CSS Specificity|Not to worry, this will override the AngularJS default... - * display:block!important; - * * //this is just another form of hiding an element + * display:block!important; * position:absolute; * top:-9999px; * left:-9999px; * } * ``` * - * Just remember to include the important flag so the CSS override will function. - * - *
- * **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):
- * "f" / "0" / "false" / "no" / "n" / "[]" - *
+ * 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 you can perform an animation when the element is hidden during the time of the animation. + * is true and false. This system works like the animation system present with ngClass, except that the `.ng-hide` + * CSS class is added and removed for you instead of your own CSS class. * * ```css * // @@ -20338,7 +20752,6 @@ var ngShowDirective = ['$animate', function($animate) { * // * .my-element.ng-hide-add, .my-element.ng-hide-remove { * transition:0.5s linear all; - * display:block!important; * } * * .my-element.ng-hide-add { ... } @@ -20347,6 +20760,9 @@ var ngShowDirective = ['$animate', function($animate) { * .my-element.ng-hide-remove.ng-hide-remove-active { ... } * ``` * + * Keep in mind that, as of AngularJS version 1.2.17 (and 1.3.0-beta.11), there is no need to change the display + * property to block during animation states--ngAnimate will handle the style toggling automatically for you. + * * @animations * removeClass: .ng-hide - happens after the ngHide expression evaluates to a truthy value and just before the contents are set to hidden * addClass: .ng-hide - happens after the ngHide expression evaluates to a non truthy value and just before the contents are set to visible @@ -20386,11 +20802,6 @@ var ngShowDirective = ['$animate', function($animate) { background:white; } - .animate-hide.ng-hide-add, - .animate-hide.ng-hide-remove { - display:block!important; - } - .animate-hide.ng-hide { line-height:0; opacity:0; @@ -20436,14 +20847,20 @@ var ngHideDirective = ['$animate', function($animate) { * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally. * * @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. + * @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 - + +
Sample Text @@ -20459,7 +20876,7 @@ var ngHideDirective = ['$animate', function($animate) { it('should check ng-style', function() { expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)'); - element(by.css('input[value=set]')).click(); + 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)'); @@ -20507,11 +20924,14 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { * leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM * * @usage + * + * ``` * * ... * ... * ... * + * ``` * * * @scope @@ -20528,9 +20948,9 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { * * * @example - + -
+
selection={{selection}} @@ -20544,10 +20964,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
- function Ctrl($scope) { - $scope.items = ['settings', 'home', 'other']; - $scope.selection = $scope.items[0]; - } + angular.module('switchExample', ['ngAnimate']) + .controller('ExampleController', ['$scope', function($scope) { + $scope.items = ['settings', 'home', 'other']; + $scope.selection = $scope.items[0]; + }]); .animate-switch-container { @@ -20590,11 +21011,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { expect(switchElem.getText()).toMatch(/Settings Div/); }); it('should change to home', function() { - select.element.all(by.css('option')).get(1).click(); + select.all(by.css('option')).get(1).click(); expect(switchElem.getText()).toMatch(/Home Span/); }); it('should select default', function() { - select.element.all(by.css('option')).get(2).click(); + select.all(by.css('option')).get(2).click(); expect(switchElem.getText()).toMatch(/default/); }); @@ -20611,37 +21032,29 @@ var ngSwitchDirective = ['$animate', function($animate) { }], link: function(scope, element, attr, ngSwitchController) { var watchExpr = attr.ngSwitch || attr.on, - selectedTranscludes, - selectedElements, - previousElements, + selectedTranscludes = [], + selectedElements = [], + previousElements = [], selectedScopes = []; scope.$watch(watchExpr, function ngSwitchWatchAction(value) { - var i, ii = selectedScopes.length; - if(ii > 0) { - if(previousElements) { - for (i = 0; i < ii; i++) { - previousElements[i].remove(); - } - previousElements = null; - } + var i, ii; + for (i = 0, ii = previousElements.length; i < ii; ++i) { + previousElements[i].remove(); + } + previousElements.length = 0; - previousElements = []; - for (i= 0; i + -
+


{{text}} @@ -20874,21 +21286,22 @@ var ngOptionsMinErr = minErr('ngOptions'); * `value` variable (e.g. `value.propertyName`). * * @example - + -
+
  • Name: @@ -20900,37 +21313,37 @@ var ngOptionsMinErr = minErr('ngOptions');

Color (null not allowed): -
+
Color (null allowed): -
Color grouped by shade: -
- Select bogus.
+ Select bogus.

- Currently selected: {{ {selected_color:color} }} + Currently selected: {{ {selected_color:myColor} }}
+ ng-style="{'background-color':myColor.name}">
it('should check ng-options', function() { - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red'); - element.all(by.select('color')).first().click(); - element.all(by.css('select[ng-model="color"] option')).first().click(); - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black'); - element(by.css('.nullable select[ng-model="color"]')).click(); - element.all(by.css('.nullable select[ng-model="color"] option')).first().click(); - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null'); + 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'); }); @@ -21085,7 +21498,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // we need to work of an array, so we need to see if anything was inserted/removed scope.$watch(function selectMultipleWatch() { if (!equals(lastView, ctrl.$viewValue)) { - lastView = copy(ctrl.$viewValue); + lastView = shallowCopy(ctrl.$viewValue); ctrl.$render(); } }); @@ -21341,6 +21754,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // lastElement.prop('selected') provided by jQuery has side-effects if (existingOption.selected !== option.selected) { lastElement.prop('selected', (existingOption.selected = option.selected)); + if (msie) { + // See #7692 + // The selected item wouldn't visually update on IE without this. + // Tested on Win7: IE9, IE10 and IE11. Future IEs should be tested as well + lastElement.prop('selected', existingOption.selected); + } } } else { // grow elements @@ -21355,7 +21774,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // rather then the element. (element = optionTemplate.clone()) .val(option.id) - .attr('selected', option.selected) + .prop('selected', option.selected) .text(option.label); } @@ -21461,4 +21880,4 @@ var styleDirective = valueFn({ })(window, document); -!angular.$$csp() && angular.element(document).find('head').prepend(''); \ No newline at end of file +!window.angular.$$csp() && window.angular.element(document).find('head').prepend(''); \ No newline at end of file diff --git a/app/bower_components/angular/angular.min.js b/app/bower_components/angular/angular.min.js index 43f31f6..78280c7 100644 --- a/app/bower_components/angular/angular.min.js +++ b/app/bower_components/angular/angular.min.js @@ -1,210 +1,214 @@ /* - AngularJS v1.2.16 + AngularJS v1.2.21 (c) 2010-2014 Google, Inc. http://angularjs.org License: MIT */ -(function(O,U,s){'use strict';function t(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.16/"+(b?b+"/":"")+a;for(c=1;c").append(b).html();try{return 3===b[0].nodeType?K(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/, -function(a,b){return"<"+K(b)})}catch(d){return K(c)}}function Xb(b){try{return decodeURIComponent(b)}catch(a){}}function Yb(b){var a={},c,d;q((b||"").split("&"),function(b){b&&(c=b.split("="),d=Xb(c[0]),B(d)&&(b=B(c[1])?Xb(c[1]):!0,a[d]?M(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Zb(b){var a=[];q(b,function(b,d){M(b)?q(b,function(b){a.push(za(d,!0)+(!0===b?"":"="+za(b,!0)))}):a.push(za(d,!0)+(!0===b?"":"="+za(b,!0)))});return a.length?a.join("&"):""}function wb(b){return za(b, -!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function za(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Wc(b,a){function c(a){a&&d.push(a)}var d=[b],e,g,f=["ng:app","ng-app","x-ng-app","data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;q(f,function(a){f[a]=!0;c(U.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(q(b.querySelectorAll("."+a),c),q(b.querySelectorAll("."+ -a+"\\:"),c),q(b.querySelectorAll("["+a+"]"),c))});q(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):q(a.attributes,function(b){!e&&f[b.name]&&(e=a,g=b.value)})}});e&&a(e,g?[g]:[])}function $b(b,a){var c=function(){b=y(b);if(b.injector()){var c=b[0]===U?"document":ha(b);throw Pa("btstrpd",c);}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=ac(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate", -function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(O&&!d.test(O.name))return c();O.name=O.name.replace(d,"");Ea.resumeBootstrap=function(b){q(b,function(b){a.push(b)});c()}}function fb(b,a){a=a||"_";return b.replace(Xc,function(b,d){return(d?a:"")+b.toLowerCase()})}function xb(b,a,c){if(!b)throw Pa("areq",a||"?",c||"required");return b}function Ra(b,a,c){c&&M(b)&&(b=b[b.length-1]);xb(P(b),a,"not a function, got "+(b&&"object"==typeof b? -b.constructor.name||"Object":typeof b));return b}function Aa(b,a){if("hasOwnProperty"===b)throw Pa("badname",a);}function bc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,g=a.length,f=0;f 
"+e[1]+a.replace(le,"<$1>")+e[2]; -d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a=S?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ia(b){var a=typeof b,c;"object"==a&&null!==b?"function"==typeof(c=b.$$hashKey)?c=b.$$hashKey():c===s&&(c=b.$$hashKey=bb()):c=b;return a+":"+c}function Va(b){q(b,this.put,this)}function oc(b){var a,c;"function"==typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(oe, -""),c=c.match(pe),q(c[1].split(qe),function(b){b.replace(re,function(b,c,d){a.push(d)})})),b.$inject=a):M(b)?(c=b.length-1,Ra(b[c],"fn"),a=b.slice(0,c)):Ra(b,"fn",!0);return a}function ac(b){function a(a){return function(b,c){if(X(b))q(b,Rb(a));else return a(b,c)}}function c(a,b){Aa(a,"service");if(P(b)||M(b))b=n.instantiate(b);if(!b.$get)throw Wa("pget",a);return m[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,g,h;q(a,function(a){if(!k.get(a)){k.put(a,!0);try{if(w(a))for(c= -Sa(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,g=0,h=d.length;g 4096 bytes)!"));else{if(l.cookie!==da)for(da=l.cookie,d=da.split("; "),Q={},g=0;gk&&this.remove(p.key),b},get:function(a){if(k").parent()[0])});var g=L(a,b,a,c,d,e);ma(a,"ng-scope");return function(b,c,d){xb(b,"scope");var e=c?Ja.clone.call(a):a;q(d,function(a,b){e.data("$"+b+"Controller",a)});d=0;for(var f=e.length;darguments.length&& -(b=a,a=s);D&&(c=lb);return p(a,b,c)}var I,x,v,A,R,H,lb={},da;I=c===g?d:Ub(d,new Hb(y(g),d.$attr));x=I.$$element;if(Q){var T=/^\s*([@=&])(\??)\s*(\w*)\s*$/;f=y(g);H=e.$new(!0);ia&&ia===Q.$$originalDirective?f.data("$isolateScope",H):f.data("$isolateScopeNoTemplate",H);ma(f,"ng-isolate-scope");q(Q.scope,function(a,c){var d=a.match(T)||[],g=d[3]||c,f="?"==d[2],d=d[1],l,m,n,p;H.$$isolateBindings[c]=d+g;switch(d){case "@":I.$observe(g,function(a){H[c]=a});I.$$observers[g].$$scope=e;I[g]&&(H[c]=b(I[g])(e)); -break;case "=":if(f&&!I[g])break;m=r(I[g]);p=m.literal?xa:function(a,b){return a===b};n=m.assign||function(){l=H[c]=m(e);throw ja("nonassign",I[g],Q.name);};l=H[c]=m(e);H.$watch(function(){var a=m(e);p(a,H[c])||(p(a,l)?n(e,a=H[c]):H[c]=a);return l=a},null,m.literal);break;case "&":m=r(I[g]);H[c]=function(a){return m(e,a)};break;default:throw ja("iscp",Q.name,c,a);}})}da=p&&u;L&&q(L,function(a){var b={$scope:a===Q||a.$$isolateScope?H:e,$element:x,$attrs:I,$transclude:da},c;R=a.controller;"@"==R&&(R= -I[a.name]);c=z(R,b);lb[a.name]=c;D||x.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});f=0;for(v=l.length;fG.priority)break;if(V=G.scope)A=A||G,G.templateUrl||(K("new/isolated scope",Q,G,Z),X(V)&&(Q=G));t=G.name;!G.templateUrl&&G.controller&&(V=G.controller,L=L||{},K("'"+t+"' controller",L[t],G,Z),L[t]=G);if(V=G.transclude)E=!0,G.$$tlb||(K("transclusion",T,G,Z),T=G),"element"==V?(D=!0,v=G.priority, -V=H(c,ra,W),Z=d.$$element=y(U.createComment(" "+t+": "+d[t]+" ")),c=Z[0],mb(g,y(ya.call(V,0)),c),Xa=x(V,e,v,f&&f.name,{nonTlbTranscludeDirective:T})):(V=y(Eb(c)).contents(),Z.empty(),Xa=x(V,e));if(G.template)if(K("template",ia,G,Z),ia=G,V=P(G.template)?G.template(Z,d):G.template,V=Y(V),G.replace){f=G;V=Cb.test(V)?y(V):[];c=V[0];if(1!=V.length||1!==c.nodeType)throw ja("tplrt",t,"");mb(g,Z,c);S={$attr:{}};V=da(c,[],S);var $=a.splice(N+1,a.length-(N+1));Q&&pc(V);a=a.concat(V).concat($);B(d,S);S=a.length}else Z.html(V); -if(G.templateUrl)K("template",ia,G,Z),ia=G,G.replace&&(f=G),J=C(a.splice(N,a.length-N),Z,d,g,Xa,l,n,{controllerDirectives:L,newIsolateScopeDirective:Q,templateDirective:ia,nonTlbTranscludeDirective:T}),S=a.length;else if(G.compile)try{O=G.compile(Z,d,Xa),P(O)?u(null,O,ra,W):O&&u(O.pre,O.post,ra,W)}catch(aa){m(aa,ha(Z))}G.terminal&&(J.terminal=!0,v=Math.max(v,G.priority))}J.scope=A&&!0===A.scope;J.transclude=E&&Xa;p.hasElementTranscludeDirective=D;return J}function pc(a){for(var b=0,c=a.length;bp.priority)&&-1!=p.restrict.indexOf(g)&&(n&&(p=Tb(p,{$$start:n,$$end:r})),b.push(p),k=p)}catch(F){m(F)}}return k}function B(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;q(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});q(b,function(b,g){"class"==g?(ma(e,b),a["class"]=(a["class"]? -a["class"]+" ":"")+b):"style"==g?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==g.charAt(0)||a.hasOwnProperty(g)||(a[g]=b,d[g]=c[g])})}function C(a,b,c,d,e,g,f,l){var k=[],m,r,z=b[0],u=a.shift(),F=D({},u,{templateUrl:null,transclude:null,replace:null,$$originalDirective:u}),x=P(u.templateUrl)?u.templateUrl(b,c):u.templateUrl;b.empty();n.get(v.getTrustedResourceUrl(x),{cache:p}).success(function(n){var p,J;n=Y(n);if(u.replace){n=Cb.test(n)?y(n):[];p=n[0];if(1!=n.length|| -1!==p.nodeType)throw ja("tplrt",u.name,x);n={$attr:{}};mb(d,b,p);var v=da(p,[],n);X(u.scope)&&pc(v);a=v.concat(a);B(c,n)}else p=z,b.html(n);a.unshift(F);m=ia(a,p,c,e,b,u,g,f,l);q(d,function(a,c){a==p&&(d[c]=b[0])});for(r=L(b[0].childNodes,e);k.length;){n=k.shift();J=k.shift();var A=k.shift(),R=k.shift(),v=b[0];if(J!==z){var H=J.className;l.hasElementTranscludeDirective&&u.replace||(v=Eb(p));mb(A,y(J),v);ma(y(v),H)}J=m.transclude?Q(n,m.transclude):R;m(r,n,v,d,J)}k=null}).error(function(a,b,c,d){throw ja("tpload", -d.url);});return function(a,b,c,d,e){k?(k.push(b),k.push(c),k.push(d),k.push(e)):m(r,b,c,d,e)}}function E(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.namea.status? -b:n.reject(b)}var d={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},g=function(a){function b(a){var c;q(a,function(b,d){P(b)&&(c=b(),null!=c?a[d]=c:delete a[d])})}var c=e.headers,d=D({},a.headers),g,f,c=D({},c.common,c[K(a.method)]);b(c);b(d);a:for(g in c){a=K(g);for(f in d)if(K(f)===a)continue a;d[g]=c[g]}return d}(a);D(d,a);d.headers=g;d.method=Fa(d.method);(a=Ib(d.url)?b.cookies()[d.xsrfCookieName||e.xsrfCookieName]:s)&&(g[d.xsrfHeaderName||e.xsrfHeaderName]= -a);var f=[function(a){g=a.headers;var b=uc(a.data,tc(g),a.transformRequest);E(a.data)&&q(g,function(a,b){"content-type"===K(b)&&delete g[b]});E(a.withCredentials)&&!E(e.withCredentials)&&(a.withCredentials=e.withCredentials);return z(a,b,g).then(c,c)},s],h=n.when(d);for(q(v,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var k=f.shift(),h=h.then(a,k)}h.success=function(a){h.then(function(b){a(b.data, -b.status,b.headers,d)});return h};h.error=function(a){h.then(null,function(b){a(b.data,b.status,b.headers,d)});return h};return h}function z(b,c,g){function f(a,b,c,e){v&&(200<=a&&300>a?v.put(s,[a,b,sc(c),e]):v.remove(s));l(b,a,c,e);d.$$phase||d.$apply()}function l(a,c,d,e){c=Math.max(c,0);(200<=c&&300>c?p.resolve:p.reject)({data:a,status:c,headers:tc(d),config:b,statusText:e})}function k(){var a=db(r.pendingRequests,b);-1!==a&&r.pendingRequests.splice(a,1)}var p=n.defer(),z=p.promise,v,q,s=u(b.url, -b.params);r.pendingRequests.push(b);z.then(k,k);(b.cache||e.cache)&&(!1!==b.cache&&"GET"==b.method)&&(v=X(b.cache)?b.cache:X(e.cache)?e.cache:F);if(v)if(q=v.get(s),B(q)){if(q.then)return q.then(k,k),q;M(q)?l(q[1],q[0],ba(q[2]),q[3]):l(q,200,{},"OK")}else v.put(s,z);E(q)&&a(b.method,s,c,f,g,b.timeout,b.withCredentials,b.responseType);return z}function u(a,b){if(!b)return a;var c=[];Sc(b,function(a,b){null===a||E(a)||(M(a)||(a=[a]),q(a,function(a){X(a)&&(a=qa(a));c.push(za(b)+"="+za(a))}))});0=S&&(!b.match(/^(get|post|head|put|delete|options)$/i)||!O.XMLHttpRequest))return new O.ActiveXObject("Microsoft.XMLHTTP");if(O.XMLHttpRequest)return new O.XMLHttpRequest;throw t("$httpBackend")("noxhr");}function Ud(){this.$get=["$browser","$window","$document",function(b,a,c){return ve(b,ue,b.defer,a.angular.callbacks,c[0])}]}function ve(b,a,c,d,e){function g(a,b){var c=e.createElement("script"),d=function(){c.onreadystatechange= -c.onload=c.onerror=null;e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;S&&8>=S?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=function(){d()};e.body.appendChild(c);return d}var f=-1;return function(e,l,k,m,n,p,r,z){function u(){v=f;A&&A();x&&x.abort()}function F(a,d,e,g,f){L&&c.cancel(L);A=x=null;0===d&&(d=e?200:"file"==sa(l).protocol?404:0);a(1223===d?204:d,e,g,f||"");b.$$completeOutstandingRequest(C)}var v;b.$$incOutstandingRequestCount(); -l=l||b.url();if("jsonp"==K(e)){var J="_"+(d.counter++).toString(36);d[J]=function(a){d[J].data=a};var A=g(l.replace("JSON_CALLBACK","angular.callbacks."+J),function(){d[J].data?F(m,200,d[J].data):F(m,v||-2);d[J]=Ea.noop})}else{var x=a(e);x.open(e,l,!0);q(n,function(a,b){B(a)&&x.setRequestHeader(b,a)});x.onreadystatechange=function(){if(x&&4==x.readyState){var a=null,b=null;v!==f&&(a=x.getAllResponseHeaders(),b="response"in x?x.response:x.responseText);F(m,v||x.status,b,a,x.statusText||"")}};r&&(x.withCredentials= -!0);if(z)try{x.responseType=z}catch(s){if("json"!==z)throw s;}x.send(k||null)}if(0=h&&(n.resolve(r),m(p.$$intervalId),delete e[p.$$intervalId]);z||b.$apply()},f);e[p.$$intervalId]=n;return p}var e={};d.cancel=function(a){return a&&a.$$intervalId in e?(e[a.$$intervalId].reject("canceled"),clearInterval(a.$$intervalId),delete e[a.$$intervalId], -!0):!1};return d}]}function ad(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "), -DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function wc(b){b=b.split("/");for(var a=b.length;a--;)b[a]=wb(b[a]);return b.join("/")}function xc(b,a,c){b=sa(b,c);a.$$protocol= -b.protocol;a.$$host=b.hostname;a.$$port=Y(b.port)||we[b.protocol]||null}function yc(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=sa(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=Yb(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function oa(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Ya(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function Jb(b){return b.substr(0, -Ya(b).lastIndexOf("/")+1)}function zc(b,a){this.$$html5=!0;a=a||"";var c=Jb(b);xc(b,this,b);this.$$parse=function(a){var e=oa(c,a);if(!w(e))throw Kb("ipthprfx",a,c);yc(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Zb(this.$$search),b=this.$$hash?"#"+wb(this.$$hash):"";this.$$url=wc(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e;if((e=oa(b,d))!==s)return d=e,(e=oa(a,e))!==s?c+(oa("/",e)||e):b+d;if((e=oa(c, -d))!==s)return c+e;if(c==d+"/")return c}}function Lb(b,a){var c=Jb(b);xc(b,this,b);this.$$parse=function(d){var e=oa(b,d)||oa(c,d),e="#"==e.charAt(0)?oa(a,e):this.$$html5?e:"";if(!w(e))throw Kb("ihshprfx",d,a);yc(e,this,b);d=this.$$path;var g=/^\/?.*?:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));g.exec(e)||(d=(e=g.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Zb(this.$$search),e=this.$$hash?"#"+wb(this.$$hash):"";this.$$url=wc(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl= -b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(Ya(b)==Ya(a))return a}}function Ac(b,a){this.$$html5=!0;Lb.apply(this,arguments);var c=Jb(b);this.$$rewrite=function(d){var e;if(b==Ya(d))return d;if(e=oa(c,d))return b+a+e;if(c===d+"/")return c}}function nb(b){return function(){return this[b]}}function Bc(b,a){return function(c){if(E(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Vd(){var b="",a=!1;this.hashPrefix=function(a){return B(a)?(b=a,this):b};this.html5Mode= -function(b){return B(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,g){function f(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),a)}var h,l=d.baseHref(),k=d.url();a?(l=k.substring(0,k.indexOf("/",k.indexOf("//")+2))+(l||"/"),e=e.history?zc:Ac):(l=Ya(k),e=Lb);h=new e(l,"#"+b);h.$$parse(h.$$rewrite(k));g.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var b=y(a.target);"a"!==K(b[0].nodeName);)if(b[0]===g[0]||!(b=b.parent())[0])return; -var e=b.prop("href");X(e)&&"[object SVGAnimatedString]"===e.toString()&&(e=sa(e.animVal).href);var f=h.$$rewrite(e);e&&(!b.attr("target")&&f&&!a.isDefaultPrevented())&&(a.preventDefault(),f!=d.url()&&(h.$$parse(f),c.$apply(),O.angular["ff-684208-preventDefault"]=!0))}});h.absUrl()!=k&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$evalAsync(function(){var b=h.absUrl();h.$$parse(a);c.$broadcast("$locationChangeStart",a,b).defaultPrevented?(h.$$parse(b),d.url(b)):f(b)}),c.$$phase|| -c.$digest())});var m=0;c.$watch(function(){var a=d.url(),b=h.$$replace;m&&a==h.absUrl()||(m++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),f(a))}));h.$$replace=!1;return m});return h}]}function Wd(){var b=!0,a=this;this.debugEnabled=function(a){return B(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack: -a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||C;a=!1;try{a=!!e.apply}catch(l){}return a?function(){var a=[];q(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function fa(b,a){if("constructor"===b)throw Ba("isecfld",a);return b}function Za(b, -a){if(b){if(b.constructor===b)throw Ba("isecfn",a);if(b.document&&b.location&&b.alert&&b.setInterval)throw Ba("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw Ba("isecdom",a);}return b}function ob(b,a,c,d,e){e=e||{};a=a.split(".");for(var g,f=0;1e?Cc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,g){var f=0,h;do h=Cc(d[f++],d[f++],d[f++],d[f++],d[f++],c,a)(b,g),g=s,b=h;while(fa)for(b in l++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(q--,delete e[b])}else e!==d&&(e=d,l++);return l},function(){p?(p=!1,b(d,d,c)):b(d,f,c);if(h)if(X(d))if(ab(d)){f=Array(d.length);for(var a=0;as&&(y=4-s,Q[y]||(Q[y]=[]),H=P(d.exp)?"fn: "+(d.exp.name||d.exp.toString()):d.exp,H+="; newVal: "+qa(g)+"; oldVal: "+qa(f),Q[y].push(H));else if(d===c){x=!1;break a}}catch(w){p.$$phase= -null,e(w)}if(!(h=L.$$childHead||L!==this&&L.$$nextSibling))for(;L!==this&&!(h=L.$$nextSibling);)L=L.$parent}while(L=h);if((x||k.length)&&!s--)throw p.$$phase=null,a("infdig",b,qa(Q));}while(x||k.length);for(p.$$phase=null;m.length;)try{m.shift()()}catch(T){e(T)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==p&&(q(this.$$listenerCount,eb(null,m,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&& -(a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling),this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=C,this.$on=this.$watch=function(){return C})}},$eval:function(a,b){return g(a)(this,b)},$evalAsync:function(a){p.$$phase|| -p.$$asyncQueue.length||f.defer(function(){p.$$asyncQueue.length&&p.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return l("$apply"),this.$eval(a)}catch(b){e(b)}finally{p.$$phase=null;try{p.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent); -var e=this;return function(){c[db(c,b)]=null;m(e,1,a)}},$emit:function(a,b){var c=[],d,g=this,f=!1,h={name:a,targetScope:g,stopPropagation:function(){f=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},l=[h].concat(ya.call(arguments,1)),k,m;do{d=g.$$listeners[a]||c;h.currentScope=g;k=0;for(m=d.length;kc.msieDocumentMode)throw ua("iequirks");var e=ba(ga);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},e.valueOf=Da);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b, -d(a,c))}};var g=e.parseAs,f=e.getTrusted,h=e.trustAs;q(ga,function(a,b){var c=K(b);e[Ta("parse_as_"+c)]=function(b){return g(a,b)};e[Ta("get_trusted_"+c)]=function(b){return f(a,b)};e[Ta("trust_as_"+c)]=function(b){return h(a,b)}});return e}]}function be(){this.$get=["$window","$document",function(b,a){var c={},d=Y((/android (\d+)/.exec(K((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),g=a[0]||{},f=g.documentMode,h,l=/^(Moz|webkit|O|ms)(?=[A-Z])/,k=g.body&&g.body.style, -m=!1,n=!1;if(k){for(var p in k)if(m=l.exec(p)){h=m[0];h=h.substr(0,1).toUpperCase()+h.substr(1);break}h||(h="WebkitOpacity"in k&&"webkit");m=!!("transition"in k||h+"Transition"in k);n=!!("animation"in k||h+"Animation"in k);!d||m&&n||(m=w(g.body.style.webkitTransition),n=w(g.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!f||7b;b=Math.abs(b);var f=b+"",h="",l=[],k=!1;if(-1!==f.indexOf("e")){var m=f.match(/([\d\.]+)e(-?)(\d+)/);m&&"-"==m[2]&&m[3]>e+1?f="0":(h=f,k=!0)}if(k)0b)&&(h=b.toFixed(e)); -else{f=(f.split(Nc)[1]||"").length;E(e)&&(e=Math.min(Math.max(a.minFrac,f),a.maxFrac));f=Math.pow(10,e);b=Math.round(b*f)/f;b=(""+b).split(Nc);f=b[0];b=b[1]||"";var m=0,n=a.lgSize,p=a.gSize;if(f.length>=n+p)for(m=f.length-n,k=0;kb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Ob(e,a,d)}}function pb(b,a){return function(c,d){var e=c["get"+b](),g=Fa(a?"SHORT"+b:b);return d[g][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var g=0,f=0,h=b[8]?a.setUTCFullYear:a.setFullYear,l=b[8]?a.setUTCHours:a.setHours;b[9]&&(g=Y(b[9]+b[10]),f=Y(b[9]+b[11])); -h.call(a,Y(b[1]),Y(b[2])-1,Y(b[3]));g=Y(b[4]||0)-g;f=Y(b[5]||0)-f;h=Y(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));l.call(a,g,f,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var g="",f=[],h,l;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;w(c)&&(c=Ge.test(c)?Y(c):a(c));vb(c)&&(c=new Date(c));if(!Na(c))return c;for(;e;)(l=He.exec(e))?(f=f.concat(ya.call(l,1)),e=f.pop()):(f.push(e),e=null);q(f,function(a){h= -Ie[a];g+=h?h(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function Ce(){return function(b){return qa(b,!0)}}function De(){return function(b,a){if(!M(b)&&!w(b))return b;a=Y(a);if(w(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0a||37<=a&&40>=a)||m()});if(e.hasEvent("paste"))a.on("paste cut",m)}a.on("change",l);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)? -"":d.$viewValue)};var n=c.ngPattern;n&&((e=n.match(/^\/(.*)\/([gim]*)$/))?(n=RegExp(e[1],e[2]),e=function(a){return pa(d,"pattern",d.$isEmpty(a)||n.test(a),a)}):e=function(c){var e=b.$eval(n);if(!e||!e.test)throw t("ngPattern")("noregexp",n,e,ha(a));return pa(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var p=Y(c.ngMinlength);e=function(a){return pa(d,"minlength",d.$isEmpty(a)||a.length>=p,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var r= -Y(c.ngMaxlength);e=function(a){return pa(d,"maxlength",d.$isEmpty(a)||a.length<=r,a)};d.$parsers.push(e);d.$formatters.push(e)}}function Pb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;dS?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Fa(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Xc=/[A-Z]/g,$c={full:"1.2.16",major:1,minor:2,dot:16,codeName:"badger-enumeration"},Ua=N.cache={},gb=N.expando="ng-"+(new Date).getTime(), -me=1,Pc=O.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},Fb=O.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};N._data=function(b){return this.cache[b[this.expando]]||{}};var he=/([\:\-\_]+(.))/g,ie=/^moz([A-Z])/,Bb=t("jqLite"),je=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Cb=/<|&#?\w+;/,ke=/<([\w:]+)/,le=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ea= -{option:[1,'"],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ea.optgroup=ea.option;ea.tbody=ea.tfoot=ea.colgroup=ea.caption=ea.thead;ea.th=ea.td;var Ja=N.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===U.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),N(O).on("load",a))},toString:function(){var b= -[];q(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?y(this[b]):y(this[this.length+b])},length:0,push:Ke,sort:[].sort,splice:[].splice},kb={};q("multiple selected checked disabled readOnly required open".split(" "),function(b){kb[K(b)]=b});var nc={};q("input select option textarea button form details".split(" "),function(b){nc[Fa(b)]=!0});q({data:jc,inheritedData:jb,scope:function(b){return y(b).data("$scope")||jb(b.parentNode||b,["$isolateScope","$scope"])}, -isolateScope:function(b){return y(b).data("$isolateScope")||y(b).data("$isolateScopeNoTemplate")},controller:kc,injector:function(b){return jb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Gb,css:function(b,a,c){a=Ta(a);if(B(c))b.style[a]=c;else{var d;8>=S&&(d=b.currentStyle&&b.currentStyle[a],""===d&&(d="auto"));d=d||b.style[a];8>=S&&(d=""===d?s:d);return d}},attr:function(b,a,c){var d=K(a);if(kb[d])if(B(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d)); -else return b[a]||(b.attributes.getNamedItem(a)||C).specified?d:s;else if(B(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?s:b},prop:function(b,a,c){if(B(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(E(d))return e?b[e]:"";b[e]=d}var a=[];9>S?(a[1]="innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(E(a)){if("SELECT"===Ka(b)&&b.multiple){var c=[];q(b.options,function(a){a.selected&& -c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(E(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Ne={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'}, -Nb=function(a){this.options=a};Nb.prototype={constructor:Nb,lex:function(a){this.text=a;this.index=0;this.ch=s;this.lastCh=":";this.tokens=[];var c;for(a=[];this.index=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"=== -a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=B(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw Ba("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn($a.ZERO,a.fn, -this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Dc(d,this.options,this.text);return D(function(c,d,h){return e(h||a(c,d))},{assign:function(e,f,h){return ob(a(e,h),d,f,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return D(function(e,g){var f=a(e,g),h=d(e,g),l;if(!f)return s;(f=Za(f[h],c.text))&&(f.then&&c.options.unwrapPromises)&&(l=f,"$$v"in f||(l.$$v=s,l.then(function(a){l.$$v= -a})),f=f.$$v);return f},{assign:function(e,g,f){var h=d(e,f);return Za(a(e,f),c.text)[h]=g}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(g,f){for(var h=[],l=c?c(g,f):g,k=0;ka.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Ob(Math[0=S&&(c.href||c.name||c.$set("href",""),a.append(U.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var g="[object SVGAnimatedString]"===wa.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(g)||a.preventDefault()})}}}),zb={};q(kb,function(a,c){if("multiple"!=a){var d=na("ng-"+c);zb[d]=function(){return{priority:100,link:function(a,g,f){a.$watch(f[d],function(a){f.$set(c,!!a)})}}}}});q(["src", -"srcset","href"],function(a){var c=na("ng-"+a);zb[c]=function(){return{priority:99,link:function(d,e,g){var f=a,h=a;"href"===a&&"[object SVGAnimatedString]"===wa.call(e.prop("href"))&&(h="xlinkHref",g.$attr[h]="xlink:href",f=null);g.$observe(c,function(a){a&&(g.$set(h,a),S&&f&&e.prop(f,g[h]))})}}}});var sb={$addControl:C,$removeControl:C,$setValidity:C,$setDirty:C,$setPristine:C};Oc.$inject=["$element","$attrs","$scope","$animate"];var Qc=function(a){return["$timeout",function(c){return{name:"form", -restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,g,f){if(!g.action){var h=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};Pc(e[0],"submit",h);e.on("$destroy",function(){c(function(){Fb(e[0],"submit",h)},0,!1)})}var l=e.parent().controller("form"),k=g.name||g.ngForm;k&&ob(a,k,f,k);if(l)e.on("$destroy",function(){l.$removeControl(f);k&&ob(a,k,s,k);D(f,sb)})}}}}}]},dd=Qc(),qd=Qc(!0),Oe=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/, -Pe=/^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i,Qe=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Rc={text:ub,number:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Qe.test(a))return e.$setValidity("number",!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return s});Je(e,"number",c);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return pa(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a), -e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return pa(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return pa(e,"number",e.$isEmpty(a)||vb(a),a)})},url:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);a=function(a){return pa(e,"url",e.$isEmpty(a)||Oe.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);a=function(a){return pa(e,"email",e.$isEmpty(a)||Pe.test(a),a)};e.$formatters.push(a); -e.$parsers.push(a)},radio:function(a,c,d,e){E(d.name)&&c.attr("name",bb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var g=d.ngTrueValue,f=d.ngFalseValue;w(g)||(g=!0);w(f)||(f=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==g}; -e.$formatters.push(function(a){return a===g});e.$parsers.push(function(a){return a?g:f})},hidden:C,button:C,submit:C,reset:C,file:C},dc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,g,f){f&&(Rc[K(g.type)]||Rc.text)(d,e,g,f,c,a)}}}],rb="ng-valid",qb="ng-invalid",La="ng-pristine",tb="ng-dirty",Re=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,g,f){function h(a,c){c=c?"-"+fb(c,"-"):"";f.removeClass(e,(a?qb:rb)+c); -f.addClass(e,(a?rb:qb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var l=g(d.ngModel),k=l.assign;if(!k)throw t("ngModel")("nonassign",d.ngModel,ha(e));this.$render=C;this.$isEmpty=function(a){return E(a)||""===a||null===a||a!==a};var m=e.inheritedData("$formController")||sb,n=0,p=this.$error={};e.addClass(La);h(!0);this.$setValidity=function(a,c){p[a]!== -!c&&(c?(p[a]&&n--,n||(h(!0),this.$valid=!0,this.$invalid=!1)):(h(!1),this.$invalid=!0,this.$valid=!1,n++),p[a]=!c,h(c,a),m.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine=!0;f.removeClass(e,tb);f.addClass(e,La)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,f.removeClass(e,La),f.addClass(e,tb),m.$setDirty());q(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,k(a,d),q(this.$viewChangeListeners, -function(a){try{a()}catch(d){c(d)}}))};var r=this;a.$watch(function(){var c=l(a);if(r.$modelValue!==c){var d=r.$formatters,e=d.length;for(r.$modelValue=c;e--;)c=d[e](c);r.$viewValue!==c&&(r.$viewValue=c,r.$render())}return c})}],Fd=function(){return{require:["ngModel","^?form"],controller:Re,link:function(a,c,d,e){var g=e[0],f=e[1]||sb;f.$addControl(g);a.$on("$destroy",function(){f.$removeControl(g)})}}},Hd=aa({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}), -ec=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var g=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(g);e.$parsers.unshift(g);d.$observe("required",function(){g(e.$viewValue)})}}}},Gd=function(){return{require:"ngModel",link:function(a,c,d,e){var g=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!E(a)){var c=[];a&&q(a.split(g),function(a){a&& -c.push(ca(a))});return c}});e.$formatters.push(function(a){return M(a)?a.join(", "):s});e.$isEmpty=function(a){return!a||!a.length}}}},Se=/^(true|false|\d+)$/,Id=function(){return{priority:100,compile:function(a,c){return Se.test(c.ngValue)?function(a,c,g){g.$set("value",a.$eval(g.ngValue))}:function(a,c,g){a.$watch(g.ngValue,function(a){g.$set("value",a)})}}}},id=va(function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==s?"":a)})}),kd=["$interpolate", -function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],jd=["$sce","$parse",function(a,c){return function(d,e,g){e.addClass("ng-binding").data("$binding",g.ngBindHtml);var f=c(g.ngBindHtml);d.$watch(function(){return(f(d)||"").toString()},function(c){e.html(a.getTrustedHtml(f(d))||"")})}}],ld=Pb("",!0),nd=Pb("Odd",0),md=Pb("Even",1),od=va({compile:function(a,c){c.$set("ngCloak",s);a.removeClass("ng-cloak")}}), -pd=[function(){return{scope:!0,controller:"@",priority:500}}],fc={};q("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var c=na("ng-"+a);fc[c]=["$parse",function(d){return{compile:function(e,g){var f=d(g[c]);return function(c,d,e){d.on(K(a),function(a){c.$apply(function(){f(c,{$event:a})})})}}}}]});var sd=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A", -$$tlb:!0,link:function(c,d,e,g,f){var h,l,k;c.$watch(e.ngIf,function(g){Qa(g)?l||(l=c.$new(),f(l,function(c){c[c.length++]=U.createComment(" end ngIf: "+e.ngIf+" ");h={clone:c};a.enter(c,d.parent(),d)})):(k&&(k.remove(),k=null),l&&(l.$destroy(),l=null),h&&(k=yb(h.clone),a.leave(k,function(){k=null}),h=null))})}}}],td=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,g){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Ea.noop,compile:function(f, -h){var l=h.ngInclude||h.src,k=h.onload||"",m=h.autoscroll;return function(f,h,q,s,u){var F=0,v,y,A,x=function(){y&&(y.remove(),y=null);v&&(v.$destroy(),v=null);A&&(e.leave(A,function(){y=null}),y=A,A=null)};f.$watch(g.parseAsResourceUrl(l),function(g){var l=function(){!B(m)||m&&!f.$eval(m)||d()},q=++F;g?(a.get(g,{cache:c}).success(function(a){if(q===F){var c=f.$new();s.template=a;a=u(c,function(a){x();e.enter(a,null,h,l)});v=c;A=a;v.$emit("$includeContentLoaded");f.$eval(k)}}).error(function(){q=== -F&&x()}),f.$emit("$includeContentRequested")):(x(),s.template=null)})}}}}],Jd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(c,d,e,g){d.html(g.template);a(d.contents())(c)}}}],ud=va({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),vd=va({terminal:!0,priority:1E3}),wd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,g,f){var h=f.count,l=f.$attr.when&&g.attr(f.$attr.when),k=f.offset|| -0,m=e.$eval(l)||{},n={},p=c.startSymbol(),r=c.endSymbol(),s=/^when(Minus)?(.+)$/;q(f,function(a,c){s.test(c)&&(m[K(c.replace("when","").replace("Minus","-"))]=g.attr(f.$attr[c]))});q(m,function(a,e){n[e]=c(a.replace(d,p+h+"-"+k+r))});e.$watch(function(){var c=parseFloat(e.$eval(h));if(isNaN(c))return"";c in m||(c=a.pluralCat(c-k));return n[c](e,g,!0)},function(a){g.text(a)})}}}],xd=["$parse","$animate",function(a,c){var d=t("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0, -link:function(e,g,f,h,l){var k=f.ngRepeat,m=k.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,p,r,s,u,F,v={$id:Ia};if(!m)throw d("iexp",k);f=m[1];h=m[2];(m=m[3])?(n=a(m),p=function(a,c,d){F&&(v[F]=a);v[u]=c;v.$index=d;return n(e,v)}):(r=function(a,c){return Ia(c)},s=function(a){return a});m=f.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!m)throw d("iidexp",f);u=m[3]||m[1];F=m[2];var B={};e.$watchCollection(h,function(a){var f,h,m=g[0],n,v={},H,R,w,C,T,t, -E=[];if(ab(a))T=a,n=p||r;else{n=p||s;T=[];for(w in a)a.hasOwnProperty(w)&&"$"!=w.charAt(0)&&T.push(w);T.sort()}H=T.length;h=E.length=T.length;for(f=0;fA;)z.pop().element.remove()}for(;x.length>I;)x.pop()[0].element.remove()}var k;if(!(k=t.match(d)))throw Te("iexp",t,ha(f));var l=c(k[2]||k[1]),m=k[4]||k[6],n=k[5],p=c(k[3]||""),q= -c(k[2]?k[1]:m),y=c(k[7]),w=k[8]?c(k[8]):null,x=[[{element:f,label:""}]];u&&(a(u)(e),u.removeClass("ng-scope"),u.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=y(e)||[],d={},h,k,l,p,t,v,u;if(r)for(k=[],p=0,v=x.length;p@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}'); +(function(P,W,s){'use strict';function y(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.21/"+(b?b+"/":"")+a;for(c=1;c").append(b).html();try{return 3===b[0].nodeType?K(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+K(b)})}catch(d){return K(c)}}function dc(b){try{return decodeURIComponent(b)}catch(a){}}function ec(b){var a={},c,d;q((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g,"%20").split("="),d=dc(c[0]),B(d)&&(b=B(c[1])?dc(c[1]):!0,hb.call(a,d)?I(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Cb(b){var a=[];q(b,function(b,d){I(b)?q(b,function(b){a.push(Ba(d, +!0)+(!0===b?"":"="+Ba(b,!0)))}):a.push(Ba(d,!0)+(!0===b?"":"="+Ba(b,!0)))});return a.length?a.join("&"):""}function ib(b){return Ba(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Ba(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Xc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,g=["ng:app","ng-app","x-ng-app","data-ng-app"],k=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/; +q(g,function(a){g[a]=!0;c(W.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(q(b.querySelectorAll("."+a),c),q(b.querySelectorAll("."+a+"\\:"),c),q(b.querySelectorAll("["+a+"]"),c))});q(d,function(a){if(!e){var b=k.exec(" "+a.className+" ");b?(e=a,f=(b[2]||"").replace(/\s+/g,",")):q(a.attributes,function(b){!e&&g[b.name]&&(e=a,f=b.value)})}});e&&a(e,f?[f]:[])}function fc(b,a){var c=function(){b=x(b);if(b.injector()){var c=b[0]===W?"document":ha(b);throw Ra("btstrpd",c);}a=a||[];a.unshift(["$provide", +function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=gc(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate",function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(P&&!d.test(P.name))return c();P.name=P.name.replace(d,"");Ta.resumeBootstrap=function(b){q(b,function(b){a.push(b)});c()}}function jb(b,a){a=a||"_";return b.replace(Yc,function(b,d){return(d?a:"")+b.toLowerCase()})}function Db(b,a,c){if(!b)throw Ra("areq", +a||"?",c||"required");return b}function Ua(b,a,c){c&&I(b)&&(b=b[b.length-1]);Db(C(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function Ca(b,a){if("hasOwnProperty"===b)throw Ra("badname",a);}function hc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g 
"+e[1]+a.replace(me,"<$1>")+e[2];d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a=Q?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ka(b,a){var c=typeof b,d;"function"==c||"object"==c&&null!==b?"function"==typeof(d=b.$$hashKey)?d=b.$$hashKey():d===s&&(d=b.$$hashKey=(a||fb)()): +d=b;return c+":"+d}function $a(b,a){if(a){var c=0;this.nextUid=function(){return++c}}q(b,this.put,this)}function sc(b){var a,c;"function"===typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(pe,""),c=c.match(qe),q(c[1].split(re),function(b){b.replace(se,function(b,c,d){a.push(d)})})),b.$inject=a):I(b)?(c=b.length-1,Ua(b[c],"fn"),a=b.slice(0,c)):Ua(b,"fn",!0);return a}function gc(b){function a(a){return function(b,c){if(S(b))q(b,$b(a));else return a(b,c)}}function c(a,b){Ca(a,"service"); +if(C(b)||I(b))b=p.instantiate(b);if(!b.$get)throw ab("pget",a);return l[a+k]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,f,k;q(a,function(a){if(!h.get(a)){h.put(a,!0);try{if(z(a))for(c=Wa(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,f=0,k=d.length;f 4096 bytes)!"));else{if(m.cookie!==ea)for(ea=m.cookie,d=ea.split("; "),T={},f=0;fh&&this.remove(n.key),b},get:function(a){if(h").parent()[0])}); +var f=J(a,b,a,c,d,e);da(a,"ng-scope");return function(b,c,d,e){Db(b,"scope");var g=c?La.clone.call(a):a;q(d,function(a,b){g.data("$"+b+"Controller",a)});d=0;for(var m=g.length;darguments.length&&(b=a,a=s);Ea&&(c=ea);return n(a,b,c)}var u,N,A,E,T,O,ea={},pb;u=c===f?d:ga(d,new Ob(x(f),d.$attr));N=u.$$element;if(J){var ca=/^\s*([@=&])(\??)\s*(\w*)\s*$/; +O=e.$new(!0);!H||H!==J&&H!==J.$$originalDirective?N.data("$isolateScopeNoTemplate",O):N.data("$isolateScope",O);da(N,"ng-isolate-scope");q(J.scope,function(a,c){var d=a.match(ca)||[],f=d[3]||c,g="?"==d[2],d=d[1],m,l,p,n;O.$$isolateBindings[c]=d+f;switch(d){case "@":u.$observe(f,function(a){O[c]=a});u.$$observers[f].$$scope=e;u[f]&&(O[c]=b(u[f])(e));break;case "=":if(g&&!u[f])break;l=r(u[f]);n=l.literal?za:function(a,b){return a===b};p=l.assign||function(){m=O[c]=l(e);throw ia("nonassign",u[f],J.name); +};m=O[c]=l(e);O.$watch(function(){var a=l(e);n(a,O[c])||(n(a,m)?p(e,a=O[c]):O[c]=a);return m=a},null,l.literal);break;case "&":l=r(u[f]);O[c]=function(a){return l(e,a)};break;default:throw ia("iscp",J.name,c,a);}})}pb=n&&w;X&&q(X,function(a){var b={$scope:a===J||a.$$isolateScope?O:e,$element:N,$attrs:u,$transclude:pb},c;T=a.controller;"@"==T&&(T=u[a.name]);c=t(T,b);ea[a.name]=c;Ea||N.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});g=0;for(A=m.length;gG.priority)break;if(U=G.scope)T=T||G,G.templateUrl||(K("new/isolated scope",J,G,y),S(U)&&(J=G));na=G.name;!G.templateUrl&&G.controller&&(U=G.controller,X=X||{},K("'"+na+"' controller",X[na],G,y),X[na]=G);if(U=G.transclude)v=!0,G.$$tlb||(K("transclusion",ca,G,y),ca=G),"element"==U?(Ea=!0,u=G.priority,U=y,y=d.$$element=x(W.createComment(" "+na+": "+d[na]+" ")),c=y[0],qb(f,Aa.call(U,0),c),R=A(U,e,u, +g&&g.name,{nonTlbTranscludeDirective:ca})):(U=x(Kb(c)).contents(),y.empty(),R=A(U,e));if(G.template)if(F=!0,K("template",H,G,y),H=G,U=C(G.template)?G.template(y,d):G.template,U=Z(U),G.replace){g=G;U=Ib.test(U)?x(aa(U)):[];c=U[0];if(1!=U.length||1!==c.nodeType)throw ia("tplrt",na,"");qb(f,y,c);oa={$attr:{}};U=ea(c,[],oa);var $=a.splice(P+1,a.length-(P+1));J&&ob(U);a=a.concat(U).concat($);B(d,oa);oa=a.length}else y.html(U);if(G.templateUrl)F=!0,K("template",H,G,y),H=G,G.replace&&(g=G),M=D(a.splice(P, +a.length-P),y,d,f,v&&R,m,p,{controllerDirectives:X,newIsolateScopeDirective:J,templateDirective:H,nonTlbTranscludeDirective:ca}),oa=a.length;else if(G.compile)try{Q=G.compile(y,d,R),C(Q)?w(null,Q,V,Y):Q&&w(Q.pre,Q.post,V,Y)}catch(ba){l(ba,ha(y))}G.terminal&&(M.terminal=!0,u=Math.max(u,G.priority))}M.scope=T&&!0===T.scope;M.transcludeOnThisElement=v;M.templateOnThisElement=F;M.transclude=R;n.hasElementTranscludeDirective=Ea;return M}function ob(a){for(var b=0,c=a.length;bn.priority)&&-1!=n.restrict.indexOf(f)&&(r&&(n=bc(n,{$$start:r,$$end:p})),b.push(n),h=n)}catch(L){l(L)}}return h}function B(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;q(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});q(b,function(b,f){"class"==f?(da(e,b),a["class"]=(a["class"]?a["class"]+" ": +"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function D(a,b,c,d,e,f,g,m){var h=[],l,r,t=b[0],w=a.shift(),L=F({},w,{templateUrl:null,transclude:null,replace:null,$$originalDirective:w}),M=C(w.templateUrl)?w.templateUrl(b,c):w.templateUrl;b.empty();p.get(u.getTrustedResourceUrl(M),{cache:n}).success(function(p){var n,u;p=Z(p);if(w.replace){p=Ib.test(p)?x(aa(p)):[];n=p[0];if(1!=p.length||1!==n.nodeType)throw ia("tplrt", +w.name,M);p={$attr:{}};qb(d,b,n);var A=ea(n,[],p);S(w.scope)&&ob(A);a=A.concat(a);B(c,p)}else n=t,b.html(p);a.unshift(L);l=H(a,n,c,e,b,w,f,g,m);q(d,function(a,c){a==n&&(d[c]=b[0])});for(r=J(b[0].childNodes,e);h.length;){p=h.shift();u=h.shift();var E=h.shift(),X=h.shift(),A=b[0];if(u!==t){var O=u.className;m.hasElementTranscludeDirective&&w.replace||(A=Kb(n));qb(E,x(u),A);da(x(A),O)}u=l.transcludeOnThisElement?T(p,l.transclude,X):X;l(r,p,A,d,u)}h=null}).error(function(a,b,c,d){throw ia("tpload",d.url); +});return function(a,b,c,d,e){a=e;h?(h.push(b),h.push(c),h.push(d),h.push(a)):(l.transcludeOnThisElement&&(a=T(b,l.transclude,e)),l(r,b,c,d,a))}}function v(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.namea.status?d:p.reject(d)}var c={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},d=function(a){var b=e.headers,c=F({},a.headers),d,f,b=F({},b.common,b[K(a.method)]);a:for(d in b){a=K(d);for(f in c)if(K(f)===a)continue a;c[d]=b[d]}(function(a){var b;q(a,function(c,d){C(c)&&(b=c(),null!=b?a[d]=b:delete a[d])})})(c);return c}(a); +F(c,a);c.headers=d;c.method=Ia(c.method);var f=[function(a){d=a.headers;var c=xc(a.data,wc(d),a.transformRequest);v(c)&&q(d,function(a,b){"content-type"===K(b)&&delete d[b]});v(a.withCredentials)&&!v(e.withCredentials)&&(a.withCredentials=e.withCredentials);return t(a,c,d).then(b,b)},s],g=p.when(c);for(q(u,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var m=f.shift(),g=g.then(a, +m)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,c)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,c)});return g};return g}function t(c,f,g){function h(a,b,c,e){E&&(200<=a&&300>a?E.put(x,[a,b,vc(c),e]):E.remove(x));n(b,a,c,e);d.$$phase||d.$apply()}function n(a,b,d,e){b=Math.max(b,0);(200<=b&&300>b?u.resolve:u.reject)({data:a,status:b,headers:wc(d),config:c,statusText:e})}function t(){var a=Pa(r.pendingRequests,c);-1!==a&&r.pendingRequests.splice(a, +1)}var u=p.defer(),q=u.promise,E,H,x=L(c.url,c.params);r.pendingRequests.push(c);q.then(t,t);(c.cache||e.cache)&&(!1!==c.cache&&"GET"==c.method)&&(E=S(c.cache)?c.cache:S(e.cache)?e.cache:w);if(E)if(H=E.get(x),B(H)){if(H&&C(H.then))return H.then(t,t),H;I(H)?n(H[1],H[0],ga(H[2]),H[3]):n(H,200,{},"OK")}else E.put(x,q);v(H)&&((H=Pb(c.url)?b.cookies()[c.xsrfCookieName||e.xsrfCookieName]:s)&&(g[c.xsrfHeaderName||e.xsrfHeaderName]=H),a(c.method,x,f,h,g,c.timeout,c.withCredentials,c.responseType));return q} +function L(a,b){if(!b)return a;var c=[];Tc(b,function(a,b){null===a||v(a)||(I(a)||(a=[a]),q(a,function(a){S(a)&&(sa(a)?a=a.toISOString():S(a)&&(a=ta(a)));c.push(Ba(b)+"="+Ba(a))}))});0=Q&&(!b.match(/^(get|post|head|put|delete|options)$/i)||!P.XMLHttpRequest))return new P.ActiveXObject("Microsoft.XMLHTTP");if(P.XMLHttpRequest)return new P.XMLHttpRequest;throw y("$httpBackend")("noxhr");}function Vd(){this.$get= +["$browser","$window","$document",function(b,a,c){return we(b,ve,b.defer,a.angular.callbacks,c[0])}]}function we(b,a,c,d,e){function f(a,b,c){var f=e.createElement("script"),g=null;f.type="text/javascript";f.src=a;f.async=!0;g=function(a){Ya(f,"load",g);Ya(f,"error",g);e.body.removeChild(f);f=null;var k=-1,t="unknown";a&&("load"!==a.type||d[b].called||(a={type:"error"}),t=a.type,k="error"===a.type?404:200);c&&c(k,t)};rb(f,"load",g);rb(f,"error",g);8>=Q&&(f.onreadystatechange=function(){z(f.readyState)&& +/loaded|complete/.test(f.readyState)&&(f.onreadystatechange=null,g({type:"load"}))});e.body.appendChild(f);return g}var g=-1;return function(e,m,h,l,p,n,r,t){function L(){u=g;X&&X();A&&A.abort()}function w(a,d,e,f,g){J&&c.cancel(J);X=A=null;0===d&&(d=e?200:"file"==ua(m).protocol?404:0);a(1223===d?204:d,e,f,g||"");b.$$completeOutstandingRequest(D)}var u;b.$$incOutstandingRequestCount();m=m||b.url();if("jsonp"==K(e)){var M="_"+(d.counter++).toString(36);d[M]=function(a){d[M].data=a;d[M].called=!0}; +var X=f(m.replace("JSON_CALLBACK","angular.callbacks."+M),M,function(a,b){w(l,a,d[M].data,"",b);d[M]=D})}else{var A=a(e);A.open(e,m,!0);q(p,function(a,b){B(a)&&A.setRequestHeader(b,a)});A.onreadystatechange=function(){if(A&&4==A.readyState){var a=null,b=null,c="";u!==g&&(a=A.getAllResponseHeaders(),b="response"in A?A.response:A.responseText);u===g&&10>Q||(c=A.statusText);w(l,u||A.status,b,a,c)}};r&&(A.withCredentials=!0);if(t)try{A.responseType=t}catch(da){if("json"!==t)throw da;}A.send(h||null)}if(0< +n)var J=c(L,n);else n&&C(n.then)&&n.then(L)}}function Sd(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse","$exceptionHandler","$sce",function(c,d,e){function f(f,h,l){for(var p,n,r=0,t=[],L=f.length,w=!1,u=[];r=k&&(p.resolve(r),l(n.$$intervalId),delete e[n.$$intervalId]);t||b.$apply()},g);e[n.$$intervalId]=p;return n}var e={};d.cancel=function(b){return b&&b.$$intervalId in e?(e[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),delete e[b.$$intervalId],!0):!1};return d}]} +function bd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "), +DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function Qb(b){b=b.split("/");for(var a=b.length;a--;)b[a]=ib(b[a]);return b.join("/")}function zc(b,a,c){b=ua(b,c);a.$$protocol= +b.protocol;a.$$host=b.hostname;a.$$port=Z(b.port)||xe[b.protocol]||null}function Ac(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=ua(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=ec(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function pa(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function bb(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function Rb(b){return b.substr(0, +bb(b).lastIndexOf("/")+1)}function Bc(b,a){this.$$html5=!0;a=a||"";var c=Rb(b);zc(b,this,b);this.$$parse=function(a){var e=pa(c,a);if(!z(e))throw Sb("ipthprfx",a,c);Ac(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Cb(this.$$search),b=this.$$hash?"#"+ib(this.$$hash):"";this.$$url=Qb(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e;if((e=pa(b,d))!==s)return d=e,(e=pa(a,e))!==s?c+(pa("/",e)||e):b+d;if((e=pa(c, +d))!==s)return c+e;if(c==d+"/")return c}}function Tb(b,a){var c=Rb(b);zc(b,this,b);this.$$parse=function(d){var e=pa(b,d)||pa(c,d),e="#"==e.charAt(0)?pa(a,e):this.$$html5?e:"";if(!z(e))throw Sb("ihshprfx",d,a);Ac(e,this,b);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash?"#"+ib(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl= +b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(bb(b)==bb(a))return a}}function Ub(b,a){this.$$html5=!0;Tb.apply(this,arguments);var c=Rb(b);this.$$rewrite=function(d){var e;if(b==bb(d))return d;if(e=pa(c,d))return b+a+e;if(c===d+"/")return c};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash?"#"+ib(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function sb(b){return function(){return this[b]}}function Cc(b,a){return function(c){if(v(c))return this[b]; +this[b]=a(c);this.$$compose();return this}}function Wd(){var b="",a=!1;this.hashPrefix=function(a){return B(a)?(b=a,this):b};this.html5Mode=function(b){return B(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a){c.$broadcast("$locationChangeSuccess",k.absUrl(),a)}var k,m,h=d.baseHref(),l=d.url(),p;a?(p=l.substring(0,l.indexOf("/",l.indexOf("//")+2))+(h||"/"),m=e.history?Bc:Ub):(p=bb(l),m=Tb);k=new m(p,"#"+b);k.$$parse(k.$$rewrite(l));f.on("click", +function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var e=x(a.target);"a"!==K(e[0].nodeName);)if(e[0]===f[0]||!(e=e.parent())[0])return;var g=e.prop("href");S(g)&&"[object SVGAnimatedString]"===g.toString()&&(g=ua(g.animVal).href);if(m===Ub){var h=e.attr("href")||e.attr("xlink:href");if(0>h.indexOf("://"))if(g="#"+b,"/"==h[0])g=p+g+h;else if("#"==h[0])g=p+g+(k.path()||"/")+h;else{for(var l=k.path().split("/"),h=h.split("/"),n=0;ne?Dc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,f){var g=0,k;do k=Dc(d[g++],d[g++],d[g++],d[g++],d[g++],c,a)(b,f),f=s,b=k;while(ga)for(b in h++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(q--,delete e[b])}else e!==d&&(e=d,h++);return h},function(){p?(p=!1,b(d,d,c)):b(d,g,c);if(k)if(S(d))if(eb(d)){g=Array(d.length);for(var a=0;as&&(x=4-s,T[x]||(T[x]=[]),O=C(d.exp)?"fn: "+(d.exp.name||d.exp.toString()):d.exp,O+="; newVal: "+ta(f)+"; oldVal: "+ta(g),T[x].push(O));else if(d===c){A=!1;break a}}catch(B){n.$$phase=null,e(B)}if(!(k=J.$$childHead||J!==this&&J.$$nextSibling))for(;J!==this&&!(k=J.$$nextSibling);)J= +J.$parent}while(J=k);if((A||h.length)&&!s--)throw n.$$phase=null,a("infdig",b,ta(T));}while(A||h.length);for(n.$$phase=null;l.length;)try{l.shift()()}catch(y){e(y)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==n&&(q(this.$$listenerCount,Bb(null,l,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&&(a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling), +this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=D,this.$on=this.$watch=function(){return D})}},$eval:function(a,b){return f(a)(this,b)},$evalAsync:function(a){n.$$phase||n.$$asyncQueue.length||g.defer(function(){n.$$asyncQueue.length&&n.$digest()});this.$$asyncQueue.push({scope:this, +expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return m("$apply"),this.$eval(a)}catch(b){e(b)}finally{n.$$phase=null;try{n.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){c[Pa(c,b)]=null;l(e,1,a)}},$emit:function(a,b){var c=[],d,f=this,g=!1,k={name:a, +targetScope:f,stopPropagation:function(){g=!0},preventDefault:function(){k.defaultPrevented=!0},defaultPrevented:!1},h=[k].concat(Aa.call(arguments,1)),m,l;do{d=f.$$listeners[a]||c;k.currentScope=f;m=0;for(l=d.length;mc.msieDocumentMode)throw wa("iequirks");var e=ga(fa);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},e.valueOf=Ga);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b,d(a,c))}};var f=e.parseAs,g=e.getTrusted,k=e.trustAs;q(fa,function(a,b){var c=K(b);e[Xa("parse_as_"+c)]= +function(b){return f(a,b)};e[Xa("get_trusted_"+c)]=function(b){return g(a,b)};e[Xa("trust_as_"+c)]=function(b){return k(a,b)}});return e}]}function ce(){this.$get=["$window","$document",function(b,a){var c={},d=Z((/android (\d+)/.exec(K((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),f=a[0]||{},g=f.documentMode,k,m=/^(Moz|webkit|O|ms)(?=[A-Z])/,h=f.body&&f.body.style,l=!1,p=!1;if(h){for(var n in h)if(l=m.exec(n)){k=l[0];k=k.substr(0,1).toUpperCase()+k.substr(1); +break}k||(k="WebkitOpacity"in h&&"webkit");l=!!("transition"in h||k+"Transition"in h);p=!!("animation"in h||k+"Animation"in h);!d||l&&p||(l=z(f.body.style.webkitTransition),p=z(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!g||7b;b=Math.abs(b);var g=b+"",k="",m=[],h=!1;if(-1!==g.indexOf("e")){var l=g.match(/([\d\.]+)e(-?)(\d+)/);l&&"-"==l[2]&&l[3]>e+1?(g="0",b=0):(k=g,h=!0)}if(h)0b)&&(k=b.toFixed(e));else{g=(g.split(Nc)[1]||"").length;v(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac)); +b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);b=(""+b).split(Nc);g=b[0];b=b[1]||"";var l=0,p=a.lgSize,n=a.gSize;if(g.length>=p+n)for(l=g.length-p,h=0;hb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Xb(e,a,d)}}function ub(b,a){return function(c,d){var e=c["get"+b](),f=Ia(a?"SHORT"+b:b);return d[f][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,k=b[8]?a.setUTCFullYear:a.setFullYear,m=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=Z(b[9]+b[10]),g=Z(b[9]+b[11]));k.call(a,Z(b[1]),Z(b[2])-1,Z(b[3]));f=Z(b[4]||0)-f;g=Z(b[5]||0)- +g;k=Z(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));m.call(a,f,g,k,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var f="",g=[],k,m;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;z(c)&&(c=Fe.test(c)?Z(c):a(c));Ab(c)&&(c=new Date(c));if(!sa(c))return c;for(;e;)(m=Ge.exec(e))?(g=g.concat(Aa.call(m,1)),e=g.pop()):(g.push(e),e=null);q(g,function(a){k=He[a];f+=k?k(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g, +"").replace(/''/g,"'")});return f}}function Be(){return function(b){return ta(b,!0)}}function Ce(){return function(b,a){if(!I(b)&&!z(b))return b;a=Infinity===Math.abs(Number(a))?Number(a):Z(a);if(z(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0a||37<=a&&40>=a)||n()});if(e.hasEvent("paste"))a.on("paste cut",n)}a.on("change",l);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var r=c.ngPattern;r&&((e=r.match(/^\/(.*)\/([gim]*)$/))?(r=RegExp(e[1],e[2]),e=function(a){return ra(d,"pattern",d.$isEmpty(a)||r.test(a),a)}):e=function(c){var e=b.$eval(r);if(!e||!e.test)throw y("ngPattern")("noregexp",r,e,ha(a));return ra(d,"pattern",d.$isEmpty(c)||e.test(c), +c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var t=Z(c.ngMinlength);e=function(a){return ra(d,"minlength",d.$isEmpty(a)||a.length>=t,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var q=Z(c.ngMaxlength);e=function(a){return ra(d,"maxlength",d.$isEmpty(a)||a.length<=q,a)};d.$parsers.push(e);d.$formatters.push(e)}}function Yb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;dQ?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Ia(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Va=function(){if(B(Va.isActive_))return Va.isActive_;var b=!(!W.querySelector("[ng-csp]")&&!W.querySelector("[data-ng-csp]"));if(!b)try{new Function("")}catch(a){b=!0}return Va.isActive_=b},Yc=/[A-Z]/g,ad={full:"1.2.21",major:1,minor:2,dot:21,codeName:"wizard-props"};R.expando="ng339";var Za= +R.cache={},ne=1,rb=P.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},Ya=P.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};R._data=function(b){return this.cache[b[this.expando]]||{}};var ie=/([\:\-\_]+(.))/g,je=/^moz([A-Z])/,Hb=y("jqLite"),ke=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Ib=/<|&#?\w+;/,le=/<([\w:]+)/,me=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, +ba={option:[1,'"],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ba.optgroup=ba.option;ba.tbody=ba.tfoot=ba.colgroup=ba.caption=ba.thead;ba.th=ba.td;var La=R.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===W.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),R(P).on("load",a))}, +toString:function(){var b=[];q(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?x(this[b]):x(this[this.length+b])},length:0,push:Ke,sort:[].sort,splice:[].splice},nb={};q("multiple selected checked disabled readOnly required open".split(" "),function(b){nb[K(b)]=b});var rc={};q("input select option textarea button form details".split(" "),function(b){rc[Ia(b)]=!0});q({data:Mb,removeData:Lb},function(b,a){R[a]=b});q({data:Mb,inheritedData:mb,scope:function(b){return x.data(b, +"$scope")||mb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return x.data(b,"$isolateScope")||x.data(b,"$isolateScopeNoTemplate")},controller:oc,injector:function(b){return mb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Nb,css:function(b,a,c){a=Xa(a);if(B(c))b.style[a]=c;else{var d;8>=Q&&(d=b.currentStyle&&b.currentStyle[a],""===d&&(d="auto"));d=d||b.style[a];8>=Q&&(d=""===d?s:d);return d}},attr:function(b,a,c){var d=K(a);if(nb[d])if(B(c))c?(b[a]= +!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||D).specified?d:s;else if(B(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?s:b},prop:function(b,a,c){if(B(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(v(d))return e?b[e]:"";b[e]=d}var a=[];9>Q?(a[1]="innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(v(a)){if("SELECT"===Ma(b)&&b.multiple){var c= +[];q(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(v(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a, +c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Pe={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},Wb=function(a){this.options=a};Wb.prototype={constructor:Wb,lex:function(a){this.text=a;this.index=0;this.ch=s;this.lastCh=":";for(this.tokens=[];this.index=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"=== +a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=B(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw ja("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a; +return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(cb.ZERO,a.fn,this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Ec(d,this.options,this.text);return F(function(c,d,k){return e(k||a(c,d))},{assign:function(e,g,k){return tb(a(e,k),d,g,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return F(function(e,f){var g=a(e,f),k=d(e,f),m;qa(k,c.text); +if(!g)return s;(g=Na(g[k],c.text))&&(g.then&&c.options.unwrapPromises)&&(m=g,"$$v"in g||(m.$$v=s,m.then(function(a){m.$$v=a})),g=g.$$v);return g},{assign:function(e,f,g){var k=d(e,g);return Na(a(e,g),c.text)[k]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(f,g){for(var k=[],m=c?c(f,g):f,h=0;ha.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Xb(Math[0< +a?"floor":"ceil"](a/60),2)+Xb(Math.abs(a%60),2))}},Ge=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,Fe=/^\-?\d+$/;Jc.$inject=["$locale"];var De=$(K),Ee=$(Ia);Lc.$inject=["$parse"];var dd=$({restrict:"E",compile:function(a,c){8>=Q&&(c.href||c.name||c.$set("href",""),a.append(W.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var f="[object SVGAnimatedString]"===ya.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(f)|| +a.preventDefault()})}}}),Fb={};q(nb,function(a,c){if("multiple"!=a){var d=ma("ng-"+c);Fb[d]=function(){return{priority:100,link:function(a,f,g){a.$watch(g[d],function(a){g.$set(c,!!a)})}}}}});q(["src","srcset","href"],function(a){var c=ma("ng-"+a);Fb[c]=function(){return{priority:99,link:function(d,e,f){var g=a,k=a;"href"===a&&"[object SVGAnimatedString]"===ya.call(e.prop("href"))&&(k="xlinkHref",f.$attr[k]="xlink:href",g=null);f.$observe(c,function(a){a&&(f.$set(k,a),Q&&g&&e.prop(g,f[k]))})}}}}); +var xb={$addControl:D,$removeControl:D,$setValidity:D,$setDirty:D,$setPristine:D};Oc.$inject=["$element","$attrs","$scope","$animate"];var Rc=function(a){return["$timeout",function(c){return{name:"form",restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,f,g){if(!f.action){var k=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};rb(e[0],"submit",k);e.on("$destroy",function(){c(function(){Ya(e[0],"submit",k)},0,!1)})}var m=e.parent().controller("form"),h=f.name|| +f.ngForm;h&&tb(a,h,g,h);if(m)e.on("$destroy",function(){m.$removeControl(g);h&&tb(a,h,s,h);F(g,xb)})}}}}}]},ed=Rc(),rd=Rc(!0),Qe=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,Re=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,Se=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Sc={text:zb,number:function(a,c,d,e,f,g){zb(a,c,d,e,f,g);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Se.test(a))return e.$setValidity("number", +!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return s});Ie(e,"number",Te,null,e.$$validityState);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return ra(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a),e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return ra(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return ra(e,"number",e.$isEmpty(a)|| +Ab(a),a)})},url:function(a,c,d,e,f,g){zb(a,c,d,e,f,g);a=function(a){return ra(e,"url",e.$isEmpty(a)||Qe.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,f,g){zb(a,c,d,e,f,g);a=function(a){return ra(e,"email",e.$isEmpty(a)||Re.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){v(d.name)&&c.attr("name",fb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue}; +d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var f=d.ngTrueValue,g=d.ngFalseValue;z(f)||(f=!0);z(g)||(g=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==f};e.$formatters.push(function(a){return a===f});e.$parsers.push(function(a){return a?f:g})},hidden:D,button:D,submit:D,reset:D,file:D},Te=["badInput"],jc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel", +link:function(d,e,f,g){g&&(Sc[K(f.type)]||Sc.text)(d,e,f,g,c,a)}}}],wb="ng-valid",vb="ng-invalid",Oa="ng-pristine",yb="ng-dirty",Ue=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,f,g){function k(a,c){c=c?"-"+jb(c,"-"):"";g.removeClass(e,(a?vb:wb)+c);g.addClass(e,(a?wb:vb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name= +d.name;var m=f(d.ngModel),h=m.assign;if(!h)throw y("ngModel")("nonassign",d.ngModel,ha(e));this.$render=D;this.$isEmpty=function(a){return v(a)||""===a||null===a||a!==a};var l=e.inheritedData("$formController")||xb,p=0,n=this.$error={};e.addClass(Oa);k(!0);this.$setValidity=function(a,c){n[a]!==!c&&(c?(n[a]&&p--,p||(k(!0),this.$valid=!0,this.$invalid=!1)):(k(!1),this.$invalid=!0,this.$valid=!1,p++),n[a]=!c,k(c,a),l.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine= +!0;g.removeClass(e,yb);g.addClass(e,Oa)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,g.removeClass(e,Oa),g.addClass(e,yb),l.$setDirty());q(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,h(a,d),q(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}}))};var r=this;a.$watch(function(){var c=m(a);if(r.$modelValue!==c){var d=r.$formatters,e=d.length;for(r.$modelValue=c;e--;)c=d[e](c);r.$viewValue!==c&&(r.$viewValue= +c,r.$render())}return c})}],Gd=function(){return{require:["ngModel","^?form"],controller:Ue,link:function(a,c,d,e){var f=e[0],g=e[1]||xb;g.$addControl(f);a.$on("$destroy",function(){g.$removeControl(f)})}}},Id=$({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),kc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var f=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required", +!0),a};e.$formatters.push(f);e.$parsers.unshift(f);d.$observe("required",function(){f(e.$viewValue)})}}}},Hd=function(){return{require:"ngModel",link:function(a,c,d,e){var f=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!v(a)){var c=[];a&&q(a.split(f),function(a){a&&c.push(aa(a))});return c}});e.$formatters.push(function(a){return I(a)?a.join(", "):s});e.$isEmpty=function(a){return!a||!a.length}}}},Ve=/^(true|false|\d+)$/,Jd=function(){return{priority:100, +compile:function(a,c){return Ve.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},jd=xa({compile:function(a){a.addClass("ng-binding");return function(a,d,e){d.data("$binding",e.ngBind);a.$watch(e.ngBind,function(a){d.text(a==s?"":a)})}}}),ld=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}], +kd=["$sce","$parse",function(a,c){return{compile:function(d){d.addClass("ng-binding");return function(d,f,g){f.data("$binding",g.ngBindHtml);var k=c(g.ngBindHtml);d.$watch(function(){return(k(d)||"").toString()},function(c){f.html(a.getTrustedHtml(k(d))||"")})}}}}],md=Yb("",!0),od=Yb("Odd",0),nd=Yb("Even",1),pd=xa({compile:function(a,c){c.$set("ngCloak",s);a.removeClass("ng-cloak")}}),qd=[function(){return{scope:!0,controller:"@",priority:500}}],lc={};q("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "), +function(a){var c=ma("ng-"+a);lc[c]=["$parse",function(d){return{compile:function(e,f){var g=d(f[c]);return function(c,d){d.on(K(a),function(a){c.$apply(function(){g(c,{$event:a})})})}}}}]});var td=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var k,m,h;c.$watch(e.ngIf,function(f){Sa(f)?m||(m=c.$new(),g(m,function(c){c[c.length++]=W.createComment(" end ngIf: "+e.ngIf+" ");k={clone:c};a.enter(c,d.parent(),d)})):(h&&(h.remove(), +h=null),m&&(m.$destroy(),m=null),k&&(h=Eb(k.clone),a.leave(h,function(){h=null}),k=null))})}}}],ud=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,f){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Ta.noop,compile:function(g,k){var m=k.ngInclude||k.src,h=k.onload||"",l=k.autoscroll;return function(g,k,r,q,L){var w=0,u,s,x,A=function(){s&&(s.remove(),s=null);u&&(u.$destroy(),u=null);x&&(e.leave(x,function(){s=null}),s=x,x=null)};g.$watch(f.parseAsResourceUrl(m), +function(f){var m=function(){!B(l)||l&&!g.$eval(l)||d()},r=++w;f?(a.get(f,{cache:c}).success(function(a){if(r===w){var c=g.$new();q.template=a;a=L(c,function(a){A();e.enter(a,null,k,m)});u=c;x=a;u.$emit("$includeContentLoaded");g.$eval(h)}}).error(function(){r===w&&A()}),g.$emit("$includeContentRequested")):(A(),q.template=null)})}}}}],Kd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(c,d,e,f){d.html(f.template);a(d.contents())(c)}}}],vd=xa({priority:450, +compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),wd=xa({terminal:!0,priority:1E3}),xd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,g){var k=g.count,m=g.$attr.when&&f.attr(g.$attr.when),h=g.offset||0,l=e.$eval(m)||{},p={},n=c.startSymbol(),r=c.endSymbol(),t=/^when(Minus)?(.+)$/;q(g,function(a,c){t.test(c)&&(l[K(c.replace("when","").replace("Minus","-"))]=f.attr(g.$attr[c]))});q(l,function(a,e){p[e]=c(a.replace(d,n+k+"-"+h+r))});e.$watch(function(){var c= +parseFloat(e.$eval(k));if(isNaN(c))return"";c in l||(c=a.pluralCat(c-h));return p[c](e,f,!0)},function(a){f.text(a)})}}}],yd=["$parse","$animate",function(a,c){var d=y("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,link:function(e,f,g,k,m){var h=g.ngRepeat,l=h.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),p,n,r,t,s,w,u={$id:Ka};if(!l)throw d("iexp",h);g=l[1];k=l[2];(l=l[3])?(p=a(l),n=function(a,c,d){w&&(u[w]=a);u[s]=c;u.$index=d;return p(e, +u)}):(r=function(a,c){return Ka(c)},t=function(a){return a});l=g.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!l)throw d("iidexp",g);s=l[3]||l[1];w=l[2];var B={};e.$watchCollection(k,function(a){var g,k,l=f[0],p,u={},y,E,H,z,D,v,I=[];if(eb(a))D=a,p=n||r;else{p=n||t;D=[];for(H in a)a.hasOwnProperty(H)&&"$"!=H.charAt(0)&&D.push(H);D.sort()}y=D.length;k=I.length=D.length;for(g=0;gC;)v.pop().element.remove()}for(;y.length>N;)y.pop()[0].element.remove()}var h;if(!(h=t.match(d)))throw We("iexp",t,ha(f));var l=c(h[2]||h[1]),m=h[4]||h[6],n=h[5],p=c(h[3]||""),q=c(h[2]?h[1]:m),x=c(h[7]),w=h[8]?c(h[8]):null,y=[[{element:f,label:""}]];z&&(a(z)(e),z.removeClass("ng-scope"),z.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=x(e)||[],d={},h,k,l,p,t,u,v;if(r)for(k=[],p=0,u=y.length;p@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}.ng-hide-add-active,.ng-hide-remove{display:block!important;}'); //# sourceMappingURL=angular.min.js.map diff --git a/app/bower_components/angular/angular.min.js.gzip b/app/bower_components/angular/angular.min.js.gzip index 5daa0cdc93f8c3f207689eed4fd93cc6b007b21d..03d92a2a4d0b1f4ac1bf4ecfa61143f78545347f 100644 GIT binary patch literal 39367 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%0DP_J$*(3aXuaS&^J!a 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

P8W$j|{F))cucbQ0LuWex_UqnT}`oic`R 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","<=",">=","&&","||","&","|","!","ESCAPE","lex","ch","lastCh","tokens","is","readString","peek","readNumber","isIdent","readIdent","was","isWhitespace","ch2","ch3","fn2","fn3","throwError","chars","isExpOperator","start","end","colStr","peekCh","ident","lastDot","peekIndex","methodName","quote","rawString","hex","rep","ZERO","assignment","logicalOR","functionCall","fieldAccess","objectIndex","filterChain","this.filterChain","primary","statements","expect","consume","arrayDeclaration","msg","peekToken","e1","e2","e3","e4","t","unaryFn","right","ternaryFn","left","middle","binaryFn","statement","argsFn","fnInvoke","ternary","logicalAND","equality","relational","additive","multiplicative","unary","field","indexFn","o","safe","contextGetter","fnPtr","elementFns","allConstant","elementFn","keyValues","ampmGetter","getHours","AMPMS","timeZoneGetter","zone","getTimezoneOffset","paddedZone","xlinkHref","propName","normalized","ngBooleanAttrWatchAction","formDirectiveFactory","isNgForm","formElement","action","preventDefaultListener","parentFormCtrl","alias","URL_REGEXP","EMAIL_REGEXP","NUMBER_REGEXP","inputType","numberInputType","minValidator","maxValidator","urlInputType","urlValidator","emailInputType","emailValidator","radioInputType","checked","checkboxInputType","trueValue","ngTrueValue","falseValue","ngFalseValue","ctrl.$isEmpty","NgModelController","$modelValue","NaN","$viewChangeListeners","ngModelGet","ngModel","ngModelSet","this.$isEmpty","inheritedData","this.$setValidity","this.$setPristine","this.$setViewValue","ngModelWatch","formatters","ctrls","modelCtrl","formCtrl","ngChange","required","ngList","viewValue","CONSTANT_VALUE_REGEXP","tpl","tplAttr","ngValue","ngValueConstantLink","ngValueLink","valueWatchAction","ngBind","ngBindWatchAction","ngBindTemplate","ngBindHtml","getStringValue","ngBindHtmlWatchAction","getTrustedHtml","$transclude","previousElements","ngIf","ngIfWatchAction","$anchorScroll","srcExp","ngInclude","onloadExp","autoScrollExp","autoscroll","previousElement","currentElement","cleanupLastIncludeContent","parseAsResourceUrl","ngIncludeWatchAction","afterAnimation","thisChangeId","newScope","$compile","ngInit","BRACE","numberExp","whenExp","whens","whensExpFns","isWhen","attributeName","ngPluralizeWatch","ngPluralizeWatchAction","ngRepeatMinErr","ngRepeat","trackByExpGetter","trackByIdExpFn","trackByIdArrayFn","trackByIdObjFn","valueIdentifier","keyIdentifier","hashFnLocals","lhs","rhs","trackByExp","lastBlockMap","ngRepeatAction","collection","previousNode","nextNode","nextBlockMap","arrayLength","collectionKeys","nextBlockOrder","trackByIdFn","trackById","$first","$last","$middle","$odd","$even","ngShow","ngShowWatchAction","ngHide","ngHideWatchAction","ngStyle","ngStyleWatchAction","newStyles","oldStyles","ngSwitchController","cases","selectedTranscludes","selectedElements","selectedScopes","ngSwitch","ngSwitchWatchAction","change","selectedTransclude","selectedScope","caseElement","anchor","ngSwitchWhen","$attrs","ngOptionsMinErr","NG_OPTIONS_REGEXP","nullModelCtrl","optionsMap","ngModelCtrl","unknownOption","databound","init","self.init","ngModelCtrl_","nullOption_","unknownOption_","addOption","self.addOption","removeOption","self.removeOption","hasOption","renderUnknownOption","self.renderUnknownOption","unknownVal","self.hasOption","setupAsSingle","selectElement","selectCtrl","ngModelCtrl.$render","emptyOption","setupAsMultiple","lastView","items","selectMultipleWatch","setupAsOptions","render","optionGroups","optionGroupNames","optionGroupName","optionGroup","existingParent","existingOptions","modelValue","valuesFn","keyName","groupIndex","selectedSet","lastElement","trackFn","trackIndex","valueName","groupByFn","modelCast","label","displayFn","nullOption","groupLength","optionGroupsCache","optGroupTemplate","existingOption","optionTemplate","optionsExp","track","optionElement","ngOptions","ngModelCtrl.$isEmpty","nullSelectCtrl","selectCtrlName","interpolateWatchAction","$$csp"] +"names":["window","document","undefined","minErr","isArrayLike","obj","isWindow","length","nodeType","isString","isArray","forEach","iterator","context","key","isFunction","hasOwnProperty","call","sortedKeys","keys","push","sort","forEachSorted","i","reverseParams","iteratorFn","value","nextUid","index","uid","digit","charCodeAt","join","String","fromCharCode","unshift","setHashKey","h","$$hashKey","extend","dst","arguments","int","str","parseInt","inherit","parent","extra","noop","identity","$","valueFn","isUndefined","isDefined","isObject","isNumber","isDate","toString","isRegExp","location","alert","setInterval","isElement","node","nodeName","prop","attr","find","map","results","list","indexOf","array","arrayRemove","splice","copy","source","destination","stackSource","stackDest","$evalAsync","$watch","ngMinErr","result","Date","getTime","RegExp","match","lastIndex","shallowCopy","src","charAt","equals","o1","o2","t1","t2","keySet","bind","self","fn","curryArgs","slice","startIndex","apply","concat","toJsonReplacer","val","toJson","pretty","JSON","stringify","fromJson","json","parse","toBoolean","v","lowercase","startingTag","element","jqLite","clone","empty","e","elemHtml","append","html","TEXT_NODE","replace","tryDecodeURIComponent","decodeURIComponent","parseKeyValue","keyValue","key_value","split","toKeyValue","parts","arrayValue","encodeUriQuery","encodeUriSegment","pctEncodeSpaces","encodeURIComponent","angularInit","bootstrap","elements","appElement","module","names","NG_APP_CLASS_REGEXP","name","getElementById","querySelectorAll","exec","className","attributes","modules","doBootstrap","injector","tag","$provide","createInjector","invoke","scope","compile","animate","$apply","data","NG_DEFER_BOOTSTRAP","test","angular","resumeBootstrap","angular.resumeBootstrap","extraModules","snake_case","separator","SNAKE_CASE_REGEXP","letter","pos","toLowerCase","assertArg","arg","reason","assertArgFn","acceptArrayAnnotation","constructor","assertNotHasOwnProperty","getter","path","bindFnToScope","lastInstance","len","getBlockElements","nodes","startNode","endNode","nextSibling","setupModuleLoader","$injectorMinErr","$$minErr","factory","requires","configFn","invokeLater","provider","method","insertMethod","invokeQueue","moduleInstance","runBlocks","config","run","block","publishExternalAPI","version","uppercase","csp","angularModule","$LocaleProvider","ngModule","$$SanitizeUriProvider","$CompileProvider","directive","htmlAnchorDirective","inputDirective","formDirective","scriptDirective","selectDirective","styleDirective","optionDirective","ngBindDirective","ngBindHtmlDirective","ngBindTemplateDirective","ngClassDirective","ngClassEvenDirective","ngClassOddDirective","ngCloakDirective","ngControllerDirective","ngFormDirective","ngHideDirective","ngIfDirective","ngIncludeDirective","ngInitDirective","ngNonBindableDirective","ngPluralizeDirective","ngRepeatDirective","ngShowDirective","ngStyleDirective","ngSwitchDirective","ngSwitchWhenDirective","ngSwitchDefaultDirective","ngOptionsDirective","ngTranscludeDirective","ngModelDirective","ngListDirective","ngChangeDirective","requiredDirective","ngValueDirective","ngIncludeFillContentDirective","ngAttributeAliasDirectives","ngEventDirectives","$AnchorScrollProvider","$AnimateProvider","$BrowserProvider","$CacheFactoryProvider","$ControllerProvider","$DocumentProvider","$ExceptionHandlerProvider","$FilterProvider","$InterpolateProvider","$IntervalProvider","$HttpProvider","$HttpBackendProvider","$LocationProvider","$LogProvider","$ParseProvider","$RootScopeProvider","$QProvider","$SceProvider","$SceDelegateProvider","$SnifferProvider","$TemplateCacheProvider","$TimeoutProvider","$WindowProvider","$$RAFProvider","$$AsyncCallbackProvider","camelCase","SPECIAL_CHARS_REGEXP","_","offset","toUpperCase","MOZ_HACK_REGEXP","jqLitePatchJQueryRemove","dispatchThis","filterElems","getterIfNoArguments","removePatch","param","filter","fireEvent","set","setIndex","setLength","childIndex","children","shift","triggerHandler","childLength","jQuery","originalJqFn","$original","JQLite","trim","jqLiteMinErr","parsed","SINGLE_TAG_REGEXP","fragment","createDocumentFragment","HTML_REGEXP","tmp","appendChild","createElement","TAG_NAME_REGEXP","wrap","wrapMap","_default","innerHTML","XHTML_TAG_REGEXP","removeChild","firstChild","lastChild","j","jj","childNodes","textContent","createTextNode","jqLiteAddNodes","jqLiteClone","cloneNode","jqLiteDealoc","jqLiteRemoveData","jqLiteOff","type","unsupported","events","jqLiteExpandoStore","handle","eventHandler","removeEventListenerFn","expandoId","ng339","expandoStore","jqCache","$destroy","jqId","jqLiteData","isSetter","keyDefined","isSimpleGetter","jqLiteHasClass","selector","getAttribute","jqLiteRemoveClass","cssClasses","setAttribute","cssClass","jqLiteAddClass","existingClasses","root","jqLiteController","jqLiteInheritedData","documentElement","ii","parentNode","host","jqLiteEmpty","getBooleanAttrName","booleanAttr","BOOLEAN_ATTR","BOOLEAN_ELEMENTS","createEventHandler","event","preventDefault","event.preventDefault","returnValue","stopPropagation","event.stopPropagation","cancelBubble","target","srcElement","defaultPrevented","prevent","isDefaultPrevented","event.isDefaultPrevented","eventHandlersCopy","msie","elem","hashKey","nextUidFn","objType","HashMap","isolatedUid","this.nextUid","put","annotate","$inject","fnText","STRIP_COMMENTS","argDecl","FN_ARGS","FN_ARG_SPLIT","FN_ARG","all","underscore","last","modulesToLoad","supportObject","delegate","provider_","providerInjector","instantiate","$get","providerCache","providerSuffix","factoryFn","loadModules","moduleFn","loadedModules","get","_runBlocks","_invokeQueue","invokeArgs","message","stack","createInternalInjector","cache","getService","serviceName","INSTANTIATING","err","locals","args","Type","Constructor","returnedValue","prototype","instance","has","service","$injector","constant","instanceCache","decorator","decorFn","origProvider","orig$get","origProvider.$get","origInstance","instanceInjector","servicename","autoScrollingEnabled","disableAutoScrolling","this.disableAutoScrolling","$window","$location","$rootScope","getFirstAnchor","scroll","hash","elm","scrollIntoView","getElementsByName","scrollTo","autoScrollWatch","autoScrollWatchAction","$$rAF","$timeout","supported","Browser","$log","$sniffer","completeOutstandingRequest","outstandingRequestCount","outstandingRequestCallbacks","pop","error","startPoller","interval","setTimeout","check","pollFns","pollFn","pollTimeout","fireUrlChange","newLocation","lastBrowserUrl","url","urlChangeListeners","listener","rawDocument","history","clearTimeout","pendingDeferIds","isMock","$$completeOutstandingRequest","$$incOutstandingRequestCount","self.$$incOutstandingRequestCount","notifyWhenNoOutstandingRequests","self.notifyWhenNoOutstandingRequests","callback","addPollFn","self.addPollFn","href","baseElement","self.url","replaceState","pushState","urlChangeInit","onUrlChange","self.onUrlChange","on","hashchange","baseHref","self.baseHref","lastCookies","lastCookieString","cookiePath","cookies","self.cookies","cookieLength","cookie","escape","warn","cookieArray","unescape","substring","defer","self.defer","delay","timeoutId","cancel","self.defer.cancel","deferId","$document","this.$get","cacheFactory","cacheId","options","refresh","entry","freshEnd","staleEnd","n","link","p","nextEntry","prevEntry","caches","size","stats","capacity","Number","MAX_VALUE","lruHash","lruEntry","remove","removeAll","destroy","info","cacheFactory.info","cacheFactory.get","$cacheFactory","$$sanitizeUriProvider","hasDirectives","Suffix","COMMENT_DIRECTIVE_REGEXP","CLASS_DIRECTIVE_REGEXP","EVENT_HANDLER_ATTR_REGEXP","this.directive","registerDirective","directiveFactory","$exceptionHandler","directives","priority","require","controller","restrict","aHrefSanitizationWhitelist","this.aHrefSanitizationWhitelist","regexp","imgSrcSanitizationWhitelist","this.imgSrcSanitizationWhitelist","$interpolate","$http","$templateCache","$parse","$controller","$sce","$animate","$$sanitizeUri","$compileNodes","transcludeFn","maxPriority","ignoreDirective","previousCompileContext","nodeValue","compositeLinkFn","compileNodes","safeAddClass","publicLinkFn","cloneConnectFn","transcludeControllers","parentBoundTranscludeFn","$linkNode","JQLitePrototype","eq","$element","addClass","nodeList","$rootElement","childLinkFn","childScope","childBoundTranscludeFn","nodeListLength","stableNodeList","Array","linkFns","nodeLinkFn","$new","transcludeOnThisElement","createBoundTranscludeFn","transclude","templateOnThisElement","attrs","linkFnFound","Attributes","collectDirectives","applyDirectivesToNode","$$element","terminal","previousBoundTranscludeFn","boundTranscludeFn","transcludedScope","cloneFn","controllers","scopeCreated","$$transcluded","attrsMap","$attr","addDirective","directiveNormalize","nodeName_","isNgAttr","nAttrs","attrStartName","attrEndName","specified","ngAttrName","NG_ATTR_BINDING","substr","directiveNName","nName","addAttrInterpolateDirective","addTextInterpolateDirective","byPriority","groupScan","attrStart","attrEnd","depth","hasAttribute","$compileMinErr","groupElementsLinkFnWrapper","linkFn","compileNode","templateAttrs","jqCollection","originalReplaceDirective","preLinkFns","postLinkFns","addLinkFns","pre","post","directiveName","newIsolateScopeDirective","$$isolateScope","cloneAndAnnotateFn","getControllers","elementControllers","retrievalMethod","optional","linkNode","controllersBoundTransclude","cloneAttachFn","hasElementTranscludeDirective","isolateScope","LOCAL_REGEXP","templateDirective","$$originalDirective","definition","scopeName","attrName","mode","lastValue","parentGet","parentSet","compare","$$isolateBindings","$observe","$$observers","$$scope","literal","a","b","assign","parentValueWatch","parentValue","controllerDirectives","controllerInstance","controllerAs","$scope","scopeToChild","template","templateUrl","terminalPriority","newScopeDirective","nonTlbTranscludeDirective","hasTranscludeDirective","hasTemplate","$compileNode","$template","childTranscludeFn","$$start","$$end","directiveValue","assertNoDuplicate","$$tlb","createComment","replaceWith","replaceDirective","contents","denormalizeTemplate","newTemplateAttrs","templateDirectives","unprocessedDirectives","markDirectivesAsIsolate","mergeTemplateAttributes","compileTemplateUrl","Math","max","tDirectives","startAttrName","endAttrName","srcAttr","dstAttr","$set","tAttrs","linkQueue","afterTemplateNodeLinkFn","afterTemplateChildLinkFn","beforeTemplateCompileNode","origAsyncDirective","derivedSyncDirective","getTrustedResourceUrl","success","content","tempTemplateAttrs","beforeTemplateLinkNode","linkRootElement","oldClasses","response","code","headers","delayedNodeLinkFn","ignoreChildLinkFn","rootElement","diff","what","previousDirective","text","interpolateFn","textInterpolateCompileFn","templateNode","hasCompileParent","textInterpolateLinkFn","bindings","interpolateFnWatchAction","getTrustedContext","attrNormalizedName","HTML","RESOURCE_URL","attrInterpolatePreLinkFn","$$inter","newValue","oldValue","$updateClass","elementsToRemove","newNode","firstElementToRemove","removeCount","j2","replaceChild","expando","k","kk","annotation","$addClass","classVal","$removeClass","removeClass","newClasses","toAdd","tokenDifference","toRemove","setClass","writeAttr","booleanKey","removeAttr","listeners","startSymbol","endSymbol","PREFIX_REGEXP","str1","str2","values","tokens1","tokens2","token","CNTRL_REG","register","this.register","expression","identifier","exception","cause","parseHeaders","line","headersGetter","headersObj","transformData","fns","JSON_START","JSON_END","PROTECTION_PREFIX","CONTENT_TYPE_APPLICATION_JSON","defaults","d","interceptorFactories","interceptors","responseInterceptorFactories","responseInterceptors","$httpBackend","$browser","$q","requestConfig","transformResponse","resp","status","reject","transformRequest","mergeHeaders","defHeaders","reqHeaders","defHeaderName","reqHeaderName","common","lowercaseDefHeaderName","execHeaders","headerContent","headerFn","header","chain","serverRequest","reqData","withCredentials","sendReq","then","promise","when","reversedInterceptors","interceptor","request","requestError","responseError","thenFn","rejectFn","promise.success","promise.error","done","headersString","statusText","resolvePromise","$$phase","deferred","resolve","removePendingReq","idx","pendingRequests","cachedResp","buildUrl","params","defaultCache","xsrfValue","urlIsSameOrigin","xsrfCookieName","xsrfHeaderName","timeout","responseType","toISOString","interceptorFactory","responseFn","createShortMethods","createShortMethodsWithData","createXhr","XMLHttpRequest","ActiveXObject","createHttpBackend","callbacks","$browserDefer","jsonpReq","callbackId","script","async","body","called","addEventListenerFn","onreadystatechange","script.onreadystatechange","readyState","ABORTED","timeoutRequest","jsonpDone","xhr","abort","completeRequest","urlResolve","protocol","counter","open","setRequestHeader","xhr.onreadystatechange","responseHeaders","getAllResponseHeaders","responseText","send","this.startSymbol","this.endSymbol","mustHaveExpression","trustedContext","endIndex","hasInterpolation","startSymbolLength","exp","endSymbolLength","$interpolateMinErr","part","getTrusted","valueOf","newErr","$interpolate.startSymbol","$interpolate.endSymbol","count","invokeApply","clearInterval","iteration","skipApply","$$intervalId","tick","notify","intervals","interval.cancel","short","pluralCat","num","encodePath","segments","parseAbsoluteUrl","absoluteUrl","locationObj","appBase","parsedUrl","$$protocol","$$host","hostname","$$port","port","DEFAULT_PORTS","parseAppUrl","relativeUrl","prefixed","$$path","pathname","$$search","search","$$hash","beginsWith","begin","whole","stripHash","stripFile","lastIndexOf","LocationHtml5Url","basePrefix","$$html5","appBaseNoFile","$$parse","this.$$parse","pathUrl","$locationMinErr","$$compose","this.$$compose","$$url","$$absUrl","$$rewrite","this.$$rewrite","appUrl","prevAppUrl","LocationHashbangUrl","hashPrefix","withoutBaseUrl","withoutHashUrl","windowsFilePathExp","firstPathSegmentMatch","LocationHashbangInHtml5Url","locationGetter","property","locationGetterSetter","preprocess","html5Mode","this.hashPrefix","prefix","this.html5Mode","afterLocationChange","oldUrl","$broadcast","absUrl","LocationMode","initialUrl","ctrlKey","metaKey","which","absHref","animVal","rewrittenUrl","newUrl","$digest","changeCounter","$locationWatch","currentReplace","$$replace","debug","debugEnabled","this.debugEnabled","flag","formatError","Error","sourceURL","consoleLog","console","logFn","log","hasApply","arg1","arg2","ensureSafeMemberName","fullExpression","$parseMinErr","ensureSafeObject","Object","setter","setValue","fullExp","propertyObj","unwrapPromises","promiseWarning","$$v","cspSafeGetterFn","key0","key1","key2","key3","key4","cspSafePromiseEnabledGetter","pathVal","cspSafeGetter","getterFn","getterFnCache","pathKeys","pathKeysLength","evaledFnGetter","Function","$parseOptions","this.unwrapPromises","logPromiseWarnings","this.logPromiseWarnings","$filter","promiseWarningCache","parsedExpression","lexer","Lexer","parser","Parser","qFactory","nextTick","exceptionHandler","defaultCallback","defaultErrback","pending","ref","createInternalRejectedPromise","progress","errback","progressback","wrappedCallback","wrappedErrback","wrappedProgressback","catch","finally","makePromise","resolved","handleCallback","isResolved","callbackOutput","promises","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","webkitCancelRequestAnimationFrame","rafSupported","raf","id","timer","TTL","$rootScopeMinErr","lastDirtyWatch","digestTtl","this.digestTtl","Scope","$id","$parent","$$watchers","$$nextSibling","$$prevSibling","$$childHead","$$childTail","$root","$$destroyed","$$asyncQueue","$$postDigestQueue","$$listeners","$$listenerCount","beginPhase","phase","compileToFn","decrementListenerCount","current","initWatchVal","isolate","child","$$childScopeClass","this.$$childScopeClass","watchExp","objectEquality","watcher","listenFn","watcher.fn","newVal","oldVal","originalFn","deregisterWatch","$watchCollection","veryOldValue","trackVeryOldValue","changeDetected","objGetter","internalArray","internalObject","initRun","oldLength","$watchCollectionWatch","newLength","bothNaN","$watchCollectionAction","watch","watchers","asyncQueue","postDigestQueue","dirty","ttl","watchLog","logIdx","logMsg","asyncTask","$eval","isNaN","next","$on","this.$watch","expr","$$postDigest","namedListeners","$emit","listenerArgs","array1","currentScope","sanitizeUri","uri","isImage","regex","normalizedVal","adjustMatcher","matcher","$sceMinErr","adjustMatchers","matchers","adjustedMatchers","SCE_CONTEXTS","resourceUrlWhitelist","resourceUrlBlacklist","this.resourceUrlWhitelist","this.resourceUrlBlacklist","generateHolderType","Base","holderType","trustedValue","$$unwrapTrustedValue","this.$$unwrapTrustedValue","holderType.prototype.valueOf","holderType.prototype.toString","htmlSanitizer","trustedValueHolderBase","byType","CSS","URL","JS","trustAs","maybeTrusted","allowed","enabled","this.enabled","$sceDelegate","msieDocumentMode","sce","isEnabled","sce.isEnabled","sce.getTrusted","parseAs","sce.parseAs","sceParseAsTrusted","enumValue","lName","eventSupport","android","userAgent","navigator","boxee","documentMode","vendorPrefix","vendorRegex","bodyStyle","style","transitions","animations","webkitTransition","webkitAnimation","hasEvent","divElm","deferreds","$$timeoutId","timeout.cancel","base","urlParsingNode","requestUrl","originUrl","filters","suffix","currencyFilter","dateFilter","filterFilter","jsonFilter","limitToFilter","lowercaseFilter","numberFilter","orderByFilter","uppercaseFilter","comparator","comparatorType","predicates","predicates.check","objKey","filtered","$locale","formats","NUMBER_FORMATS","amount","currencySymbol","CURRENCY_SYM","formatNumber","PATTERNS","GROUP_SEP","DECIMAL_SEP","number","fractionSize","pattern","groupSep","decimalSep","isFinite","isNegative","abs","numStr","formatedText","hasExponent","toFixed","fractionLen","min","minFrac","maxFrac","round","fraction","lgroup","lgSize","group","gSize","negPre","posPre","negSuf","posSuf","padNumber","digits","neg","dateGetter","date","dateStrGetter","shortForm","jsonStringToDate","string","R_ISO8601_STR","tzHour","tzMin","dateSetter","setUTCFullYear","setFullYear","timeSetter","setUTCHours","setHours","m","s","ms","parseFloat","format","DATETIME_FORMATS","NUMBER_STRING","DATE_FORMATS_SPLIT","DATE_FORMATS","object","input","limit","Infinity","out","sortPredicate","reverseOrder","reverseComparator","comp","descending","v1","v2","predicate","arrayCopy","ngDirective","FormController","toggleValidCss","isValid","validationErrorKey","INVALID_CLASS","VALID_CLASS","form","parentForm","nullFormCtrl","invalidCount","errors","$error","controls","$name","ngForm","$dirty","$pristine","$valid","$invalid","$addControl","PRISTINE_CLASS","form.$addControl","control","$removeControl","form.$removeControl","queue","validationToken","$setValidity","form.$setValidity","$setDirty","form.$setDirty","DIRTY_CLASS","$setPristine","form.$setPristine","validate","ctrl","validatorName","validity","testFlags","flags","addNativeHtml5Validators","badFlags","ignoreFlags","$$hasNativeValidators","$parsers","validator","textInputType","VALIDITY_STATE_PROPERTY","placeholder","noevent","$$validityState","composing","ev","ngTrim","revalidate","$viewValue","$setViewValue","deferListener","keyCode","$render","ctrl.$render","$isEmpty","ngPattern","patternValidator","patternObj","$formatters","ngMinlength","minlength","minLengthValidator","ngMaxlength","maxlength","maxLengthValidator","classDirective","arrayDifference","arrayClasses","classes","digestClassCounts","classCounts","classesToUpdate","ngClassWatchAction","$index","old$index","mod","isActive_","active","querySelector","addEventListener","attachEvent","removeEventListener","detachEvent","_data","JQLite._data","optgroup","option","tbody","tfoot","colgroup","caption","thead","th","td","ready","trigger","fired","removeAttribute","css","currentStyle","lowercasedName","getNamedItem","ret","getText","textProp","NODE_TYPE_TEXT_PROPERTY","$dv","multiple","selected","nodeCount","onFn","eventFns","contains","compareDocumentPosition","adown","bup","eventmap","related","relatedTarget","one","off","replaceNode","insertBefore","contentDocument","prepend","wrapNode","after","newElement","toggleClass","condition","classCondition","nextElementSibling","getElementsByTagName","eventName","eventData","eventFnsCopy","arg3","unbind","$animateMinErr","$$selectors","classNameFilter","this.classNameFilter","$$classNameFilter","$$asyncCallback","enter","leave","move","add","PATH_MATCH","paramValue","CALL","APPLY","BIND","OPERATORS","null","true","false","+","-","*","/","%","^","===","!==","==","!=","<",">","<=",">=","&&","||","&","|","!","ESCAPE","lex","ch","lastCh","tokens","is","readString","peek","readNumber","isIdent","readIdent","isWhitespace","ch2","ch3","fn2","fn3","throwError","chars","was","isExpOperator","start","end","colStr","peekCh","ident","lastDot","peekIndex","methodName","quote","rawString","hex","rep","ZERO","statements","primary","expect","filterChain","consume","arrayDeclaration","functionCall","objectIndex","fieldAccess","msg","peekToken","e1","e2","e3","e4","t","unaryFn","right","ternaryFn","left","middle","binaryFn","statement","argsFn","fnInvoke","assignment","ternary","logicalOR","logicalAND","equality","relational","additive","multiplicative","unary","field","indexFn","o","safe","contextGetter","fnPtr","elementFns","allConstant","elementFn","keyValues","ampmGetter","getHours","AMPMS","timeZoneGetter","zone","getTimezoneOffset","paddedZone","xlinkHref","propName","normalized","ngBooleanAttrWatchAction","formDirectiveFactory","isNgForm","formElement","action","preventDefaultListener","parentFormCtrl","alias","URL_REGEXP","EMAIL_REGEXP","NUMBER_REGEXP","inputType","numberInputType","numberBadFlags","minValidator","maxValidator","urlInputType","urlValidator","emailInputType","emailValidator","radioInputType","checked","checkboxInputType","trueValue","ngTrueValue","falseValue","ngFalseValue","ctrl.$isEmpty","NgModelController","$modelValue","NaN","$viewChangeListeners","ngModelGet","ngModel","ngModelSet","this.$isEmpty","inheritedData","this.$setValidity","this.$setPristine","this.$setViewValue","ngModelWatch","formatters","ctrls","modelCtrl","formCtrl","ngChange","required","ngList","viewValue","CONSTANT_VALUE_REGEXP","tpl","tplAttr","ngValue","ngValueConstantLink","ngValueLink","valueWatchAction","templateElement","ngBind","ngBindWatchAction","ngBindTemplate","tElement","ngBindHtml","getStringValue","ngBindHtmlWatchAction","getTrustedHtml","ngEventHandler","$transclude","previousElements","ngIf","ngIfWatchAction","$anchorScroll","srcExp","ngInclude","onloadExp","onload","autoScrollExp","autoscroll","previousElement","currentElement","cleanupLastIncludeContent","parseAsResourceUrl","ngIncludeWatchAction","afterAnimation","thisChangeId","newScope","$compile","ngInit","BRACE","numberExp","whenExp","whens","whensExpFns","isWhen","attributeName","ngPluralizeWatch","ngPluralizeWatchAction","ngRepeatMinErr","ngRepeat","trackByExpGetter","trackByIdExpFn","trackByIdArrayFn","trackByIdObjFn","valueIdentifier","keyIdentifier","hashFnLocals","lhs","rhs","trackByExp","lastBlockMap","ngRepeatAction","collection","previousNode","nextNode","nextBlockMap","arrayLength","collectionKeys","nextBlockOrder","trackByIdFn","trackById","$first","$last","$middle","$odd","$even","ngShow","ngShowWatchAction","ngHide","ngHideWatchAction","ngStyle","ngStyleWatchAction","newStyles","oldStyles","ngSwitchController","cases","selectedTranscludes","selectedElements","selectedScopes","ngSwitch","ngSwitchWatchAction","change","selectedTransclude","selectedScope","caseElement","anchor","ngSwitchWhen","$attrs","ngOptionsMinErr","NG_OPTIONS_REGEXP","nullModelCtrl","optionsMap","ngModelCtrl","unknownOption","databound","init","self.init","ngModelCtrl_","nullOption_","unknownOption_","addOption","self.addOption","removeOption","self.removeOption","hasOption","renderUnknownOption","self.renderUnknownOption","unknownVal","self.hasOption","setupAsSingle","selectElement","selectCtrl","ngModelCtrl.$render","emptyOption","setupAsMultiple","lastView","items","selectMultipleWatch","setupAsOptions","render","optionGroups","optionGroupNames","optionGroupName","optionGroup","existingParent","existingOptions","modelValue","valuesFn","keyName","groupIndex","selectedSet","lastElement","trackFn","trackIndex","valueName","groupByFn","modelCast","label","displayFn","nullOption","groupLength","optionGroupsCache","optGroupTemplate","existingOption","optionTemplate","optionsExp","track","optionElement","ngOptions","ngModelCtrl.$isEmpty","nullSelectCtrl","selectCtrlName","interpolateWatchAction","$$csp"] } diff --git a/app/bower_components/angular/bower.json b/app/bower_components/angular/bower.json index 55a3b8e..c82fcdd 100644 --- a/app/bower_components/angular/bower.json +++ b/app/bower_components/angular/bower.json @@ -1,6 +1,6 @@ { "name": "angular", - "version": "1.2.16", + "version": "1.2.21", "main": "./angular.js", "dependencies": { } diff --git a/app/bower_components/bootstrap-sass-official/.bower.json b/app/bower_components/bootstrap-sass-official/.bower.json index f6dbf9c..f26e05d 100644 --- a/app/bower_components/bootstrap-sass-official/.bower.json +++ b/app/bower_components/bootstrap-sass-official/.bower.json @@ -1,6 +1,6 @@ { "name": "bootstrap-sass", - "version": "3.1.1+2", + "version": "3.2.0+1", "homepage": "https://github.com/twbs/bootstrap-sass", "authors": [ "Thomas McDonald", @@ -10,23 +10,23 @@ ], "description": "bootstrap-sass is a Sass-powered version of Bootstrap, ready to drop right into your Sass powered applications.", "main": [ - "vendor/assets/stylesheets/bootstrap.scss", - "vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.eot", - "vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.svg", - "vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf", - "vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.woff", - "vendor/assets/javascripts/bootstrap/affix.js", - "vendor/assets/javascripts/bootstrap/alert.js", - "vendor/assets/javascripts/bootstrap/button.js", - "vendor/assets/javascripts/bootstrap/carousel.js", - "vendor/assets/javascripts/bootstrap/collapse.js", - "vendor/assets/javascripts/bootstrap/dropdown.js", - "vendor/assets/javascripts/bootstrap/tab.js", - "vendor/assets/javascripts/bootstrap/transition.js", - "vendor/assets/javascripts/bootstrap/scrollspy.js", - "vendor/assets/javascripts/bootstrap/modal.js", - "vendor/assets/javascripts/bootstrap/tooltip.js", - "vendor/assets/javascripts/bootstrap/popover.js" + "assets/stylesheets/bootstrap.scss", + "assets/fonts/bootstrap/glyphicons-halflings-regular.eot", + "assets/fonts/bootstrap/glyphicons-halflings-regular.svg", + "assets/fonts/bootstrap/glyphicons-halflings-regular.ttf", + "assets/fonts/bootstrap/glyphicons-halflings-regular.woff", + "assets/javascripts/bootstrap/affix.js", + "assets/javascripts/bootstrap/alert.js", + "assets/javascripts/bootstrap/button.js", + "assets/javascripts/bootstrap/carousel.js", + "assets/javascripts/bootstrap/collapse.js", + "assets/javascripts/bootstrap/dropdown.js", + "assets/javascripts/bootstrap/tab.js", + "assets/javascripts/bootstrap/transition.js", + "assets/javascripts/bootstrap/scrollspy.js", + "assets/javascripts/bootstrap/modal.js", + "assets/javascripts/bootstrap/tooltip.js", + "assets/javascripts/bootstrap/popover.js" ], "keywords": [ "twbs", @@ -44,13 +44,16 @@ "Rakefile", "Gemfile" ], - "_release": "3.1.1+2", + "dependencies": { + "jquery": ">= 1.9.0" + }, + "_release": "3.2.0+1", "_resolution": { "type": "version", - "tag": "v3.1.1+2", - "commit": "039f08dc011ea5f6be4b9bd2d00789cb440cc358" + "tag": "v3.2.0+1", + "commit": "6f45298818f454aead771ecd0c6398d7c17d8649" }, "_source": "git://github.com/twbs/bootstrap-sass.git", - "_target": "~3.1.1", + "_target": "~3.2.0", "_originalSource": "bootstrap-sass-official" } \ No newline at end of file diff --git a/app/bower_components/bootstrap-sass-official/CHANGELOG.md b/app/bower_components/bootstrap-sass-official/CHANGELOG.md index 8f1cfe4..d6d1d62 100644 --- a/app/bower_components/bootstrap-sass-official/CHANGELOG.md +++ b/app/bower_components/bootstrap-sass-official/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 3.2.0.0 + +- Assets (Sass, JS, fonts) moved from `vendor/assets` to `assets`. `bootstrap.js` now contains concatenated JS. +- Compass generator now copies JS and fonts, and provides a better default `styles.sass`. +- Compass, Sprockets, and Mincer asset path helpers are now provided in pure Sass: `bootstrap-compass`, `bootstrap-sprockets`, and `bootstrap-mincer`. +Asset path helpers must be imported before `bootstrap`, more in Readme. +- Sprockets / Mincer JS manifest has been moved to `bootstrap-sprockets.js`. +It can be required without adding Bootstrap JS directory to load path, as it now uses relative paths. +- Sprockets: `depend_on_asset` (`glyphicons.scss`) has been changed to `depend_on` to work around an issue with `depend_on_asset`. +[More information](https://github.com/twbs/bootstrap-sass/issues/592#issuecomment-46570286). + ## 3.1.1.0 - Updated Bower docs diff --git a/app/bower_components/bootstrap-sass-official/README.md b/app/bower_components/bootstrap-sass-official/README.md index a132ca9..18b028d 100644 --- a/app/bower_components/bootstrap-sass-official/README.md +++ b/app/bower_components/bootstrap-sass-official/README.md @@ -1,4 +1,4 @@ -# Bootstrap for Sass [![Build Status](http://img.shields.io/travis/twbs/bootstrap-sass.svg)](http://travis-ci.org/twbs/bootstrap-sass) +# Bootstrap for Sass [![Gem Version](https://badge.fury.io/rb/bootstrap-sass.svg)](http://badge.fury.io/rb/bootstrap-sass) [![Bower Version](https://badge.fury.io/bo/bootstrap-sass-official.svg)](http://badge.fury.io/bo/bootstrap-sass-official) [![Build Status](http://img.shields.io/travis/twbs/bootstrap-sass.svg)](http://travis-ci.org/twbs/bootstrap-sass) `bootstrap-sass` is a Sass-powered version of [Bootstrap](http://github.com/twbs/bootstrap), ready to drop right into your Sass powered applications. @@ -13,21 +13,39 @@ Please see the appropriate guide for your environment of choice: In your Gemfile you need to add the `bootstrap-sass` gem, and ensure that the `sass-rails` gem is present - it is added to new Rails applications by default. ```ruby +gem 'bootstrap-sass', '~> 3.2.0' gem 'sass-rails', '>= 3.2' -gem 'bootstrap-sass', '~> 3.1.1' +``` + +It is also recommended to use [Autoprefixer](https://github.com/ai/autoprefixer-rails) with Bootstrap +to add browser vendor prefixes automatically. Simply add the gem: + +```ruby +gem 'autoprefixer-rails' ``` `bundle install` and restart your server to make the files available through the pipeline. +In `app/assets/stylesheets/application.css.scss`: + +```scss +@import "bootstrap-sprockets"; +@import "bootstrap"; +``` + +Do not use `//= require` in Sass or your other stylesheets will not be [able to access][antirequire] the Bootstrap mixins or variables. + +In `app/assets/javascripts/application.js`: + +```js +//= require jquery +//= require bootstrap-sprockets +``` #### Rails 3.2.x Rails 3.2 is [no longer maintained for bugfixes](http://guides.rubyonrails.org/maintenance_policy.html), and you should upgrade as soon as possible. -If you must use it, make sure bootstrap-sass is moved out of the `:assets` group. -This is because, by default in Rails 3.2, assets group gems are not required in `production`. -However, for pre-compilation to succeed in production, `bootstrap-sass` gem must be required. - Starting with bootstrap-sass v3.1.1.1, due to the structural changes from upstream you will need these backported asset pipeline gems on Rails 3.2. There is more on why this is necessary in https://github.com/twbs/bootstrap-sass/issues/523 and https://github.com/twbs/bootstrap-sass/issues/578. @@ -53,55 +71,49 @@ require 'bootstrap-sass' ``` ```console -bundle exec compass install bootstrap +$ bundle exec compass install bootstrap ``` If you are creating a new Compass project, you can generate it with bootstrap-sass support: ```console -bundle exec compass create my-new-project -r bootstrap-sass --using bootstrap +$ bundle exec compass create my-new-project -r bootstrap-sass --using bootstrap ``` or, alternatively, if you're not using a Gemfile for your dependencies: ```console -compass create my-new-project -r bootstrap-sass --using bootstrap +$ compass create my-new-project -r bootstrap-sass --using bootstrap ``` This will create a new Compass project with the following files in it: -* [_variables.scss](/templates/project/_variables.sass.erb) - all of bootstrap variables (override them here). -* [styles.scss](/templates/project/styles.sass) - main project SCSS file, import `variables` and `bootstrap`. +* [styles.sass](/templates/project/styles.sass) - main project Sass file, imports Bootstrap and variables. +* [_bootstrap-variables.sass](/templates/project/_bootstrap-variables.sass.erb) - all of Bootstrap variables, override them here. Some bootstrap-sass mixins may conflict with the Compass ones. If this happens, change the import order so that Compass mixins are loaded later. -### c. Ruby without Compass / Rails - -Require the gem, and load paths and Sass helpers will be configured automatically: - -```ruby -require 'bootstrap-sass' -``` - -### d. Node.js / Bower +### c. Bower Using bootstrap-sass as a Bower package is still being tested. It is compatible with node-sass 0.8.3+. You can install it with: -```bash -bower install bootstrap-sass-official +```console +$ bower install bootstrap-sass-official ``` `bootstrap-sass` is taken so make sure you use the command above. -Sass, JS, and all other assets are located at [vendor/assets](/vendor/assets). +Sass, JS, and all other assets are located at [assets](/assets). By default, `bower.json` main field list only the main `bootstrap.scss` and all the static assets (fonts and JS). This is compatible by default with asset managers such as [wiredep](https://github.com/taptapship/wiredep). -#### Mincer +#### Node.js Mincer -If you use [mincer][mincer] with node-sass, import bootstrap into a `.css.ejs.scss` file like so: +If you use [mincer][mincer] with node-sass, import bootstrap into like so: + +In `application.css.ejs.scss` (NB **.css.ejs.css**): ```scss // Import mincer asset paths helper integration @@ -109,47 +121,95 @@ If you use [mincer][mincer] with node-sass, import bootstrap into a `.css.ejs.sc @import "bootstrap"; ``` +In `application.js`: + +```js +//= require bootstrap-sprockets +``` + See also this [example manifest.js](/test/dummy_node_mincer/manifest.js) for mincer. -#### Number precision + +### Configuration + +#### Sass + +By default all of Bootstrap is imported. + +You can also import components explicitly. To start with a full list of modules copy +[`bootstrap.scss`](assets/stylesheets/bootstrap.scss) file into your assets as `bootstrap-custom.scss`. +Then comment out components you do not want from `bootstrap-custom`. +In the application Sass file, replace `@import 'bootstrap'` with: + +```scss +@import 'bootstrap-custom'; +``` + +#### Sass: Number Precision bootstrap-sass [requires](https://github.com/twbs/bootstrap-sass/issues/409) minimum [Sass number precision][sass-precision] of 10 (default is 5). -When using ruby Sass compiler with the bower version you can enforce the limit with: +Precision is set for Rails and Compass automatically. +When using ruby Sass compiler standalone or with the Bower version you can set it with: ```ruby ::Sass::Script::Number.precision = [10, ::Sass::Script::Number.precision].max ``` -Precision option is now available in libsass, but it has not made into node-sass yet. +Note that libsass and node-sass do not currently support the precision option, due to an open bug ([bug #364](https://github.com/sass/libsass/issues/364)) in libsass. -#### JS and fonts -Assets are discovered automatically on Rails, Sprockets, Compass, and Node + Mincer, using native asset path helpers. +#### Sass: Autoprefixer -Otherwise the fonts are referenced as: +Using [Autoprefixer][autoprefixer] with Bootstrap is recommended. +[Autoprefixer][autoprefixer] adds vendor prefixes to CSS rules using values from [Can I Use](http://caniuse.com/). -```sass +#### JavaScript + +[`assets/javascripts/bootstrap.js`](/assets/javascripts/bootstrap.js) contains all of Bootstrap JavaScript, +concatenated in the [correct order](/assets/javascripts/bootstrap-sprockets.js). + + +#### JavaScript with Sprockets or Mincer + +If you use Sprockets or Mincer, you can require `bootstrap-sprockets` instead to load the individual modules: + +```js +// Load all Bootstrap JavaScript +//= require bootstrap-sprockets +``` + +You can also load individual modules, provided you also require any dependencies. +You can check dependencies in the [Bootstrap JS documentation][jsdocs]. + +```js +//= require bootstrap/scrollspy +//= require bootstrap/modal +//= require bootstrap/dropdown +``` + +#### Fonts + +The fonts are referenced as: + +```scss "#{$icon-font-path}#{$icon-font-name}.eot" ``` -`$icon-font-path` defaults to `bootstrap/`. +`$icon-font-path` defaults to `bootstrap/` if asset path helpers are used, and `../fonts/bootstrap/` otherwise. -When not using an asset pipeline, you can copy fonts and JS from bootstrap-sass, they are located at [vendor/assets](/vendor/assets): +When using bootstrap-sass with Compass, Sprockets, or Mincer, you **must** import the relevant path helpers before Bootstrap itself, for example: -```bash -mkdir public/fonts -cp -r $(bundle show bootstrap-sass)/vendor/assets/fonts/ public/fonts/ -mkdir public/javascripts -cp -r $(bundle show bootstrap-sass)/vendor/assets/javascripts/ public/javascripts/ +```scss +@import "bootstrap-compass"; +@import "bootstrap"; ``` ## Usage ### Sass -Import Bootstrap into a Sass file (for example, `application.css.scss`) to get all of Bootstrap's styles, mixins and variables! -We recommend against using `//= require` directives, since none of your other stylesheets will be [able to access][antirequire] the Bootstrap mixins or variables. +Import Bootstrap into a Sass file (for example, application.css.scss) to get all of Bootstrap's styles, mixins and variables! ```scss @import "bootstrap"; @@ -171,38 +231,6 @@ $navbar-default-color: $light-orange; @import "bootstrap"; ``` -You can also import components explicitly. To start with a full list of modules copy this file from the gem: - -```bash -cp $(bundle show bootstrap-sass)/vendor/assets/stylesheets/bootstrap.scss \ - app/assets/stylesheets/bootstrap-custom.scss -``` -Comment out components you do not want from `bootstrap-custom`. - -In `application.sass`, replace `@import 'bootstrap'` with: - -```scss - @import 'bootstrap-custom'; -``` - -### Javascript - -We have a helper that includes all Bootstrap javascripts. If you use Rails (or Sprockets separately), -put this in your Javascript manifest (usually in `application.js`) to load the files in the [correct order](/vendor/assets/javascripts/bootstrap.js): - -```js -// Loads all Bootstrap javascripts -//= require bootstrap -``` - -You can also load individual modules, provided you also require any dependencies. You can check dependencies in the [Bootstrap JS documentation][jsdocs]. - -```js -//= require bootstrap/scrollspy -//= require bootstrap/modal -//= require bootstrap/dropdown -``` - --- ## Development and Contributing @@ -229,9 +257,8 @@ To convert a specific branch or version, pass the branch name or the commit hash The latest converter script is located [here][converter] and does the following: * Converts upstream bootstrap LESS files to its matching SCSS file. -* Copies all upstream JavaScript into `vendor/assets/javascripts/bootstrap` -* Generates a javascript manifest at `vendor/assets/javascripts/bootstrap.js` -* Copies all upstream font files into `vendor/assets/fonts/bootstrap` +* Copies all upstream JavaScript into `assets/javascripts/bootstrap`, an Sprockets manifest at `assets/javascripts/bootstrap-sprockets.js`, and a concatenation at `assets/javascripts/bootstrap.js`. +* Copies all upstream font files into `assets/fonts/bootstrap`. * Sets `Bootstrap::BOOTSTRAP_SHA` in [version.rb][version] to the branch sha. This converter fully converts original LESS to SCSS. Conversion is automatic but requires instructions for certain transformations (see converter output). @@ -262,3 +289,4 @@ Michael Hartl's [Rails Tutorial](http://railstutorial.org/), [gitlabhq](http://g [jsdocs]: http://getbootstrap.com/javascript/#transitions [sass-precision]: http://sass-lang.com/documentation/Sass/Script/Number.html#precision-class_method [mincer]: https://github.com/nodeca/mincer +[autoprefixer]: https://github.com/ai/autoprefixer diff --git a/app/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.eot b/app/bower_components/bootstrap-sass-official/assets/fonts/bootstrap/glyphicons-halflings-regular.eot similarity index 100% rename from app/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.eot rename to app/bower_components/bootstrap-sass-official/assets/fonts/bootstrap/glyphicons-halflings-regular.eot diff --git a/app/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.svg b/app/bower_components/bootstrap-sass-official/assets/fonts/bootstrap/glyphicons-halflings-regular.svg similarity index 100% rename from app/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.svg rename to app/bower_components/bootstrap-sass-official/assets/fonts/bootstrap/glyphicons-halflings-regular.svg diff --git a/app/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf b/app/bower_components/bootstrap-sass-official/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf similarity index 100% rename from app/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf rename to app/bower_components/bootstrap-sass-official/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf diff --git a/app/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.woff b/app/bower_components/bootstrap-sass-official/assets/fonts/bootstrap/glyphicons-halflings-regular.woff similarity index 100% rename from app/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/glyphicons-halflings-regular.woff rename to app/bower_components/bootstrap-sass-official/assets/fonts/bootstrap/glyphicons-halflings-regular.woff diff --git a/app/bower_components/bootstrap-sass-official/assets/javascripts/bootstrap-sprockets.js b/app/bower_components/bootstrap-sass-official/assets/javascripts/bootstrap-sprockets.js new file mode 100644 index 0000000..1abde49 --- /dev/null +++ b/app/bower_components/bootstrap-sass-official/assets/javascripts/bootstrap-sprockets.js @@ -0,0 +1,12 @@ +//= require ./bootstrap/affix +//= require ./bootstrap/alert +//= require ./bootstrap/button +//= require ./bootstrap/carousel +//= require ./bootstrap/collapse +//= require ./bootstrap/dropdown +//= require ./bootstrap/tab +//= require ./bootstrap/transition +//= require ./bootstrap/scrollspy +//= require ./bootstrap/modal +//= require ./bootstrap/tooltip +//= require ./bootstrap/popover diff --git a/app/bower_components/bootstrap-sass-official/assets/javascripts/bootstrap.js b/app/bower_components/bootstrap-sass-official/assets/javascripts/bootstrap.js new file mode 100644 index 0000000..30409f4 --- /dev/null +++ b/app/bower_components/bootstrap-sass-official/assets/javascripts/bootstrap.js @@ -0,0 +1,2107 @@ +/* ======================================================================== + * Bootstrap: affix.js v3.2.0 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = + this.unpin = + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.2.0' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var scrollHeight = $(document).height() + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false : + offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' : + offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false + + if (this.affixed === affix) return + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger($.Event(affixType.replace('affix', 'affixed'))) + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - this.$element.height() - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom) data.offset.bottom = data.offsetBottom + if (data.offsetTop) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.2.0 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.2.0' + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.hasClass('alert') ? $this : $this.parent() + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(150) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.2.0 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.2.0' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state = state + 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + $el[val](data[state] == null ? this.options[state] : data[state]) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked') && this.$element.hasClass('active')) changed = false + else $parent.find('.active').removeClass('active') + } + if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') + } + + if (changed) this.$element.toggleClass('active') + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + Plugin.call($btn, 'toggle') + e.preventDefault() + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.2.0 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this)) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = + this.sliding = + this.interval = + this.$active = + this.$items = null + + this.options.pause == 'hover' && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.2.0' + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true + } + + Carousel.prototype.keydown = function (e) { + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || $active[type]() + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var fallback = type == 'next' ? 'first' : 'last' + var that = this + + if (!$next.length) { + if (!this.options.wrap) return + $next = this.$element.find('.item')[fallback]() + } + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + }) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.2.0 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.transitioning = null + + if (this.options.parent) this.$parent = $(this.options.parent) + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.2.0' + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var actives = this.$parent && this.$parent.find('> .panel > .in') + + if (actives && actives.length) { + var hasData = actives.data('bs.collapse') + if (hasData && hasData.transitioning) return + Plugin.call(actives, 'hide') + hasData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse') + .removeClass('in') + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .trigger('hidden.bs.collapse') + .removeClass('collapsing') + .addClass('collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(350) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && option == 'show') option = !option + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var href + var $this = $(this) + var target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + var $target = $(target) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + var parent = $this.attr('data-parent') + var $parent = parent && $(parent) + + if (!data || !data.transitioning) { + if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') + $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + } + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.2.0 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.2.0' + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $('