upgrading to angular 0.9.15 lethal-stutter
authorIgor Minar <iiminar@gmail.com>
Mon, 11 Apr 2011 21:37:19 +0000 (14:37 -0700)
committerIgor Minar <iiminar@gmail.com>
Mon, 11 Apr 2011 21:37:19 +0000 (14:37 -0700)
app/lib/angular/angular.js
app/lib/angular/angular.min.js
app/lib/angular/version.txt
test/lib/angular/angular-scenario.js
test/lib/angular/version.txt

index f9750f2..3810877 100644 (file)
@@ -452,7 +452,7 @@ function HTML(html, option) {
       };
 }
 
-if (msie) {
+if (msie < 9) {
   nodeName_ = function(element) {
     element = element.nodeName ? element : element[0];
     return (element.scopeName && element.scopeName != 'HTML' ) ? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName;
@@ -571,7 +571,8 @@ function isLeafNode (node) {
  *
  * @param {*} source The source to be used to make a copy.
  *                   Can be any type including primitives, `null` and `undefined`.
- * @param {(Object|Array)=} destination Optional destination into which the source is copied.
+ * @param {(Object|Array)=} destination Optional destination into which the source is copied. If
+ *     provided, must be of the same type as `source`.
  * @returns {*} The copy or updated `destination` if `destination` was specified.
  *
  * @example
@@ -893,13 +894,17 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  * @TODO rename to ng:autobind to ng:autoboot
  *
  * @description
- * This section explains how to bootstrap your application with angular, using either the angular
- * javascript file, or manually.
+ * This doc explains how to bootstrap your application with angular. You can either use
+ * `ng:autobind` script tag attribute or perform a manual bootstrap.
  *
  * # Auto-bootstrap with `ng:autobind`
- * The simplest way to get an <angular/> application up and running is by inserting a script tag in
- * your HTML file that bootstraps the `http://code.angularjs.org/angular-x.x.x.min.js` code and uses
- * the special `ng:autobind` attribute, like in this snippet of HTML:
+ * The simplest way to get an angular application up and running is by adding a script tag in
+ * your HTML file that contains `ng:autobind` attribute. This will:
+ *
+ * * Load the angular script
+ * * Tell angular to compile the entire document (or just its portion if the attribute has a value)
+ *
+ * For example:
  *
  * <pre>
     &lt;!doctype html&gt;
@@ -919,14 +924,14 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  * you don't need to explicitly add an `onLoad` event handler; auto bind mode takes care of all the
  * work for you.
  *
- * In order to compile only a part of the document, specify the id of the element that should be
- * compiled as the value of the `ng:autobind` attribute, e.g. `ng:autobind="angularContent"`.
+ * In order to compile only a part of the document with a root element, specify the id of the root
+ * element as the value of the `ng:autobind` attribute, e.g. `ng:autobind="angularContent"`.
  *
  *
  * ## Auto-bootstrap with `#autobind`
- * In rare cases when you can't define the `ng` namespace before the script tag (e.g. in some CMS
- * systems, etc), it is possible to auto-bootstrap angular by appending `#autobind` to the script
- * src URL, like in this snippet:
+ * In some rare cases you can't define the `ng:` prefix before the script tag's attribute  (e.g. in
+ * some CMS systems). In these situations it is possible to auto-bootstrap angular by appending
+ * `#autobind` to the script `src` URL, like in this snippet:
  *
  * <pre>
     &lt;!doctype html&gt;
@@ -943,14 +948,14 @@ function encodeUriQuery(val, pctEncodeSpaces) {
     &lt;/html&gt;
  * </pre>
  *
- * In this case it's the `#autobind` URL fragment that tells angular to auto-bootstrap.
+ * In this snippet it is the `#autobind` URL fragment that tells angular to auto-bootstrap.
  *
  * Similarly to `ng:autobind`, you can specify an element id that should be exclusively targeted for
  * compilation as the value of the `#autobind`, e.g. `#autobind=angularContent`.
  *
  * ## Filename Restrictions for Auto-bootstrap
  * In order for us to find the auto-bootstrap script attribute or URL fragment, the value of the
- * `script` `src` attribute that loads angular script must match one of these naming
+ * `script` `src` attribute that loads the angular script must match one of these naming
  * conventions:
  *
  * - `angular.js`
@@ -961,15 +966,15 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  * - `angular-x.x.x-xxxxxxxx.min.js` (dev snapshot)
  * - `angular-bootstrap.js` (used for development of angular)
  *
- * Optionally, any of the filename format above can be prepended with relative or absolute URL that
- * ends with `/`.
+ * Optionally, any of the filename formats above can be prepended with a relative or absolute URL
+ * that ends with `/`.
  *
  *
- * ## Manual Bootstrap
- * Using auto-bootstrap is a handy way to start using <angular/>, but advanced users who want more
- * control over the initialization process might prefer to use manual bootstrap instead.
+ * # Manual Bootstrap
+ * Using auto-bootstrap is a handy way to start using angular, but advanced users who want more
+ * control over the initialization process might prefer to use the manual bootstrap method instead.
  *
- * The best way to get started with manual bootstraping is to look at the magic behind `ng:autobind`
+ * The best way to get started with manual bootstraping is to look at the magic behind `ng:autobind`,
  * by writing out each step of the autobind process explicitly. Note that the following code is
  * equivalent to the code in the previous section.
  *
@@ -993,22 +998,23 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  *
  * This is the sequence that your code should follow if you're bootstrapping angular on your own:
  *
- * * After the page is loaded, find the root of the HTML template, which is typically the root of
- *   the document.
- * * Run the HTML compiler, which converts the templates into an executable, bi-directionally bound
- *   application.
+ * 1. After the page is loaded, find the root of the HTML template, which is typically the root of
+ *    the document.
+ * 2. Run the HTML compiler, which converts the templates into an executable, bi-directionally bound
+ *    application.
  *
  *
- * ##XML Namespace
- * *IMPORTANT:* When using <angular/> you must declare the ng namespace using the xmlns tag. If you
- * don't declare the namespace, Internet Explorer does not render widgets properly.
+ * ## XML Namespace
+ * *IMPORTANT:* When using angular, you must declare the ng namespace using the xmlns tag. If you
+ * don't declare the namespace, Internet Explorer older than 9 does not render widgets properly. The
+ * namespace must be declared even if you use HTML instead of XHTML.
  *
  * <pre>
  * &lt;html xmlns:ng="http://angularjs.org"&gt;
  * </pre>
  *
  *
- * ## Create your own namespace
+ * ### Create your own namespace
  * If you want to define your own widgets, you must create your own namespace and use that namespace
  * to form the fully qualified widget name. For example, you could map the alias `my` to your domain
  * and create a widget called my:widget. To create your own namespace, simply add another xmlsn tag
@@ -1019,8 +1025,8 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  * </pre>
  *
  *
- * ## Global Object
- * The <angular/> script creates a single global variable `angular` in the global namespace. All
+ * ### Global Object
+ * The angular script creates a single global variable `angular` in the global namespace. All
  * APIs are bound to fields of this global object.
  *
  */
@@ -3143,7 +3149,7 @@ ResourceFactory.prototype = {
           route.url(extend({}, action.params || {}, extractParams(data), params)),
           data,
           function(status, response, clear) {
-            if (status == 200) {
+            if (200 <= status && status < 300) {
               if (response) {
                 if (action.isArray) {
                   value.length = 0;
@@ -4103,7 +4109,7 @@ forEach({
     }
   },
 
-  text: extend(msie
+  text: extend((msie < 9)
       ? function(element, value) {
         // NodeType == 3 is text node
         if (element.nodeType == 3) {
@@ -5449,10 +5455,10 @@ angularFilter.uppercase = uppercase;
  * @example
    <doc:example>
      <doc:source>
-       Snippet: <textarea name="snippet" cols="60" rows="3">
-&lt;p style="color:blue"&gt;an html
-&lt;em onmouseover="this.textContent='PWN3D!'"&gt;click here&lt;/em&gt;
-snippet&lt;/p&gt;</textarea>
+      Snippet: <textarea name="snippet" cols="60" rows="3">
+     &lt;p style="color:blue"&gt;an html
+     &lt;em onmouseover="this.textContent='PWN3D!'"&gt;click here&lt;/em&gt;
+     snippet&lt;/p&gt;</textarea>
        <table>
          <tr>
            <td>Filter</td>
@@ -6651,31 +6657,61 @@ var URL_MATCH = /^(file|ftp|http|https):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+)
  * @name angular.service.$location
  * @requires $browser
  *
- * @property {string} href
- * @property {string} protocol
- * @property {string} host
- * @property {number} port
- * @property {string} path
- * @property {Object.<string|boolean>} search
- * @property {string} hash
- * @property {string} hashPath
- * @property {Object.<string|boolean>} hashSearch
+ * @property {string} href The full URL of the current location.
+ * @property {string} protocol The protocol part of the URL (e.g. http or https).
+ * @property {string} host The host name, ip address or FQDN of the current location.
+ * @property {number} port The port number of the current location (e.g. 80, 443, 8080).
+ * @property {string} path The path of the current location (e.g. /myapp/inbox).
+ * @property {Object.<string|boolean>} search Map of query parameters (e.g. {user:"foo", page:23}).
+ * @property {string} hash The fragment part of the URL of the current location (e.g. #foo).
+ * @property {string} hashPath Similar to `path`, but located in the `hash` fragment
+ *     (e.g. ../foo#/some/path  => /some/path).
+ * @property {Object.<string|boolean>} hashSearch Similar to `search` but located in `hash`
+ *     fragment (e.g. .../foo#/some/path?hashQuery=param  =>  {hashQuery: "param"}).
  *
  * @description
  * Parses the browser location url and makes it available to your application.
- * Any changes to the url are reflected into $location service and changes to
- * $location are reflected to url.
+ * Any changes to the url are reflected into `$location` service and changes to
+ * `$location` are reflected in the browser location url.
+ *
  * Notice that using browser's forward/back buttons changes the $location.
  *
  * @example
    <doc:example>
      <doc:source>
-       <a href="#">clear hash</a> |
-       <a href="#myPath?name=misko">test hash</a><br/>
-       <input type='text' name="$location.hash"/>
-       <pre>$location = {{$location}}</pre>
+       <div ng:init="$location = $service('$location')">
+         <a id="ex-test" href="#myPath?name=misko">test hash</a>|
+         <a id="ex-reset" href="#!angular.service.$location">reset hash</a><br/>
+         <input type='text' name="$location.hash" size="30">
+         <pre>$location = {{$location}}</pre>
+       </div>
      </doc:source>
      <doc:scenario>
+       it('should initialize the input field', function() {
+         expect(using('.doc-example-live').element('input[name=$location.hash]').val()).
+           toBe('!angular.service.$location');
+       });
+
+
+       it('should bind $location.hash to the input field', function() {
+         using('.doc-example-live').input('$location.hash').enter('foo');
+         expect(browser().location().hash()).toBe('foo');
+       });
+
+
+       it('should set the hash to a test string with test link is presed', function() {
+         using('.doc-example-live').element('#ex-test').click();
+         expect(using('.doc-example-live').element('input[name=$location.hash]').val()).
+           toBe('myPath?name=misko');
+       });
+
+       it('should reset $location when reset link is pressed', function() {
+         using('.doc-example-live').input('$location.hash').enter('foo');
+         using('.doc-example-live').element('#ex-reset').click();
+         expect(using('.doc-example-live').element('input[name=$location.hash]').val()).
+           toBe('!angular.service.$location');
+       });
+
      </doc:scenario>
     </doc:example>
  */
@@ -6704,22 +6740,18 @@ angularServiceInject("$location", function($browser) {
    * @methodOf angular.service.$location
    *
    * @description
-   * Update location object
-   * Does not immediately update the browser
-   * Browser is updated at the end of $eval()
+   * Updates the location object.
    *
-   * @example
-    <doc:example>
-      <doc:source>
-        scope.$location.update('http://www.angularjs.org/path#hash?search=x');
-        scope.$location.update({host: 'www.google.com', protocol: 'https'});
-        scope.$location.update({hashPath: '/path', hashSearch: {a: 'b', x: true}});
-      </doc:source>
-      <doc:scenario>
-      </doc:scenario>
-    </doc:example>
+   * Does not immediately update the browser. Instead the browser is updated at the end of $eval()
+   * cycle.
+   *
+   * <pre>
+       $location.update('http://www.angularjs.org/path#hash?search=x');
+       $location.update({host: 'www.google.com', protocol: 'https'});
+       $location.update({hashPath: '/path', hashSearch: {a: 'b', x: true}});
+     </pre>
    *
-   * @param {(string|Object)} href Full href as a string or object with properties
+   * @param {string|Object} href Full href as a string or object with properties
    */
   function update(href) {
     if (isString(href)) {
@@ -6746,24 +6778,20 @@ angularServiceInject("$location", function($browser) {
    * @methodOf angular.service.$location
    *
    * @description
-   * Update location hash part
+   * Updates the hash fragment part of the url.
+   *
    * @see update()
    *
-   * @example
-    <doc:example>
-      <doc:source>
-        scope.$location.updateHash('/hp')
+   * <pre>
+       scope.$location.updateHash('/hp')
          ==> update({hashPath: '/hp'})
-        scope.$location.updateHash({a: true, b: 'val'})
+       scope.$location.updateHash({a: true, b: 'val'})
          ==> update({hashSearch: {a: true, b: 'val'}})
-        scope.$location.updateHash('/hp', {a: true})
+       scope.$location.updateHash('/hp', {a: true})
          ==> update({hashPath: '/hp', hashSearch: {a: true}})
-      </doc:source>
-      <doc:scenario>
-      </doc:scenario>
-    </doc:example>
+     </pre>
    *
-   * @param {(string|Object)} path A hashPath or hashSearch object
+   * @param {string|Object} path A hashPath or hashSearch object
    * @param {Object=} search A hashSearch object
    */
   function updateHash(path, search) {
@@ -6795,11 +6823,11 @@ angularServiceInject("$location", function($browser) {
    * - `$location.hash`
    * - everything else
    *
-   * @example
-   * <pre>
-   *   scope.$location.href = 'http://www.angularjs.org/path#a/b'
-   * </pre>
-   * immediately after this call, other properties are still the old ones...
+   * Keep in mind that if the following code is executed:
+   *
+   * scope.$location.href = 'http://www.angularjs.org/path#a/b'
+   *
+   * immediately afterwards all other properties are still the old ones...
    *
    * This method checks the changes and update location to the consistent state
    */
@@ -7894,7 +7922,7 @@ angularServiceInject('$xhr', function($browser, $error, $log, $updateView){
  * @name angular.directive.ng:init
  *
  * @description
- * `ng:init` attribute allows the for initialization tasks to be executed
+ * The `ng:init` attribute specifies initialization tasks to be executed
  *  before the template enters execution mode during bootstrap.
  *
  * @element ANY
@@ -7927,21 +7955,31 @@ angularDirective("ng:init", function(expression){
  * @name angular.directive.ng:controller
  *
  * @description
- * To support the Model-View-Controller design pattern, it is possible
- * to assign behavior to a scope through `ng:controller`. The scope is
- * the MVC model. The HTML (with data bindings) is the MVC view.
- * The `ng:controller` directive specifies the MVC controller class
+ * The `ng:controller` directive assigns behavior to a scope. This is a key aspect of how angular
+ * supports the principles behind the Model-View-Controller design pattern.
+ *
+ * MVC components in angular:
+ *
+ * * Model — The Model is data in scope properties; scopes are attached to the DOM.
+ * * View — The template (HTML with data bindings) is rendered into the View.
+ * * Controller — The `ng:controller` directive specifies a Controller class; the class has
+ *   methods that typically express the business logic behind the application.
+ *
+ * Note that an alternative way to define controllers is via the `{@link angular.service.$route}`
+ * service.
  *
  * @element ANY
- * @param {expression} expression {@link guide.expression Expression} to eval.
+ * @param {expression} expression Name of a globally accessible constructor function or an
+ *     {@link guide.expression expression} that on the current scope evaluates to a constructor
+ *     function.
  *
  * @example
- * Here is a simple form for editing the user contact information. Adding, removing clearing and
- * greeting are methods which are declared on the controller (see source tab). These methods can
- * easily be called from the angular markup. Notice that the scope becomes the controller's class
- * this. 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 to update it
- * manually.
+ * 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.
    <doc:example>
      <doc:source>
       <script type="text/javascript">
@@ -8034,8 +8072,9 @@ angularDirective("ng:controller", function(expression){
          * <input name="obj.b" value="2">
          = {{obj.multiplied = obj.a * obj.b}} <br>
        <span ng:eval="obj.divide = obj.a / obj.b"></span>
-       <span ng:eval="obj.updateCount = 1 + (obj.updateCount||0)"></span>
-       <tt>obj.divide = {{obj.divide}}</tt><br/>
+       <span ng:eval="obj.updateCount = 1 + (obj.updateCount||0)">
+       </span>
+       <tt>obj.divide = {{obj.divide}}</tt><br>
        <tt>obj.updateCount = {{obj.updateCount}}</tt>
      </doc:source>
      <doc:scenario>
@@ -8061,20 +8100,20 @@ angularDirective("ng:eval", function(expression){
  * @name angular.directive.ng:bind
  *
  * @description
- * The `ng:bind` attribute asks <angular/> to replace the text content of this
- * HTML element with the value of the given expression and kept it up to
- * date when the expression's value changes. Usually you just write
- * {{expression}} and let <angular/> compile it into
+ * The `ng:bind` attribute asks angular to replace the text content of this
+ * HTML element with the value of the given expression, and to keep the text
+ * content up to date when the expression's value changes. Usually you would
+ * just write `{{ expression }}` and let angular compile it into
  * `<span ng:bind="expression"></span>` at bootstrap time.
  *
  * @element ANY
  * @param {expression} expression {@link guide.expression Expression} to eval.
  *
  * @example
- * Try it here: enter text in text box and watch the greeting change.
+ * You can try it right here: enter text in the text box and watch the greeting change.
    <doc:example>
      <doc:source>
-       Enter name: <input type="text" name="name" value="Whirled">. <br>
+       Enter name: <input type="text" name="name" value="Whirled"> <br>
        Hello <span ng:bind="name" />!
      </doc:source>
      <doc:scenario>
@@ -8232,7 +8271,7 @@ var REMOVE_ATTRIBUTES = {
  * contains a JSON key value pairs representing which attributes need to be mapped to which
  * {@link guide.expression expressions}.
  *
- * You dont usually write the `ng:bind-attr` in the HTML since embedding
+ * You don't usually write the `ng:bind-attr` in the HTML since embedding
  * <tt ng:non-bindable>{{expression}}</tt> into the attribute directly as the attribute value is
  * preferred. The attributes get translated into `<span ng:bind-attr="{attr:expression}"/>` at
  * compile time.
@@ -8543,8 +8582,8 @@ angularDirective("ng:class-even", ngClass(function(i){return i % 2 === 1;}));
  * @name angular.directive.ng:show
  *
  * @description
- * The `ng:show` and `ng:hide` allows you to show or hide a portion
- * of the HTML conditionally.
+ * The `ng:show` and `ng:hide` directives show or hide a portion of the DOM tree (HTML)
+ * conditionally.
  *
  * @element ANY
  * @param {expression} expression If the {@link guide.expression expression} is truthy then the element
@@ -8554,8 +8593,8 @@ angularDirective("ng:class-even", ngClass(function(i){return i % 2 === 1;}));
    <doc:example>
      <doc:source>
         Click me: <input type="checkbox" name="checked"><br/>
-        Show: <span ng:show="checked">I show up when you checkbox is checked?</span> <br/>
-        Hide: <span ng:hide="checked">I hide when you checkbox is checked?</span>
+        Show: <span ng:show="checked">I show up when your checkbox is checked.</span> <br/>
+        Hide: <span ng:hide="checked">I hide when your checkbox is checked.</span>
      </doc:source>
      <doc:scenario>
        it('should check ng:show / ng:hide', function(){
@@ -8584,7 +8623,7 @@ angularDirective("ng:show", function(expression, element){
  * @name angular.directive.ng:hide
  *
  * @description
- * The `ng:show` and `ng:hide` allows you to show or hide a portion
+ * The `ng:hide` and `ng:show` directives hide or show a portion
  * of the HTML conditionally.
  *
  * @element ANY
@@ -8825,8 +8864,8 @@ angularAttrMarkup('{{}}', function(value, name, element){
  * @name angular.widget.HTML
  *
  * @description
- * The most common widgets you will use will be in the from of the
- * standard HTML set. These widgets are bound using the name attribute
+ * The most common widgets you will use will be in the form of the
+ * standard HTML set. These widgets are bound using the `name` attribute
  * to an expression. In addition they can have `ng:validate`, `ng:required`,
  * `ng:format`, `ng:change` attribute to further control their behavior.
  *
@@ -9657,18 +9696,20 @@ angularWidget('a', function() {
  * @name angular.widget.@ng:repeat
  *
  * @description
- * `ng:repeat` instantiates a template once per item from a collection. The collection is enumerated
- * with `ng:repeat-index` attribute starting from 0. Each template instance gets its own scope where
- * the given loop variable is set to the current collection item and `$index` is set to the item
- * index or key.
+ * The `ng:repeat` widget instantiates a template once per item from a collection. The collection is
+ * enumerated with the `ng:repeat-index` attribute, starting from 0. Each template instance gets 
+ * its own scope, where the given loop variable is set to the current collection item, and `$index` 
+ * is set to the item index or key.
  *
- * There are special properties exposed on the local scope of each template instance:
+ * Special properties are exposed on the local scope of each template instance, including:
  *
  *   * `$index` – `{number}` – iterator offset of the repeated element (0..length-1)
- *   * `$position` – {string} – position of the repeated element in the iterator. One of: `'first'`,
- *     `'middle'` or `'last'`.
+ *   * `$position` – `{string}` – position of the repeated element in the iterator. One of: 
+ *        * `'first'`,
+ *        * `'middle'` 
+ *        * `'last'`
  *
- * NOTE: `ng:repeat` looks like a directive, but is actually an attribute widget.
+ * Note: Although `ng:repeat` looks like a directive, it is actually an attribute widget.
  *
  * @element ANY
  * @param {string} repeat_expression The expression indicating how to enumerate a collection. Two
@@ -9678,6 +9719,7 @@ angularWidget('a', function() {
  *     is a scope expression giving the collection to enumerate.
  *
  *     For example: `track in cd.tracks`.
+ *
  *   * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
  *     and `expression` is the scope expression giving the collection to enumerate.
  *
@@ -9685,7 +9727,7 @@ angularWidget('a', function() {
  *
  * @example
  * This example initializes the scope to a list of names and
- * than uses `ng:repeat` to display every person.
+ * then uses `ng:repeat` to display every person:
     <doc:example>
       <doc:source>
         <div ng:init="friends = [{name:'John', age:25}, {name:'Mary', age:28}]">
@@ -9893,10 +9935,11 @@ angularWidget('ng:view', function(element) {
         }
 
         if (src) {
-          $xhr('GET', src, null, function(code, response){
+          //xhr's callback must be async, see commit history for more info
+          $xhr('GET', src, function(code, response){
             element.html(response);
             compiler.compile(element)(childScope);
-          }, false, true);
+          });
         } else {
           element.html('');
         }
index e630a7e..d8a02b6 100644 (file)
@@ -47,7 +47,7 @@ var h,i,j,v,p=a.$service("$invalidWidgets")||{markValid:q,markInvalid:q};if(!e)t
 c.push(d.parse(a,b.value))});return c},set:function(c){var f={};k(c,function(b){f[d.format(a,b)]=!0});k(b[0].options,function(a){a.selected=f[a.value]})}}}function Tb(){return{get:q,set:q}}function Ea(a){return function(b,c){var d=c.get();!d&&x(a)&&(d=A(a));z(b.get())&&x(d)&&b.set(d)}}function la(a,b,c,d,e){return n(function(f,g,h){var i=this,j=b(i,h),v=c(i,h),p=h.attr("ng:change")||"",r;j&&(d.call(i,j,v,h),this.$eval(h.attr("ng:init")||""),h.bind(a,function(a){function b(){var a=v.get();if(!e||a!=
 r)j.set(a),r=j.get(),i.$tryEval(p,h),f()}a.type=="keydown"?g(b):b()}),i.$watch(j.get,function(a){r!==a&&v.set(r=a)}))},{$inject:["$updateView","$defer"]})}function Fa(a){this.directives(!0);this.descend(!0);return Dc[D(a[0].type)]||q}if(typeof L.getAttribute==$)L.getAttribute=function(){};var D=function(a){return w(a)?a.toLowerCase():a},fb=function(a){return w(a)?a.toUpperCase():a},Rb="$element",eb="$validate",gc="boolean",R="function",Wb="length",Xb="name",wa="null",$b="number",gb="object",Zb="string",
 $="undefined",xa="ng-exception",ta="ng-validation-error",Da="noop",yb=-1E3,Ec={FIRST:-99999,LAST:99999,WATCH:yb},K=s.Error,S=parseInt((/msie (\d+)/.exec(D(navigator.userAgent))||[])[1],10),o,Ma,ba=[].slice,H=[].push,fc=s.console?F(s.console,s.console.error||q):q,u=s.angular||(s.angular={}),Ja=P(u,"markup"),nb=P(u,"attrMarkup"),B=P(u,"directive"),J=P(u,"widget",D),Va=P(u,"validator"),N=P(u,"filter"),Y=P(u,"formatter"),Ta=P(u,"service");P(u,"callbacks");var pa,ec=/^(|.*\/)angular(-.*?)?(\.min)?.js(\?[^#]*)?(#(.*))?$/,
-sb=24;pa=S?function(a){a=a.nodeName?a:a[0];return a.scopeName&&a.scopeName!="HTML"?fb(a.scopeName+":"+a.nodeName):a.nodeName}:function(a){return a.nodeName?a.nodeName:a[0].nodeName};u.toJson=M;u.fromJson=ca;Qa.prototype={attach:function(a,b){var c={};this.collectInits(a,c,b);Ga(c,function(a){k(a,function(a){a()})})},collectInits:function(a,b,c){var d=b[this.priority],e=c;d||(b[this.priority]=d=[]);this.newScope&&(e=T(c),c.$onEval(e.$eval),a.data("$scope",e));k(this.inits,function(b){d.push(function(){e.$tryEval(function(){return e.$service(b,
+sb=24;pa=S<9?function(a){a=a.nodeName?a:a[0];return a.scopeName&&a.scopeName!="HTML"?fb(a.scopeName+":"+a.nodeName):a.nodeName}:function(a){return a.nodeName?a.nodeName:a[0].nodeName};u.toJson=M;u.fromJson=ca;Qa.prototype={attach:function(a,b){var c={};this.collectInits(a,c,b);Ga(c,function(a){k(a,function(a){a()})})},collectInits:function(a,b,c){var d=b[this.priority],e=c;d||(b[this.priority]=d=[]);this.newScope&&(e=T(c),c.$onEval(e.$eval),a.data("$scope",e));k(this.inits,function(b){d.push(function(){e.$tryEval(function(){return e.$service(b,
 e,a)},a)})});var f=a[0].childNodes,g=this.children,h=this.paths,i=h.length;for(c=0;c<i;c++)g[c].collectInits(o(f[h[c]]),b,e)},addInit:function(a){a&&this.inits.push(a)},addChild:function(a,b){b&&(this.paths.push(a),this.children.push(b))},empty:function(){return this.inits.length===0&&this.paths.length===0}};mb.prototype={compile:function(a){a=o(a);var b=0,c,d=a.parent();if(d&&d[0]){d=d[0];for(var e=0;e<d.childNodes.length;e++)d.childNodes[e]==a[0]&&(b=e)}c=this.templatize(a,b,0)||new Qa;return function(b,
 d){var e=d?qb.clone.call(a):a;b=b||T();e.data("$scope",b);b.$element=e;(d||q)(e,b);c.attach(e,b);b.$eval();return b}},templatize:function(a,b,c){var d=this,e,f,g=d.directives,h=!0,i=!0,j=pa(a),v=j.indexOf(":")>0?D(j).replace(":","-"):"",p,r={compile:F(d,d.compile),descend:function(a){x(a)&&(h=a);return h},directives:function(a){x(a)&&(i=a);return i},scope:function(a){if(x(a))p.newScope=p.newScope||a;return p.newScope}};try{c=a.attr("ng:eval-order")||c||0}catch(y){c=c||0}a.addClass(v);w(c)&&(c=Ec[fb(c)]||
 parseInt(c,10));p=new Qa(c);va(a,function(b,c){if(!e&&(e=d.widgets("@"+c)))a.addClass("ng-attr-widget"),e=F(r,e,b,a)});if(!e&&(e=d.widgets(j)))v&&a.addClass("ng-widget"),e=F(r,e,a);e&&(i=h=!1,j=a.parent(),p.addInit(e.call(r,a)),j&&j[0]&&(a=o(j[0].childNodes[b])));if(h)for(var l=0,n=a[0].childNodes;l<n.length;l++)pa(n[l])=="#text"&&k(d.markup,function(b){if(l<n.length){var c=o(n[l]);b.call(r,c.text(),c,a)}});i&&(va(a,function(b,c){k(d.attrMarkup,function(d){d.call(r,b,c,a)})}),va(a,function(b,c){if(f=
@@ -56,13 +56,13 @@ function(a){wb[a]=!0});var kc=/^function\s*[^\(]*\(([^\)]*)\)/,lc=/,/,mc=/^\s*((
 c},"!=":function(a,b,c){return b!=c},"<":function(a,b,c){return b<c},">":function(a,b,c){return b>c},"<=":function(a,b,c){return b<=c},">=":function(a,b,c){return b>=c},"&&":function(a,b,c){return b&&c},"||":function(a,b,c){return b||c},"&":function(a,b,c){return b&c},"|":function(a,b,c){return c(a,b)},"!":function(a,b){return!b}},oc={n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'};Ab.prototype={url:function(a){var b=this,c=this.template,d;a=a||{};k(this.urlParams,function(e,g){d=La(a[g]||
 b.defaults[g]||"",!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+");c=c.replace(RegExp(":"+g+"(\\W)"),d+"$1")});c=c.replace(/\/?#$/,"");var e=[];Ga(a,function(a,c){b.urlParams[c]||e.push(La(c)+"="+La(a))});c=c.replace(/\/*$/,"");return c+(e.length?"?"+e.join("&"):"")}};ya.DEFAULT_ACTIONS={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}};ya.prototype={route:function(a,b,c){function d(a){var c={};k(b||{},function(b,
 d){c[d]=b.charAt&&b.charAt(0)=="@"?qa(a,b.substr(1)):b});return c}function e(a){A(a||{},this)}var f=this,g=new Ab(a);c=n({},ya.DEFAULT_ACTIONS,c);k(c,function(h,i){var j=h.method=="POST"||h.method=="PUT";e[i]=function(a,b,c){var i={},l,o=q;switch(arguments.length){case 3:o=c;case 2:if(m(b))o=b;else{i=a;l=b;break}case 1:m(a)?o=a:j?l=a:i=a;break;case 0:break;default:throw"Expected between 0-3 arguments [params, data, callback], got "+arguments.length+" arguments.";}var t=this instanceof e?this:h.isArray?
-[]:new e(l);f.xhr(h.method,g.url(n({},h.params||{},d(l),i)),l,function(a,b){if(a==200){if(b)h.isArray?(t.length=0,k(b,function(a){t.push(new e(a))})):A(b,t);(o||q)(t)}else throw{status:a,response:b,message:a+": "+b};},h.verifyCache);return t};e.bind=function(d){return f.route(a,n({},b,d),c)};e.prototype["$"+i]=function(a,b){var c=d(this),g=q;switch(arguments.length){case 2:c=a,g=b;case 1:typeof a==R?g=a:c=a;case 0:break;default:throw"Expected between 1-2 arguments [params, callback], got "+arguments.length+
-" arguments.";}e[i].call(this,c,j?this:E,g)}});return e}};var Fc=s.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(b){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(c){}throw new K("This browser does not support XMLHttpRequest.");},rc={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"},Hb=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
+[]:new e(l);f.xhr(h.method,g.url(n({},h.params||{},d(l),i)),l,function(a,b){if(200<=a&&a<300){if(b)h.isArray?(t.length=0,k(b,function(a){t.push(new e(a))})):A(b,t);(o||q)(t)}else throw{status:a,response:b,message:a+": "+b};},h.verifyCache);return t};e.bind=function(d){return f.route(a,n({},b,d),c)};e.prototype["$"+i]=function(a,b){var c=d(this),g=q;switch(arguments.length){case 2:c=a,g=b;case 1:typeof a==R?g=a:c=a;case 0:break;default:throw"Expected between 1-2 arguments [params, callback], got "+
+arguments.length+" arguments.";}e[i].call(this,c,j?this:E,g)}});return e}};var Fc=s.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(b){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(c){}throw new K("This browser does not support XMLHttpRequest.");},rc={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"},Hb=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
 Gb=/^<\s*\/\s*([\w:-]+)[^>]*>/,sc=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,uc=/^</,tc=/^<\s*\//,vc=/<\!--(.*?)--\>/g,wc=/<!\[CDATA\[(.*?)]]\>/g,zc=/^((ftp|https?):\/\/|mailto:|#)/,xc=/([^\#-~| |!])/g,Eb=fa("area,br,col,hr,img"),Bb=fa("address,blockquote,center,dd,del,dir,div,dl,dt,hr,ins,li,map,menu,ol,p,pre,script,table,tbody,td,tfoot,th,thead,tr,ul"),Cb=fa("a,abbr,acronym,b,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,q,s,samp,small,span,strike,strong,sub,sup,tt,u,var"),
 Db=fa("colgroup,dd,dt,li,p,td,tfoot,th,thead,tr"),Fb=fa("script,style"),Jb=n({},Eb,Bb,Cb,Db),Kb=fa("background,href,longdesc,src,usemap"),yc=n({},Kb,fa("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,span,start,summary,target,title,type,valign,value,vspace,width")),Xa=L.createElement("pre"),Aa={},za="ng-"+(new Date).getTime(),
 Cc=1,Gc=s.document.addEventListener?function(a,b,c){a.addEventListener(b,c,!1)}:function(a,b,c){a.attachEvent("on"+b,c)},Bc=s.document.removeEventListener?function(a,b,c){a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent("on"+b,c)};S&&n(V.prototype,{text:function(a){var b=this[0];if(b.nodeType==3){if(x(a))b.nodeValue=a;return b.nodeValue}else{if(x(a))b.innerText=a;return b.innerText}}});var qb=V.prototype={ready:function(a){function b(){c||(c=!0,a())}var c=!1;this.bind("DOMContentLoaded",
-b);Na(s).bind("load",b)},toString:function(){var a=[];k(this,function(b){a.push(""+b)});return"["+a.join(", ")+"]"},length:0,push:H,sort:[].sort,splice:[].splice};k({data:Za,scope:function(a){for(var b;a&&!(b=o(a).data("$scope"));)a=a.parentNode;return b},removeAttr:function(a,b){a.removeAttribute(b)},hasClass:$a,css:function(a,b,c){if(x(c))a.style[b]=c;else return a.style[b]},attr:function(a,b,c){if(x(c))a.setAttribute(b,c);else if(a.getAttribute)return a.getAttribute(b,2)},text:n(S?function(a,b){if(a.nodeType==
-3){if(z(b))return a.nodeValue;a.nodeValue=b}else{if(z(b))return a.innerText;a.innerText=b}}:function(a,b){if(z(b))return a.textContent;a.textContent=b},{$dv:""}),val:function(a,b){if(z(b))return a.value;a.value=b},html:function(a,b){if(z(b))return a.innerHTML;for(var c=0,d=a.childNodes;c<d.length;c++)ra(d[c]);a.innerHTML=b}},function(a,b){V.prototype[b]=function(b,d){var e,f;if((a.length==2?b:d)===E)if(I(b)){for(e=0;e<this.length;e++)for(f in b)a(this[e],f,b[f]);return this}else{if(this.length)return a(this[0],
+b);Na(s).bind("load",b)},toString:function(){var a=[];k(this,function(b){a.push(""+b)});return"["+a.join(", ")+"]"},length:0,push:H,sort:[].sort,splice:[].splice};k({data:Za,scope:function(a){for(var b;a&&!(b=o(a).data("$scope"));)a=a.parentNode;return b},removeAttr:function(a,b){a.removeAttribute(b)},hasClass:$a,css:function(a,b,c){if(x(c))a.style[b]=c;else return a.style[b]},attr:function(a,b,c){if(x(c))a.setAttribute(b,c);else if(a.getAttribute)return a.getAttribute(b,2)},text:n(S<9?function(a,
+b){if(a.nodeType==3){if(z(b))return a.nodeValue;a.nodeValue=b}else{if(z(b))return a.innerText;a.innerText=b}}:function(a,b){if(z(b))return a.textContent;a.textContent=b},{$dv:""}),val:function(a,b){if(z(b))return a.value;a.value=b},html:function(a,b){if(z(b))return a.innerHTML;for(var c=0,d=a.childNodes;c<d.length;c++)ra(d[c]);a.innerHTML=b}},function(a,b){V.prototype[b]=function(b,d){var e,f;if((a.length==2?b:d)===E)if(I(b)){for(e=0;e<this.length;e++)for(f in b)a(this[e],f,b[f]);return this}else{if(this.length)return a(this[0],
 b,d)}else{for(e=0;e<this.length;e++)a(this[e],b,d);return this}return a.$dv}});k({removeData:Lb,dealoc:ra,bind:function(a,b,c){var d=Za(a,"bind"),e;d||Za(a,"bind",d={});k(b.split(" "),function(b){e=d[b];if(!e)d[b]=e=function(b){if(!b.preventDefault)b.preventDefault=function(){b.returnValue=!1};if(!b.stopPropagation)b.stopPropagation=function(){b.cancelBubble=!0};k(e.fns,function(c){c.call(a,b)})},e.fns=[],Gc(a,b,e);e.fns.push(c)})},replaceWith:function(a,b){var c,d=a.parentNode;ra(a);k(new V(b),function(b){c?
 d.insertBefore(b,c.nextSibling):d.replaceChild(b,a);c=b})},children:function(a){var b=[];k(a.childNodes,function(a){a.nodeName!="#text"&&b.push(a)});return b},append:function(a,b){k(new V(b),function(b){a.nodeType===1&&a.appendChild(b)})},remove:function(a){ra(a);var b=a.parentNode;b&&b.removeChild(a)},after:function(a,b){var c=a,d=a.parentNode;k(new V(b),function(a){d.insertBefore(a,c.nextSibling);c=a})},addClass:Nb,removeClass:Mb,toggleClass:function(a,b,c){z(c)&&(c=!$a(a,b));(c?Nb:Mb)(a,b)},parent:function(a){return(a=
 a.parentNode)&&a.nodeType!==11?a:null},next:function(a){return a.nextSibling},find:function(a,b){return a.getElementsByTagName(b)},clone:function(a){return a.cloneNode(!0)}},function(a,b){V.prototype[b]=function(b,d){for(var e,f=0;f<this.length;f++)e==E?(e=a(this[f],b,d),e!==E&&(e=o(e))):Ya(e,a(this[f],b,d));return e==E?this:e}});H={typeOf:function(a){if(a===null)return wa;var b=typeof a;if(b==gb){if(a instanceof Array)return"array";if(a instanceof Date)return"date";if(a.nodeType==1)return"element"}return b}};
@@ -107,6 +107,6 @@ function(a){var b=this,c=a.attr("src"),d=a.attr("scope")||"",e=a[0].getAttribute
 ua(!0),h.push(d)});k(h,function(a){a.element.remove()});a.html("");return function(a){var b=this,d;this.$watch(c,function(c){var e=!1;a.html("");d=T(b);k(h,function(b){!e&&b.when(d,c)&&(e=!0,d.$tryEval(b.change,a),b.template(d,function(b){a.append(b)}))})});b.$onEval(function(){d&&d.$eval()})}},{equals:function(a,b){return""+a==b}});J("a",function(){this.descend(!0);this.directives(!0);return function(a){a.attr("href")===""&&a.bind("click",function(a){a.preventDefault()})}});J("@ng:repeat",function(a,
 b){b.removeAttr("ng:repeat");b.replaceWith(o("<\!-- ng:repeat: "+a+" --!>"));var c=this.compile(b);return function(d){var e=a.match(/^\s*(.+)\s+in\s+(.*)\s*$/),f,g,h,i;if(!e)throw K("Expected ng:repeat in form of 'item in collection' but got '"+a+"'.");f=e[1];g=e[2];e=f.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/);if(!e)throw K("'item' in 'item in collection' should be identifier or (key, value) but got '"+keyValue+"'.");h=e[3]||e[1];i=e[2];var j=[],k=this;this.$onEval(function(){var a=0,e=
 j.length,f=d,l=this.$tryEval(g,d),n=jb(l,!0),t=b[0].nodeName!="OPTION"?L.createDocumentFragment():null,s,m,q;for(q in l)if(l.hasOwnProperty(q))a<e?(m=j[a],m[h]=l[q],i&&(m[i]=q),f=m.$element,m.$eval()):(m=T(k),m[h]=l[q],i&&(m[i]=q),m.$index=a,m.$position=a==0?"first":a==n-1?"last":"middle",j.push(m),c(m,function(b){b.attr("ng:repeat-index",a);t?(t.appendChild(b[0]),s=!0):(f.after(b),f=b)})),a++;for(s&&f.after(o(t));j.length>a;)j.pop().$element.remove()},d)}});J("@ng:non-bindable",q);J("ng:view",function(a){var b=
-this;if(a[0]["ng:compiled"])this.descend(!0),this.directives(!0);else return a[0]["ng:compiled"]=!0,n(function(a,d,e){var f;d.onChange(function(){var g;if(d.current)g=d.current.template,f=d.current.scope;g?a("GET",g,null,function(a,c){e.html(c);b.compile(e)(f)},!1,!0):e.html("")})();this.$onEval(function(){f&&f.$eval()})},{$inject:["$xhr.cache","$route"]})});var X;Ta("$browser",function(a){if(!X){X=new qc(s,o(s.document),o(s.document.body),Fc,a);var b=X.addPollFn;X.addPollFn=function(){X.addPollFn=
-b;X.startPoller(100,function(a,b){setTimeout(a,b)});return b.apply(X,arguments)};X.bind()}return X},{$inject:["$log"]});n(u,{element:o,compile:lb,scope:T,copy:A,extend:n,equals:oa,forEach:k,injector:zb,noop:q,bind:F,toJson:M,fromJson:ca,identity:Z,isUndefined:z,isDefined:x,isString:w,isFunction:m,isObject:I,isNumber:ma,isArray:Q});pb();Na(L).ready(function(){var a=dc(L),b=L,c=a.autobind;c&&(b=w(c)?b.getElementById(c):b,b=lb(b)(T({$config:a})).$service("$browser"),a.css?b.addCss(a.base_url+a.css):
-S<8&&b.addJs(a.base_url+a.ie_compat,a.ie_compat_id))})})(window,document);angular.element(document).find("head").append('<style type="text/css">@charset "UTF-8";.ng-format-negative{color:red;}.ng-exception{border:2px solid #FF0000;font-family:"Courier New",Courier,monospace;font-size:smaller;white-space:pre;}.ng-validation-error{border:2px solid #FF0000;}#ng-callout{margin:0;padding:0;border:0;outline:0;font-size:13px;font-weight:normal;font-family:Verdana,Arial,Helvetica,sans-serif;vertical-align:baseline;background:transparent;text-decoration:none;}#ng-callout .ng-arrow-left{background-image:url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrSLoc/AG8FeUUIN+sGebWAnbKSJodqqlsOxJtqYooU9vvk+vcJIcTkg+QAAA7");background-repeat:no-repeat;background-position:left top;position:absolute;z-index:101;left:-12px;height:23px;width:10px;top:-3px;}#ng-callout .ng-arrow-right{background-image:url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrCLTcoM29yN6k9socs91e5X3EyJloipYrO4ohTMqA0Fn2XVNswJe+H+SXAAA7");background-repeat:no-repeat;background-position:left top;position:absolute;z-index:101;height:23px;width:11px;top:-2px;}#ng-callout{position:absolute;z-index:100;border:2px solid #CCCCCC;background-color:#fff;}#ng-callout .ng-content{padding:10px 10px 10px 10px;color:#333333;}#ng-callout .ng-title{background-color:#CCCCCC;text-align:left;padding-left:8px;padding-bottom:5px;padding-top:2px;font-weight:bold;}.ng-input-indicator-wait{background-image:url("data:image/png;base64,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");background-position:right;background-repeat:no-repeat;}</style>');
+this;if(a[0]["ng:compiled"])this.descend(!0),this.directives(!0);else return a[0]["ng:compiled"]=!0,n(function(a,d,e){var f;d.onChange(function(){var g;if(d.current)g=d.current.template,f=d.current.scope;g?a("GET",g,function(a,c){e.html(c);b.compile(e)(f)}):e.html("")})();this.$onEval(function(){f&&f.$eval()})},{$inject:["$xhr.cache","$route"]})});var X;Ta("$browser",function(a){if(!X){X=new qc(s,o(s.document),o(s.document.body),Fc,a);var b=X.addPollFn;X.addPollFn=function(){X.addPollFn=b;X.startPoller(100,
+function(a,b){setTimeout(a,b)});return b.apply(X,arguments)};X.bind()}return X},{$inject:["$log"]});n(u,{element:o,compile:lb,scope:T,copy:A,extend:n,equals:oa,forEach:k,injector:zb,noop:q,bind:F,toJson:M,fromJson:ca,identity:Z,isUndefined:z,isDefined:x,isString:w,isFunction:m,isObject:I,isNumber:ma,isArray:Q});pb();Na(L).ready(function(){var a=dc(L),b=L,c=a.autobind;c&&(b=w(c)?b.getElementById(c):b,b=lb(b)(T({$config:a})).$service("$browser"),a.css?b.addCss(a.base_url+a.css):S<8&&b.addJs(a.base_url+
+a.ie_compat,a.ie_compat_id))})})(window,document);angular.element(document).find("head").append('<style type="text/css">@charset "UTF-8";.ng-format-negative{color:red;}.ng-exception{border:2px solid #FF0000;font-family:"Courier New",Courier,monospace;font-size:smaller;white-space:pre;}.ng-validation-error{border:2px solid #FF0000;}#ng-callout{margin:0;padding:0;border:0;outline:0;font-size:13px;font-weight:normal;font-family:Verdana,Arial,Helvetica,sans-serif;vertical-align:baseline;background:transparent;text-decoration:none;}#ng-callout .ng-arrow-left{background-image:url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrSLoc/AG8FeUUIN+sGebWAnbKSJodqqlsOxJtqYooU9vvk+vcJIcTkg+QAAA7");background-repeat:no-repeat;background-position:left top;position:absolute;z-index:101;left:-12px;height:23px;width:10px;top:-3px;}#ng-callout .ng-arrow-right{background-image:url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrCLTcoM29yN6k9socs91e5X3EyJloipYrO4ohTMqA0Fn2XVNswJe+H+SXAAA7");background-repeat:no-repeat;background-position:left top;position:absolute;z-index:101;height:23px;width:11px;top:-2px;}#ng-callout{position:absolute;z-index:100;border:2px solid #CCCCCC;background-color:#fff;}#ng-callout .ng-content{padding:10px 10px 10px 10px;color:#333333;}#ng-callout .ng-title{background-color:#CCCCCC;text-align:left;padding-left:8px;padding-bottom:5px;padding-top:2px;font-weight:bold;}.ng-input-indicator-wait{background-image:url("data:image/png;base64,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");background-position:right;background-repeat:no-repeat;}</style>');
index ed6ff69..7df0ac4 100644 (file)
@@ -6693,7 +6693,7 @@ function HTML(html, option) {
       };
 }
 
-if (msie) {
+if (msie < 9) {
   nodeName_ = function(element) {
     element = element.nodeName ? element : element[0];
     return (element.scopeName && element.scopeName != 'HTML' ) ? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName;
@@ -6812,7 +6812,8 @@ function isLeafNode (node) {
  *
  * @param {*} source The source to be used to make a copy.
  *                   Can be any type including primitives, `null` and `undefined`.
- * @param {(Object|Array)=} destination Optional destination into which the source is copied.
+ * @param {(Object|Array)=} destination Optional destination into which the source is copied. If
+ *     provided, must be of the same type as `source`.
  * @returns {*} The copy or updated `destination` if `destination` was specified.
  *
  * @example
@@ -7134,13 +7135,17 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  * @TODO rename to ng:autobind to ng:autoboot
  *
  * @description
- * This section explains how to bootstrap your application with angular, using either the angular
- * javascript file, or manually.
+ * This doc explains how to bootstrap your application with angular. You can either use
+ * `ng:autobind` script tag attribute or perform a manual bootstrap.
  *
  * # Auto-bootstrap with `ng:autobind`
- * The simplest way to get an <angular/> application up and running is by inserting a script tag in
- * your HTML file that bootstraps the `http://code.angularjs.org/angular-x.x.x.min.js` code and uses
- * the special `ng:autobind` attribute, like in this snippet of HTML:
+ * The simplest way to get an angular application up and running is by adding a script tag in
+ * your HTML file that contains `ng:autobind` attribute. This will:
+ *
+ * * Load the angular script
+ * * Tell angular to compile the entire document (or just its portion if the attribute has a value)
+ *
+ * For example:
  *
  * <pre>
     &lt;!doctype html&gt;
@@ -7160,14 +7165,14 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  * you don't need to explicitly add an `onLoad` event handler; auto bind mode takes care of all the
  * work for you.
  *
- * In order to compile only a part of the document, specify the id of the element that should be
- * compiled as the value of the `ng:autobind` attribute, e.g. `ng:autobind="angularContent"`.
+ * In order to compile only a part of the document with a root element, specify the id of the root
+ * element as the value of the `ng:autobind` attribute, e.g. `ng:autobind="angularContent"`.
  *
  *
  * ## Auto-bootstrap with `#autobind`
- * In rare cases when you can't define the `ng` namespace before the script tag (e.g. in some CMS
- * systems, etc), it is possible to auto-bootstrap angular by appending `#autobind` to the script
- * src URL, like in this snippet:
+ * In some rare cases you can't define the `ng:` prefix before the script tag's attribute  (e.g. in
+ * some CMS systems). In these situations it is possible to auto-bootstrap angular by appending
+ * `#autobind` to the script `src` URL, like in this snippet:
  *
  * <pre>
     &lt;!doctype html&gt;
@@ -7184,14 +7189,14 @@ function encodeUriQuery(val, pctEncodeSpaces) {
     &lt;/html&gt;
  * </pre>
  *
- * In this case it's the `#autobind` URL fragment that tells angular to auto-bootstrap.
+ * In this snippet it is the `#autobind` URL fragment that tells angular to auto-bootstrap.
  *
  * Similarly to `ng:autobind`, you can specify an element id that should be exclusively targeted for
  * compilation as the value of the `#autobind`, e.g. `#autobind=angularContent`.
  *
  * ## Filename Restrictions for Auto-bootstrap
  * In order for us to find the auto-bootstrap script attribute or URL fragment, the value of the
- * `script` `src` attribute that loads angular script must match one of these naming
+ * `script` `src` attribute that loads the angular script must match one of these naming
  * conventions:
  *
  * - `angular.js`
@@ -7202,15 +7207,15 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  * - `angular-x.x.x-xxxxxxxx.min.js` (dev snapshot)
  * - `angular-bootstrap.js` (used for development of angular)
  *
- * Optionally, any of the filename format above can be prepended with relative or absolute URL that
- * ends with `/`.
+ * Optionally, any of the filename formats above can be prepended with a relative or absolute URL
+ * that ends with `/`.
  *
  *
- * ## Manual Bootstrap
- * Using auto-bootstrap is a handy way to start using <angular/>, but advanced users who want more
- * control over the initialization process might prefer to use manual bootstrap instead.
+ * # Manual Bootstrap
+ * Using auto-bootstrap is a handy way to start using angular, but advanced users who want more
+ * control over the initialization process might prefer to use the manual bootstrap method instead.
  *
- * The best way to get started with manual bootstraping is to look at the magic behind `ng:autobind`
+ * The best way to get started with manual bootstraping is to look at the magic behind `ng:autobind`,
  * by writing out each step of the autobind process explicitly. Note that the following code is
  * equivalent to the code in the previous section.
  *
@@ -7234,22 +7239,23 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  *
  * This is the sequence that your code should follow if you're bootstrapping angular on your own:
  *
- * * After the page is loaded, find the root of the HTML template, which is typically the root of
- *   the document.
- * * Run the HTML compiler, which converts the templates into an executable, bi-directionally bound
- *   application.
+ * 1. After the page is loaded, find the root of the HTML template, which is typically the root of
+ *    the document.
+ * 2. Run the HTML compiler, which converts the templates into an executable, bi-directionally bound
+ *    application.
  *
  *
- * ##XML Namespace
- * *IMPORTANT:* When using <angular/> you must declare the ng namespace using the xmlns tag. If you
- * don't declare the namespace, Internet Explorer does not render widgets properly.
+ * ## XML Namespace
+ * *IMPORTANT:* When using angular, you must declare the ng namespace using the xmlns tag. If you
+ * don't declare the namespace, Internet Explorer older than 9 does not render widgets properly. The
+ * namespace must be declared even if you use HTML instead of XHTML.
  *
  * <pre>
  * &lt;html xmlns:ng="http://angularjs.org"&gt;
  * </pre>
  *
  *
- * ## Create your own namespace
+ * ### Create your own namespace
  * If you want to define your own widgets, you must create your own namespace and use that namespace
  * to form the fully qualified widget name. For example, you could map the alias `my` to your domain
  * and create a widget called my:widget. To create your own namespace, simply add another xmlsn tag
@@ -7260,8 +7266,8 @@ function encodeUriQuery(val, pctEncodeSpaces) {
  * </pre>
  *
  *
- * ## Global Object
- * The <angular/> script creates a single global variable `angular` in the global namespace. All
+ * ### Global Object
+ * The angular script creates a single global variable `angular` in the global namespace. All
  * APIs are bound to fields of this global object.
  *
  */
@@ -9384,7 +9390,7 @@ ResourceFactory.prototype = {
           route.url(extend({}, action.params || {}, extractParams(data), params)),
           data,
           function(status, response, clear) {
-            if (status == 200) {
+            if (200 <= status && status < 300) {
               if (response) {
                 if (action.isArray) {
                   value.length = 0;
@@ -10344,7 +10350,7 @@ forEach({
     }
   },
 
-  text: extend(msie
+  text: extend((msie < 9)
       ? function(element, value) {
         // NodeType == 3 is text node
         if (element.nodeType == 3) {
@@ -11690,10 +11696,10 @@ angularFilter.uppercase = uppercase;
  * @example
    <doc:example>
      <doc:source>
-       Snippet: <textarea name="snippet" cols="60" rows="3">
-&lt;p style="color:blue"&gt;an html
-&lt;em onmouseover="this.textContent='PWN3D!'"&gt;click here&lt;/em&gt;
-snippet&lt;/p&gt;</textarea>
+      Snippet: <textarea name="snippet" cols="60" rows="3">
+     &lt;p style="color:blue"&gt;an html
+     &lt;em onmouseover="this.textContent='PWN3D!'"&gt;click here&lt;/em&gt;
+     snippet&lt;/p&gt;</textarea>
        <table>
          <tr>
            <td>Filter</td>
@@ -12892,31 +12898,61 @@ var URL_MATCH = /^(file|ftp|http|https):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+)
  * @name angular.service.$location
  * @requires $browser
  *
- * @property {string} href
- * @property {string} protocol
- * @property {string} host
- * @property {number} port
- * @property {string} path
- * @property {Object.<string|boolean>} search
- * @property {string} hash
- * @property {string} hashPath
- * @property {Object.<string|boolean>} hashSearch
+ * @property {string} href The full URL of the current location.
+ * @property {string} protocol The protocol part of the URL (e.g. http or https).
+ * @property {string} host The host name, ip address or FQDN of the current location.
+ * @property {number} port The port number of the current location (e.g. 80, 443, 8080).
+ * @property {string} path The path of the current location (e.g. /myapp/inbox).
+ * @property {Object.<string|boolean>} search Map of query parameters (e.g. {user:"foo", page:23}).
+ * @property {string} hash The fragment part of the URL of the current location (e.g. #foo).
+ * @property {string} hashPath Similar to `path`, but located in the `hash` fragment
+ *     (e.g. ../foo#/some/path  => /some/path).
+ * @property {Object.<string|boolean>} hashSearch Similar to `search` but located in `hash`
+ *     fragment (e.g. .../foo#/some/path?hashQuery=param  =>  {hashQuery: "param"}).
  *
  * @description
  * Parses the browser location url and makes it available to your application.
- * Any changes to the url are reflected into $location service and changes to
- * $location are reflected to url.
+ * Any changes to the url are reflected into `$location` service and changes to
+ * `$location` are reflected in the browser location url.
+ *
  * Notice that using browser's forward/back buttons changes the $location.
  *
  * @example
    <doc:example>
      <doc:source>
-       <a href="#">clear hash</a> |
-       <a href="#myPath?name=misko">test hash</a><br/>
-       <input type='text' name="$location.hash"/>
-       <pre>$location = {{$location}}</pre>
+       <div ng:init="$location = $service('$location')">
+         <a id="ex-test" href="#myPath?name=misko">test hash</a>|
+         <a id="ex-reset" href="#!angular.service.$location">reset hash</a><br/>
+         <input type='text' name="$location.hash" size="30">
+         <pre>$location = {{$location}}</pre>
+       </div>
      </doc:source>
      <doc:scenario>
+       it('should initialize the input field', function() {
+         expect(using('.doc-example-live').element('input[name=$location.hash]').val()).
+           toBe('!angular.service.$location');
+       });
+
+
+       it('should bind $location.hash to the input field', function() {
+         using('.doc-example-live').input('$location.hash').enter('foo');
+         expect(browser().location().hash()).toBe('foo');
+       });
+
+
+       it('should set the hash to a test string with test link is presed', function() {
+         using('.doc-example-live').element('#ex-test').click();
+         expect(using('.doc-example-live').element('input[name=$location.hash]').val()).
+           toBe('myPath?name=misko');
+       });
+
+       it('should reset $location when reset link is pressed', function() {
+         using('.doc-example-live').input('$location.hash').enter('foo');
+         using('.doc-example-live').element('#ex-reset').click();
+         expect(using('.doc-example-live').element('input[name=$location.hash]').val()).
+           toBe('!angular.service.$location');
+       });
+
      </doc:scenario>
     </doc:example>
  */
@@ -12945,22 +12981,18 @@ angularServiceInject("$location", function($browser) {
    * @methodOf angular.service.$location
    *
    * @description
-   * Update location object
-   * Does not immediately update the browser
-   * Browser is updated at the end of $eval()
+   * Updates the location object.
    *
-   * @example
-    <doc:example>
-      <doc:source>
-        scope.$location.update('http://www.angularjs.org/path#hash?search=x');
-        scope.$location.update({host: 'www.google.com', protocol: 'https'});
-        scope.$location.update({hashPath: '/path', hashSearch: {a: 'b', x: true}});
-      </doc:source>
-      <doc:scenario>
-      </doc:scenario>
-    </doc:example>
+   * Does not immediately update the browser. Instead the browser is updated at the end of $eval()
+   * cycle.
+   *
+   * <pre>
+       $location.update('http://www.angularjs.org/path#hash?search=x');
+       $location.update({host: 'www.google.com', protocol: 'https'});
+       $location.update({hashPath: '/path', hashSearch: {a: 'b', x: true}});
+     </pre>
    *
-   * @param {(string|Object)} href Full href as a string or object with properties
+   * @param {string|Object} href Full href as a string or object with properties
    */
   function update(href) {
     if (isString(href)) {
@@ -12987,24 +13019,20 @@ angularServiceInject("$location", function($browser) {
    * @methodOf angular.service.$location
    *
    * @description
-   * Update location hash part
+   * Updates the hash fragment part of the url.
+   *
    * @see update()
    *
-   * @example
-    <doc:example>
-      <doc:source>
-        scope.$location.updateHash('/hp')
+   * <pre>
+       scope.$location.updateHash('/hp')
          ==> update({hashPath: '/hp'})
-        scope.$location.updateHash({a: true, b: 'val'})
+       scope.$location.updateHash({a: true, b: 'val'})
          ==> update({hashSearch: {a: true, b: 'val'}})
-        scope.$location.updateHash('/hp', {a: true})
+       scope.$location.updateHash('/hp', {a: true})
          ==> update({hashPath: '/hp', hashSearch: {a: true}})
-      </doc:source>
-      <doc:scenario>
-      </doc:scenario>
-    </doc:example>
+     </pre>
    *
-   * @param {(string|Object)} path A hashPath or hashSearch object
+   * @param {string|Object} path A hashPath or hashSearch object
    * @param {Object=} search A hashSearch object
    */
   function updateHash(path, search) {
@@ -13036,11 +13064,11 @@ angularServiceInject("$location", function($browser) {
    * - `$location.hash`
    * - everything else
    *
-   * @example
-   * <pre>
-   *   scope.$location.href = 'http://www.angularjs.org/path#a/b'
-   * </pre>
-   * immediately after this call, other properties are still the old ones...
+   * Keep in mind that if the following code is executed:
+   *
+   * scope.$location.href = 'http://www.angularjs.org/path#a/b'
+   *
+   * immediately afterwards all other properties are still the old ones...
    *
    * This method checks the changes and update location to the consistent state
    */
@@ -14135,7 +14163,7 @@ angularServiceInject('$xhr', function($browser, $error, $log, $updateView){
  * @name angular.directive.ng:init
  *
  * @description
- * `ng:init` attribute allows the for initialization tasks to be executed
+ * The `ng:init` attribute specifies initialization tasks to be executed
  *  before the template enters execution mode during bootstrap.
  *
  * @element ANY
@@ -14168,21 +14196,31 @@ angularDirective("ng:init", function(expression){
  * @name angular.directive.ng:controller
  *
  * @description
- * To support the Model-View-Controller design pattern, it is possible
- * to assign behavior to a scope through `ng:controller`. The scope is
- * the MVC model. The HTML (with data bindings) is the MVC view.
- * The `ng:controller` directive specifies the MVC controller class
+ * The `ng:controller` directive assigns behavior to a scope. This is a key aspect of how angular
+ * supports the principles behind the Model-View-Controller design pattern.
+ *
+ * MVC components in angular:
+ *
+ * * Model — The Model is data in scope properties; scopes are attached to the DOM.
+ * * View — The template (HTML with data bindings) is rendered into the View.
+ * * Controller — The `ng:controller` directive specifies a Controller class; the class has
+ *   methods that typically express the business logic behind the application.
+ *
+ * Note that an alternative way to define controllers is via the `{@link angular.service.$route}`
+ * service.
  *
  * @element ANY
- * @param {expression} expression {@link guide.expression Expression} to eval.
+ * @param {expression} expression Name of a globally accessible constructor function or an
+ *     {@link guide.expression expression} that on the current scope evaluates to a constructor
+ *     function.
  *
  * @example
- * Here is a simple form for editing the user contact information. Adding, removing clearing and
- * greeting are methods which are declared on the controller (see source tab). These methods can
- * easily be called from the angular markup. Notice that the scope becomes the controller's class
- * this. 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 to update it
- * manually.
+ * 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.
    <doc:example>
      <doc:source>
       <script type="text/javascript">
@@ -14275,8 +14313,9 @@ angularDirective("ng:controller", function(expression){
          * <input name="obj.b" value="2">
          = {{obj.multiplied = obj.a * obj.b}} <br>
        <span ng:eval="obj.divide = obj.a / obj.b"></span>
-       <span ng:eval="obj.updateCount = 1 + (obj.updateCount||0)"></span>
-       <tt>obj.divide = {{obj.divide}}</tt><br/>
+       <span ng:eval="obj.updateCount = 1 + (obj.updateCount||0)">
+       </span>
+       <tt>obj.divide = {{obj.divide}}</tt><br>
        <tt>obj.updateCount = {{obj.updateCount}}</tt>
      </doc:source>
      <doc:scenario>
@@ -14302,20 +14341,20 @@ angularDirective("ng:eval", function(expression){
  * @name angular.directive.ng:bind
  *
  * @description
- * The `ng:bind` attribute asks <angular/> to replace the text content of this
- * HTML element with the value of the given expression and kept it up to
- * date when the expression's value changes. Usually you just write
- * {{expression}} and let <angular/> compile it into
+ * The `ng:bind` attribute asks angular to replace the text content of this
+ * HTML element with the value of the given expression, and to keep the text
+ * content up to date when the expression's value changes. Usually you would
+ * just write `{{ expression }}` and let angular compile it into
  * `<span ng:bind="expression"></span>` at bootstrap time.
  *
  * @element ANY
  * @param {expression} expression {@link guide.expression Expression} to eval.
  *
  * @example
- * Try it here: enter text in text box and watch the greeting change.
+ * You can try it right here: enter text in the text box and watch the greeting change.
    <doc:example>
      <doc:source>
-       Enter name: <input type="text" name="name" value="Whirled">. <br>
+       Enter name: <input type="text" name="name" value="Whirled"> <br>
        Hello <span ng:bind="name" />!
      </doc:source>
      <doc:scenario>
@@ -14473,7 +14512,7 @@ var REMOVE_ATTRIBUTES = {
  * contains a JSON key value pairs representing which attributes need to be mapped to which
  * {@link guide.expression expressions}.
  *
- * You dont usually write the `ng:bind-attr` in the HTML since embedding
+ * You don't usually write the `ng:bind-attr` in the HTML since embedding
  * <tt ng:non-bindable>{{expression}}</tt> into the attribute directly as the attribute value is
  * preferred. The attributes get translated into `<span ng:bind-attr="{attr:expression}"/>` at
  * compile time.
@@ -14784,8 +14823,8 @@ angularDirective("ng:class-even", ngClass(function(i){return i % 2 === 1;}));
  * @name angular.directive.ng:show
  *
  * @description
- * The `ng:show` and `ng:hide` allows you to show or hide a portion
- * of the HTML conditionally.
+ * The `ng:show` and `ng:hide` directives show or hide a portion of the DOM tree (HTML)
+ * conditionally.
  *
  * @element ANY
  * @param {expression} expression If the {@link guide.expression expression} is truthy then the element
@@ -14795,8 +14834,8 @@ angularDirective("ng:class-even", ngClass(function(i){return i % 2 === 1;}));
    <doc:example>
      <doc:source>
         Click me: <input type="checkbox" name="checked"><br/>
-        Show: <span ng:show="checked">I show up when you checkbox is checked?</span> <br/>
-        Hide: <span ng:hide="checked">I hide when you checkbox is checked?</span>
+        Show: <span ng:show="checked">I show up when your checkbox is checked.</span> <br/>
+        Hide: <span ng:hide="checked">I hide when your checkbox is checked.</span>
      </doc:source>
      <doc:scenario>
        it('should check ng:show / ng:hide', function(){
@@ -14825,7 +14864,7 @@ angularDirective("ng:show", function(expression, element){
  * @name angular.directive.ng:hide
  *
  * @description
- * The `ng:show` and `ng:hide` allows you to show or hide a portion
+ * The `ng:hide` and `ng:show` directives hide or show a portion
  * of the HTML conditionally.
  *
  * @element ANY
@@ -15066,8 +15105,8 @@ angularAttrMarkup('{{}}', function(value, name, element){
  * @name angular.widget.HTML
  *
  * @description
- * The most common widgets you will use will be in the from of the
- * standard HTML set. These widgets are bound using the name attribute
+ * The most common widgets you will use will be in the form of the
+ * standard HTML set. These widgets are bound using the `name` attribute
  * to an expression. In addition they can have `ng:validate`, `ng:required`,
  * `ng:format`, `ng:change` attribute to further control their behavior.
  *
@@ -15898,18 +15937,20 @@ angularWidget('a', function() {
  * @name angular.widget.@ng:repeat
  *
  * @description
- * `ng:repeat` instantiates a template once per item from a collection. The collection is enumerated
- * with `ng:repeat-index` attribute starting from 0. Each template instance gets its own scope where
- * the given loop variable is set to the current collection item and `$index` is set to the item
- * index or key.
+ * The `ng:repeat` widget instantiates a template once per item from a collection. The collection is
+ * enumerated with the `ng:repeat-index` attribute, starting from 0. Each template instance gets 
+ * its own scope, where the given loop variable is set to the current collection item, and `$index` 
+ * is set to the item index or key.
  *
- * There are special properties exposed on the local scope of each template instance:
+ * Special properties are exposed on the local scope of each template instance, including:
  *
  *   * `$index` – `{number}` – iterator offset of the repeated element (0..length-1)
- *   * `$position` – {string} – position of the repeated element in the iterator. One of: `'first'`,
- *     `'middle'` or `'last'`.
+ *   * `$position` – `{string}` – position of the repeated element in the iterator. One of: 
+ *        * `'first'`,
+ *        * `'middle'` 
+ *        * `'last'`
  *
- * NOTE: `ng:repeat` looks like a directive, but is actually an attribute widget.
+ * Note: Although `ng:repeat` looks like a directive, it is actually an attribute widget.
  *
  * @element ANY
  * @param {string} repeat_expression The expression indicating how to enumerate a collection. Two
@@ -15919,6 +15960,7 @@ angularWidget('a', function() {
  *     is a scope expression giving the collection to enumerate.
  *
  *     For example: `track in cd.tracks`.
+ *
  *   * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
  *     and `expression` is the scope expression giving the collection to enumerate.
  *
@@ -15926,7 +15968,7 @@ angularWidget('a', function() {
  *
  * @example
  * This example initializes the scope to a list of names and
- * than uses `ng:repeat` to display every person.
+ * then uses `ng:repeat` to display every person:
     <doc:example>
       <doc:source>
         <div ng:init="friends = [{name:'John', age:25}, {name:'Mary', age:28}]">
@@ -16134,10 +16176,11 @@ angularWidget('ng:view', function(element) {
         }
 
         if (src) {
-          $xhr('GET', src, null, function(code, response){
+          //xhr's callback must be async, see commit history for more info
+          $xhr('GET', src, function(code, response){
             element.html(response);
             compiler.compile(element)(childScope);
-          }, false, true);
+          });
         } else {
           element.html('');
         }
@@ -16461,7 +16504,7 @@ function browserTrigger(element, type) {
     element = element.parentNode;
     type = 'change';
   }
-  if (msie) {
+  if (msie < 9) {
     switch(element.type) {
       case 'radio':
       case 'checkbox':
@@ -16592,7 +16635,7 @@ angular.scenario.Application.prototype.getWindow_ = function() {
 angular.scenario.Application.prototype.checkUrlStatus_ = function(url, callback) {
   var self = this;
   _jQuery.ajax({
-    url: url,
+    url: url.replace(/#.*/, ''), //IE encodes and sends the url fragment, so we must strip it
     type: 'HEAD',
     complete: function(request) {
       if (request.status < 200 || request.status >= 300) {
@@ -17617,19 +17660,19 @@ angular.scenario.dsl('browser', function() {
 
     api.search = function() {
       return this.addFutureAction('browser url search', function($window, $document, done) {
-        done(null, $window.angular.scope().$location.search);
+        done(null, $window.angular.scope().$service('$location').search);
       });
     };
 
     api.hashSearch = function() {
       return this.addFutureAction('browser url hash search', function($window, $document, done) {
-        done(null, $window.angular.scope().$location.hashSearch);
+        done(null, $window.angular.scope().$service('$location').hashSearch);
       });
     };
 
     api.hashPath = function() {
       return this.addFutureAction('browser url hash path', function($window, $document, done) {
-        done(null, $window.angular.scope().$location.hashPath);
+        done(null, $window.angular.scope().$service('$location').hashPath);
       });
     };