js/can.jquery-2.1.1.js
changeset 0 52d30e6014a0
equal deleted inserted replaced
-1:000000000000 0:52d30e6014a0
       
     1 /*!
       
     2  * CanJS - 2.1.1
       
     3  * http://canjs.us/
       
     4  * Copyright (c) 2014 Bitovi
       
     5  * Fri, 23 May 2014 15:47:45 GMT
       
     6  * Licensed MIT
       
     7  * Includes: can/construct/construct.js,can/map/map.js,can/list/list.js,can/compute/compute.js,can/model/model.js,can/view/view.js,can/control/control.js,can/route/route.js,can/control/route/route.js,can/view/ejs/ejs.js,can/map/backup/backup.js,can/util/object/object.js
       
     8  * Download from: http://bitbuilder.herokuapp.com/can.custom.js?configuration=jquery&plugins=can%2Fconstruct%2Fconstruct.js&plugins=can%2Fmap%2Fmap.js&plugins=can%2Flist%2Flist.js&plugins=can%2Fcompute%2Fcompute.js&plugins=can%2Fmodel%2Fmodel.js&plugins=can%2Fview%2Fview.js&plugins=can%2Fcontrol%2Fcontrol.js&plugins=can%2Froute%2Froute.js&plugins=can%2Fcontrol%2Froute%2Froute.js&plugins=can%2Fview%2Fejs%2Fejs.js&plugins=can%2Fmap%2Fbackup%2Fbackup.js&plugins=can%2Futil%2Fobject%2Fobject.js
       
     9  */
       
    10 (function(undefined) {
       
    11 
       
    12     // ## can/util/can.js
       
    13     var __m5 = (function() {
       
    14 
       
    15         var can = window.can || {};
       
    16         if (typeof GLOBALCAN === 'undefined' || GLOBALCAN !== false) {
       
    17             window.can = can;
       
    18         }
       
    19 
       
    20         // An empty function useful for where you need a dummy callback.
       
    21         can.k = function() {};
       
    22 
       
    23         can.isDeferred = function(obj) {
       
    24             var isFunction = this.isFunction;
       
    25             // Returns `true` if something looks like a deferred.
       
    26             return obj && isFunction(obj.then) && isFunction(obj.pipe);
       
    27         };
       
    28 
       
    29         var cid = 0;
       
    30         can.cid = function(object, name) {
       
    31             if (!object._cid) {
       
    32                 cid++;
       
    33                 object._cid = (name || '') + cid;
       
    34             }
       
    35             return object._cid;
       
    36         };
       
    37         can.VERSION = '@EDGE';
       
    38 
       
    39         can.simpleExtend = function(d, s) {
       
    40             for (var prop in s) {
       
    41                 d[prop] = s[prop];
       
    42             }
       
    43             return d;
       
    44         };
       
    45 
       
    46         can.frag = function(item) {
       
    47             var frag;
       
    48             if (!item || typeof item === "string") {
       
    49                 frag = can.buildFragment(item == null ? "" : "" + item, document.body);
       
    50                 // If we have an empty frag...
       
    51                 if (!frag.childNodes.length) {
       
    52                     frag.appendChild(document.createTextNode(''));
       
    53                 }
       
    54                 return frag;
       
    55             } else if (item.nodeType === 11) {
       
    56                 return item;
       
    57             } else if (typeof item.nodeType === "number") {
       
    58                 frag = document.createDocumentFragment();
       
    59                 frag.appendChild(item);
       
    60                 return frag;
       
    61             } else if (typeof item.length === "number") {
       
    62                 frag = document.createDocumentFragment();
       
    63                 can.each(item, function(item) {
       
    64                     frag.appendChild(can.frag(item));
       
    65                 });
       
    66                 return frag;
       
    67             } else {
       
    68                 frag = can.buildFragment("" + item, document.body);
       
    69                 // If we have an empty frag...
       
    70                 if (!frag.childNodes.length) {
       
    71                     frag.appendChild(document.createTextNode(''));
       
    72                 }
       
    73                 return frag;
       
    74             }
       
    75         };
       
    76 
       
    77         // this is here in case can.compute hasn't loaded
       
    78         can.__reading = function() {};
       
    79 
       
    80         return can;
       
    81     })();
       
    82 
       
    83     // ## can/util/attr/attr.js
       
    84     var __m6 = (function(can) {
       
    85 
       
    86         // Acts as a polyfill for setImmediate which only works in IE 10+. Needed to make
       
    87         // the triggering of `attributes` event async.
       
    88         var setImmediate = window.setImmediate || function(cb) {
       
    89                 return setTimeout(cb, 0);
       
    90             },
       
    91             attr = {
       
    92                 // This property lets us know if the browser supports mutation observers.
       
    93                 // If they are supported then that will be setup in can/util/jquery and those native events will be used to inform observers of attribute changes.
       
    94                 // Otherwise this module handles triggering an `attributes` event on the element.
       
    95                 MutationObserver: window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
       
    96 
       
    97 
       
    98                 map: {
       
    99                     "class": "className",
       
   100                     "value": "value",
       
   101                     "innerText": "innerText",
       
   102                     "textContent": "textContent",
       
   103                     "checked": true,
       
   104                     "disabled": true,
       
   105                     "readonly": true,
       
   106                     "required": true,
       
   107                     // For the `src` attribute we are using a setter function to prevent values such as an empty string or null from being set.
       
   108                     // An `img` tag attempts to fetch the `src` when it is set, so we need to prevent that from happening by removing the attribute instead.
       
   109                     src: function(el, val) {
       
   110                         if (val == null || val === "") {
       
   111                             el.removeAttribute("src");
       
   112                             return null;
       
   113                         } else {
       
   114                             el.setAttribute("src", val);
       
   115                             return val;
       
   116                         }
       
   117                     },
       
   118                     style: function(el, val) {
       
   119                         return el.style.cssText = val || "";
       
   120                     }
       
   121                 },
       
   122                 // These are elements whos default value we should set.
       
   123                 defaultValue: ["input", "textarea"],
       
   124                 // ## attr.set
       
   125                 // Set the value an attribute on an element.
       
   126                 set: function(el, attrName, val) {
       
   127                     var oldValue;
       
   128                     // In order to later trigger an event we need to compare the new value to the old value, so here we go ahead and retrieve the old value for browsers that don't have native MutationObservers.
       
   129                     if (!attr.MutationObserver) {
       
   130                         oldValue = attr.get(el, attrName);
       
   131                     }
       
   132 
       
   133                     var tagName = el.nodeName.toString()
       
   134                         .toLowerCase(),
       
   135                         prop = attr.map[attrName],
       
   136                         newValue;
       
   137 
       
   138                     // Using the property of `attr.map`, go through and check if the property is a function, and if so call it. Then check if the property is `true`, and if so set the value to `true`, also making sure to set `defaultChecked` to `true` for elements of `attr.defaultValue`. We always set the value to true because for these boolean properties, setting them to false would be the same as removing the attribute.
       
   139                     // For all other attributes use `setAttribute` to set the new value.
       
   140                     if (typeof prop === "function") {
       
   141                         newValue = prop(el, val);
       
   142                     } else if (prop === true) {
       
   143                         newValue = el[attrName] = true;
       
   144 
       
   145                         if (attrName === "checked" && el.type === "radio") {
       
   146                             if (can.inArray(tagName, attr.defaultValue) >= 0) {
       
   147                                 el.defaultChecked = true;
       
   148                             }
       
   149                         }
       
   150 
       
   151                     } else if (prop) {
       
   152                         newValue = el[prop] = val;
       
   153                         if (prop === "value" && can.inArray(tagName, attr.defaultValue) >= 0) {
       
   154                             el.defaultValue = val;
       
   155                         }
       
   156                     } else {
       
   157                         el.setAttribute(attrName, val);
       
   158                         newValue = val;
       
   159                     }
       
   160 
       
   161                     // Now that the value has been set, for browsers without MutationObservers, check to see that value has changed and if so trigger the "attributes" event on the element.
       
   162                     if (!attr.MutationObserver && newValue !== oldValue) {
       
   163                         attr.trigger(el, attrName, oldValue);
       
   164                     }
       
   165                 },
       
   166                 // ## attr.trigger
       
   167                 // Used to trigger an "attributes" event on an element. Checks to make sure that someone is listening for the event and then queues a function to be called asynchronously using `setImmediate.
       
   168                 trigger: function(el, attrName, oldValue) {
       
   169                     if (can.data(can.$(el), "canHasAttributesBindings")) {
       
   170                         return setImmediate(function() {
       
   171                             can.trigger(el, {
       
   172                                     type: "attributes",
       
   173                                     attributeName: attrName,
       
   174                                     target: el,
       
   175                                     oldValue: oldValue,
       
   176                                     bubbles: false
       
   177                                 }, []);
       
   178                         });
       
   179                     }
       
   180                 },
       
   181                 // ## attr.get
       
   182                 // Gets the value of an attribute. First checks to see if the property is a string on `attr.map` and if so returns the value from the element's property. Otherwise uses `getAttribute` to retrieve the value.
       
   183                 get: function(el, attrName) {
       
   184                     var prop = attr.map[attrName];
       
   185                     if (typeof prop === "string" && el[prop]) {
       
   186                         return el[prop];
       
   187                     }
       
   188 
       
   189                     return el.getAttribute(attrName);
       
   190                 },
       
   191                 // ## attr.remove
       
   192                 // Removes an attribute from an element. Works by using the `attr.map` to see if the attribute is a special type of property. If the property is a function then the fuction is called with `undefined` as the value. If the property is `true` then the attribute is set to false. If the property is a string then the attribute is set to an empty string. Otherwise `removeAttribute` is used.
       
   193                 // If the attribute previously had a value and the browser doesn't support MutationObservers we then trigger an "attributes" event.
       
   194                 remove: function(el, attrName) {
       
   195                     var oldValue;
       
   196                     if (!attr.MutationObserver) {
       
   197                         oldValue = attr.get(el, attrName);
       
   198                     }
       
   199 
       
   200                     var setter = attr.map[attrName];
       
   201                     if (typeof setter === "function") {
       
   202                         setter(el, undefined);
       
   203                     }
       
   204                     if (setter === true) {
       
   205                         el[attrName] = false;
       
   206                     } else if (typeof setter === "string") {
       
   207                         el[setter] = "";
       
   208                     } else {
       
   209                         el.removeAttribute(attrName);
       
   210                     }
       
   211                     if (!attr.MutationObserver && oldValue != null) {
       
   212                         attr.trigger(el, attrName, oldValue);
       
   213                     }
       
   214 
       
   215                 },
       
   216                 // ## attr.has
       
   217                 // Checks if an element contains an attribute.
       
   218                 // For browsers that support `hasAttribute`, creates a function that calls hasAttribute, otherwise creates a function that uses `getAttribute` to check that the attribute is not null.
       
   219                 has: (function() {
       
   220                     var el = document.createElement('div');
       
   221                     if (el.hasAttribute) {
       
   222                         return function(el, name) {
       
   223                             return el.hasAttribute(name);
       
   224                         };
       
   225                     } else {
       
   226                         return function(el, name) {
       
   227                             return el.getAttribute(name) !== null;
       
   228                         };
       
   229                     }
       
   230                 })()
       
   231             };
       
   232 
       
   233         return attr;
       
   234 
       
   235     })(__m5);
       
   236 
       
   237     // ## can/event/event.js
       
   238     var __m7 = (function(can) {
       
   239         // ## can.event.addEvent
       
   240         // Adds a basic event listener to an object.
       
   241         // This consists of storing a cache of event listeners on each object,
       
   242         // that are iterated through later when events are dispatched.
       
   243 
       
   244         can.addEvent = function(event, handler) {
       
   245             // Initialize event cache.
       
   246             var allEvents = this.__bindEvents || (this.__bindEvents = {}),
       
   247                 eventList = allEvents[event] || (allEvents[event] = []);
       
   248 
       
   249             // Add the event
       
   250             eventList.push({
       
   251                     handler: handler,
       
   252                     name: event
       
   253                 });
       
   254             return this;
       
   255         };
       
   256 
       
   257         // ## can.event.listenTo
       
   258         // Listens to an event without know how bind is implemented.
       
   259         // The primary use for this is to listen to another's objects event while 
       
   260         // tracking events on the local object (similar to namespacing).
       
   261         // The API was heavily influenced by BackboneJS: http://backbonejs.org/
       
   262 
       
   263         can.listenTo = function(other, event, handler) {
       
   264             // Initialize event cache
       
   265             var idedEvents = this.__listenToEvents;
       
   266             if (!idedEvents) {
       
   267                 idedEvents = this.__listenToEvents = {};
       
   268             }
       
   269 
       
   270             // Identify the other object
       
   271             var otherId = can.cid(other);
       
   272             var othersEvents = idedEvents[otherId];
       
   273 
       
   274             // Create a local event cache
       
   275             if (!othersEvents) {
       
   276                 othersEvents = idedEvents[otherId] = {
       
   277                     obj: other,
       
   278                     events: {}
       
   279                 };
       
   280             }
       
   281             var eventsEvents = othersEvents.events[event];
       
   282             if (!eventsEvents) {
       
   283                 eventsEvents = othersEvents.events[event] = [];
       
   284             }
       
   285 
       
   286             // Add the event, both locally and to the other object
       
   287             eventsEvents.push(handler);
       
   288             can.bind.call(other, event, handler);
       
   289         };
       
   290 
       
   291         // ## can.event.stopListening
       
   292         // Stops listening for events on other objects
       
   293 
       
   294         can.stopListening = function(other, event, handler) {
       
   295             var idedEvents = this.__listenToEvents,
       
   296                 iterIdedEvents = idedEvents,
       
   297                 i = 0;
       
   298             if (!idedEvents) {
       
   299                 return this;
       
   300             }
       
   301             if (other) {
       
   302                 var othercid = can.cid(other);
       
   303                 (iterIdedEvents = {})[othercid] = idedEvents[othercid];
       
   304                 // you might be trying to listen to something that is not there
       
   305                 if (!idedEvents[othercid]) {
       
   306                     return this;
       
   307                 }
       
   308             }
       
   309 
       
   310             // Clean up events on the other object
       
   311             for (var cid in iterIdedEvents) {
       
   312                 var othersEvents = iterIdedEvents[cid],
       
   313                     eventsEvents;
       
   314                 other = idedEvents[cid].obj;
       
   315 
       
   316                 // Find the cache of events
       
   317                 if (!event) {
       
   318                     eventsEvents = othersEvents.events;
       
   319                 } else {
       
   320                     (eventsEvents = {})[event] = othersEvents.events[event];
       
   321                 }
       
   322 
       
   323                 // Unbind event handlers, both locally and on the other object
       
   324                 for (var eventName in eventsEvents) {
       
   325                     var handlers = eventsEvents[eventName] || [];
       
   326                     i = 0;
       
   327                     while (i < handlers.length) {
       
   328                         if (handler && handler === handlers[i] || !handler) {
       
   329                             can.unbind.call(other, eventName, handlers[i]);
       
   330                             handlers.splice(i, 1);
       
   331                         } else {
       
   332                             i++;
       
   333                         }
       
   334                     }
       
   335                     // no more handlers?
       
   336                     if (!handlers.length) {
       
   337                         delete othersEvents.events[eventName];
       
   338                     }
       
   339                 }
       
   340                 if (can.isEmptyObject(othersEvents.events)) {
       
   341                     delete idedEvents[cid];
       
   342                 }
       
   343             }
       
   344             return this;
       
   345         };
       
   346 
       
   347         // ## can.event.removeEvent
       
   348         // Removes a basic event listener from an object.
       
   349         // This removes event handlers from the cache of listened events.
       
   350 
       
   351         can.removeEvent = function(event, fn, __validate) {
       
   352             if (!this.__bindEvents) {
       
   353                 return this;
       
   354             }
       
   355             var events = this.__bindEvents[event] || [],
       
   356                 i = 0,
       
   357                 ev, isFunction = typeof fn === 'function';
       
   358             while (i < events.length) {
       
   359                 ev = events[i];
       
   360                 // Determine whether this event handler is "equivalent" to the one requested
       
   361                 // Generally this requires the same event/function, but a validation function 
       
   362                 // can be included for extra conditions. This is used in some plugins like `can/event/namespace`.
       
   363                 if (__validate ? __validate(ev, event, fn) : isFunction && ev.handler === fn || !isFunction && (ev.cid === fn || !fn)) {
       
   364                     events.splice(i, 1);
       
   365                 } else {
       
   366                     i++;
       
   367                 }
       
   368             }
       
   369             return this;
       
   370         };
       
   371 
       
   372         // ## can.event.dispatch
       
   373         // Dispatches/triggers a basic event on an object.
       
   374 
       
   375         can.dispatch = function(event, args) {
       
   376             var events = this.__bindEvents;
       
   377             if (!events) {
       
   378                 return;
       
   379             }
       
   380 
       
   381             // Initialize the event object
       
   382             if (typeof event === 'string') {
       
   383                 event = {
       
   384                     type: event
       
   385                 };
       
   386             }
       
   387 
       
   388             // Grab event listeners
       
   389             var eventName = event.type,
       
   390                 handlers = (events[eventName] || []).slice(0);
       
   391 
       
   392             // Execute handlers listening for this event.
       
   393             args = [event].concat(args || []);
       
   394             for (var i = 0, len = handlers.length; i < len; i++) {
       
   395                 handlers[i].handler.apply(this, args);
       
   396             }
       
   397 
       
   398             return event;
       
   399         };
       
   400 
       
   401         // ## can.event.one
       
   402         // Adds a basic event listener that listens to an event once and only once.
       
   403 
       
   404         can.one = function(event, handler) {
       
   405             // Unbind the listener after it has been executed
       
   406             var one = function() {
       
   407                 can.unbind.call(this, event, one);
       
   408                 return handler.apply(this, arguments);
       
   409             };
       
   410 
       
   411             // Bind the altered listener
       
   412             can.bind.call(this, event, one);
       
   413             return this;
       
   414         };
       
   415 
       
   416         // ## can.event
       
   417         // Create and export the `can.event` mixin
       
   418         can.event = {
       
   419             // Event method aliases
       
   420 
       
   421             on: function() {
       
   422                 if (arguments.length === 0 && can.Control && this instanceof can.Control) {
       
   423                     return can.Control.prototype.on.call(this);
       
   424                 } else {
       
   425                     return can.addEvent.apply(this, arguments);
       
   426                 }
       
   427             },
       
   428 
       
   429 
       
   430             off: function() {
       
   431                 if (arguments.length === 0 && can.Control && this instanceof can.Control) {
       
   432                     return can.Control.prototype.off.call(this);
       
   433                 } else {
       
   434                     return can.removeEvent.apply(this, arguments);
       
   435                 }
       
   436             },
       
   437 
       
   438 
       
   439             bind: can.addEvent,
       
   440 
       
   441             unbind: can.removeEvent,
       
   442 
       
   443             delegate: function(selector, event, handler) {
       
   444                 return can.addEvent.call(event, handler);
       
   445             },
       
   446 
       
   447             undelegate: function(selector, event, handler) {
       
   448                 return can.removeEvent.call(event, handler);
       
   449             },
       
   450 
       
   451             trigger: can.dispatch,
       
   452 
       
   453             // Normal can/event methods
       
   454             one: can.one,
       
   455             addEvent: can.addEvent,
       
   456             removeEvent: can.removeEvent,
       
   457             listenTo: can.listenTo,
       
   458             stopListening: can.stopListening,
       
   459             dispatch: can.dispatch
       
   460         };
       
   461 
       
   462         return can.event;
       
   463     })(__m5);
       
   464 
       
   465     // ## can/util/array/each.js
       
   466     var __m8 = (function(can) {
       
   467 
       
   468         // The following is from jQuery
       
   469         var isArrayLike = function(obj) {
       
   470             var length = obj.length;
       
   471             return typeof arr !== "function" &&
       
   472             (length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj);
       
   473         };
       
   474 
       
   475         can.each = function(elements, callback, context) {
       
   476             var i = 0,
       
   477                 key,
       
   478                 len,
       
   479                 item;
       
   480             if (elements) {
       
   481                 if (isArrayLike(elements)) {
       
   482                     if (can.List && elements instanceof can.List) {
       
   483                         for (len = elements.attr("length"); i < len; i++) {
       
   484                             item = elements.attr(i);
       
   485                             if (callback.call(context || item, item, i, elements) === false) {
       
   486                                 break;
       
   487                             }
       
   488                         }
       
   489                     } else {
       
   490                         for (len = elements.length; i < len; i++) {
       
   491                             item = elements[i];
       
   492                             if (callback.call(context || item, item, i, elements) === false) {
       
   493                                 break;
       
   494                             }
       
   495                         }
       
   496                     }
       
   497 
       
   498                 } else if (typeof elements === "object") {
       
   499 
       
   500                     if (can.Map && elements instanceof can.Map || elements === can.route) {
       
   501                         var keys = can.Map.keys(elements);
       
   502                         for (i = 0, len = keys.length; i < len; i++) {
       
   503                             key = keys[i];
       
   504                             item = elements.attr(key);
       
   505                             if (callback.call(context || item, item, key, elements) === false) {
       
   506                                 break;
       
   507                             }
       
   508                         }
       
   509                     } else {
       
   510                         for (key in elements) {
       
   511                             if (elements.hasOwnProperty(key) && callback.call(context || elements[key], elements[key], key, elements) === false) {
       
   512                                 break;
       
   513                             }
       
   514                         }
       
   515                     }
       
   516 
       
   517                 }
       
   518             }
       
   519             return elements;
       
   520         };
       
   521         return can;
       
   522     })(__m5);
       
   523 
       
   524     // ## can/util/inserted/inserted.js
       
   525     var __m9 = (function(can) {
       
   526         can.inserted = function(elems) {
       
   527             // Turn the `elems` property into an array to prevent mutations from changing the looping.
       
   528             elems = can.makeArray(elems);
       
   529             var inDocument = false,
       
   530                 // Gets the `doc` to use as a reference for finding out whether the element is in the document.
       
   531                 doc = can.$(document.contains ? document : document.body),
       
   532                 children;
       
   533             // Go through `elems` and trigger the `inserted` event.
       
   534             // If the first element is not in the document (a Document Fragment) it will exit the function. If it is in the document it sets the `inDocument` flag to true. This means that we only check for the first element and either exit the function or start triggering "inserted" for child elements.
       
   535             for (var i = 0, elem;
       
   536                 (elem = elems[i]) !== undefined; i++) {
       
   537                 if (!inDocument) {
       
   538                     if (elem.getElementsByTagName) {
       
   539                         if (can.has(doc, elem)
       
   540                             .length) {
       
   541                             inDocument = true;
       
   542                         } else {
       
   543                             return;
       
   544                         }
       
   545                     } else {
       
   546                         continue;
       
   547                     }
       
   548                 }
       
   549 
       
   550                 // If we've found an element in the document then we can now trigger **"inserted"** for `elem` and all of its children. We are using `getElementsByTagName("*")` so that we grab all of the descendant nodes.
       
   551                 if (inDocument && elem.getElementsByTagName) {
       
   552                     children = can.makeArray(elem.getElementsByTagName("*"));
       
   553                     can.trigger(elem, "inserted", [], false);
       
   554                     for (var j = 0, child;
       
   555                         (child = children[j]) !== undefined; j++) {
       
   556                         can.trigger(child, "inserted", [], false);
       
   557                     }
       
   558                 }
       
   559             }
       
   560         };
       
   561 
       
   562         // ## can.appendChild
       
   563         // Used to append a node to an element and trigger the "inserted" event on all of the newly inserted children. Since `can.inserted` takes an array we convert the child to an array, or in the case of a DocumentFragment we first convert the childNodes to an array and call inserted on those.
       
   564         can.appendChild = function(el, child) {
       
   565             var children;
       
   566             if (child.nodeType === 11) {
       
   567                 children = can.makeArray(child.childNodes);
       
   568             } else {
       
   569                 children = [child];
       
   570             }
       
   571             el.appendChild(child);
       
   572             can.inserted(children);
       
   573         };
       
   574 
       
   575         // ## can.insertBefore
       
   576         // Like can.appendChild, used to insert a node to an element before a reference node and then trigger the "inserted" event.
       
   577         can.insertBefore = function(el, child, ref) {
       
   578             var children;
       
   579             if (child.nodeType === 11) {
       
   580                 children = can.makeArray(child.childNodes);
       
   581             } else {
       
   582                 children = [child];
       
   583             }
       
   584             el.insertBefore(child, ref);
       
   585             can.inserted(children);
       
   586         };
       
   587     })(__m5);
       
   588 
       
   589     // ## can/util/jquery/jquery.js
       
   590     var __m3 = (function($, can, attr, event) {
       
   591         var isBindableElement = function(node) {
       
   592             // In IE8 window.window !== window.window, so we allow == here.
       
   593 
       
   594             return (node.nodeName && (node.nodeType === 1 || node.nodeType === 9)) || node == window;
       
   595         };
       
   596         // _jQuery node list._
       
   597         $.extend(can, $, {
       
   598                 trigger: function(obj, event, args, bubbles) {
       
   599                     if (isBindableElement(obj)) {
       
   600                         $.event.trigger(event, args, obj, !bubbles);
       
   601                     } else if (obj.trigger) {
       
   602                         obj.trigger(event, args);
       
   603                     } else {
       
   604                         if (typeof event === 'string') {
       
   605                             event = {
       
   606                                 type: event
       
   607                             };
       
   608                         }
       
   609                         event.target = event.target || obj;
       
   610                         can.dispatch.call(obj, event, args);
       
   611                     }
       
   612                 },
       
   613                 event: can.event,
       
   614                 addEvent: can.addEvent,
       
   615                 removeEvent: can.removeEvent,
       
   616                 buildFragment: function(elems, context) {
       
   617                     // Check if this has any html nodes on our own.
       
   618                     var ret;
       
   619                     elems = [elems];
       
   620                     // Set context per 1.8 logic
       
   621                     context = context || document;
       
   622                     context = !context.nodeType && context[0] || context;
       
   623                     context = context.ownerDocument || context;
       
   624                     ret = $.buildFragment(elems, context);
       
   625                     return ret.cacheable ? $.clone(ret.fragment) : ret.fragment || ret;
       
   626                 },
       
   627                 $: $,
       
   628                 each: can.each,
       
   629                 bind: function(ev, cb) {
       
   630                     // If we can bind to it...
       
   631                     if (this.bind && this.bind !== can.bind) {
       
   632                         this.bind(ev, cb);
       
   633                     } else if (isBindableElement(this)) {
       
   634                         $.event.add(this, ev, cb);
       
   635                     } else {
       
   636                         // Make it bind-able...
       
   637                         can.addEvent.call(this, ev, cb);
       
   638                     }
       
   639                     return this;
       
   640                 },
       
   641                 unbind: function(ev, cb) {
       
   642                     // If we can bind to it...
       
   643                     if (this.unbind && this.unbind !== can.unbind) {
       
   644                         this.unbind(ev, cb);
       
   645                     } else if (isBindableElement(this)) {
       
   646                         $.event.remove(this, ev, cb);
       
   647                     } else {
       
   648                         // Make it bind-able...
       
   649                         can.removeEvent.call(this, ev, cb);
       
   650                     }
       
   651                     return this;
       
   652                 },
       
   653                 delegate: function(selector, ev, cb) {
       
   654                     if (this.delegate) {
       
   655                         this.delegate(selector, ev, cb);
       
   656                     } else if (isBindableElement(this)) {
       
   657                         $(this)
       
   658                             .delegate(selector, ev, cb);
       
   659                     } else {
       
   660                         // make it bind-able ...
       
   661                         can.bind.call(this, ev, cb);
       
   662                     }
       
   663                     return this;
       
   664                 },
       
   665                 undelegate: function(selector, ev, cb) {
       
   666                     if (this.undelegate) {
       
   667                         this.undelegate(selector, ev, cb);
       
   668                     } else if (isBindableElement(this)) {
       
   669                         $(this)
       
   670                             .undelegate(selector, ev, cb);
       
   671                     } else {
       
   672                         can.unbind.call(this, ev, cb);
       
   673                     }
       
   674                     return this;
       
   675                 },
       
   676                 proxy: function(fn, context) {
       
   677                     return function() {
       
   678                         return fn.apply(context, arguments);
       
   679                     };
       
   680                 },
       
   681                 attr: attr
       
   682             });
       
   683         // Wrap binding functions.
       
   684 
       
   685         // Aliases
       
   686         can.on = can.bind;
       
   687         can.off = can.unbind;
       
   688         // Wrap modifier functions.
       
   689         $.each([
       
   690                 'append',
       
   691                 'filter',
       
   692                 'addClass',
       
   693                 'remove',
       
   694                 'data',
       
   695                 'get',
       
   696                 'has'
       
   697             ], function(i, name) {
       
   698                 can[name] = function(wrapped) {
       
   699                     return wrapped[name].apply(wrapped, can.makeArray(arguments)
       
   700                         .slice(1));
       
   701                 };
       
   702             });
       
   703         // Memory safe destruction.
       
   704         var oldClean = $.cleanData;
       
   705         $.cleanData = function(elems) {
       
   706             $.each(elems, function(i, elem) {
       
   707                 if (elem) {
       
   708                     can.trigger(elem, 'removed', [], false);
       
   709                 }
       
   710             });
       
   711             oldClean(elems);
       
   712         };
       
   713         var oldDomManip = $.fn.domManip,
       
   714             cbIndex;
       
   715         // feature detect which domManip we are using
       
   716         $.fn.domManip = function(args, cb1, cb2) {
       
   717             for (var i = 1; i < arguments.length; i++) {
       
   718                 if (typeof arguments[i] === 'function') {
       
   719                     cbIndex = i;
       
   720                     break;
       
   721                 }
       
   722             }
       
   723             return oldDomManip.apply(this, arguments);
       
   724         };
       
   725         $(document.createElement("div"))
       
   726             .append(document.createElement("div"));
       
   727 
       
   728         $.fn.domManip = (cbIndex === 2 ? function(args, table, callback) {
       
   729             return oldDomManip.call(this, args, table, function(elem) {
       
   730                 var elems;
       
   731                 if (elem.nodeType === 11) {
       
   732                     elems = can.makeArray(elem.childNodes);
       
   733                 }
       
   734                 var ret = callback.apply(this, arguments);
       
   735                 can.inserted(elems ? elems : [elem]);
       
   736                 return ret;
       
   737             });
       
   738         } : function(args, callback) {
       
   739             return oldDomManip.call(this, args, function(elem) {
       
   740                 var elems;
       
   741                 if (elem.nodeType === 11) {
       
   742                     elems = can.makeArray(elem.childNodes);
       
   743                 }
       
   744                 var ret = callback.apply(this, arguments);
       
   745                 can.inserted(elems ? elems : [elem]);
       
   746                 return ret;
       
   747             });
       
   748         });
       
   749 
       
   750         if (!can.attr.MutationObserver) {
       
   751             // handle via calls to attr
       
   752             var oldAttr = $.attr;
       
   753             $.attr = function(el, attrName) {
       
   754                 var oldValue, newValue;
       
   755                 if (arguments.length >= 3) {
       
   756                     oldValue = oldAttr.call(this, el, attrName);
       
   757                 }
       
   758                 var res = oldAttr.apply(this, arguments);
       
   759                 if (arguments.length >= 3) {
       
   760                     newValue = oldAttr.call(this, el, attrName);
       
   761                 }
       
   762                 if (newValue !== oldValue) {
       
   763                     can.attr.trigger(el, attrName, oldValue);
       
   764                 }
       
   765                 return res;
       
   766             };
       
   767             var oldRemove = $.removeAttr;
       
   768             $.removeAttr = function(el, attrName) {
       
   769                 var oldValue = oldAttr.call(this, el, attrName),
       
   770                     res = oldRemove.apply(this, arguments);
       
   771 
       
   772                 if (oldValue != null) {
       
   773                     can.attr.trigger(el, attrName, oldValue);
       
   774                 }
       
   775                 return res;
       
   776             };
       
   777             $.event.special.attributes = {
       
   778                 setup: function() {
       
   779                     can.data(can.$(this), "canHasAttributesBindings", true);
       
   780                 },
       
   781                 teardown: function() {
       
   782                     $.removeData(this, "canHasAttributesBindings");
       
   783                 }
       
   784             };
       
   785         } else {
       
   786             // setup a special events
       
   787             $.event.special.attributes = {
       
   788                 setup: function() {
       
   789                     var self = this;
       
   790                     var observer = new can.attr.MutationObserver(function(mutations) {
       
   791                         mutations.forEach(function(mutation) {
       
   792                             var copy = can.simpleExtend({}, mutation);
       
   793                             can.trigger(self, copy, []);
       
   794                         });
       
   795 
       
   796                     });
       
   797                     observer.observe(this, {
       
   798                             attributes: true,
       
   799                             attributeOldValue: true
       
   800                         });
       
   801                     can.data(can.$(this), "canAttributesObserver", observer);
       
   802                 },
       
   803                 teardown: function() {
       
   804                     can.data(can.$(this), "canAttributesObserver")
       
   805                         .disconnect();
       
   806                     $.removeData(this, "canAttributesObserver");
       
   807 
       
   808                 }
       
   809             };
       
   810         }
       
   811 
       
   812         // ## Fix build fragment.
       
   813         // In IE8, we can pass jQuery a fragment and it removes newlines.
       
   814         // This checks for that and replaces can.buildFragment with something
       
   815         // that if only a single text node is returned, returns a fragment with
       
   816         // a text node that is set to the content.
       
   817         (function() {
       
   818 
       
   819             var text = "<-\n>",
       
   820                 frag = can.buildFragment(text, document);
       
   821             if (text !== frag.childNodes[0].nodeValue) {
       
   822 
       
   823                 var oldBuildFragment = can.buildFragment;
       
   824                 can.buildFragment = function(content, context) {
       
   825                     var res = oldBuildFragment(content, context);
       
   826                     if (res.childNodes.length === 1 && res.childNodes[0].nodeType === 3) {
       
   827                         res.childNodes[0].nodeValue = content;
       
   828                     }
       
   829                     return res;
       
   830                 };
       
   831 
       
   832             }
       
   833 
       
   834 
       
   835 
       
   836         })();
       
   837 
       
   838         $.event.special.inserted = {};
       
   839         $.event.special.removed = {};
       
   840         return can;
       
   841     })(jQuery, __m5, __m6, __m7, __m8, __m9);
       
   842 
       
   843     // ## can/util/string/string.js
       
   844     var __m2 = (function(can) {
       
   845         // ##string.js
       
   846         // _Miscellaneous string utility functions._  
       
   847         // Several of the methods in this plugin use code adapated from Prototype
       
   848         // Prototype JavaScript framework, version 1.6.0.1.
       
   849         // © 2005-2007 Sam Stephenson
       
   850         var strUndHash = /_|-/,
       
   851             strColons = /\=\=/,
       
   852             strWords = /([A-Z]+)([A-Z][a-z])/g,
       
   853             strLowUp = /([a-z\d])([A-Z])/g,
       
   854             strDash = /([a-z\d])([A-Z])/g,
       
   855             strReplacer = /\{([^\}]+)\}/g,
       
   856             strQuote = /"/g,
       
   857             strSingleQuote = /'/g,
       
   858             strHyphenMatch = /-+(.)?/g,
       
   859             strCamelMatch = /[a-z][A-Z]/g,
       
   860             // Returns the `prop` property from `obj`.
       
   861             // If `add` is true and `prop` doesn't exist in `obj`, create it as an
       
   862             // empty object.
       
   863             getNext = function(obj, prop, add) {
       
   864                 var result = obj[prop];
       
   865                 if (result === undefined && add === true) {
       
   866                     result = obj[prop] = {};
       
   867                 }
       
   868                 return result;
       
   869             },
       
   870             // Returns `true` if the object can have properties (no `null`s).
       
   871             isContainer = function(current) {
       
   872                 return /^f|^o/.test(typeof current);
       
   873             }, convertBadValues = function(content) {
       
   874                 // Convert bad values into empty strings
       
   875                 var isInvalid = content === null || content === undefined || isNaN(content) && '' + content === 'NaN';
       
   876                 return '' + (isInvalid ? '' : content);
       
   877             };
       
   878         can.extend(can, {
       
   879                 esc: function(content) {
       
   880                     return convertBadValues(content)
       
   881                         .replace(/&/g, '&amp;')
       
   882                         .replace(/</g, '&lt;')
       
   883                         .replace(/>/g, '&gt;')
       
   884                         .replace(strQuote, '&#34;')
       
   885                         .replace(strSingleQuote, '&#39;');
       
   886                 },
       
   887                 getObject: function(name, roots, add) {
       
   888                     // The parts of the name we are looking up
       
   889                     // `['App','Models','Recipe']`
       
   890                     var parts = name ? name.split('.') : [],
       
   891                         length = parts.length,
       
   892                         current, r = 0,
       
   893                         i, container, rootsLength;
       
   894                     // Make sure roots is an `array`.
       
   895                     roots = can.isArray(roots) ? roots : [roots || window];
       
   896                     rootsLength = roots.length;
       
   897                     if (!length) {
       
   898                         return roots[0];
       
   899                     }
       
   900                     // For each root, mark it as current.
       
   901                     for (r; r < rootsLength; r++) {
       
   902                         current = roots[r];
       
   903                         container = undefined;
       
   904                         // Walk current to the 2nd to last object or until there
       
   905                         // is not a container.
       
   906                         for (i = 0; i < length && isContainer(current); i++) {
       
   907                             container = current;
       
   908                             current = getNext(container, parts[i]);
       
   909                         }
       
   910                         // If we found property break cycle
       
   911                         if (container !== undefined && current !== undefined) {
       
   912                             break;
       
   913                         }
       
   914                     }
       
   915                     // Remove property from found container
       
   916                     if (add === false && current !== undefined) {
       
   917                         delete container[parts[i - 1]];
       
   918                     }
       
   919                     // When adding property add it to the first root
       
   920                     if (add === true && current === undefined) {
       
   921                         current = roots[0];
       
   922                         for (i = 0; i < length && isContainer(current); i++) {
       
   923                             current = getNext(current, parts[i], true);
       
   924                         }
       
   925                     }
       
   926                     return current;
       
   927                 },
       
   928                 capitalize: function(s, cache) {
       
   929                     // Used to make newId.
       
   930                     return s.charAt(0)
       
   931                         .toUpperCase() + s.slice(1);
       
   932                 },
       
   933                 camelize: function(str) {
       
   934                     return convertBadValues(str)
       
   935                         .replace(strHyphenMatch, function(match, chr) {
       
   936                             return chr ? chr.toUpperCase() : '';
       
   937                         });
       
   938                 },
       
   939                 hyphenate: function(str) {
       
   940                     return convertBadValues(str)
       
   941                         .replace(strCamelMatch, function(str, offset) {
       
   942                             return str.charAt(0) + '-' + str.charAt(1)
       
   943                                 .toLowerCase();
       
   944                         });
       
   945                 },
       
   946                 underscore: function(s) {
       
   947                     return s.replace(strColons, '/')
       
   948                         .replace(strWords, '$1_$2')
       
   949                         .replace(strLowUp, '$1_$2')
       
   950                         .replace(strDash, '_')
       
   951                         .toLowerCase();
       
   952                 },
       
   953                 sub: function(str, data, remove) {
       
   954                     var obs = [];
       
   955                     str = str || '';
       
   956                     obs.push(str.replace(strReplacer, function(whole, inside) {
       
   957                                 // Convert inside to type.
       
   958                                 var ob = can.getObject(inside, data, remove === true ? false : undefined);
       
   959                                 if (ob === undefined || ob === null) {
       
   960                                     obs = null;
       
   961                                     return '';
       
   962                                 }
       
   963                                 // If a container, push into objs (which will return objects found).
       
   964                                 if (isContainer(ob) && obs) {
       
   965                                     obs.push(ob);
       
   966                                     return '';
       
   967                                 }
       
   968                                 return '' + ob;
       
   969                             }));
       
   970                     return obs === null ? obs : obs.length <= 1 ? obs[0] : obs;
       
   971                 },
       
   972                 replacer: strReplacer,
       
   973                 undHash: strUndHash
       
   974             });
       
   975         return can;
       
   976     })(__m3);
       
   977 
       
   978     // ## can/construct/construct.js
       
   979     var __m1 = (function(can) {
       
   980         // ## construct.js
       
   981         // `can.Construct`  
       
   982         // _This is a modified version of
       
   983         // [John Resig's class](http://ejohn.org/blog/simple-javascript-inheritance/).  
       
   984         // It provides class level inheritance and callbacks._
       
   985         // A private flag used to initialize a new class instance without
       
   986         // initializing it's bindings.
       
   987         var initializing = 0;
       
   988 
       
   989         can.Construct = function() {
       
   990             if (arguments.length) {
       
   991                 return can.Construct.extend.apply(can.Construct, arguments);
       
   992             }
       
   993         };
       
   994 
       
   995         can.extend(can.Construct, {
       
   996 
       
   997                 constructorExtends: true,
       
   998 
       
   999                 newInstance: function() {
       
  1000                     // Get a raw instance object (`init` is not called).
       
  1001                     var inst = this.instance(),
       
  1002                         args;
       
  1003                     // Call `setup` if there is a `setup`
       
  1004                     if (inst.setup) {
       
  1005                         args = inst.setup.apply(inst, arguments);
       
  1006                     }
       
  1007                     // Call `init` if there is an `init`  
       
  1008                     // If `setup` returned `args`, use those as the arguments
       
  1009                     if (inst.init) {
       
  1010                         inst.init.apply(inst, args || arguments);
       
  1011                     }
       
  1012                     return inst;
       
  1013                 },
       
  1014                 // Overwrites an object with methods. Used in the `super` plugin.
       
  1015                 // `newProps` - New properties to add.
       
  1016                 // `oldProps` - Where the old properties might be (used with `super`).
       
  1017                 // `addTo` - What we are adding to.
       
  1018                 _inherit: function(newProps, oldProps, addTo) {
       
  1019                     can.extend(addTo || newProps, newProps || {});
       
  1020                 },
       
  1021                 // used for overwriting a single property.
       
  1022                 // this should be used for patching other objects
       
  1023                 // the super plugin overwrites this
       
  1024                 _overwrite: function(what, oldProps, propName, val) {
       
  1025                     what[propName] = val;
       
  1026                 },
       
  1027                 // Set `defaults` as the merger of the parent `defaults` and this
       
  1028                 // object's `defaults`. If you overwrite this method, make sure to
       
  1029                 // include option merging logic.
       
  1030 
       
  1031                 setup: function(base, fullName) {
       
  1032                     this.defaults = can.extend(true, {}, base.defaults, this.defaults);
       
  1033                 },
       
  1034                 // Create's a new `class` instance without initializing by setting the
       
  1035                 // `initializing` flag.
       
  1036                 instance: function() {
       
  1037                     // Prevents running `init`.
       
  1038                     initializing = 1;
       
  1039                     var inst = new this();
       
  1040                     // Allow running `init`.
       
  1041                     initializing = 0;
       
  1042                     return inst;
       
  1043                 },
       
  1044                 // Extends classes.
       
  1045 
       
  1046                 extend: function(fullName, klass, proto) {
       
  1047                     // Figure out what was passed and normalize it.
       
  1048                     if (typeof fullName !== 'string') {
       
  1049                         proto = klass;
       
  1050                         klass = fullName;
       
  1051                         fullName = null;
       
  1052                     }
       
  1053                     if (!proto) {
       
  1054                         proto = klass;
       
  1055                         klass = null;
       
  1056                     }
       
  1057                     proto = proto || {};
       
  1058                     var _super_class = this,
       
  1059                         _super = this.prototype,
       
  1060                         parts, current, _fullName, _shortName, name, shortName, namespace, prototype;
       
  1061                     // Instantiate a base class (but only create the instance,
       
  1062                     // don't run the init constructor).
       
  1063                     prototype = this.instance();
       
  1064                     // Copy the properties over onto the new prototype.
       
  1065                     can.Construct._inherit(proto, _super, prototype);
       
  1066                     // The dummy class constructor.
       
  1067 
       
  1068                     function Constructor() {
       
  1069                         // All construction is actually done in the init method.
       
  1070                         if (!initializing) {
       
  1071 
       
  1072 
       
  1073                             return this.constructor !== Constructor &&
       
  1074                             // We are being called without `new` or we are extending.
       
  1075                             arguments.length && Constructor.constructorExtends ? Constructor.extend.apply(Constructor, arguments) :
       
  1076                             // We are being called with `new`.
       
  1077                             Constructor.newInstance.apply(Constructor, arguments);
       
  1078                         }
       
  1079                     }
       
  1080                     // Copy old stuff onto class (can probably be merged w/ inherit)
       
  1081                     for (name in _super_class) {
       
  1082                         if (_super_class.hasOwnProperty(name)) {
       
  1083                             Constructor[name] = _super_class[name];
       
  1084                         }
       
  1085                     }
       
  1086                     // Copy new static properties on class.
       
  1087                     can.Construct._inherit(klass, _super_class, Constructor);
       
  1088                     // Setup namespaces.
       
  1089                     if (fullName) {
       
  1090 
       
  1091                         parts = fullName.split('.');
       
  1092                         shortName = parts.pop();
       
  1093                         current = can.getObject(parts.join('.'), window, true);
       
  1094                         namespace = current;
       
  1095                         _fullName = can.underscore(fullName.replace(/\./g, "_"));
       
  1096                         _shortName = can.underscore(shortName);
       
  1097 
       
  1098 
       
  1099 
       
  1100                         current[shortName] = Constructor;
       
  1101                     }
       
  1102                     // Set things that shouldn't be overwritten.
       
  1103                     can.extend(Constructor, {
       
  1104                             constructor: Constructor,
       
  1105                             prototype: prototype,
       
  1106 
       
  1107                             namespace: namespace,
       
  1108 
       
  1109                             _shortName: _shortName,
       
  1110 
       
  1111                             fullName: fullName,
       
  1112                             _fullName: _fullName
       
  1113                         });
       
  1114                     // Dojo and YUI extend undefined
       
  1115                     if (shortName !== undefined) {
       
  1116                         Constructor.shortName = shortName;
       
  1117                     }
       
  1118                     // Make sure our prototype looks nice.
       
  1119                     Constructor.prototype.constructor = Constructor;
       
  1120                     // Call the class `setup` and `init`
       
  1121                     var t = [_super_class].concat(can.makeArray(arguments)),
       
  1122                         args = Constructor.setup.apply(Constructor, t);
       
  1123                     if (Constructor.init) {
       
  1124                         Constructor.init.apply(Constructor, args || t);
       
  1125                     }
       
  1126 
       
  1127                     return Constructor;
       
  1128                 }
       
  1129             });
       
  1130 
       
  1131         can.Construct.prototype.setup = function() {};
       
  1132 
       
  1133         can.Construct.prototype.init = function() {};
       
  1134         return can.Construct;
       
  1135     })(__m2);
       
  1136 
       
  1137     // ## can/util/bind/bind.js
       
  1138     var __m11 = (function(can) {
       
  1139 
       
  1140         // ## Bind helpers
       
  1141         can.bindAndSetup = function() {
       
  1142             // Add the event to this object
       
  1143             can.addEvent.apply(this, arguments);
       
  1144             // If not initializing, and the first binding
       
  1145             // call bindsetup if the function exists.
       
  1146             if (!this._init) {
       
  1147                 if (!this._bindings) {
       
  1148                     this._bindings = 1;
       
  1149                     // setup live-binding
       
  1150                     if (this._bindsetup) {
       
  1151                         this._bindsetup();
       
  1152                     }
       
  1153                 } else {
       
  1154                     this._bindings++;
       
  1155                 }
       
  1156             }
       
  1157             return this;
       
  1158         };
       
  1159         can.unbindAndTeardown = function(ev, handler) {
       
  1160             // Remove the event handler
       
  1161             can.removeEvent.apply(this, arguments);
       
  1162             if (this._bindings === null) {
       
  1163                 this._bindings = 0;
       
  1164             } else {
       
  1165                 this._bindings--;
       
  1166             }
       
  1167             // If there are no longer any bindings and
       
  1168             // there is a bindteardown method, call it.
       
  1169             if (!this._bindings && this._bindteardown) {
       
  1170                 this._bindteardown();
       
  1171             }
       
  1172             return this;
       
  1173         };
       
  1174         return can;
       
  1175     })(__m3);
       
  1176 
       
  1177     // ## can/map/bubble.js
       
  1178     var __m12 = (function(can) {
       
  1179 
       
  1180 
       
  1181 
       
  1182         var bubble = can.bubble = {
       
  1183             // Given a binding, returns a string event name used to set up bubbline.
       
  1184             // If no binding should be done, undefined or null should be returned
       
  1185             event: function(map, eventName) {
       
  1186                 return map.constructor._bubbleRule(eventName, map);
       
  1187             },
       
  1188             childrenOf: function(parentMap, eventName) {
       
  1189 
       
  1190                 parentMap._each(function(child, prop) {
       
  1191                     if (child && child.bind) {
       
  1192                         bubble.toParent(child, parentMap, prop, eventName);
       
  1193                     }
       
  1194                 });
       
  1195 
       
  1196             },
       
  1197             teardownChildrenFrom: function(parentMap, eventName) {
       
  1198                 parentMap._each(function(child) {
       
  1199 
       
  1200                     bubble.teardownFromParent(parentMap, child, eventName);
       
  1201 
       
  1202                 });
       
  1203             },
       
  1204             toParent: function(child, parent, prop, eventName) {
       
  1205                 can.listenTo.call(parent, child, eventName, function() {
       
  1206                     // `batchTrigger` the type on this...
       
  1207                     var args = can.makeArray(arguments),
       
  1208                         ev = args.shift();
       
  1209 
       
  1210                     args[0] =
       
  1211                     (can.List && parent instanceof can.List ?
       
  1212                         parent.indexOf(child) :
       
  1213                         prop) + (args[0] ? "." + args[0] : "");
       
  1214 
       
  1215                     // track objects dispatched on this map		
       
  1216                     ev.triggeredNS = ev.triggeredNS || {};
       
  1217 
       
  1218                     // if it has already been dispatched exit
       
  1219                     if (ev.triggeredNS[parent._cid]) {
       
  1220                         return;
       
  1221                     }
       
  1222 
       
  1223                     ev.triggeredNS[parent._cid] = true;
       
  1224                     // send change event with modified attr to parent	
       
  1225                     can.trigger(parent, ev, args);
       
  1226                 });
       
  1227             },
       
  1228             teardownFromParent: function(parent, child, eventName) {
       
  1229                 if (child && child.unbind) {
       
  1230                     can.stopListening.call(parent, child, eventName);
       
  1231                 }
       
  1232             },
       
  1233             bind: function(parent, eventName) {
       
  1234                 if (!parent._init) {
       
  1235                     var bubbleEvent = bubble.event(parent, eventName);
       
  1236                     if (bubbleEvent) {
       
  1237                         if (!parent._bubbleBindings) {
       
  1238                             parent._bubbleBindings = {};
       
  1239                         }
       
  1240                         if (!parent._bubbleBindings[bubbleEvent]) {
       
  1241                             parent._bubbleBindings[bubbleEvent] = 1;
       
  1242                             // setup live-binding
       
  1243                             bubble.childrenOf(parent, bubbleEvent);
       
  1244                         } else {
       
  1245                             parent._bubbleBindings[bubbleEvent]++;
       
  1246                         }
       
  1247 
       
  1248                     }
       
  1249                 }
       
  1250             },
       
  1251             unbind: function(parent, eventName) {
       
  1252                 var bubbleEvent = bubble.event(parent, eventName);
       
  1253                 if (bubbleEvent) {
       
  1254                     if (parent._bubbleBindings) {
       
  1255                         parent._bubbleBindings[bubbleEvent]--;
       
  1256                     }
       
  1257 
       
  1258                     if (!parent._bubbleBindings[bubbleEvent]) {
       
  1259                         delete parent._bubbleBindings[bubbleEvent];
       
  1260                         bubble.teardownChildrenFrom(parent, bubbleEvent);
       
  1261                         if (can.isEmptyObject(parent._bubbleBindings)) {
       
  1262                             delete parent._bubbleBindings;
       
  1263                         }
       
  1264                     }
       
  1265                 }
       
  1266             },
       
  1267             add: function(parent, child, prop) {
       
  1268                 if (child instanceof can.Map && parent._bubbleBindings) {
       
  1269                     for (var eventName in parent._bubbleBindings) {
       
  1270                         if (parent._bubbleBindings[eventName]) {
       
  1271                             bubble.teardownFromParent(parent, child, eventName);
       
  1272                             bubble.toParent(child, parent, prop, eventName);
       
  1273                         }
       
  1274                     }
       
  1275                 }
       
  1276             },
       
  1277             removeMany: function(parent, children) {
       
  1278                 for (var i = 0, len = children.length; i < len; i++) {
       
  1279                     bubble.remove(parent, children[i]);
       
  1280                 }
       
  1281             },
       
  1282             remove: function(parent, child) {
       
  1283                 if (child instanceof can.Map && parent._bubbleBindings) {
       
  1284                     for (var eventName in parent._bubbleBindings) {
       
  1285                         if (parent._bubbleBindings[eventName]) {
       
  1286                             bubble.teardownFromParent(parent, child, eventName);
       
  1287                         }
       
  1288                     }
       
  1289                 }
       
  1290             },
       
  1291             set: function(parent, prop, value, current) {
       
  1292 
       
  1293                 //var res = parent.__type(value, prop);
       
  1294                 if (can.Map.helpers.isObservable(value)) {
       
  1295                     bubble.add(parent, value, prop);
       
  1296                 }
       
  1297                 // bubble.add will remove, so only remove if we are replacing another object
       
  1298                 if (can.Map.helpers.isObservable(current)) {
       
  1299                     bubble.remove(parent, current);
       
  1300                 }
       
  1301                 return value;
       
  1302             }
       
  1303         };
       
  1304 
       
  1305         return bubble;
       
  1306 
       
  1307     })(__m3);
       
  1308 
       
  1309     // ## can/util/batch/batch.js
       
  1310     var __m13 = (function(can) {
       
  1311         // Which batch of events this is for -- might not want to send multiple
       
  1312         // messages on the same batch.  This is mostly for event delegation.
       
  1313         var batchNum = 1,
       
  1314             // how many times has start been called without a stop
       
  1315             transactions = 0,
       
  1316             // an array of events within a transaction
       
  1317             batchEvents = [],
       
  1318             stopCallbacks = [];
       
  1319         can.batch = {
       
  1320 
       
  1321             start: function(batchStopHandler) {
       
  1322                 transactions++;
       
  1323                 if (batchStopHandler) {
       
  1324                     stopCallbacks.push(batchStopHandler);
       
  1325                 }
       
  1326             },
       
  1327 
       
  1328             stop: function(force, callStart) {
       
  1329                 if (force) {
       
  1330                     transactions = 0;
       
  1331                 } else {
       
  1332                     transactions--;
       
  1333                 }
       
  1334                 if (transactions === 0) {
       
  1335                     var items = batchEvents.slice(0),
       
  1336                         callbacks = stopCallbacks.slice(0),
       
  1337                         i, len;
       
  1338                     batchEvents = [];
       
  1339                     stopCallbacks = [];
       
  1340                     batchNum++;
       
  1341                     if (callStart) {
       
  1342                         can.batch.start();
       
  1343                     }
       
  1344                     for (i = 0, len = items.length; i < len; i++) {
       
  1345                         can.trigger.apply(can, items[i]);
       
  1346                     }
       
  1347                     for (i = 0, len = callbacks.length; i < callbacks.length; i++) {
       
  1348                         callbacks[i]();
       
  1349                     }
       
  1350                 }
       
  1351             },
       
  1352 
       
  1353             trigger: function(item, event, args) {
       
  1354                 // Don't send events if initalizing.
       
  1355                 if (!item._init) {
       
  1356                     if (transactions === 0) {
       
  1357                         return can.trigger(item, event, args);
       
  1358                     } else {
       
  1359                         event = typeof event === 'string' ? {
       
  1360                             type: event
       
  1361                         } : event;
       
  1362                         event.batchNum = batchNum;
       
  1363                         batchEvents.push([
       
  1364                                 item,
       
  1365                                 event,
       
  1366                                 args
       
  1367                             ]);
       
  1368                     }
       
  1369                 }
       
  1370             }
       
  1371         };
       
  1372     })(__m5);
       
  1373 
       
  1374     // ## can/map/map.js
       
  1375     var __m10 = (function(can, bind, bubble) {
       
  1376         // ## Helpers
       
  1377 
       
  1378         // A temporary map of Maps that have been made from plain JS objects.
       
  1379         var madeMap = null;
       
  1380         // Clears out map of converted objects.
       
  1381         var teardownMap = function() {
       
  1382             for (var cid in madeMap) {
       
  1383                 if (madeMap[cid].added) {
       
  1384                     delete madeMap[cid].obj._cid;
       
  1385                 }
       
  1386             }
       
  1387             madeMap = null;
       
  1388         };
       
  1389         // Retrieves a Map instance from an Object.
       
  1390         var getMapFromObject = function(obj) {
       
  1391             return madeMap && madeMap[obj._cid] && madeMap[obj._cid].instance;
       
  1392         };
       
  1393         // A temporary map of Maps
       
  1394         var serializeMap = null;
       
  1395 
       
  1396 
       
  1397         var Map = can.Map = can.Construct.extend({
       
  1398 
       
  1399                 setup: function() {
       
  1400 
       
  1401                     can.Construct.setup.apply(this, arguments);
       
  1402 
       
  1403                     // Do not run if we are defining can.Map.
       
  1404                     if (can.Map) {
       
  1405                         if (!this.defaults) {
       
  1406                             this.defaults = {};
       
  1407                         }
       
  1408                         // Builds a list of compute and non-compute properties in this Object's prototype.
       
  1409                         this._computes = [];
       
  1410 
       
  1411                         for (var prop in this.prototype) {
       
  1412                             // Non-functions are regular defaults.
       
  1413                             if (prop !== "define" && typeof this.prototype[prop] !== "function") {
       
  1414                                 this.defaults[prop] = this.prototype[prop];
       
  1415                                 // Functions with an `isComputed` property are computes.
       
  1416                             } else if (this.prototype[prop].isComputed) {
       
  1417                                 this._computes.push(prop);
       
  1418                             }
       
  1419                         }
       
  1420                         this.helpers.define(this);
       
  1421                     }
       
  1422                     // If we inherit from can.Map, but not can.List, make sure any lists are the correct type.
       
  1423                     if (can.List && !(this.prototype instanceof can.List)) {
       
  1424                         this.List = Map.List.extend({
       
  1425                                 Map: this
       
  1426                             }, {});
       
  1427                     }
       
  1428 
       
  1429                 },
       
  1430                 // Reference to bubbling helpers.
       
  1431                 _bubble: bubble,
       
  1432                 // Given an eventName, determine if bubbling should be setup.
       
  1433                 _bubbleRule: function(eventName) {
       
  1434                     return (eventName === "change" || eventName.indexOf(".") >= 0) && "change";
       
  1435                 },
       
  1436                 // List of computes on the Map's prototype.
       
  1437                 _computes: [],
       
  1438                 // Adds an event to this Map.
       
  1439                 bind: can.bindAndSetup,
       
  1440                 on: can.bindAndSetup,
       
  1441                 // Removes an event from this Map.
       
  1442                 unbind: can.unbindAndTeardown,
       
  1443                 off: can.unbindAndTeardown,
       
  1444                 // Name of the id field. Used in can.Model.
       
  1445                 id: "id",
       
  1446                 // ## Internal helpers
       
  1447                 helpers: {
       
  1448                     // ### can.Map.helpers.define
       
  1449                     // Stub function for the define plugin.
       
  1450                     define: function() {},
       
  1451 
       
  1452                     // ### can.Map.helpers.attrParts
       
  1453                     // Parses attribute name into its parts.
       
  1454                     attrParts: function(attr, keepKey) {
       
  1455                         //Keep key intact
       
  1456                         if (keepKey) {
       
  1457                             return [attr];
       
  1458                         }
       
  1459                         // Split key on '.'
       
  1460                         return can.isArray(attr) ? attr : ("" + attr)
       
  1461                             .split(".");
       
  1462                     },
       
  1463 
       
  1464                     // ### can.Map.helpers.addToMap
       
  1465                     // Tracks Map instances created from JS Objects
       
  1466                     addToMap: function(obj, instance) {
       
  1467                         var teardown;
       
  1468                         // Setup a fresh mapping if `madeMap` is missing.
       
  1469                         if (!madeMap) {
       
  1470                             teardown = teardownMap;
       
  1471                             madeMap = {};
       
  1472                         }
       
  1473                         // Record if Object has a `_cid` before adding one.
       
  1474                         var hasCid = obj._cid;
       
  1475                         var cid = can.cid(obj);
       
  1476 
       
  1477                         // Only update if there already isn't one already.
       
  1478                         if (!madeMap[cid]) {
       
  1479 
       
  1480                             madeMap[cid] = {
       
  1481                                 obj: obj,
       
  1482                                 instance: instance,
       
  1483                                 added: !hasCid
       
  1484                             };
       
  1485                         }
       
  1486                         return teardown;
       
  1487                     },
       
  1488 
       
  1489                     // ### can.Map.helpers.isObservable
       
  1490                     // Determines if `obj` is observable.
       
  1491                     isObservable: function(obj) {
       
  1492                         return obj instanceof can.Map || (obj && obj === can.route);
       
  1493                     },
       
  1494 
       
  1495                     // ### can.Map.helpers.canMakeObserve
       
  1496                     // Determines if an object can be made into an observable.
       
  1497                     canMakeObserve: function(obj) {
       
  1498                         return obj && !can.isDeferred(obj) && (can.isArray(obj) || can.isPlainObject(obj));
       
  1499                     },
       
  1500 
       
  1501                     // ### can.Map.helpers.serialize
       
  1502                     // Serializes a Map or Map.List
       
  1503                     serialize: function(map, how, where) {
       
  1504                         var cid = can.cid(map),
       
  1505                             firstSerialize = false;
       
  1506                         if (!serializeMap) {
       
  1507                             firstSerialize = true;
       
  1508                             // Serialize might call .attr() so we need to keep different map 
       
  1509                             serializeMap = {
       
  1510                                 attr: {},
       
  1511                                 serialize: {}
       
  1512                             };
       
  1513                         }
       
  1514                         serializeMap[how][cid] = where;
       
  1515                         // Go through each property.
       
  1516                         map.each(function(val, name) {
       
  1517                             // If the value is an `object`, and has an `attrs` or `serialize` function.
       
  1518                             var result,
       
  1519                                 isObservable = Map.helpers.isObservable(val),
       
  1520                                 serialized = isObservable && serializeMap[how][can.cid(val)];
       
  1521                             if (serialized) {
       
  1522                                 result = serialized;
       
  1523                             } else {
       
  1524                                 if (how === "serialize") {
       
  1525                                     result = Map.helpers._serialize(map, name, val);
       
  1526                                 } else {
       
  1527                                     result = Map.helpers._getValue(map, name, val, how);
       
  1528                                 }
       
  1529                             }
       
  1530                             // this is probably removable
       
  1531                             if (result !== undefined) {
       
  1532                                 where[name] = result;
       
  1533                             }
       
  1534                         });
       
  1535 
       
  1536                         can.__reading(map, '__keys');
       
  1537                         if (firstSerialize) {
       
  1538                             serializeMap = null;
       
  1539                         }
       
  1540                         return where;
       
  1541                     },
       
  1542                     _serialize: function(map, name, val) {
       
  1543                         return Map.helpers._getValue(map, name, val, "serialize");
       
  1544                     },
       
  1545                     _getValue: function(map, name, val, how) {
       
  1546                         if (Map.helpers.isObservable(val)) {
       
  1547                             return val[how]();
       
  1548                         } else {
       
  1549                             return val;
       
  1550                         }
       
  1551                     }
       
  1552                 },
       
  1553 
       
  1554                 keys: function(map) {
       
  1555                     var keys = [];
       
  1556                     can.__reading(map, '__keys');
       
  1557                     for (var keyName in map._data) {
       
  1558                         keys.push(keyName);
       
  1559                     }
       
  1560                     return keys;
       
  1561                 }
       
  1562             },
       
  1563 
       
  1564             {
       
  1565                 setup: function(obj) {
       
  1566                     // `_data` is where we keep the properties.
       
  1567                     this._data = {};
       
  1568 
       
  1569                     // The namespace this `object` uses to listen to events.
       
  1570                     can.cid(this, ".map");
       
  1571                     // Sets all `attrs`.
       
  1572                     this._init = 1;
       
  1573                     // It's handy if we pass this to comptues, because computes can have a default value.
       
  1574                     var defaultValues = this._setupDefaults();
       
  1575                     this._setupComputes(defaultValues);
       
  1576                     var teardownMapping = obj && can.Map.helpers.addToMap(obj, this);
       
  1577 
       
  1578                     var data = can.extend(can.extend(true, {}, defaultValues), obj);
       
  1579 
       
  1580                     this.attr(data);
       
  1581 
       
  1582                     if (teardownMapping) {
       
  1583                         teardownMapping();
       
  1584                     }
       
  1585 
       
  1586                     // `batchTrigger` change events.
       
  1587                     this.bind('change', can.proxy(this._changes, this));
       
  1588 
       
  1589                     delete this._init;
       
  1590                 },
       
  1591                 // Sets up computed properties on a Map.
       
  1592                 _setupComputes: function() {
       
  1593                     var computes = this.constructor._computes;
       
  1594                     this._computedBindings = {};
       
  1595 
       
  1596                     for (var i = 0, len = computes.length, prop; i < len; i++) {
       
  1597                         prop = computes[i];
       
  1598                         // Make the context of the compute the current Map
       
  1599                         this[prop] = this[prop].clone(this);
       
  1600                         // Keep track of computed properties
       
  1601                         this._computedBindings[prop] = {
       
  1602                             count: 0
       
  1603                         };
       
  1604                     }
       
  1605                 },
       
  1606                 _setupDefaults: function() {
       
  1607                     return this.constructor.defaults || {};
       
  1608                 },
       
  1609                 // Setup child bindings.
       
  1610                 _bindsetup: function() {},
       
  1611                 // Teardown child bindings.
       
  1612                 _bindteardown: function() {},
       
  1613                 // `change`event handler.
       
  1614                 _changes: function(ev, attr, how, newVal, oldVal) {
       
  1615                     // when a change happens, create the named event.
       
  1616                     can.batch.trigger(this, {
       
  1617                             type: attr,
       
  1618                             batchNum: ev.batchNum
       
  1619                         }, [newVal, oldVal]);
       
  1620 
       
  1621                     if (how === "remove" || how === "add") {
       
  1622                         can.batch.trigger(this, {
       
  1623                                 type: "__keys",
       
  1624                                 batchNum: ev.batchNum
       
  1625                             });
       
  1626                     }
       
  1627                 },
       
  1628                 // Trigger a change event.
       
  1629                 _triggerChange: function(attr, how, newVal, oldVal) {
       
  1630                     can.batch.trigger(this, "change", can.makeArray(arguments));
       
  1631                 },
       
  1632                 // Iterator that does not trigger live binding.
       
  1633                 _each: function(callback) {
       
  1634                     var data = this.__get();
       
  1635                     for (var prop in data) {
       
  1636                         if (data.hasOwnProperty(prop)) {
       
  1637                             callback(data[prop], prop);
       
  1638                         }
       
  1639                     }
       
  1640                 },
       
  1641 
       
  1642                 attr: function(attr, val) {
       
  1643                     // This is super obfuscated for space -- basically, we're checking
       
  1644                     // if the type of the attribute is not a `number` or a `string`.
       
  1645                     var type = typeof attr;
       
  1646                     if (type !== "string" && type !== "number") {
       
  1647                         return this._attrs(attr, val);
       
  1648                         // If we are getting a value.
       
  1649                     } else if (arguments.length === 1) {
       
  1650                         // Let people know we are reading.
       
  1651                         can.__reading(this, attr);
       
  1652                         return this._get(attr);
       
  1653                     } else {
       
  1654                         // Otherwise we are setting.
       
  1655                         this._set(attr, val);
       
  1656                         return this;
       
  1657                     }
       
  1658                 },
       
  1659 
       
  1660                 each: function() {
       
  1661                     return can.each.apply(undefined, [this].concat(can.makeArray(arguments)));
       
  1662                 },
       
  1663 
       
  1664                 removeAttr: function(attr) {
       
  1665                     // If this is List.
       
  1666                     var isList = can.List && this instanceof can.List,
       
  1667                         // Convert the `attr` into parts (if nested).
       
  1668                         parts = can.Map.helpers.attrParts(attr),
       
  1669                         // The actual property to remove.
       
  1670                         prop = parts.shift(),
       
  1671                         // The current value.
       
  1672                         current = isList ? this[prop] : this._data[prop];
       
  1673 
       
  1674                     // If we have more parts, call `removeAttr` on that part.
       
  1675                     if (parts.length && current) {
       
  1676                         return current.removeAttr(parts);
       
  1677                     } else {
       
  1678 
       
  1679                         // If attr does not have a `.`
       
  1680                         if (typeof attr === 'string' && !! ~attr.indexOf('.')) {
       
  1681                             prop = attr;
       
  1682                         }
       
  1683 
       
  1684                         this._remove(prop, current);
       
  1685                         return current;
       
  1686                     }
       
  1687                 },
       
  1688                 // Remove a property.
       
  1689                 _remove: function(prop, current) {
       
  1690                     if (prop in this._data) {
       
  1691                         // Delete the property from `_data` and the Map
       
  1692                         // as long as it isn't part of the Map's prototype.
       
  1693                         delete this._data[prop];
       
  1694                         if (!(prop in this.constructor.prototype)) {
       
  1695                             delete this[prop];
       
  1696                         }
       
  1697                         // Let others now this property has been removed.
       
  1698                         this._triggerChange(prop, "remove", undefined, current);
       
  1699 
       
  1700                     }
       
  1701                 },
       
  1702                 // Reads a property from the `object`.
       
  1703                 _get: function(attr) {
       
  1704                     var value;
       
  1705                     // Handles the case of a key having a `.` in its name
       
  1706                     if (typeof attr === 'string' && !! ~attr.indexOf('.')) {
       
  1707                         // Attempt to get the value
       
  1708                         value = this.__get(attr);
       
  1709                         // For keys with a `.` in them, value will be defined
       
  1710                         if (value !== undefined) {
       
  1711                             return value;
       
  1712                         }
       
  1713                     }
       
  1714 
       
  1715                     // Otherwise we have to dig deeper into the Map to get the value.
       
  1716                     // First, break up the attr (`"foo.bar"`) into parts like `["foo","bar"]`.
       
  1717                     var parts = can.Map.helpers.attrParts(attr),
       
  1718                         // Then get the value of the first attr name (`"foo"`).
       
  1719                         current = this.__get(parts.shift());
       
  1720                     // If there are other attributes to read...
       
  1721                     return parts.length ?
       
  1722                     // and current has a value...
       
  1723                     current ?
       
  1724                     // then lookup the remaining attrs on current
       
  1725                     current._get(parts) :
       
  1726                     // or if there's no current, return undefined.
       
  1727                     undefined :
       
  1728                     // If there are no more parts, return current.
       
  1729                     current;
       
  1730                 },
       
  1731                 // Reads a property directly if an `attr` is provided, otherwise
       
  1732                 // returns the "real" data object itself.
       
  1733                 __get: function(attr) {
       
  1734                     if (attr) {
       
  1735                         // If property is a compute return the result, otherwise get the value directly
       
  1736                         if (this._computedBindings[attr]) {
       
  1737                             return this[attr]();
       
  1738                         } else {
       
  1739                             return this._data[attr];
       
  1740                         }
       
  1741                         // If not property is provided, return entire `_data` object
       
  1742                     } else {
       
  1743                         return this._data;
       
  1744                     }
       
  1745                 },
       
  1746                 // converts the value into an observable if needed
       
  1747                 __type: function(value, prop) {
       
  1748                     // If we are getting an object.
       
  1749                     if (!(value instanceof can.Map) && can.Map.helpers.canMakeObserve(value)) {
       
  1750 
       
  1751                         var cached = getMapFromObject(value);
       
  1752                         if (cached) {
       
  1753                             return cached;
       
  1754                         }
       
  1755                         if (can.isArray(value)) {
       
  1756                             var List = can.List;
       
  1757                             return new List(value);
       
  1758                         } else {
       
  1759                             var Map = this.constructor.Map || can.Map;
       
  1760                             return new Map(value);
       
  1761                         }
       
  1762                     }
       
  1763                     return value;
       
  1764                 },
       
  1765                 // Sets `attr` prop as value on this object where.
       
  1766                 // `attr` - Is a string of properties or an array  of property values.
       
  1767                 // `value` - The raw value to set.
       
  1768                 _set: function(attr, value, keepKey) {
       
  1769                     // Convert `attr` to attr parts (if it isn't already).
       
  1770                     var parts = can.Map.helpers.attrParts(attr, keepKey),
       
  1771                         // The immediate prop we are setting.
       
  1772                         prop = parts.shift(),
       
  1773                         // We only need to get the current value if we are not in init.
       
  1774                         current = this._init ? undefined : this.__get(prop);
       
  1775 
       
  1776                     if (parts.length && Map.helpers.isObservable(current)) {
       
  1777                         // If we have an `object` and remaining parts that `object` should set it.
       
  1778                         current._set(parts, value);
       
  1779                     } else if (!parts.length) {
       
  1780                         // We're in "real" set territory.
       
  1781                         if (this.__convert) {
       
  1782                             //Convert if there is a converter
       
  1783                             value = this.__convert(prop, value);
       
  1784                         }
       
  1785                         this.__set(prop, this.__type(value, prop), current);
       
  1786                     } else {
       
  1787                         throw "can.Map: Object does not exist";
       
  1788                     }
       
  1789                 },
       
  1790                 __set: function(prop, value, current) {
       
  1791                     // TODO: Check if value is object and transform.
       
  1792                     // Don't do anything if the value isn't changing.
       
  1793                     if (value !== current) {
       
  1794                         // Check if we are adding this for the first time --
       
  1795                         // if we are, we need to create an `add` event.
       
  1796                         var changeType = this.__get()
       
  1797                             .hasOwnProperty(prop) ? "set" : "add";
       
  1798 
       
  1799                         // Set the value on `_data` and hook it up to send event.
       
  1800                         this.___set(prop, this.constructor._bubble.set(this, prop, value, current));
       
  1801 
       
  1802                         // `batchTrigger` the change event.
       
  1803                         this._triggerChange(prop, changeType, value, current);
       
  1804 
       
  1805                         // If we can stop listening to our old value, do it.
       
  1806                         if (current) {
       
  1807                             this.constructor._bubble.teardownFromParent(this, current);
       
  1808                         }
       
  1809                     }
       
  1810 
       
  1811                 },
       
  1812                 // Directly sets a property on this `object`.
       
  1813                 ___set: function(prop, val) {
       
  1814                     if (this._computedBindings[prop]) {
       
  1815                         this[prop](val);
       
  1816                     } else {
       
  1817                         this._data[prop] = val;
       
  1818                     }
       
  1819                     // Add property directly for easy writing.
       
  1820                     // Check if its on the `prototype` so we don't overwrite methods like `attrs`.
       
  1821                     if (!can.isFunction(this.constructor.prototype[prop]) && !this._computedBindings[prop]) {
       
  1822                         this[prop] = val;
       
  1823                     }
       
  1824                 },
       
  1825 
       
  1826                 bind: function(eventName, handler) {
       
  1827                     var computedBinding = this._computedBindings && this._computedBindings[eventName];
       
  1828                     if (computedBinding) {
       
  1829                         // The first time we bind to this computed property we
       
  1830                         // initialize `count` and `batchTrigger` the change event.
       
  1831                         if (!computedBinding.count) {
       
  1832                             computedBinding.count = 1;
       
  1833                             var self = this;
       
  1834                             computedBinding.handler = function(ev, newVal, oldVal) {
       
  1835                                 can.batch.trigger(self, {
       
  1836                                         type: eventName,
       
  1837                                         batchNum: ev.batchNum
       
  1838                                     }, [newVal, oldVal]);
       
  1839                             };
       
  1840                             this[eventName].bind("change", computedBinding.handler);
       
  1841                         } else {
       
  1842                             // Increment number of things listening to this computed property.
       
  1843                             computedBinding.count++;
       
  1844                         }
       
  1845 
       
  1846                     }
       
  1847                     // The first time we bind to this Map, `_bindsetup` will
       
  1848                     // be called to setup child event bubbling.
       
  1849                     this.constructor._bubble.bind(this, eventName);
       
  1850                     return can.bindAndSetup.apply(this, arguments);
       
  1851 
       
  1852                 },
       
  1853 
       
  1854                 unbind: function(eventName, handler) {
       
  1855                     var computedBinding = this._computedBindings && this._computedBindings[eventName];
       
  1856                     if (computedBinding) {
       
  1857                         // If there is only one listener, we unbind the change event handler
       
  1858                         // and clean it up since no one is listening to this property any more.
       
  1859                         if (computedBinding.count === 1) {
       
  1860                             computedBinding.count = 0;
       
  1861                             this[eventName].unbind("change", computedBinding.handler);
       
  1862                             delete computedBinding.handler;
       
  1863                         } else {
       
  1864                             // Decrement number of things listening to this computed property
       
  1865                             computedBinding.count--;
       
  1866                         }
       
  1867 
       
  1868                     }
       
  1869                     this.constructor._bubble.unbind(this, eventName);
       
  1870                     return can.unbindAndTeardown.apply(this, arguments);
       
  1871 
       
  1872                 },
       
  1873 
       
  1874                 serialize: function() {
       
  1875                     return can.Map.helpers.serialize(this, 'serialize', {});
       
  1876                 },
       
  1877 
       
  1878                 _attrs: function(props, remove) {
       
  1879                     if (props === undefined) {
       
  1880                         return Map.helpers.serialize(this, 'attr', {});
       
  1881                     }
       
  1882 
       
  1883                     props = can.simpleExtend({}, props);
       
  1884                     var prop,
       
  1885                         self = this,
       
  1886                         newVal;
       
  1887 
       
  1888                     // Batch all of the change events until we are done.
       
  1889                     can.batch.start();
       
  1890                     // Merge current properties with the new ones.
       
  1891                     this.each(function(curVal, prop) {
       
  1892                         // You can not have a _cid property; abort.
       
  1893                         if (prop === "_cid") {
       
  1894                             return;
       
  1895                         }
       
  1896                         newVal = props[prop];
       
  1897 
       
  1898                         // If we are merging, remove the property if it has no value.
       
  1899                         if (newVal === undefined) {
       
  1900                             if (remove) {
       
  1901                                 self.removeAttr(prop);
       
  1902                             }
       
  1903                             return;
       
  1904                         }
       
  1905 
       
  1906                         // Run converter if there is one
       
  1907                         if (self.__convert) {
       
  1908                             newVal = self.__convert(prop, newVal);
       
  1909                         }
       
  1910 
       
  1911                         // If we're dealing with models, we want to call _set to let converters run.
       
  1912                         if (Map.helpers.isObservable(newVal)) {
       
  1913 
       
  1914                             self.__set(prop, self.__type(newVal, prop), curVal);
       
  1915                             // If its an object, let attr merge.
       
  1916                         } else if (Map.helpers.isObservable(curVal) && Map.helpers.canMakeObserve(newVal)) {
       
  1917                             curVal.attr(newVal, remove);
       
  1918                             // Otherwise just set.
       
  1919                         } else if (curVal !== newVal) {
       
  1920                             self.__set(prop, self.__type(newVal, prop), curVal);
       
  1921                         }
       
  1922 
       
  1923                         delete props[prop];
       
  1924                     });
       
  1925                     // Add remaining props.
       
  1926                     for (prop in props) {
       
  1927                         // Ignore _cid.
       
  1928                         if (prop !== "_cid") {
       
  1929                             newVal = props[prop];
       
  1930                             this._set(prop, newVal, true);
       
  1931                         }
       
  1932 
       
  1933                     }
       
  1934                     can.batch.stop();
       
  1935                     return this;
       
  1936                 },
       
  1937 
       
  1938                 compute: function(prop) {
       
  1939                     // If the property is a function, use it as the getter/setter
       
  1940                     // otherwise, create a new compute that returns the value of a property on `this`
       
  1941                     if (can.isFunction(this.constructor.prototype[prop])) {
       
  1942                         return can.compute(this[prop], this);
       
  1943                     } else {
       
  1944                         var reads = prop.split("."),
       
  1945                             last = reads.length - 1,
       
  1946                             options = {
       
  1947                                 args: []
       
  1948                             };
       
  1949                         return can.compute(function(newVal) {
       
  1950                             if (arguments.length) {
       
  1951                                 can.compute.read(this, reads.slice(0, last))
       
  1952                                     .value.attr(reads[last], newVal);
       
  1953                             } else {
       
  1954                                 return can.compute.read(this, reads, options)
       
  1955                                     .value;
       
  1956                             }
       
  1957                         }, this);
       
  1958                     }
       
  1959 
       
  1960                 }
       
  1961             });
       
  1962 
       
  1963         // Setup on/off aliases
       
  1964         Map.prototype.on = Map.prototype.bind;
       
  1965         Map.prototype.off = Map.prototype.unbind;
       
  1966 
       
  1967         return Map;
       
  1968     })(__m3, __m11, __m12, __m1, __m13);
       
  1969 
       
  1970     // ## can/list/list.js
       
  1971     var __m14 = (function(can, Map, bubble) {
       
  1972 
       
  1973         // Helpers for `observable` lists.
       
  1974         var splice = [].splice,
       
  1975             // test if splice works correctly
       
  1976             spliceRemovesProps = (function() {
       
  1977                 // IE's splice doesn't remove properties
       
  1978                 var obj = {
       
  1979                     0: "a",
       
  1980                     length: 1
       
  1981                 };
       
  1982                 splice.call(obj, 0, 1);
       
  1983                 return !obj[0];
       
  1984             })();
       
  1985 
       
  1986 
       
  1987         var list = Map.extend(
       
  1988 
       
  1989             {
       
  1990 
       
  1991                 Map: Map
       
  1992 
       
  1993             },
       
  1994 
       
  1995             {
       
  1996                 setup: function(instances, options) {
       
  1997                     this.length = 0;
       
  1998                     can.cid(this, ".map");
       
  1999                     this._init = 1;
       
  2000                     this._setupComputes();
       
  2001                     instances = instances || [];
       
  2002                     var teardownMapping;
       
  2003 
       
  2004                     if (can.isDeferred(instances)) {
       
  2005                         this.replace(instances);
       
  2006                     } else {
       
  2007                         teardownMapping = instances.length && can.Map.helpers.addToMap(instances, this);
       
  2008                         this.push.apply(this, can.makeArray(instances || []));
       
  2009                     }
       
  2010 
       
  2011                     if (teardownMapping) {
       
  2012                         teardownMapping();
       
  2013                     }
       
  2014 
       
  2015                     // this change needs to be ignored
       
  2016                     this.bind('change', can.proxy(this._changes, this));
       
  2017                     can.simpleExtend(this, options);
       
  2018                     delete this._init;
       
  2019                 },
       
  2020                 _triggerChange: function(attr, how, newVal, oldVal) {
       
  2021 
       
  2022                     Map.prototype._triggerChange.apply(this, arguments);
       
  2023                     // `batchTrigger` direct add and remove events...
       
  2024                     var index = +attr;
       
  2025                     // Make sure this is not nested and not an expando
       
  2026                     if (!~attr.indexOf('.') && !isNaN(index)) {
       
  2027 
       
  2028                         if (how === 'add') {
       
  2029                             can.batch.trigger(this, how, [newVal, index]);
       
  2030                             can.batch.trigger(this, 'length', [this.length]);
       
  2031                         } else if (how === 'remove') {
       
  2032                             can.batch.trigger(this, how, [oldVal, index]);
       
  2033                             can.batch.trigger(this, 'length', [this.length]);
       
  2034                         } else {
       
  2035                             can.batch.trigger(this, how, [newVal, index]);
       
  2036                         }
       
  2037 
       
  2038                     }
       
  2039 
       
  2040                 },
       
  2041                 __get: function(attr) {
       
  2042                     if (attr) {
       
  2043                         if (this[attr] && this[attr].isComputed && can.isFunction(this.constructor.prototype[attr])) {
       
  2044                             return this[attr]();
       
  2045                         } else {
       
  2046                             return this[attr];
       
  2047                         }
       
  2048                     } else {
       
  2049                         return this;
       
  2050                     }
       
  2051                 },
       
  2052                 ___set: function(attr, val) {
       
  2053                     this[attr] = val;
       
  2054                     if (+attr >= this.length) {
       
  2055                         this.length = (+attr + 1);
       
  2056                     }
       
  2057                 },
       
  2058                 _remove: function(prop, current) {
       
  2059                     // if removing an expando property
       
  2060                     if (isNaN(+prop)) {
       
  2061                         delete this[prop];
       
  2062                         this._triggerChange(prop, "remove", undefined, current);
       
  2063                     } else {
       
  2064                         this.splice(prop, 1);
       
  2065                     }
       
  2066                 },
       
  2067                 _each: function(callback) {
       
  2068                     var data = this.__get();
       
  2069                     for (var i = 0; i < data.length; i++) {
       
  2070                         callback(data[i], i);
       
  2071                     }
       
  2072                 },
       
  2073                 // Returns the serialized form of this list.
       
  2074 
       
  2075                 serialize: function() {
       
  2076                     return Map.helpers.serialize(this, 'serialize', []);
       
  2077                 },
       
  2078 
       
  2079                 splice: function(index, howMany) {
       
  2080                     var args = can.makeArray(arguments),
       
  2081                         i;
       
  2082 
       
  2083                     for (i = 2; i < args.length; i++) {
       
  2084                         args[i] = bubble.set(this, i, this.__type(args[i], i));
       
  2085 
       
  2086                     }
       
  2087                     if (howMany === undefined) {
       
  2088                         howMany = args[1] = this.length - index;
       
  2089                     }
       
  2090                     var removed = splice.apply(this, args);
       
  2091 
       
  2092                     if (!spliceRemovesProps) {
       
  2093                         for (i = this.length; i < removed.length + this.length; i++) {
       
  2094                             delete this[i];
       
  2095                         }
       
  2096                     }
       
  2097 
       
  2098                     can.batch.start();
       
  2099                     if (howMany > 0) {
       
  2100                         this._triggerChange("" + index, "remove", undefined, removed);
       
  2101                         bubble.removeMany(this, removed);
       
  2102                     }
       
  2103                     if (args.length > 2) {
       
  2104                         this._triggerChange("" + index, "add", args.slice(2), removed);
       
  2105                     }
       
  2106                     can.batch.stop();
       
  2107                     return removed;
       
  2108                 },
       
  2109 
       
  2110                 _attrs: function(items, remove) {
       
  2111                     if (items === undefined) {
       
  2112                         return Map.helpers.serialize(this, 'attr', []);
       
  2113                     }
       
  2114 
       
  2115                     // Create a copy.
       
  2116                     items = can.makeArray(items);
       
  2117 
       
  2118                     can.batch.start();
       
  2119                     this._updateAttrs(items, remove);
       
  2120                     can.batch.stop();
       
  2121                 },
       
  2122 
       
  2123                 _updateAttrs: function(items, remove) {
       
  2124                     var len = Math.min(items.length, this.length);
       
  2125 
       
  2126                     for (var prop = 0; prop < len; prop++) {
       
  2127                         var curVal = this[prop],
       
  2128                             newVal = items[prop];
       
  2129 
       
  2130                         if (Map.helpers.isObservable(curVal) && Map.helpers.canMakeObserve(newVal)) {
       
  2131                             curVal.attr(newVal, remove);
       
  2132                             //changed from a coercion to an explicit
       
  2133                         } else if (curVal !== newVal) {
       
  2134                             this._set(prop, newVal);
       
  2135                         } else {
       
  2136 
       
  2137                         }
       
  2138                     }
       
  2139                     if (items.length > this.length) {
       
  2140                         // Add in the remaining props.
       
  2141                         this.push.apply(this, items.slice(this.length));
       
  2142                     } else if (items.length < this.length && remove) {
       
  2143                         this.splice(items.length);
       
  2144                     }
       
  2145                 }
       
  2146             }),
       
  2147 
       
  2148             // Converts to an `array` of arguments.
       
  2149             getArgs = function(args) {
       
  2150                 return args[0] && can.isArray(args[0]) ?
       
  2151                     args[0] :
       
  2152                     can.makeArray(args);
       
  2153             };
       
  2154         // Create `push`, `pop`, `shift`, and `unshift`
       
  2155         can.each({
       
  2156 
       
  2157                 push: "length",
       
  2158 
       
  2159                 unshift: 0
       
  2160             },
       
  2161             // Adds a method
       
  2162             // `name` - The method name.
       
  2163             // `where` - Where items in the `array` should be added.
       
  2164 
       
  2165             function(where, name) {
       
  2166                 var orig = [][name];
       
  2167                 list.prototype[name] = function() {
       
  2168                     // Get the items being added.
       
  2169                     var args = [],
       
  2170                         // Where we are going to add items.
       
  2171                         len = where ? this.length : 0,
       
  2172                         i = arguments.length,
       
  2173                         res, val;
       
  2174 
       
  2175                     // Go through and convert anything to an `map` that needs to be converted.
       
  2176                     while (i--) {
       
  2177                         val = arguments[i];
       
  2178                         args[i] = bubble.set(this, i, this.__type(val, i));
       
  2179                     }
       
  2180 
       
  2181                     // Call the original method.
       
  2182                     res = orig.apply(this, args);
       
  2183 
       
  2184                     if (!this.comparator || args.length) {
       
  2185 
       
  2186                         this._triggerChange("" + len, "add", args, undefined);
       
  2187                     }
       
  2188 
       
  2189                     return res;
       
  2190                 };
       
  2191             });
       
  2192 
       
  2193         can.each({
       
  2194 
       
  2195                 pop: "length",
       
  2196 
       
  2197                 shift: 0
       
  2198             },
       
  2199             // Creates a `remove` type method
       
  2200 
       
  2201             function(where, name) {
       
  2202                 list.prototype[name] = function() {
       
  2203 
       
  2204                     var args = getArgs(arguments),
       
  2205                         len = where && this.length ? this.length - 1 : 0;
       
  2206 
       
  2207                     var res = [][name].apply(this, args);
       
  2208 
       
  2209                     // Create a change where the args are
       
  2210                     // `len` - Where these items were removed.
       
  2211                     // `remove` - Items removed.
       
  2212                     // `undefined` - The new values (there are none).
       
  2213                     // `res` - The old, removed values (should these be unbound).
       
  2214                     this._triggerChange("" + len, "remove", undefined, [res]);
       
  2215 
       
  2216                     if (res && res.unbind) {
       
  2217                         bubble.remove(this, res);
       
  2218                     }
       
  2219 
       
  2220                     return res;
       
  2221                 };
       
  2222             });
       
  2223 
       
  2224         can.extend(list.prototype, {
       
  2225 
       
  2226                 indexOf: function(item, fromIndex) {
       
  2227                     this.attr('length');
       
  2228                     return can.inArray(item, this, fromIndex);
       
  2229                 },
       
  2230 
       
  2231 
       
  2232                 join: function() {
       
  2233                     return [].join.apply(this.attr(), arguments);
       
  2234                 },
       
  2235 
       
  2236 
       
  2237                 reverse: function() {
       
  2238                     var list = can.makeArray([].reverse.call(this));
       
  2239                     this.replace(list);
       
  2240                 },
       
  2241 
       
  2242 
       
  2243                 slice: function() {
       
  2244                     var temp = Array.prototype.slice.apply(this, arguments);
       
  2245                     return new this.constructor(temp);
       
  2246                 },
       
  2247 
       
  2248 
       
  2249                 concat: function() {
       
  2250                     var args = [];
       
  2251                     can.each(can.makeArray(arguments), function(arg, i) {
       
  2252                         args[i] = arg instanceof can.List ? arg.serialize() : arg;
       
  2253                     });
       
  2254                     return new this.constructor(Array.prototype.concat.apply(this.serialize(), args));
       
  2255                 },
       
  2256 
       
  2257 
       
  2258                 forEach: function(cb, thisarg) {
       
  2259                     return can.each(this, cb, thisarg || this);
       
  2260                 },
       
  2261 
       
  2262 
       
  2263                 replace: function(newList) {
       
  2264                     if (can.isDeferred(newList)) {
       
  2265                         newList.then(can.proxy(this.replace, this));
       
  2266                     } else {
       
  2267                         this.splice.apply(this, [0, this.length].concat(can.makeArray(newList || [])));
       
  2268                     }
       
  2269 
       
  2270                     return this;
       
  2271                 },
       
  2272                 filter: function(callback, thisArg) {
       
  2273                     var filteredList = new can.List(),
       
  2274                         self = this,
       
  2275                         filtered;
       
  2276                     this.each(function(item, index, list) {
       
  2277                         filtered = callback.call(thisArg | self, item, index, self);
       
  2278                         if (filtered) {
       
  2279                             filteredList.push(item);
       
  2280                         }
       
  2281                     });
       
  2282                     return filteredList;
       
  2283                 }
       
  2284             });
       
  2285         can.List = Map.List = list;
       
  2286         return can.List;
       
  2287     })(__m3, __m10, __m12);
       
  2288 
       
  2289     // ## can/compute/compute.js
       
  2290     var __m15 = (function(can, bind) {
       
  2291 
       
  2292         // ## Reading Helpers
       
  2293         // The following methods are used to call a function that relies on
       
  2294         // observable data and to track the observable events which should 
       
  2295         // be listened to when changes occur.
       
  2296         // To do this, [`can.__reading(observable, event)`](#can-__reading) is called to
       
  2297         // "broadcast" the corresponding event on each read.
       
  2298         // ### Observed
       
  2299         // An "Observed" is an object of observable objects and events that
       
  2300         // a function relies on. These objects and events must be listened to
       
  2301         // in order to determine when to check a function for updates.
       
  2302         // This looks like the following:
       
  2303         //     { 
       
  2304         //       "map1|first": {obj: map, event: "first"},
       
  2305         //       "map1|last" : {obj: map, event: "last"}
       
  2306         //     }
       
  2307         // Each object-event pair is mapped so no duplicates will be listed.
       
  2308 
       
  2309         // ### State
       
  2310         // `can.__read` may call a function that calls `can.__read` again. For
       
  2311         // example, a compute can read another compute. To track each compute's
       
  2312         // `Observed` object (containing observable objects and events), we maintain
       
  2313         // a stack of Observed values for each call to `__read`.
       
  2314         var stack = [];
       
  2315 
       
  2316         // ### can.__read
       
  2317         // With a given function and context, calls the function
       
  2318         // and returns the resulting value of the function as well
       
  2319         // as the observable properties and events that were read.
       
  2320         can.__read = function(func, self) {
       
  2321 
       
  2322             // Add an object that `can.__read` will write to.
       
  2323             stack.push({});
       
  2324 
       
  2325             var value = func.call(self);
       
  2326 
       
  2327             // Example return value:
       
  2328             // `{value: 100, observed: Observed}`
       
  2329             return {
       
  2330                 value: value,
       
  2331                 observed: stack.pop()
       
  2332             };
       
  2333         };
       
  2334 
       
  2335         // ### can.__reading
       
  2336         // When an observable value is read, it must call `can.__reading` to 
       
  2337         // broadcast which object and event should be listened to.
       
  2338         can.__reading = function(obj, event) {
       
  2339             // Add the observable object and the event
       
  2340             // that was read to the `Observed` object on
       
  2341             // the stack.
       
  2342             if (stack.length) {
       
  2343                 stack[stack.length - 1][obj._cid + '|' + event] = {
       
  2344                     obj: obj,
       
  2345                     event: event + ""
       
  2346                 };
       
  2347             }
       
  2348 
       
  2349         };
       
  2350 
       
  2351         // ### can.__clearReading
       
  2352         // Clears and returns the current observables.
       
  2353         // This can be used to access a value without 
       
  2354         // it being handled as a regular `read`.
       
  2355         can.__clearReading = function() {
       
  2356             if (stack.length) {
       
  2357                 var ret = stack[stack.length - 1];
       
  2358                 stack[stack.length - 1] = {};
       
  2359                 return ret;
       
  2360             }
       
  2361         };
       
  2362         // Specifies current observables.
       
  2363         can.__setReading = function(o) {
       
  2364             if (stack.length) {
       
  2365                 stack[stack.length - 1] = o;
       
  2366             }
       
  2367         };
       
  2368         can.__addReading = function(o) {
       
  2369             if (stack.length) {
       
  2370                 can.simpleExtend(stack[stack.length - 1], o);
       
  2371             }
       
  2372         };
       
  2373 
       
  2374         // ## Section Name
       
  2375 
       
  2376         // ### getValueAndBind
       
  2377         // Calls a function and sets up bindings to call `onchanged`
       
  2378         // when events from its "Observed" object are triggered.
       
  2379         // Removes bindings from `oldObserved` that are no longer needed.
       
  2380         // - func - the function to call.
       
  2381         // - context - the `this` of the function.
       
  2382         // - oldObserved - an object that contains what has already been bound to
       
  2383         // - onchanged - the function to call when any change occurs
       
  2384         var getValueAndBind = function(func, context, oldObserved, onchanged) {
       
  2385             // Call the function, get the value as well as the observed objects and events
       
  2386             var info = can.__read(func, context),
       
  2387                 // The objects-event pairs that must be bound to
       
  2388                 newObserveSet = info.observed,
       
  2389                 // A flag that is used to determine if an event is already being observed.
       
  2390                 obEv,
       
  2391                 name;
       
  2392             // Go through what needs to be observed.
       
  2393             for (name in newObserveSet) {
       
  2394 
       
  2395                 if (oldObserved[name]) {
       
  2396                     // After binding is set up, values
       
  2397                     // in `oldObserved` will be unbound. So if a name
       
  2398                     // has already be observed, remove from `oldObserved`
       
  2399                     // to prevent this.
       
  2400                     delete oldObserved[name];
       
  2401                 } else {
       
  2402                     // If current name has not been observed, listen to it.
       
  2403                     obEv = newObserveSet[name];
       
  2404                     obEv.obj.bind(obEv.event, onchanged);
       
  2405                 }
       
  2406             }
       
  2407 
       
  2408             // Iterate through oldObserved, looking for observe/attributes
       
  2409             // that are no longer being bound and unbind them.
       
  2410             for (name in oldObserved) {
       
  2411                 obEv = oldObserved[name];
       
  2412                 obEv.obj.unbind(obEv.event, onchanged);
       
  2413             }
       
  2414 
       
  2415             return info;
       
  2416         };
       
  2417 
       
  2418         // ### updateOnChange
       
  2419         // Fires a change event when a compute's value changes
       
  2420         var updateOnChange = function(compute, newValue, oldValue, batchNum) {
       
  2421             // Only trigger event when value has changed
       
  2422             if (newValue !== oldValue) {
       
  2423                 can.batch.trigger(compute, batchNum ? {
       
  2424                         type: "change",
       
  2425                         batchNum: batchNum
       
  2426                     } : 'change', [
       
  2427                         newValue,
       
  2428                         oldValue
       
  2429                     ]);
       
  2430             }
       
  2431         };
       
  2432 
       
  2433         // ###setupComputeHandlers
       
  2434         // Sets up handlers for a compute.
       
  2435         // - compute - the compute to set up handlers for
       
  2436         // - func - the getter/setter function for the compute
       
  2437         // - context - the `this` for the compute
       
  2438         // - setCachedValue - function for setting cached value
       
  2439         // Returns an object with `on` and `off` functions.
       
  2440         var setupComputeHandlers = function(compute, func, context, setCachedValue) {
       
  2441             var readInfo,
       
  2442                 onchanged,
       
  2443                 batchNum;
       
  2444 
       
  2445             return {
       
  2446                 // Set up handler for when the compute changes
       
  2447                 on: function(updater) {
       
  2448                     if (!onchanged) {
       
  2449                         onchanged = function(ev) {
       
  2450                             if (compute.bound && (ev.batchNum === undefined || ev.batchNum !== batchNum)) {
       
  2451                                 // Keep the old value
       
  2452                                 var oldValue = readInfo.value;
       
  2453 
       
  2454                                 // Get the new value
       
  2455                                 readInfo = getValueAndBind(func, context, readInfo.observed, onchanged);
       
  2456 
       
  2457                                 // Call the updater with old and new values
       
  2458                                 updater(readInfo.value, oldValue, ev.batchNum);
       
  2459 
       
  2460                                 batchNum = batchNum = ev.batchNum;
       
  2461                             }
       
  2462                         };
       
  2463                     }
       
  2464 
       
  2465                     readInfo = getValueAndBind(func, context, {}, onchanged);
       
  2466 
       
  2467                     setCachedValue(readInfo.value);
       
  2468 
       
  2469                     compute.hasDependencies = !can.isEmptyObject(readInfo.observed);
       
  2470                 },
       
  2471                 // Remove handler for the compute
       
  2472                 off: function(updater) {
       
  2473                     for (var name in readInfo.observed) {
       
  2474                         var ob = readInfo.observed[name];
       
  2475                         ob.obj.unbind(ob.event, onchanged);
       
  2476                     }
       
  2477                 }
       
  2478             };
       
  2479         };
       
  2480 
       
  2481         // ###isObserve
       
  2482         // Checks if an object is observable
       
  2483         var isObserve = function(obj) {
       
  2484             return obj instanceof can.Map || obj && obj.__get;
       
  2485         },
       
  2486             // Instead of calculating whether anything is listening every time,
       
  2487             // use a function to do nothing (which may be overwritten)
       
  2488             k = function() {};
       
  2489 
       
  2490         // ## Creating a can.compute
       
  2491         // A `can.compute` can be created by
       
  2492         // - [Specifying the getterSeter function](#specifying-gettersetter-function)
       
  2493         // - [Observing a property of an object](#observing-a-property-of-an-object)
       
  2494         // - [Specifying an initial value and a setter function](#specifying-an-initial-value-and-a-setter)
       
  2495         // - [Specifying an initial value and how to read, update, and listen to changes](#specifying-an-initial-value-and-a-settings-object)
       
  2496         // - [Simply specifying an initial value](#specifying-only-a-value)
       
  2497         can.compute = function(getterSetter, context, eventName) {
       
  2498             // ### Setting up
       
  2499             // Do nothing if getterSetter is already a compute
       
  2500             if (getterSetter && getterSetter.isComputed) {
       
  2501                 return getterSetter;
       
  2502             }
       
  2503             // The computed object
       
  2504             var computed,
       
  2505                 // The following functions are overwritten depending on how compute() is called
       
  2506                 // A method to set up listening
       
  2507                 on = k,
       
  2508                 // A method to teardown listening
       
  2509                 off = k,
       
  2510                 // Current cached value (valid only when bound is true)
       
  2511                 value,
       
  2512                 // How the value is read by default
       
  2513                 get = function() {
       
  2514                     return value;
       
  2515                 },
       
  2516                 // How the value is set by default
       
  2517                 set = function(newVal) {
       
  2518                     value = newVal;
       
  2519                 },
       
  2520                 setCached = set,
       
  2521                 // Save arguments for cloning
       
  2522                 args = can.makeArray(arguments),
       
  2523                 // updater for when value is changed
       
  2524                 updater = function(newValue, oldValue, batchNum) {
       
  2525                     setCached(newValue);
       
  2526                     updateOnChange(computed, newValue, oldValue, batchNum);
       
  2527                 },
       
  2528                 // the form of the arguments
       
  2529                 form;
       
  2530             computed = function(newVal) {
       
  2531                 // If the computed function is called with arguments,
       
  2532                 // a value should be set
       
  2533                 if (arguments.length) {
       
  2534                     // Save a reference to the old value
       
  2535                     var old = value;
       
  2536                     // Setter may return the value if setter
       
  2537                     // is for a value maintained exclusively by this compute.
       
  2538                     var setVal = set.call(context, newVal, old);
       
  2539                     // If the computed function has dependencies,
       
  2540                     // return the current value
       
  2541                     if (computed.hasDependencies) {
       
  2542                         return get.call(context);
       
  2543                     }
       
  2544                     // Setting may not fire a change event, in which case
       
  2545                     // the value must be read
       
  2546                     if (setVal === undefined) {
       
  2547                         value = get.call(context);
       
  2548                     } else {
       
  2549                         value = setVal;
       
  2550                     }
       
  2551                     // Fire the change
       
  2552                     updateOnChange(computed, value, old);
       
  2553                     return value;
       
  2554                 } else {
       
  2555                     // Another compute may bind to this `computed`
       
  2556                     if (stack.length && computed.canReadForChangeEvent !== false) {
       
  2557 
       
  2558                         // Tell the compute to listen to change on this computed
       
  2559                         // Use `can.__reading` to allow other compute to listen
       
  2560                         // for a change on this `computed`
       
  2561                         can.__reading(computed, 'change');
       
  2562                         // We are going to bind on this compute.
       
  2563                         // If we are not bound, we should bind so that
       
  2564                         // we don't have to re-read to get the value of this compute.
       
  2565                         if (!computed.bound) {
       
  2566                             can.compute.temporarilyBind(computed);
       
  2567                         }
       
  2568                     }
       
  2569                     // If computed is bound, use the cached value
       
  2570                     if (computed.bound) {
       
  2571                         return value;
       
  2572                     } else {
       
  2573                         return get.call(context);
       
  2574                     }
       
  2575                 }
       
  2576             };
       
  2577             // ###Specifying getterSetter function
       
  2578             // If `can.compute` is [called with a getterSetter function](http://canjs.com/docs/can.compute.html#sig_can_compute_getterSetter__context__),
       
  2579             // override set and get
       
  2580             if (typeof getterSetter === 'function') {
       
  2581                 // `can.compute(getterSetter, [context])`
       
  2582                 set = getterSetter;
       
  2583                 get = getterSetter;
       
  2584                 computed.canReadForChangeEvent = eventName === false ? false : true;
       
  2585 
       
  2586                 var handlers = setupComputeHandlers(computed, getterSetter, context || this, setCached);
       
  2587                 on = handlers.on;
       
  2588                 off = handlers.off;
       
  2589 
       
  2590                 // ###Observing a property of an object
       
  2591                 // If `can.compute` is called with an 
       
  2592                 // [object, property name, and optional event name](http://canjs.com/docs/can.compute.html#sig_can_compute_object_propertyName__eventName__),
       
  2593                 // create a compute from a property of an object. This allows the
       
  2594                 // creation of a compute on objects that can be listened to with [`can.bind`](http://canjs.com/docs/can.bind.html)
       
  2595             } else if (context) {
       
  2596                 if (typeof context === 'string') {
       
  2597                     // `can.compute(obj, "propertyName", [eventName])`
       
  2598                     var propertyName = context,
       
  2599                         isObserve = getterSetter instanceof can.Map;
       
  2600                     if (isObserve) {
       
  2601                         computed.hasDependencies = true;
       
  2602                     }
       
  2603                     // If object is observable, `attr` will be used
       
  2604                     // for getting and setting.
       
  2605                     get = function() {
       
  2606                         if (isObserve) {
       
  2607                             return getterSetter.attr(propertyName);
       
  2608                         } else {
       
  2609                             return getterSetter[propertyName];
       
  2610                         }
       
  2611                     };
       
  2612                     set = function(newValue) {
       
  2613                         if (isObserve) {
       
  2614                             getterSetter.attr(propertyName, newValue);
       
  2615                         } else {
       
  2616                             getterSetter[propertyName] = newValue;
       
  2617                         }
       
  2618                     };
       
  2619                     var handler;
       
  2620                     on = function(update) {
       
  2621                         handler = function() {
       
  2622                             update(get(), value);
       
  2623                         };
       
  2624                         can.bind.call(getterSetter, eventName || propertyName, handler);
       
  2625                         // use can.__read because
       
  2626                         // we should not be indicating that some parent
       
  2627                         // reads this property if it happens to be binding on it
       
  2628                         value = can.__read(get)
       
  2629                             .value;
       
  2630                     };
       
  2631                     off = function() {
       
  2632                         can.unbind.call(getterSetter, eventName || propertyName, handler);
       
  2633                     };
       
  2634                     // ###Specifying an initial value and a setter
       
  2635                     // If `can.compute` is called with an [initial value and a setter function](http://canjs.com/docs/can.compute.html#sig_can_compute_initialValue_setter_newVal_oldVal__),
       
  2636                     // a compute that can adjust incoming values is set up.
       
  2637                 } else {
       
  2638                     // `can.compute(initialValue, setter)`
       
  2639                     if (typeof context === 'function') {
       
  2640 
       
  2641                         value = getterSetter;
       
  2642                         set = context;
       
  2643                         context = eventName;
       
  2644                         form = 'setter';
       
  2645                         // ###Specifying an initial value and a settings object
       
  2646                         // If `can.compute` is called with an [initial value and optionally a settings object](http://canjs.com/docs/can.compute.html#sig_can_compute_initialValue__settings__),
       
  2647                         // a can.compute is created that can optionally specify how to read,
       
  2648                         // update, and listen to changes in dependent values. This form of
       
  2649                         // can.compute can be used to derive a compute that derives its
       
  2650                         // value from any source
       
  2651                     } else {
       
  2652                         // `can.compute(initialValue,{get:, set:, on:, off:})`
       
  2653 
       
  2654 
       
  2655                         value = getterSetter;
       
  2656                         var options = context,
       
  2657                             oldUpdater = updater;
       
  2658 
       
  2659                         context = options.context || options;
       
  2660                         get = options.get || get;
       
  2661                         set = options.set || function() {
       
  2662                             return value;
       
  2663                         };
       
  2664                         // This is a "hack" to allow async computes.
       
  2665                         if (options.fn) {
       
  2666                             var fn = options.fn,
       
  2667                                 data;
       
  2668                             // make sure get is called with the newVal, but not setter
       
  2669                             get = function() {
       
  2670                                 return fn.call(context, value);
       
  2671                             };
       
  2672                             // Check the number of arguments the 
       
  2673                             // async function takes.
       
  2674                             if (fn.length === 0) {
       
  2675 
       
  2676                                 data = setupComputeHandlers(computed, fn, context, setCached);
       
  2677 
       
  2678                             } else if (fn.length === 1) {
       
  2679                                 data = setupComputeHandlers(computed, function() {
       
  2680                                     return fn.call(context, value);
       
  2681                                 }, context, setCached);
       
  2682                             } else {
       
  2683                                 updater = function(newVal) {
       
  2684                                     if (newVal !== undefined) {
       
  2685                                         oldUpdater(newVal, value);
       
  2686                                     }
       
  2687                                 };
       
  2688                                 data = setupComputeHandlers(computed, function() {
       
  2689                                     var res = fn.call(context, value, function(newVal) {
       
  2690                                         oldUpdater(newVal, value);
       
  2691                                     });
       
  2692                                     // If undefined is returned, don't update the value.
       
  2693                                     return res !== undefined ? res : value;
       
  2694                                 }, context, setCached);
       
  2695                             }
       
  2696 
       
  2697 
       
  2698                             on = data.on;
       
  2699                             off = data.off;
       
  2700                         } else {
       
  2701                             updater = function() {
       
  2702                                 var newVal = get.call(context);
       
  2703                                 oldUpdater(newVal, value);
       
  2704                             };
       
  2705                         }
       
  2706 
       
  2707                         on = options.on || on;
       
  2708                         off = options.off || off;
       
  2709                     }
       
  2710                 }
       
  2711                 // ###Specifying only a value
       
  2712                 // If can.compute is called with an initialValue only,
       
  2713                 // reads to this value can be observed.
       
  2714             } else {
       
  2715                 // `can.compute(initialValue)`
       
  2716                 value = getterSetter;
       
  2717             }
       
  2718             can.cid(computed, 'compute');
       
  2719             return can.simpleExtend(computed, {
       
  2720 
       
  2721                     isComputed: true,
       
  2722                     _bindsetup: function() {
       
  2723                         this.bound = true;
       
  2724                         // Set up live-binding
       
  2725                         // While binding, this should not count as a read
       
  2726                         var oldReading = can.__clearReading();
       
  2727                         on.call(this, updater);
       
  2728                         // Restore "Observed" for reading
       
  2729                         can.__setReading(oldReading);
       
  2730                     },
       
  2731                     _bindteardown: function() {
       
  2732                         off.call(this, updater);
       
  2733                         this.bound = false;
       
  2734                     },
       
  2735 
       
  2736                     bind: can.bindAndSetup,
       
  2737 
       
  2738                     unbind: can.unbindAndTeardown,
       
  2739                     clone: function(context) {
       
  2740                         if (context) {
       
  2741                             if (form === 'setter') {
       
  2742                                 args[2] = context;
       
  2743                             } else {
       
  2744                                 args[1] = context;
       
  2745                             }
       
  2746                         }
       
  2747                         return can.compute.apply(can, args);
       
  2748                     }
       
  2749                 });
       
  2750         };
       
  2751         // A list of temporarily bound computes
       
  2752         var computes, unbindComputes = function() {
       
  2753                 for (var i = 0, len = computes.length; i < len; i++) {
       
  2754                     computes[i].unbind('change', k);
       
  2755                 }
       
  2756                 computes = null;
       
  2757             };
       
  2758         // Binds computes for a moment to retain their value and prevent caching
       
  2759         can.compute.temporarilyBind = function(compute) {
       
  2760             compute.bind('change', k);
       
  2761             if (!computes) {
       
  2762                 computes = [];
       
  2763                 setTimeout(unbindComputes, 10);
       
  2764             }
       
  2765             computes.push(compute);
       
  2766         };
       
  2767 
       
  2768         // Whether a compute is truthy
       
  2769         can.compute.truthy = function(compute) {
       
  2770             return can.compute(function() {
       
  2771                 var res = compute();
       
  2772                 if (typeof res === 'function') {
       
  2773                     res = res();
       
  2774                 }
       
  2775                 return !!res;
       
  2776             });
       
  2777         };
       
  2778         can.compute.async = function(initialValue, asyncComputer, context) {
       
  2779             return can.compute(initialValue, {
       
  2780                     fn: asyncComputer,
       
  2781                     context: context
       
  2782                 });
       
  2783         };
       
  2784         // {map: new can.Map({first: "Justin"})}, ["map","first"]
       
  2785         can.compute.read = function(parent, reads, options) {
       
  2786             options = options || {};
       
  2787             // `cur` is the current value.
       
  2788             var cur = parent,
       
  2789                 type,
       
  2790                 // `prev` is the object we are reading from.
       
  2791                 prev,
       
  2792                 // `foundObs` did we find an observable.
       
  2793                 foundObs;
       
  2794             for (var i = 0, readLength = reads.length; i < readLength; i++) {
       
  2795                 // Update what we are reading from.
       
  2796                 prev = cur;
       
  2797                 // Read from the compute. We can't read a property yet.
       
  2798                 if (prev && prev.isComputed) {
       
  2799                     if (options.foundObservable) {
       
  2800                         options.foundObservable(prev, i);
       
  2801                     }
       
  2802                     prev = prev();
       
  2803                 }
       
  2804                 // Look to read a property from something.
       
  2805                 if (isObserve(prev)) {
       
  2806                     if (!foundObs && options.foundObservable) {
       
  2807                         options.foundObservable(prev, i);
       
  2808                     }
       
  2809                     foundObs = 1;
       
  2810                     // is it a method on the prototype?
       
  2811                     if (typeof prev[reads[i]] === 'function' && prev.constructor.prototype[reads[i]] === prev[reads[i]]) {
       
  2812                         // call that method
       
  2813                         if (options.returnObserveMethods) {
       
  2814                             cur = cur[reads[i]];
       
  2815                         } else if (reads[i] === 'constructor' && prev instanceof can.Construct) {
       
  2816                             cur = prev[reads[i]];
       
  2817                         } else {
       
  2818                             cur = prev[reads[i]].apply(prev, options.args || []);
       
  2819                         }
       
  2820                     } else {
       
  2821                         // use attr to get that value
       
  2822                         cur = cur.attr(reads[i]);
       
  2823                     }
       
  2824                 } else {
       
  2825                     // just do the dot operator
       
  2826                     cur = prev[reads[i]];
       
  2827                 }
       
  2828                 type = typeof cur;
       
  2829                 // If it's a compute, get the compute's value
       
  2830                 // unless we are at the end of the 
       
  2831                 if (cur && cur.isComputed && (!options.isArgument && i < readLength - 1)) {
       
  2832                     if (!foundObs && options.foundObservable) {
       
  2833                         options.foundObservable(prev, i + 1);
       
  2834                     }
       
  2835                     cur = cur();
       
  2836                 }
       
  2837                 // If it's an anonymous function, execute as requested
       
  2838                 else if (i < reads.length - 1 && type === 'function' && options.executeAnonymousFunctions && !(can.Construct && cur.prototype instanceof can.Construct)) {
       
  2839                     cur = cur();
       
  2840                 }
       
  2841                 // if there are properties left to read, and we don't have an object, early exit
       
  2842                 if (i < reads.length - 1 && (cur === null || type !== 'function' && type !== 'object')) {
       
  2843                     if (options.earlyExit) {
       
  2844                         options.earlyExit(prev, i, cur);
       
  2845                     }
       
  2846                     // return undefined so we know this isn't the right value
       
  2847                     return {
       
  2848                         value: undefined,
       
  2849                         parent: prev
       
  2850                     };
       
  2851                 }
       
  2852             }
       
  2853             // handle an ending function
       
  2854             // unless it is a can.Construct-derived constructor
       
  2855             if (typeof cur === 'function' && !(can.Construct && cur.prototype instanceof can.Construct)) {
       
  2856                 if (options.isArgument) {
       
  2857                     if (!cur.isComputed && options.proxyMethods !== false) {
       
  2858                         cur = can.proxy(cur, prev);
       
  2859                     }
       
  2860                 } else {
       
  2861                     if (cur.isComputed && !foundObs && options.foundObservable) {
       
  2862                         options.foundObservable(cur, i);
       
  2863                     }
       
  2864                     cur = cur.call(prev);
       
  2865                 }
       
  2866             }
       
  2867             // if we don't have a value, exit early.
       
  2868             if (cur === undefined) {
       
  2869                 if (options.earlyExit) {
       
  2870                     options.earlyExit(prev, i - 1);
       
  2871                 }
       
  2872             }
       
  2873             return {
       
  2874                 value: cur,
       
  2875                 parent: prev
       
  2876             };
       
  2877         };
       
  2878 
       
  2879         return can.compute;
       
  2880     })(__m3, __m11, __m13);
       
  2881 
       
  2882     // ## can/model/model.js
       
  2883     var __m16 = (function(can) {
       
  2884 
       
  2885         // ## model.js
       
  2886         // (Don't steal this file directly in your code.)
       
  2887 
       
  2888         // ## pipe
       
  2889         // `pipe` lets you pipe the results of a successful deferred
       
  2890         // through a function before resolving the deferred.
       
  2891 
       
  2892         var pipe = function(def, thisArg, func) {
       
  2893             // The piped result will be available through a new Deferred.
       
  2894             var d = new can.Deferred();
       
  2895             def.then(function() {
       
  2896                 var args = can.makeArray(arguments),
       
  2897                     success = true;
       
  2898 
       
  2899                 try {
       
  2900                     // Pipe the results through the function.
       
  2901                     args[0] = func.apply(thisArg, args);
       
  2902                 } catch (e) {
       
  2903                     success = false;
       
  2904                     // The function threw an error, so reject the Deferred.
       
  2905                     d.rejectWith(d, [e].concat(args));
       
  2906                 }
       
  2907                 if (success) {
       
  2908                     // Resolve the new Deferred with the piped value.
       
  2909                     d.resolveWith(d, args);
       
  2910                 }
       
  2911             }, function() {
       
  2912                 // Pass on the rejection if the original Deferred never resolved.
       
  2913                 d.rejectWith(this, arguments);
       
  2914             });
       
  2915 
       
  2916             // `can.ajax` returns a Deferred with an abort method to halt the AJAX call.
       
  2917             if (typeof def.abort === 'function') {
       
  2918                 d.abort = function() {
       
  2919                     return def.abort();
       
  2920                 };
       
  2921             }
       
  2922 
       
  2923             // Return the new (piped) Deferred.
       
  2924             return d;
       
  2925         },
       
  2926 
       
  2927             // ## modelNum
       
  2928             // When new model constructors are set up without a full name,
       
  2929             // `modelNum` lets us name them uniquely (to keep track of them).
       
  2930             modelNum = 0,
       
  2931 
       
  2932             // ## getId
       
  2933             getId = function(inst) {
       
  2934                 // `can.__reading` makes a note that `id` was just read.
       
  2935                 can.__reading(inst, inst.constructor.id);
       
  2936                 // Use `__get` instead of `attr` for performance. (But that means we have to remember to call `can.__reading`.)
       
  2937                 return inst.__get(inst.constructor.id);
       
  2938             },
       
  2939 
       
  2940             // ## ajax
       
  2941             // This helper method makes it easier to make an AJAX call from the configuration of the Model.
       
  2942             ajax = function(ajaxOb, data, type, dataType, success, error) {
       
  2943 
       
  2944                 var params = {};
       
  2945 
       
  2946                 // A string here would be something like `"GET /endpoint"`.
       
  2947                 if (typeof ajaxOb === 'string') {
       
  2948                     // Split on spaces to separate the HTTP method and the URL.
       
  2949                     var parts = ajaxOb.split(/\s+/);
       
  2950                     params.url = parts.pop();
       
  2951                     if (parts.length) {
       
  2952                         params.type = parts.pop();
       
  2953                     }
       
  2954                 } else {
       
  2955                     // If the first argument is an object, just load it into `params`.
       
  2956                     can.extend(params, ajaxOb);
       
  2957                 }
       
  2958 
       
  2959                 // If the `data` argument is a plain object, copy it into `params`.
       
  2960                 params.data = typeof data === "object" && !can.isArray(data) ?
       
  2961                     can.extend(params.data || {}, data) : data;
       
  2962 
       
  2963                 // Substitute in data for any templated parts of the URL.
       
  2964                 params.url = can.sub(params.url, params.data, true);
       
  2965 
       
  2966                 return can.ajax(can.extend({
       
  2967                             type: type || 'post',
       
  2968                             dataType: dataType || 'json',
       
  2969                             success: success,
       
  2970                             error: error
       
  2971                         }, params));
       
  2972             },
       
  2973 
       
  2974             // ## makeRequest
       
  2975             // This function abstracts making the actual AJAX request away from the Model.
       
  2976             makeRequest = function(modelObj, type, success, error, method) {
       
  2977                 var args;
       
  2978 
       
  2979                 // If `modelObj` is an Array, it it means we are coming from
       
  2980                 // the queued request, and we're passing already-serialized data.
       
  2981                 if (can.isArray(modelObj)) {
       
  2982                     // In that case, modelObj's signature will be `[modelObj, serializedData]`, so we need to unpack it.
       
  2983                     args = modelObj[1];
       
  2984                     modelObj = modelObj[0];
       
  2985                 } else {
       
  2986                     // If we aren't supplied with serialized data, we'll make our own.
       
  2987                     args = modelObj.serialize();
       
  2988                 }
       
  2989                 args = [args];
       
  2990 
       
  2991                 var deferred,
       
  2992                     model = modelObj.constructor,
       
  2993                     jqXHR;
       
  2994 
       
  2995                 // When calling `update` and `destroy`, the current ID needs to be the first parameter in the AJAX call.
       
  2996                 if (type === 'update' || type === 'destroy') {
       
  2997                     args.unshift(getId(modelObj));
       
  2998                 }
       
  2999                 jqXHR = model[type].apply(model, args);
       
  3000 
       
  3001                 // Make sure that can.Model can react to the request before anything else does.
       
  3002                 deferred = pipe(jqXHR, modelObj, function(data) {
       
  3003                     // `method` is here because `"destroyed" !== "destroy" + "d"`.
       
  3004                     // TODO: Do something smarter/more consistent here?
       
  3005                     modelObj[method || type + "d"](data, jqXHR);
       
  3006                     return modelObj;
       
  3007                 });
       
  3008 
       
  3009                 // Hook up `abort`
       
  3010                 if (jqXHR.abort) {
       
  3011                     deferred.abort = function() {
       
  3012                         jqXHR.abort();
       
  3013                     };
       
  3014                 }
       
  3015 
       
  3016                 deferred.then(success, error);
       
  3017                 return deferred;
       
  3018             },
       
  3019 
       
  3020             initializers = {
       
  3021                 // ## models
       
  3022                 // Returns a function that, when handed a list of objects, makes them into models and returns a model list of them.
       
  3023                 // `prop` is the property on `instancesRawData` that has the array of objects in it (if it's not `data`).
       
  3024                 models: function(prop) {
       
  3025                     return function(instancesRawData, oldList) {
       
  3026                         // Increment reqs counter so new instances will be added to the store.
       
  3027                         // (This is cleaned up at the end of the method.)
       
  3028                         can.Model._reqs++;
       
  3029 
       
  3030                         // If there is no data, we can't really do anything with it.
       
  3031                         if (!instancesRawData) {
       
  3032                             return;
       
  3033                         }
       
  3034 
       
  3035                         // If the "raw" data is already a List, it's not raw.
       
  3036                         if (instancesRawData instanceof this.List) {
       
  3037                             return instancesRawData;
       
  3038                         }
       
  3039 
       
  3040                         var self = this,
       
  3041                             // `tmp` will hold the models before we push them onto `modelList`.
       
  3042                             tmp = [],
       
  3043                             // `ML` (see way below) is just `can.Model.List`.
       
  3044                             ListClass = self.List || ML,
       
  3045                             modelList = oldList instanceof can.List ? oldList : new ListClass(),
       
  3046 
       
  3047                             // Check if we were handed an Array or a model list.
       
  3048                             rawDataIsArray = can.isArray(instancesRawData),
       
  3049                             rawDataIsList = instancesRawData instanceof ML,
       
  3050 
       
  3051                             // Get the "plain" objects from the models from the list/array.
       
  3052                             raw = rawDataIsArray ? instancesRawData : (
       
  3053                                 rawDataIsList ? instancesRawData.serialize() : can.getObject(prop || "data", instancesRawData));
       
  3054 
       
  3055                         if (typeof raw === 'undefined') {
       
  3056                             throw new Error('Could not get any raw data while converting using .models');
       
  3057                         }
       
  3058 
       
  3059 
       
  3060 
       
  3061                         // If there was anything left in the list we were given, get rid of it.
       
  3062                         if (modelList.length) {
       
  3063                             modelList.splice(0);
       
  3064                         }
       
  3065 
       
  3066                         // If we pushed these directly onto the list, it would cause a change event for each model.
       
  3067                         // So, we push them onto `tmp` first and then push everything at once, causing one atomic change event that contains all the models at once.
       
  3068                         can.each(raw, function(rawPart) {
       
  3069                             tmp.push(self.model(rawPart));
       
  3070                         });
       
  3071                         modelList.push.apply(modelList, tmp);
       
  3072 
       
  3073                         // If there was other stuff on `instancesRawData`, let's transfer that onto `modelList` too.
       
  3074                         if (!rawDataIsArray) {
       
  3075                             can.each(instancesRawData, function(val, prop) {
       
  3076                                 if (prop !== 'data') {
       
  3077                                     modelList.attr(prop, val);
       
  3078                                 }
       
  3079                             });
       
  3080                         }
       
  3081                         // Clean up the store on the next turn of the event loop. (`this` is a model constructor.)
       
  3082                         setTimeout(can.proxy(this._clean, this), 1);
       
  3083                         return modelList;
       
  3084                     };
       
  3085                 },
       
  3086                 // ## model
       
  3087                 // Returns a function that, when handed a plain object, turns it into a model.
       
  3088                 // `prop` is the property on `attributes` that has the properties for the model in it.
       
  3089                 model: function(prop) {
       
  3090                     return function(attributes) {
       
  3091                         // If there're no properties, there can be no model.
       
  3092                         if (!attributes) {
       
  3093                             return;
       
  3094                         }
       
  3095                         // If this object knows how to serialize, parse, or access itself, we'll use that instead.
       
  3096                         if (typeof attributes.serialize === 'function') {
       
  3097                             attributes = attributes.serialize();
       
  3098                         }
       
  3099                         if (this.parseModel) {
       
  3100                             attributes = this.parseModel.apply(this, arguments);
       
  3101                         } else if (prop) {
       
  3102                             attributes = can.getObject(prop || "data", attributes);
       
  3103                         }
       
  3104 
       
  3105                         var id = attributes[this.id],
       
  3106                             // 0 is a valid ID.
       
  3107                             model = (id || id === 0) && this.store[id] ?
       
  3108                             // If this model is in the store already, just update it.
       
  3109                             this.store[id].attr(attributes, this.removeAttr || false) :
       
  3110                             // Otherwise, we need a new model.
       
  3111                             new this(attributes);
       
  3112 
       
  3113                         return model;
       
  3114                     };
       
  3115                 }
       
  3116             },
       
  3117 
       
  3118 
       
  3119             parserMaker = function(prop) {
       
  3120                 return function(attributes) {
       
  3121                     return prop ? can.getObject(prop || "data", attributes) : attributes;
       
  3122                 };
       
  3123             },
       
  3124 
       
  3125             // ## parsers
       
  3126             // This object describes how to take the data from an AJAX request and prepare it for `models` and `model`.
       
  3127             // These functions are meant to be overwritten (if necessary) in an extended model constructor.
       
  3128             parsers = {
       
  3129 
       
  3130                 parseModel: parserMaker,
       
  3131 
       
  3132                 parseModels: parserMaker
       
  3133             },
       
  3134 
       
  3135             // ## ajaxMethods
       
  3136             // This object describes how to make an AJAX request for each ajax method (`create`, `update`, etc.)
       
  3137             // Each AJAX method is an object in `ajaxMethods` and can have the following properties:
       
  3138             // - `url`: Which property on the model contains the default URL for this method.
       
  3139             // - `type`: The default HTTP request method.
       
  3140             // - `data`: A method that takes the arguments from `makeRequest` (see above) and returns a data object for use in the AJAX call.
       
  3141 
       
  3142 
       
  3143             ajaxMethods = {
       
  3144 
       
  3145                 create: {
       
  3146                     url: "_shortName",
       
  3147                     type: "post"
       
  3148                 },
       
  3149 
       
  3150                 update: {
       
  3151                     // ## update.data
       
  3152                     data: function(id, attrs) {
       
  3153                         attrs = attrs || {};
       
  3154 
       
  3155                         // `this.id` is the property that represents the ID (and is usually `"id"`).
       
  3156                         var identity = this.id;
       
  3157 
       
  3158                         // If the value of the property being used as the ID changed,
       
  3159                         // indicate that in the request and replace the current ID property.
       
  3160                         if (attrs[identity] && attrs[identity] !== id) {
       
  3161                             attrs["new" + can.capitalize(id)] = attrs[identity];
       
  3162                             delete attrs[identity];
       
  3163                         }
       
  3164                         attrs[identity] = id;
       
  3165 
       
  3166                         return attrs;
       
  3167                     },
       
  3168                     type: "put"
       
  3169                 },
       
  3170 
       
  3171                 destroy: {
       
  3172                     type: 'delete',
       
  3173                     // ## destroy.data
       
  3174                     data: function(id, attrs) {
       
  3175                         attrs = attrs || {};
       
  3176                         // `this.id` is the property that represents the ID (and is usually `"id"`).
       
  3177                         attrs.id = attrs[this.id] = id;
       
  3178                         return attrs;
       
  3179                     }
       
  3180                 },
       
  3181 
       
  3182                 findAll: {
       
  3183                     url: "_shortName"
       
  3184                 },
       
  3185 
       
  3186                 findOne: {}
       
  3187             },
       
  3188             // ## ajaxMaker
       
  3189             // Takes a method defined just above and a string that describes how to call that method
       
  3190             // and makes a function that calls that method with the given data.
       
  3191             // - `ajaxMethod`: The object defined above in `ajaxMethods`.
       
  3192             // - `str`: The string the configuration provided (such as `"/recipes.json"` for a `findAll` call).
       
  3193             ajaxMaker = function(ajaxMethod, str) {
       
  3194                 return function(data) {
       
  3195                     data = ajaxMethod.data ?
       
  3196                     // If the AJAX method mentioned above has its own way of getting `data`, use that.
       
  3197                     ajaxMethod.data.apply(this, arguments) :
       
  3198                     // Otherwise, just use the data passed in.
       
  3199                     data;
       
  3200 
       
  3201                     // Make the AJAX call with the URL, data, and type indicated by the proper `ajaxMethod` above.
       
  3202                     return ajax(str || this[ajaxMethod.url || "_url"], data, ajaxMethod.type || "get");
       
  3203                 };
       
  3204             },
       
  3205             // ## createURLFromResource
       
  3206             // For each of the names (create, update, destroy, findOne, and findAll) use the 
       
  3207             // URL provided by the `resource` property. For example:
       
  3208             // 		ToDo = can.Model.extend({
       
  3209             // 			resource: "/todos"
       
  3210             // 		}, {});
       
  3211             // 	Will create a can.Model that is identical to:
       
  3212             // 		ToDo = can.Model.extend({
       
  3213             // 			findAll: "GET /todos",
       
  3214             // 			findOne: "GET /todos/{id}",
       
  3215             // 			create:  "POST /todos",
       
  3216             // 			update:  "PUT /todos/{id}",
       
  3217             // 			destroy: "DELETE /todos/{id}"
       
  3218             // 		},{});
       
  3219             // - `model`: the can.Model that has the resource property
       
  3220             // - `method`: a property from the ajaxMethod object
       
  3221             createURLFromResource = function(model, name) {
       
  3222                 if (!model.resource) {
       
  3223                     return;
       
  3224                 }
       
  3225 
       
  3226                 var resource = model.resource.replace(/\/+$/, "");
       
  3227                 if (name === "findAll" || name === "create") {
       
  3228                     return resource;
       
  3229                 } else {
       
  3230                     return resource + "/{" + model.id + "}";
       
  3231                 }
       
  3232             };
       
  3233 
       
  3234         // # can.Model
       
  3235         // A can.Map that connects to a RESTful interface.
       
  3236         can.Model = can.Map.extend({
       
  3237                 // `fullName` identifies the model type in debugging.
       
  3238                 fullName: "can.Model",
       
  3239                 _reqs: 0,
       
  3240                 // ## can.Model.setup
       
  3241 
       
  3242                 setup: function(base, fullName, staticProps, protoProps) {
       
  3243                     // Assume `fullName` wasn't passed. (`can.Model.extend({ ... }, { ... })`)
       
  3244                     // This is pretty usual.
       
  3245                     if (fullName !== "string") {
       
  3246                         protoProps = staticProps;
       
  3247                         staticProps = fullName;
       
  3248                     }
       
  3249                     // Assume no static properties were passed. (`can.Model.extend({ ... })`)
       
  3250                     // This is really unusual for a model though, since there's so much configuration.
       
  3251                     if (!protoProps) {
       
  3252                         protoProps = staticProps;
       
  3253                     }
       
  3254 
       
  3255                     // Create the model store here, in case someone wants to use can.Model without inheriting from it.
       
  3256                     this.store = {};
       
  3257 
       
  3258                     can.Map.setup.apply(this, arguments);
       
  3259                     if (!can.Model) {
       
  3260                         return;
       
  3261                     }
       
  3262 
       
  3263                     // `List` is just a regular can.Model.List that knows what kind of Model it's hooked up to.
       
  3264 
       
  3265                     if (staticProps && staticProps.List) {
       
  3266                         this.List = staticProps.List;
       
  3267                         this.List.Map = this;
       
  3268                     } else {
       
  3269                         this.List = base.List.extend({
       
  3270                                 Map: this
       
  3271                             }, {});
       
  3272                     }
       
  3273 
       
  3274                     var self = this,
       
  3275                         clean = can.proxy(this._clean, self);
       
  3276 
       
  3277                     // Go through `ajaxMethods` and set up static methods according to their configurations.
       
  3278                     can.each(ajaxMethods, function(method, name) {
       
  3279                         // Check the configuration for this ajaxMethod.
       
  3280                         // If the configuration isn't a function, it should be a string (like `"GET /endpoint"`)
       
  3281                         // or an object like `{url: "/endpoint", type: 'GET'}`.
       
  3282                         if (!can.isFunction(self[name])) {
       
  3283                             // Etiher way, `ajaxMaker` will turn it into a function for us.
       
  3284                             self[name] = ajaxMaker(method, self[name] ? self[name] : createURLFromResource(self, name));
       
  3285                         }
       
  3286 
       
  3287                         // There may also be a "maker" function (like `makeFindAll`) that alters the behavior of acting upon models
       
  3288                         // by changing when and how the function we just made with `ajaxMaker` gets called.
       
  3289                         // For example, you might cache responses and only make a call when you don't have a cached response.
       
  3290                         if (self["make" + can.capitalize(name)]) {
       
  3291                             // Use the "maker" function to make the new "ajaxMethod" function.
       
  3292                             var newMethod = self["make" + can.capitalize(name)](self[name]);
       
  3293                             // Replace the "ajaxMethod" function in the configuration with the new one.
       
  3294                             // (`_overwrite` just overwrites a property in a given Construct.)
       
  3295                             can.Construct._overwrite(self, base, name, function() {
       
  3296                                 // Increment the numer of requests...
       
  3297                                 can.Model._reqs++;
       
  3298                                 // ...make the AJAX call (and whatever else you're doing)...
       
  3299                                 var def = newMethod.apply(this, arguments);
       
  3300                                 // ...and clean up the store.
       
  3301                                 var then = def.then(clean, clean);
       
  3302                                 // Pass along `abort` so you can still abort the AJAX call.
       
  3303                                 then.abort = def.abort;
       
  3304 
       
  3305                                 return then;
       
  3306                             });
       
  3307                         }
       
  3308                     });
       
  3309 
       
  3310                     // Set up the methods that will set up `models` and `model`.
       
  3311                     can.each(initializers, function(makeInitializer, name) {
       
  3312                         var parseName = "parse" + can.capitalize(name),
       
  3313                             dataProperty = self[name];
       
  3314 
       
  3315                         // If there was a different property to find the model's data in than `data`,
       
  3316                         // make `parseModel` and `parseModels` functions that look that up instead.
       
  3317                         if (typeof dataProperty === "string") {
       
  3318                             can.Construct._overwrite(self, base, parseName, parsers[parseName](dataProperty));
       
  3319                             can.Construct._overwrite(self, base, name, makeInitializer(dataProperty));
       
  3320                         }
       
  3321 
       
  3322                         // If there was no prototype, or no `model` and no `parseModel`,
       
  3323                         // we'll have to create a `parseModel`.
       
  3324                         else if (!protoProps || (!protoProps[name] && !protoProps[parseName])) {
       
  3325                             can.Construct._overwrite(self, base, parseName, parsers[parseName]());
       
  3326                         }
       
  3327                     });
       
  3328 
       
  3329                     // With the overridden parse methods, set up `models` and `model`.
       
  3330                     can.each(parsers, function(makeParser, name) {
       
  3331                         // If there was a different property to find the model's data in than `data`,
       
  3332                         // make `model` and `models` functions that look that up instead.
       
  3333                         if (typeof self[name] === "string") {
       
  3334                             can.Construct._overwrite(self, base, name, makeParser(self[name]));
       
  3335                         }
       
  3336                     });
       
  3337 
       
  3338                     // Make sure we have a unique name for this Model.
       
  3339                     if (self.fullName === "can.Model" || !self.fullName) {
       
  3340                         self.fullName = "Model" + (++modelNum);
       
  3341                     }
       
  3342 
       
  3343                     can.Model._reqs = 0;
       
  3344                     this._url = this._shortName + "/{" + this.id + "}";
       
  3345                 },
       
  3346                 _ajax: ajaxMaker,
       
  3347                 _makeRequest: makeRequest,
       
  3348                 // ## can.Model._clean
       
  3349                 // `_clean` cleans up the model store after a request happens.
       
  3350                 _clean: function() {
       
  3351                     can.Model._reqs--;
       
  3352                     // Don't clean up unless we have no pending requests.
       
  3353                     if (!can.Model._reqs) {
       
  3354                         for (var id in this.store) {
       
  3355                             // Delete all items in the store without any event bindings.
       
  3356                             if (!this.store[id]._bindings) {
       
  3357                                 delete this.store[id];
       
  3358                             }
       
  3359                         }
       
  3360                     }
       
  3361                     return arguments[0];
       
  3362                 },
       
  3363 
       
  3364                 models: initializers.models("data"),
       
  3365 
       
  3366                 model: initializers.model()
       
  3367             },
       
  3368 
       
  3369 
       
  3370             {
       
  3371                 // ## can.Model#setup
       
  3372                 setup: function(attrs) {
       
  3373                     // Try to add things as early as possible to the store (#457).
       
  3374                     // This is the earliest possible moment, even before any properties are set.
       
  3375                     var id = attrs && attrs[this.constructor.id];
       
  3376                     if (can.Model._reqs && id != null) {
       
  3377                         this.constructor.store[id] = this;
       
  3378                     }
       
  3379                     can.Map.prototype.setup.apply(this, arguments);
       
  3380                 },
       
  3381                 // ## can.Model#isNew
       
  3382                 // Something is new if its ID is `null` or `undefined`.
       
  3383 
       
  3384                 isNew: function() {
       
  3385                     var id = getId(this);
       
  3386                     // 0 is a valid ID.
       
  3387                     // TODO: Why not `return id === null || id === undefined;`?
       
  3388                     return !(id || id === 0); // If `null` or `undefined`
       
  3389                 },
       
  3390                 // ## can.Model#save
       
  3391                 // `save` calls `create` or `update` as necessary, based on whether a model is new.
       
  3392 
       
  3393                 save: function(success, error) {
       
  3394                     return makeRequest(this, this.isNew() ? 'create' : 'update', success, error);
       
  3395                 },
       
  3396                 // ## can.Model#destroy
       
  3397                 // Acts like can.Map.destroy but it also makes an AJAX call.
       
  3398 
       
  3399                 destroy: function(success, error) {
       
  3400                     // If this model is new, don't make an AJAX call.
       
  3401                     // Instead, we have to construct the Deferred ourselves and return it.
       
  3402                     if (this.isNew()) {
       
  3403                         var self = this;
       
  3404                         var def = can.Deferred();
       
  3405                         def.then(success, error);
       
  3406 
       
  3407                         return def.done(function(data) {
       
  3408                             self.destroyed(data);
       
  3409                         }).resolve(self);
       
  3410                     }
       
  3411 
       
  3412                     // If it isn't new, though, go ahead and make a request.
       
  3413                     return makeRequest(this, 'destroy', success, error, 'destroyed');
       
  3414                 },
       
  3415                 // ## can.Model#bind and can.Model#unbind
       
  3416                 // These aren't actually implemented here, but their setup needs to be changed to account for the store.
       
  3417 
       
  3418                 _bindsetup: function() {
       
  3419                     this.constructor.store[this.__get(this.constructor.id)] = this;
       
  3420                     return can.Map.prototype._bindsetup.apply(this, arguments);
       
  3421                 },
       
  3422 
       
  3423                 _bindteardown: function() {
       
  3424                     delete this.constructor.store[getId(this)];
       
  3425                     return can.Map.prototype._bindteardown.apply(this, arguments);
       
  3426                 },
       
  3427                 // Change the behavior of `___set` to account for the store.
       
  3428                 ___set: function(prop, val) {
       
  3429                     can.Map.prototype.___set.call(this, prop, val);
       
  3430                     // If we add or change the ID, update the store accordingly.
       
  3431                     // TODO: shouldn't this also delete the record from the old ID in the store?
       
  3432                     if (prop === this.constructor.id && this._bindings) {
       
  3433                         this.constructor.store[getId(this)] = this;
       
  3434                     }
       
  3435                 }
       
  3436             });
       
  3437 
       
  3438         // Returns a function that knows how to prepare data from `findAll` or `findOne` calls.
       
  3439         // `name` should be either `model` or `models`.
       
  3440         var makeGetterHandler = function(name) {
       
  3441             var parseName = "parse" + can.capitalize(name);
       
  3442             return function(data) {
       
  3443                 // If there's a `parse...` function, use its output.
       
  3444                 if (this[parseName]) {
       
  3445                     data = this[parseName].apply(this, arguments);
       
  3446                 }
       
  3447                 // Run our maybe-parsed data through `model` or `models`.
       
  3448                 return this[name](data);
       
  3449             };
       
  3450         },
       
  3451             // Handle data returned from `create`, `update`, and `destroy` calls.
       
  3452             createUpdateDestroyHandler = function(data) {
       
  3453                 if (this.parseModel) {
       
  3454                     return this.parseModel.apply(this, arguments);
       
  3455                 } else {
       
  3456                     return this.model(data);
       
  3457                 }
       
  3458             };
       
  3459 
       
  3460         var responseHandlers = {
       
  3461 
       
  3462             makeFindAll: makeGetterHandler("models"),
       
  3463 
       
  3464             makeFindOne: makeGetterHandler("model"),
       
  3465             makeCreate: createUpdateDestroyHandler,
       
  3466             makeUpdate: createUpdateDestroyHandler
       
  3467         };
       
  3468 
       
  3469         // Go through the response handlers and make the actual "make" methods.
       
  3470         can.each(responseHandlers, function(method, name) {
       
  3471             can.Model[name] = function(oldMethod) {
       
  3472                 return function() {
       
  3473                     var args = can.makeArray(arguments),
       
  3474                         // If args[1] is a function, we were only passed one argument before success and failure callbacks.
       
  3475                         oldArgs = can.isFunction(args[1]) ? args.splice(0, 1) : args.splice(0, 2),
       
  3476                         // Call the AJAX method (`findAll` or `update`, etc.) and pipe it through the response handler from above.
       
  3477                         def = pipe(oldMethod.apply(this, oldArgs), this, method);
       
  3478 
       
  3479                     def.then(args[0], args[1]);
       
  3480                     return def;
       
  3481                 };
       
  3482             };
       
  3483         });
       
  3484 
       
  3485         // ## can.Model.created, can.Model.updated, and can.Model.destroyed
       
  3486         // Livecycle methods for models.
       
  3487         can.each([
       
  3488 
       
  3489                 "created",
       
  3490 
       
  3491                 "updated",
       
  3492 
       
  3493                 "destroyed"
       
  3494             ], function(funcName) {
       
  3495                 // Each of these is pretty much the same, except for the events they trigger.
       
  3496                 can.Model.prototype[funcName] = function(attrs) {
       
  3497                     var stub,
       
  3498                         constructor = this.constructor;
       
  3499 
       
  3500                     // Update attributes if attributes have been passed
       
  3501                     stub = attrs && typeof attrs === 'object' && this.attr(attrs.attr ? attrs.attr() : attrs);
       
  3502 
       
  3503                     // triggers change event that bubble's like
       
  3504                     // handler( 'change','1.destroyed' ). This is used
       
  3505                     // to remove items on destroyed from Model Lists.
       
  3506                     // but there should be a better way.
       
  3507                     can.trigger(this, "change", funcName);
       
  3508 
       
  3509 
       
  3510 
       
  3511                     // Call event on the instance's Class
       
  3512                     can.trigger(constructor, funcName, this);
       
  3513                 };
       
  3514             });
       
  3515 
       
  3516 
       
  3517         // # can.Model.List
       
  3518         // Model Lists are just like `Map.List`s except that when their items are
       
  3519         // destroyed, they automatically get removed from the List.
       
  3520         var ML = can.Model.List = can.List.extend({
       
  3521                 // ## can.Model.List.setup
       
  3522                 // On change or a nested named event, setup change bubbling.
       
  3523                 // On any other type of event, setup "destroyed" bubbling.
       
  3524                 _bubbleRule: function(eventName, list) {
       
  3525                     return can.List._bubbleRule(eventName, list) || "destroyed";
       
  3526                 }
       
  3527             }, {
       
  3528                 setup: function(params) {
       
  3529                     // If there was a plain object passed to the List constructor,
       
  3530                     // we use those as parameters for an initial findAll.
       
  3531                     if (can.isPlainObject(params) && !can.isArray(params)) {
       
  3532                         can.List.prototype.setup.apply(this);
       
  3533                         this.replace(this.constructor.Map.findAll(params));
       
  3534                     } else {
       
  3535                         // Otherwise, set up the list like normal.
       
  3536                         can.List.prototype.setup.apply(this, arguments);
       
  3537                     }
       
  3538                     this._init = 1;
       
  3539                     this.bind('destroyed', can.proxy(this._destroyed, this));
       
  3540                     delete this._init;
       
  3541                 },
       
  3542                 _destroyed: function(ev, attr) {
       
  3543                     if (/\w+/.test(attr)) {
       
  3544                         var index;
       
  3545                         while ((index = this.indexOf(ev.target)) > -1) {
       
  3546                             this.splice(index, 1);
       
  3547                         }
       
  3548                     }
       
  3549                 }
       
  3550             });
       
  3551 
       
  3552         return can.Model;
       
  3553     })(__m3, __m10, __m14);
       
  3554 
       
  3555     // ## can/view/view.js
       
  3556     var __m17 = (function(can) {
       
  3557 
       
  3558         var isFunction = can.isFunction,
       
  3559             makeArray = can.makeArray,
       
  3560             // Used for hookup `id`s.
       
  3561             hookupId = 1;
       
  3562 
       
  3563         // internal utility methods
       
  3564         // ------------------------
       
  3565 
       
  3566         // ##### makeRenderer
       
  3567 
       
  3568         var makeRenderer = function(textRenderer) {
       
  3569             var renderer = function() {
       
  3570                 return $view.frag(textRenderer.apply(this, arguments));
       
  3571             };
       
  3572             renderer.render = function() {
       
  3573                 return textRenderer.apply(textRenderer, arguments);
       
  3574             };
       
  3575             return renderer;
       
  3576         };
       
  3577 
       
  3578         // ##### checkText
       
  3579         // Makes sure there's a template, if not, have `steal` provide a warning.
       
  3580         var checkText = function(text, url) {
       
  3581             if (!text.length) {
       
  3582 
       
  3583                 // _removed if not used as a steal module_
       
  3584 
       
  3585 
       
  3586 
       
  3587                 throw "can.view: No template or empty template:" + url;
       
  3588             }
       
  3589         };
       
  3590 
       
  3591         // ##### get
       
  3592         // get a deferred renderer for provided url
       
  3593 
       
  3594         var get = function(obj, async) {
       
  3595             var url = typeof obj === 'string' ? obj : obj.url,
       
  3596                 suffix = (obj.engine && '.' + obj.engine) || url.match(/\.[\w\d]+$/),
       
  3597                 type,
       
  3598                 // If we are reading a script element for the content of the template,
       
  3599                 // `el` will be set to that script element.
       
  3600                 el,
       
  3601                 // A unique identifier for the view (used for caching).
       
  3602                 // This is typically derived from the element id or
       
  3603                 // the url for the template.
       
  3604                 id;
       
  3605 
       
  3606             //If the url has a #, we assume we want to use an inline template
       
  3607             //from a script element and not current page's HTML
       
  3608             if (url.match(/^#/)) {
       
  3609                 url = url.substr(1);
       
  3610             }
       
  3611             // If we have an inline template, derive the suffix from the `text/???` part.
       
  3612             // This only supports `<script>` tags.
       
  3613             if (el = document.getElementById(url)) {
       
  3614                 suffix = '.' + el.type.match(/\/(x\-)?(.+)/)[2];
       
  3615             }
       
  3616 
       
  3617             // If there is no suffix, add one.
       
  3618             if (!suffix && !$view.cached[url]) {
       
  3619                 url += suffix = $view.ext;
       
  3620             }
       
  3621 
       
  3622             // if the suffix was derived from the .match() operation, pluck out the first value
       
  3623             if (can.isArray(suffix)) {
       
  3624                 suffix = suffix[0];
       
  3625             }
       
  3626 
       
  3627             // Convert to a unique and valid id.
       
  3628             id = $view.toId(url);
       
  3629 
       
  3630             // If an absolute path, use `steal`/`require` to get it.
       
  3631             // You should only be using `//` if you are using an AMD loader like `steal` or `require` (not almond).
       
  3632             if (url.match(/^\/\//)) {
       
  3633                 url = url.substr(2);
       
  3634                 url = !window.steal ?
       
  3635                     url :
       
  3636                     steal.config()
       
  3637                     .root.mapJoin("" + steal.id(url));
       
  3638             }
       
  3639 
       
  3640             // Localize for `require` (not almond)
       
  3641             if (window.require) {
       
  3642                 if (require.toUrl) {
       
  3643                     url = require.toUrl(url);
       
  3644                 }
       
  3645             }
       
  3646 
       
  3647             // Set the template engine type.
       
  3648             type = $view.types[suffix];
       
  3649 
       
  3650             // If it is cached,
       
  3651             if ($view.cached[id]) {
       
  3652                 // Return the cached deferred renderer.
       
  3653                 return $view.cached[id];
       
  3654 
       
  3655                 // Otherwise if we are getting this from a `<script>` element.
       
  3656             } else if (el) {
       
  3657                 // Resolve immediately with the element's `innerHTML`.
       
  3658                 return $view.registerView(id, el.innerHTML, type);
       
  3659             } else {
       
  3660                 // Make an ajax request for text.
       
  3661                 var d = new can.Deferred();
       
  3662                 can.ajax({
       
  3663                         async: async,
       
  3664                         url: url,
       
  3665                         dataType: 'text',
       
  3666                         error: function(jqXHR) {
       
  3667                             checkText('', url);
       
  3668                             d.reject(jqXHR);
       
  3669                         },
       
  3670                         success: function(text) {
       
  3671                             // Make sure we got some text back.
       
  3672                             checkText(text, url);
       
  3673                             $view.registerView(id, text, type, d);
       
  3674                         }
       
  3675                     });
       
  3676                 return d;
       
  3677             }
       
  3678         };
       
  3679         // ##### getDeferreds
       
  3680         // Gets an `array` of deferreds from an `object`.
       
  3681         // This only goes one level deep.
       
  3682 
       
  3683         var getDeferreds = function(data) {
       
  3684             var deferreds = [];
       
  3685 
       
  3686             // pull out deferreds
       
  3687             if (can.isDeferred(data)) {
       
  3688                 return [data];
       
  3689             } else {
       
  3690                 for (var prop in data) {
       
  3691                     if (can.isDeferred(data[prop])) {
       
  3692                         deferreds.push(data[prop]);
       
  3693                     }
       
  3694                 }
       
  3695             }
       
  3696             return deferreds;
       
  3697         };
       
  3698 
       
  3699         // ##### usefulPart
       
  3700         // Gets the useful part of a resolved deferred.
       
  3701         // When a jQuery.when is resolved, it returns an array to each argument.
       
  3702         // Reference ($.when)[https://api.jquery.com/jQuery.when/]
       
  3703         // This is for `model`s and `can.ajax` that resolve to an `array`.
       
  3704 
       
  3705         var usefulPart = function(resolved) {
       
  3706             return can.isArray(resolved) && resolved[1] === 'success' ? resolved[0] : resolved;
       
  3707         };
       
  3708 
       
  3709         // #### can.view
       
  3710         //defines $view for internal use, can.template for backwards compatibility
       
  3711 
       
  3712         var $view = can.view = can.template = function(view, data, helpers, callback) {
       
  3713             // If helpers is a `function`, it is actually a callback.
       
  3714             if (isFunction(helpers)) {
       
  3715                 callback = helpers;
       
  3716                 helpers = undefined;
       
  3717             }
       
  3718             var result;
       
  3719             // Get the result, if a renderer function is passed in, then we just use that to render the data
       
  3720             if (isFunction(view)) {
       
  3721                 result = view(data, helpers, callback);
       
  3722             } else {
       
  3723                 result = $view.renderAs("fragment", view, data, helpers, callback);
       
  3724             }
       
  3725 
       
  3726             return result;
       
  3727         };
       
  3728 
       
  3729         // can.view methods
       
  3730         // --------------------------
       
  3731         can.extend($view, {
       
  3732                 // ##### frag
       
  3733                 // creates a fragment and hooks it up all at once
       
  3734 
       
  3735                 frag: function(result, parentNode) {
       
  3736                     return $view.hookup($view.fragment(result), parentNode);
       
  3737                 },
       
  3738 
       
  3739                 // #### fragment
       
  3740                 // this is used internally to create a document fragment, insert it,then hook it up
       
  3741                 fragment: function(result) {
       
  3742                     if (typeof result !== "string" && result.nodeType === 11) {
       
  3743                         return result;
       
  3744                     }
       
  3745                     var frag = can.buildFragment(result, document.body);
       
  3746                     // If we have an empty frag...
       
  3747                     if (!frag.childNodes.length) {
       
  3748                         frag.appendChild(document.createTextNode(''));
       
  3749                     }
       
  3750                     return frag;
       
  3751                 },
       
  3752 
       
  3753                 // ##### toId
       
  3754                 // Convert a path like string into something that's ok for an `element` ID.
       
  3755                 toId: function(src) {
       
  3756                     return can.map(src.toString()
       
  3757                         .split(/\/|\./g), function(part) {
       
  3758                             // Dont include empty strings in toId functions
       
  3759                             if (part) {
       
  3760                                 return part;
       
  3761                             }
       
  3762                         })
       
  3763                         .join('_');
       
  3764                 },
       
  3765                 // ##### toStr
       
  3766                 // convert argument to a string
       
  3767                 toStr: function(txt) {
       
  3768                     return txt == null ? "" : "" + txt;
       
  3769                 },
       
  3770 
       
  3771                 // ##### hookup
       
  3772                 // attach the provided `fragment` to `parentNode`
       
  3773 
       
  3774                 hookup: function(fragment, parentNode) {
       
  3775                     var hookupEls = [],
       
  3776                         id,
       
  3777                         func;
       
  3778 
       
  3779                     // Get all `childNodes`.
       
  3780                     can.each(fragment.childNodes ? can.makeArray(fragment.childNodes) : fragment, function(node) {
       
  3781                         if (node.nodeType === 1) {
       
  3782                             hookupEls.push(node);
       
  3783                             hookupEls.push.apply(hookupEls, can.makeArray(node.getElementsByTagName('*')));
       
  3784                         }
       
  3785                     });
       
  3786 
       
  3787                     // Filter by `data-view-id` attribute.
       
  3788                     can.each(hookupEls, function(el) {
       
  3789                         if (el.getAttribute && (id = el.getAttribute('data-view-id')) && (func = $view.hookups[id])) {
       
  3790                             func(el, parentNode, id);
       
  3791                             delete $view.hookups[id];
       
  3792                             el.removeAttribute('data-view-id');
       
  3793                         }
       
  3794                     });
       
  3795 
       
  3796                     return fragment;
       
  3797                 },
       
  3798 
       
  3799                 // `hookups` keeps list of pending hookups, ie fragments to attach to a parent node
       
  3800 
       
  3801                 hookups: {},
       
  3802 
       
  3803                 // `hook` factory method for hookup function inserted into templates
       
  3804                 // hookup functions are called after the html is rendered to the page
       
  3805                 // only implemented by EJS templates.
       
  3806 
       
  3807                 hook: function(cb) {
       
  3808                     $view.hookups[++hookupId] = cb;
       
  3809                     return ' data-view-id=\'' + hookupId + '\'';
       
  3810                 },
       
  3811 
       
  3812 
       
  3813                 cached: {},
       
  3814                 cachedRenderers: {},
       
  3815 
       
  3816                 // cache view templates resolved via XHR on the client
       
  3817 
       
  3818                 cache: true,
       
  3819 
       
  3820                 // ##### register
       
  3821                 // given an info object, register a template type
       
  3822                 // different templating solutions produce strings or document fragments via their renderer function
       
  3823 
       
  3824                 register: function(info) {
       
  3825                     this.types['.' + info.suffix] = info;
       
  3826 
       
  3827                     // _removed if not used as a steal module_
       
  3828 
       
  3829 
       
  3830 
       
  3831                     can[info.suffix] = $view[info.suffix] = function(id, text) {
       
  3832                         // If there is no text, assume id is the template text, so return a nameless renderer.
       
  3833                         if (!text) {
       
  3834                             // if the template has a fragRenderer already, just return that.
       
  3835                             if (info.fragRenderer) {
       
  3836                                 return info.fragRenderer(null, id);
       
  3837                             } else {
       
  3838                                 return makeRenderer(info.renderer(null, id));
       
  3839                             }
       
  3840 
       
  3841                         }
       
  3842                         if (info.fragRenderer) {
       
  3843                             return $view.preload(id, info.fragRenderer(id, text));
       
  3844                         } else {
       
  3845                             return $view.preloadStringRenderer(id, info.renderer(id, text));
       
  3846                         }
       
  3847 
       
  3848                     };
       
  3849 
       
  3850                 },
       
  3851 
       
  3852                 //registered view types
       
  3853                 types: {},
       
  3854 
       
  3855 
       
  3856                 ext: ".ejs",
       
  3857 
       
  3858 
       
  3859                 registerScript: function(type, id, src) {
       
  3860                     return 'can.view.preloadStringRenderer(\'' + id + '\',' + $view.types['.' + type].script(id, src) + ');';
       
  3861                 },
       
  3862 
       
  3863 
       
  3864                 preload: function(id, renderer) {
       
  3865                     var def = $view.cached[id] = new can.Deferred()
       
  3866                         .resolve(function(data, helpers) {
       
  3867                             return renderer.call(data, data, helpers);
       
  3868                         });
       
  3869 
       
  3870                     // set cache references (otherwise preloaded recursive views won't recurse properly)
       
  3871                     def.__view_id = id;
       
  3872                     $view.cachedRenderers[id] = renderer;
       
  3873 
       
  3874                     return renderer;
       
  3875                 },
       
  3876 
       
  3877 
       
  3878                 preloadStringRenderer: function(id, stringRenderer) {
       
  3879                     return this.preload(id, makeRenderer(stringRenderer));
       
  3880                 },
       
  3881 
       
  3882                 // #### renderers
       
  3883                 // ---------------
       
  3884                 // can.view's primary purpose is to load templates (from strings or filesystem) and render them
       
  3885                 // can.view supports two different forms of rendering systems
       
  3886                 // mustache templates return a string based rendering function
       
  3887 
       
  3888                 // stache (or other fragment based templating systems) return a document fragment, so 'hookup' steps are not required
       
  3889                 // ##### render
       
  3890                 //call `renderAs` with a hardcoded string, as view.render
       
  3891                 // always operates against resolved template files or hardcoded strings
       
  3892                 render: function(view, data, helpers, callback) {
       
  3893                     return can.view.renderAs("string", view, data, helpers, callback);
       
  3894                 },
       
  3895 
       
  3896                 // ##### renderTo
       
  3897                 renderTo: function(format, renderer, data, helpers) {
       
  3898                     return (format === "string" && renderer.render ? renderer.render : renderer)(data, helpers);
       
  3899                 },
       
  3900 
       
  3901 
       
  3902                 renderAs: function(format, view, data, helpers, callback) {
       
  3903                     // If helpers is a `function`, it is actually a callback.
       
  3904                     if (isFunction(helpers)) {
       
  3905                         callback = helpers;
       
  3906                         helpers = undefined;
       
  3907                     }
       
  3908 
       
  3909                     // See if we got passed any deferreds.
       
  3910                     var deferreds = getDeferreds(data);
       
  3911                     var reading, deferred, dataCopy, async, response;
       
  3912                     if (deferreds.length) {
       
  3913                         // Does data contain any deferreds?
       
  3914                         // The deferred that resolves into the rendered content...
       
  3915                         deferred = new can.Deferred();
       
  3916                         dataCopy = can.extend({}, data);
       
  3917 
       
  3918                         // Add the view request to the list of deferreds.
       
  3919                         deferreds.push(get(view, true));
       
  3920                         // Wait for the view and all deferreds to finish...
       
  3921                         can.when.apply(can, deferreds)
       
  3922                             .then(function(resolved) {
       
  3923                                 // Get all the resolved deferreds.
       
  3924                                 var objs = makeArray(arguments),
       
  3925                                     // Renderer is the last index of the data.
       
  3926                                     renderer = objs.pop(),
       
  3927                                     // The result of the template rendering with data.
       
  3928                                     result;
       
  3929 
       
  3930                                 // Make data look like the resolved deferreds.
       
  3931                                 if (can.isDeferred(data)) {
       
  3932                                     dataCopy = usefulPart(resolved);
       
  3933                                 } else {
       
  3934                                     // Go through each prop in data again and
       
  3935                                     // replace the defferreds with what they resolved to.
       
  3936                                     for (var prop in data) {
       
  3937                                         if (can.isDeferred(data[prop])) {
       
  3938                                             dataCopy[prop] = usefulPart(objs.shift());
       
  3939                                         }
       
  3940                                     }
       
  3941                                 }
       
  3942 
       
  3943                                 // Get the rendered result.
       
  3944                                 result = can.view.renderTo(format, renderer, dataCopy, helpers);
       
  3945 
       
  3946                                 // Resolve with the rendered view.
       
  3947                                 deferred.resolve(result, dataCopy);
       
  3948 
       
  3949                                 // If there's a `callback`, call it back with the result.
       
  3950                                 if (callback) {
       
  3951                                     callback(result, dataCopy);
       
  3952                                 }
       
  3953                             }, function() {
       
  3954                                 deferred.reject.apply(deferred, arguments);
       
  3955                             });
       
  3956                         // Return the deferred...
       
  3957                         return deferred;
       
  3958                     } else {
       
  3959                         // get is called async but in 
       
  3960                         // ff will be async so we need to temporarily reset
       
  3961                         reading = can.__clearReading();
       
  3962 
       
  3963                         // If there's a `callback` function
       
  3964                         async = isFunction(callback);
       
  3965                         // Get the `view` type
       
  3966                         deferred = get(view, async);
       
  3967 
       
  3968                         if (reading) {
       
  3969                             can.__setReading(reading);
       
  3970                         }
       
  3971 
       
  3972                         // If we are `async`...
       
  3973                         if (async) {
       
  3974                             // Return the deferred
       
  3975                             response = deferred;
       
  3976                             // And fire callback with the rendered result.
       
  3977                             deferred.then(function(renderer) {
       
  3978                                 callback(data ? can.view.renderTo(format, renderer, data, helpers) : renderer);
       
  3979                             });
       
  3980                         } else {
       
  3981                             // if the deferred is resolved, call the cached renderer instead
       
  3982                             // this is because it's possible, with recursive deferreds to
       
  3983                             // need to render a view while its deferred is _resolving_.  A _resolving_ deferred
       
  3984                             // is a deferred that was just resolved and is calling back it's success callbacks.
       
  3985                             // If a new success handler is called while resoliving, it does not get fired by
       
  3986                             // jQuery's deferred system.  So instead of adding a new callback
       
  3987                             // we use the cached renderer.
       
  3988                             // We also add __view_id on the deferred so we can look up it's cached renderer.
       
  3989                             // In the future, we might simply store either a deferred or the cached result.
       
  3990                             if (deferred.state() === 'resolved' && deferred.__view_id) {
       
  3991                                 var currentRenderer = $view.cachedRenderers[deferred.__view_id];
       
  3992                                 return data ? can.view.renderTo(format, currentRenderer, data, helpers) : currentRenderer;
       
  3993                             } else {
       
  3994                                 // Otherwise, the deferred is complete, so
       
  3995                                 // set response to the result of the rendering.
       
  3996                                 deferred.then(function(renderer) {
       
  3997                                     response = data ? can.view.renderTo(format, renderer, data, helpers) : renderer;
       
  3998                                 });
       
  3999                             }
       
  4000                         }
       
  4001 
       
  4002                         return response;
       
  4003                     }
       
  4004                 },
       
  4005 
       
  4006 
       
  4007                 registerView: function(id, text, type, def) {
       
  4008                     // Get the renderer function.
       
  4009                     var info = (typeof type === "object" ? type : $view.types[type || $view.ext]),
       
  4010                         renderer;
       
  4011                     if (info.fragRenderer) {
       
  4012                         renderer = info.fragRenderer(id, text);
       
  4013                     } else {
       
  4014                         renderer = makeRenderer(info.renderer(id, text));
       
  4015                     }
       
  4016 
       
  4017                     def = def || new can.Deferred();
       
  4018 
       
  4019                     // Cache if we are caching.
       
  4020                     if ($view.cache) {
       
  4021                         $view.cached[id] = def;
       
  4022                         def.__view_id = id;
       
  4023                         $view.cachedRenderers[id] = renderer;
       
  4024                     }
       
  4025 
       
  4026                     // Return the objects for the response's `dataTypes`
       
  4027                     // (in this case view).
       
  4028                     return def.resolve(renderer);
       
  4029                 }
       
  4030             });
       
  4031 
       
  4032         // _removed if not used as a steal module_
       
  4033 
       
  4034         return can;
       
  4035     })(__m3);
       
  4036 
       
  4037     // ## can/control/control.js
       
  4038     var __m18 = (function(can) {
       
  4039         // ### bind
       
  4040         // this helper binds to one element and returns a function that unbinds from that element.
       
  4041         var bind = function(el, ev, callback) {
       
  4042 
       
  4043             can.bind.call(el, ev, callback);
       
  4044 
       
  4045             return function() {
       
  4046                 can.unbind.call(el, ev, callback);
       
  4047             };
       
  4048         },
       
  4049             isFunction = can.isFunction,
       
  4050             extend = can.extend,
       
  4051             each = can.each,
       
  4052             slice = [].slice,
       
  4053             paramReplacer = /\{([^\}]+)\}/g,
       
  4054             special = can.getObject("$.event.special", [can]) || {},
       
  4055 
       
  4056             // ### delegate
       
  4057             // this helper binds to elements based on a selector and returns a 
       
  4058             // function that unbinds.
       
  4059             delegate = function(el, selector, ev, callback) {
       
  4060                 can.delegate.call(el, selector, ev, callback);
       
  4061                 return function() {
       
  4062                     can.undelegate.call(el, selector, ev, callback);
       
  4063                 };
       
  4064             },
       
  4065 
       
  4066             // ### binder
       
  4067             // Calls bind or unbind depending if there is a selector.
       
  4068             binder = function(el, ev, callback, selector) {
       
  4069                 return selector ?
       
  4070                     delegate(el, can.trim(selector), ev, callback) :
       
  4071                     bind(el, ev, callback);
       
  4072             },
       
  4073 
       
  4074             basicProcessor;
       
  4075 
       
  4076         var Control = can.Control = can.Construct(
       
  4077 
       
  4078             // ## *static functions*
       
  4079 
       
  4080             {
       
  4081                 // ## can.Control.setup
       
  4082                 // This function pre-processes which methods are event listeners and which are methods of
       
  4083                 // the control. It has a mechanism to allow controllers to inherit default values from super
       
  4084                 // classes, like `can.Construct`, and will cache functions that are action functions (see `_isAction`)
       
  4085                 // or functions with an underscored name.
       
  4086                 setup: function() {
       
  4087                     can.Construct.setup.apply(this, arguments);
       
  4088 
       
  4089                     if (can.Control) {
       
  4090                         var control = this,
       
  4091                             funcName;
       
  4092 
       
  4093                         control.actions = {};
       
  4094                         for (funcName in control.prototype) {
       
  4095                             if (control._isAction(funcName)) {
       
  4096                                 control.actions[funcName] = control._action(funcName);
       
  4097                             }
       
  4098                         }
       
  4099                     }
       
  4100                 },
       
  4101                 // ## can.Control._shifter
       
  4102                 // Moves `this` to the first argument, wraps it with `jQuery` if it's 
       
  4103                 // an element.
       
  4104                 _shifter: function(context, name) {
       
  4105 
       
  4106                     var method = typeof name === "string" ? context[name] : name;
       
  4107 
       
  4108                     if (!isFunction(method)) {
       
  4109                         method = context[method];
       
  4110                     }
       
  4111 
       
  4112                     return function() {
       
  4113                         context.called = name;
       
  4114                         return method.apply(context, [this.nodeName ? can.$(this) : this].concat(slice.call(arguments, 0)));
       
  4115                     };
       
  4116                 },
       
  4117 
       
  4118                 // ## can.Control._isAction
       
  4119                 // Return `true` if `methodName` refers to an action. An action is a `methodName` value that
       
  4120                 // is not the constructor, and is either a function or string that refers to a function, or is
       
  4121                 // defined in `special`, `processors`. Detects whether `methodName` is also a valid method name.
       
  4122                 _isAction: function(methodName) {
       
  4123                     var val = this.prototype[methodName],
       
  4124                         type = typeof val;
       
  4125 
       
  4126                     return (methodName !== 'constructor') &&
       
  4127                     (type === "function" || (type === "string" && isFunction(this.prototype[val]))) && !! (special[methodName] || processors[methodName] || /[^\w]/.test(methodName));
       
  4128                 },
       
  4129                 // ## can.Control._action
       
  4130                 // Takes a method name and the options passed to a control and tries to return the data 
       
  4131                 // necessary to pass to a processor (something that binds things).
       
  4132                 // For performance reasons, `_action` is called twice: 
       
  4133                 // * It's called when the Control class is created. for templated method names (e.g., `{window} foo`), it returns null. For non-templated method names it returns the event binding data. That data is added to `this.actions`.
       
  4134                 // * It is called wehn a control instance is created, but only for templated actions.
       
  4135                 _action: function(methodName, options) {
       
  4136 
       
  4137                     // If we don't have options (a `control` instance), we'll run this later. If we have
       
  4138                     // options, run `can.sub` to replace the action template `{}` with values from the `options`
       
  4139                     // or `window`. If a `{}` template resolves to an object, `convertedName` will be an array.
       
  4140                     // In that case, the event name we want will be the last item in that array.
       
  4141                     paramReplacer.lastIndex = 0;
       
  4142                     if (options || !paramReplacer.test(methodName)) {
       
  4143                         var convertedName = options ? can.sub(methodName, this._lookup(options)) : methodName;
       
  4144                         if (!convertedName) {
       
  4145 
       
  4146                             return null;
       
  4147                         }
       
  4148                         var arr = can.isArray(convertedName),
       
  4149                             name = arr ? convertedName[1] : convertedName,
       
  4150                             parts = name.split(/\s+/g),
       
  4151                             event = parts.pop();
       
  4152 
       
  4153                         return {
       
  4154                             processor: processors[event] || basicProcessor,
       
  4155                             parts: [name, parts.join(" "), event],
       
  4156                             delegate: arr ? convertedName[0] : undefined
       
  4157                         };
       
  4158                     }
       
  4159                 },
       
  4160                 _lookup: function(options) {
       
  4161                     return [options, window];
       
  4162                 },
       
  4163                 // ## can.Control.processors
       
  4164                 // An object of `{eventName : function}` pairs that Control uses to 
       
  4165                 // hook up events automatically.
       
  4166                 processors: {},
       
  4167                 // ## can.Control.defaults
       
  4168                 // A object of name-value pairs that act as default values for a control instance
       
  4169                 defaults: {}
       
  4170             }, {
       
  4171                 // ## *prototype functions*
       
  4172 
       
  4173                 // ## setup
       
  4174                 // Setup is where most of the Control's magic happens. It performs several pre-initialization steps:
       
  4175                 // - Sets `this.element`
       
  4176                 // - Adds the Control's name to the element's className
       
  4177                 // - Saves the Control in `$.data`
       
  4178                 // - Merges Options
       
  4179                 // - Binds event handlers using `delegate`
       
  4180                 // The final step is to return pass the element and prepareed options, to be used in `init`.
       
  4181                 setup: function(element, options) {
       
  4182 
       
  4183                     var cls = this.constructor,
       
  4184                         pluginname = cls.pluginName || cls._fullName,
       
  4185                         arr;
       
  4186 
       
  4187                     // Retrieve the raw element, then set the plugin name as a class there.
       
  4188                     this.element = can.$(element);
       
  4189 
       
  4190                     if (pluginname && pluginname !== 'can_control') {
       
  4191                         this.element.addClass(pluginname);
       
  4192                     }
       
  4193 
       
  4194                     // Set up the 'controls' data on the element. If it does not exist, initialize
       
  4195                     // it to an empty array.
       
  4196                     arr = can.data(this.element, 'controls');
       
  4197                     if (!arr) {
       
  4198                         arr = [];
       
  4199                         can.data(this.element, 'controls', arr);
       
  4200                     }
       
  4201                     arr.push(this);
       
  4202 
       
  4203                     // The `this.options` property is an Object that contains configuration data
       
  4204                     // passed to a control when it is created (`new can.Control(element, options)`)
       
  4205                     // The `options` argument passed when creating the control is merged with `can.Control.defaults` 
       
  4206                     // in [can.Control.prototype.setup setup].
       
  4207                     // If no `options` value is used during creation, the value in `defaults` is used instead
       
  4208                     this.options = extend({}, cls.defaults, options);
       
  4209 
       
  4210                     this.on();
       
  4211 
       
  4212                     return [this.element, this.options];
       
  4213                 },
       
  4214                 // ## on
       
  4215                 // This binds an event handler for an event to a selector under the scope of `this.element`
       
  4216                 // If no options are specified, all events are rebound to their respective elements. The actions,
       
  4217                 // which were cached in `setup`, are used and all elements are bound using `delegate` from `this.element`.
       
  4218                 on: function(el, selector, eventName, func) {
       
  4219                     if (!el) {
       
  4220                         this.off();
       
  4221 
       
  4222                         var cls = this.constructor,
       
  4223                             bindings = this._bindings,
       
  4224                             actions = cls.actions,
       
  4225                             element = this.element,
       
  4226                             destroyCB = can.Control._shifter(this, "destroy"),
       
  4227                             funcName, ready;
       
  4228 
       
  4229                         for (funcName in actions) {
       
  4230                             // Only push if we have the action and no option is `undefined`
       
  4231                             if (actions.hasOwnProperty(funcName)) {
       
  4232                                 ready = actions[funcName] || cls._action(funcName, this.options, this);
       
  4233                                 if (ready) {
       
  4234                                     bindings.control[funcName] = ready.processor(ready.delegate || element,
       
  4235                                         ready.parts[2], ready.parts[1], funcName, this);
       
  4236                                 }
       
  4237                             }
       
  4238                         }
       
  4239 
       
  4240                         // Set up the ability to `destroy` the control later.
       
  4241                         can.bind.call(element, "removed", destroyCB);
       
  4242                         bindings.user.push(function(el) {
       
  4243                             can.unbind.call(el, "removed", destroyCB);
       
  4244                         });
       
  4245                         return bindings.user.length;
       
  4246                     }
       
  4247 
       
  4248                     // if `el` is a string, use that as `selector` and re-set it to this control's element...
       
  4249                     if (typeof el === 'string') {
       
  4250                         func = eventName;
       
  4251                         eventName = selector;
       
  4252                         selector = el;
       
  4253                         el = this.element;
       
  4254                     }
       
  4255 
       
  4256                     // ...otherwise, set `selector` to null
       
  4257                     if (func === undefined) {
       
  4258                         func = eventName;
       
  4259                         eventName = selector;
       
  4260                         selector = null;
       
  4261                     }
       
  4262 
       
  4263                     if (typeof func === 'string') {
       
  4264                         func = can.Control._shifter(this, func);
       
  4265                     }
       
  4266 
       
  4267                     this._bindings.user.push(binder(el, eventName, func, selector));
       
  4268 
       
  4269                     return this._bindings.user.length;
       
  4270                 },
       
  4271                 // ## off
       
  4272                 // Unbinds all event handlers on the controller.
       
  4273                 // This should _only_ be called in combination with .on()
       
  4274                 off: function() {
       
  4275                     var el = this.element[0],
       
  4276                         bindings = this._bindings;
       
  4277                     if (bindings) {
       
  4278                         each(bindings.user || [], function(value) {
       
  4279                             value(el);
       
  4280                         });
       
  4281                         each(bindings.control || {}, function(value) {
       
  4282                             value(el);
       
  4283                         });
       
  4284                     }
       
  4285                     // Adds bindings.
       
  4286                     this._bindings = {
       
  4287                         user: [],
       
  4288                         control: {}
       
  4289                     };
       
  4290                 },
       
  4291                 // ## destroy
       
  4292                 // Prepares a `control` for garbage collection.
       
  4293                 // First checks if it has already been removed. Then, removes all the bindings, data, and 
       
  4294                 // the element from the Control instance.
       
  4295                 destroy: function() {
       
  4296                     if (this.element === null) {
       
  4297 
       
  4298                         return;
       
  4299                     }
       
  4300                     var Class = this.constructor,
       
  4301                         pluginName = Class.pluginName || Class._fullName,
       
  4302                         controls;
       
  4303 
       
  4304                     this.off();
       
  4305 
       
  4306                     if (pluginName && pluginName !== 'can_control') {
       
  4307                         this.element.removeClass(pluginName);
       
  4308                     }
       
  4309 
       
  4310                     controls = can.data(this.element, "controls");
       
  4311                     controls.splice(can.inArray(this, controls), 1);
       
  4312 
       
  4313                     can.trigger(this, "destroyed");
       
  4314 
       
  4315                     this.element = null;
       
  4316                 }
       
  4317             });
       
  4318 
       
  4319         // ## Processors
       
  4320         // Processors do the binding. This basic processor binds events. Each returns a function that unbinds 
       
  4321         // when called.
       
  4322         var processors = can.Control.processors;
       
  4323         basicProcessor = function(el, event, selector, methodName, control) {
       
  4324             return binder(el, event, can.Control._shifter(control, methodName), selector);
       
  4325         };
       
  4326 
       
  4327         // Set common events to be processed as a `basicProcessor`
       
  4328         each(["change", "click", "contextmenu", "dblclick", "keydown", "keyup",
       
  4329                 "keypress", "mousedown", "mousemove", "mouseout", "mouseover",
       
  4330                 "mouseup", "reset", "resize", "scroll", "select", "submit", "focusin",
       
  4331                 "focusout", "mouseenter", "mouseleave",
       
  4332                 "touchstart", "touchmove", "touchcancel", "touchend", "touchleave",
       
  4333                 "inserted", "removed"
       
  4334             ], function(v) {
       
  4335                 processors[v] = basicProcessor;
       
  4336             });
       
  4337 
       
  4338         return Control;
       
  4339     })(__m3, __m1);
       
  4340 
       
  4341     // ## can/util/string/deparam/deparam.js
       
  4342     var __m20 = (function(can) {
       
  4343         // ## deparam.js  
       
  4344         // `can.deparam`  
       
  4345         // _Takes a string of name value pairs and returns a Object literal that represents those params._
       
  4346         var digitTest = /^\d+$/,
       
  4347             keyBreaker = /([^\[\]]+)|(\[\])/g,
       
  4348             paramTest = /([^?#]*)(#.*)?$/,
       
  4349             prep = function(str) {
       
  4350                 return decodeURIComponent(str.replace(/\+/g, ' '));
       
  4351             };
       
  4352         can.extend(can, {
       
  4353                 deparam: function(params) {
       
  4354                     var data = {}, pairs, lastPart;
       
  4355                     if (params && paramTest.test(params)) {
       
  4356                         pairs = params.split('&');
       
  4357                         can.each(pairs, function(pair) {
       
  4358                             var parts = pair.split('='),
       
  4359                                 key = prep(parts.shift()),
       
  4360                                 value = prep(parts.join('=')),
       
  4361                                 current = data;
       
  4362                             if (key) {
       
  4363                                 parts = key.match(keyBreaker);
       
  4364                                 for (var j = 0, l = parts.length - 1; j < l; j++) {
       
  4365                                     if (!current[parts[j]]) {
       
  4366                                         // If what we are pointing to looks like an `array`
       
  4367                                         current[parts[j]] = digitTest.test(parts[j + 1]) || parts[j + 1] === '[]' ? [] : {};
       
  4368                                     }
       
  4369                                     current = current[parts[j]];
       
  4370                                 }
       
  4371                                 lastPart = parts.pop();
       
  4372                                 if (lastPart === '[]') {
       
  4373                                     current.push(value);
       
  4374                                 } else {
       
  4375                                     current[lastPart] = value;
       
  4376                                 }
       
  4377                             }
       
  4378                         });
       
  4379                     }
       
  4380                     return data;
       
  4381                 }
       
  4382             });
       
  4383         return can;
       
  4384     })(__m3, __m2);
       
  4385 
       
  4386     // ## can/route/route.js
       
  4387     var __m19 = (function(can) {
       
  4388 
       
  4389         // ## route.js
       
  4390         // `can.route`
       
  4391         // _Helps manage browser history (and client state) by synchronizing the
       
  4392         // `window.location.hash` with a `can.Map`._
       
  4393         // Helper methods used for matching routes.
       
  4394         var
       
  4395         // `RegExp` used to match route variables of the type ':name'.
       
  4396         // Any word character or a period is matched.
       
  4397         matcher = /\:([\w\.]+)/g,
       
  4398             // Regular expression for identifying &amp;key=value lists.
       
  4399             paramsMatcher = /^(?:&[^=]+=[^&]*)+/,
       
  4400             // Converts a JS Object into a list of parameters that can be
       
  4401             // inserted into an html element tag.
       
  4402             makeProps = function(props) {
       
  4403                 var tags = [];
       
  4404                 can.each(props, function(val, name) {
       
  4405                     tags.push((name === 'className' ? 'class' : name) + '="' +
       
  4406                         (name === "href" ? val : can.esc(val)) + '"');
       
  4407                 });
       
  4408                 return tags.join(" ");
       
  4409             },
       
  4410             // Checks if a route matches the data provided. If any route variable
       
  4411             // is not present in the data, the route does not match. If all route
       
  4412             // variables are present in the data, the number of matches is returned
       
  4413             // to allow discerning between general and more specific routes.
       
  4414             matchesData = function(route, data) {
       
  4415                 var count = 0,
       
  4416                     i = 0,
       
  4417                     defaults = {};
       
  4418                 // look at default values, if they match ...
       
  4419                 for (var name in route.defaults) {
       
  4420                     if (route.defaults[name] === data[name]) {
       
  4421                         // mark as matched
       
  4422                         defaults[name] = 1;
       
  4423                         count++;
       
  4424                     }
       
  4425                 }
       
  4426                 for (; i < route.names.length; i++) {
       
  4427                     if (!data.hasOwnProperty(route.names[i])) {
       
  4428                         return -1;
       
  4429                     }
       
  4430                     if (!defaults[route.names[i]]) {
       
  4431                         count++;
       
  4432                     }
       
  4433 
       
  4434                 }
       
  4435 
       
  4436                 return count;
       
  4437             },
       
  4438             location = window.location,
       
  4439             wrapQuote = function(str) {
       
  4440                 return (str + '')
       
  4441                     .replace(/([.?*+\^$\[\]\\(){}|\-])/g, "\\$1");
       
  4442             },
       
  4443             each = can.each,
       
  4444             extend = can.extend,
       
  4445             // Helper for convert any object (or value) to stringified object (or value)
       
  4446             stringify = function(obj) {
       
  4447                 // Object is array, plain object, Map or List
       
  4448                 if (obj && typeof obj === "object") {
       
  4449                     // Get native object or array from Map or List
       
  4450                     if (obj instanceof can.Map) {
       
  4451                         obj = obj.attr();
       
  4452                         // Clone object to prevent change original values
       
  4453                     } else {
       
  4454                         obj = can.isFunction(obj.slice) ? obj.slice() : can.extend({}, obj);
       
  4455                     }
       
  4456                     // Convert each object property or array item into stringified new
       
  4457                     can.each(obj, function(val, prop) {
       
  4458                         obj[prop] = stringify(val);
       
  4459                     });
       
  4460                     // Object supports toString function
       
  4461                 } else if (obj !== undefined && obj !== null && can.isFunction(obj.toString)) {
       
  4462                     obj = obj.toString();
       
  4463                 }
       
  4464 
       
  4465                 return obj;
       
  4466             },
       
  4467             removeBackslash = function(str) {
       
  4468                 return str.replace(/\\/g, "");
       
  4469             },
       
  4470             // A ~~throttled~~ debounced function called multiple times will only fire once the
       
  4471             // timer runs down. Each call resets the timer.
       
  4472             timer,
       
  4473             // Intermediate storage for `can.route.data`.
       
  4474             curParams,
       
  4475             // The last hash caused by a data change
       
  4476             lastHash,
       
  4477             // Are data changes pending that haven't yet updated the hash
       
  4478             changingData,
       
  4479             // If the `can.route.data` changes, update the hash.
       
  4480             // Using `.serialize()` retrieves the raw data contained in the `observable`.
       
  4481             // This function is ~~throttled~~ debounced so it only updates once even if multiple values changed.
       
  4482             // This might be able to use batchNum and avoid this.
       
  4483             onRouteDataChange = function(ev, attr, how, newval) {
       
  4484                 // indicate that data is changing
       
  4485                 changingData = 1;
       
  4486                 clearTimeout(timer);
       
  4487                 timer = setTimeout(function() {
       
  4488                     // indicate that the hash is set to look like the data
       
  4489                     changingData = 0;
       
  4490                     var serialized = can.route.data.serialize(),
       
  4491                         path = can.route.param(serialized, true);
       
  4492                     can.route._call("setURL", path);
       
  4493 
       
  4494                     lastHash = path;
       
  4495                 }, 10);
       
  4496             };
       
  4497 
       
  4498         can.route = function(url, defaults) {
       
  4499             // if route ends with a / and url starts with a /, remove the leading / of the url
       
  4500             var root = can.route._call("root");
       
  4501 
       
  4502             if (root.lastIndexOf("/") === root.length - 1 &&
       
  4503                 url.indexOf("/") === 0) {
       
  4504                 url = url.substr(1);
       
  4505             }
       
  4506 
       
  4507             defaults = defaults || {};
       
  4508             // Extract the variable names and replace with `RegExp` that will match
       
  4509             // an atual URL with values.
       
  4510             var names = [],
       
  4511                 res,
       
  4512                 test = "",
       
  4513                 lastIndex = matcher.lastIndex = 0,
       
  4514                 next,
       
  4515                 querySeparator = can.route._call("querySeparator");
       
  4516 
       
  4517             // res will be something like [":foo","foo"]
       
  4518             while (res = matcher.exec(url)) {
       
  4519                 names.push(res[1]);
       
  4520                 test += removeBackslash(url.substring(lastIndex, matcher.lastIndex - res[0].length));
       
  4521                 next = "\\" + (removeBackslash(url.substr(matcher.lastIndex, 1)) || querySeparator);
       
  4522                 // a name without a default value HAS to have a value
       
  4523                 // a name that has a default value can be empty
       
  4524                 // The `\\` is for string-escaping giving single `\` for `RegExp` escaping.
       
  4525                 test += "([^" + next + "]" + (defaults[res[1]] ? "*" : "+") + ")";
       
  4526                 lastIndex = matcher.lastIndex;
       
  4527             }
       
  4528             test += url.substr(lastIndex)
       
  4529                 .replace("\\", "");
       
  4530             // Add route in a form that can be easily figured out.
       
  4531             can.route.routes[url] = {
       
  4532                 // A regular expression that will match the route when variable values
       
  4533                 // are present; i.e. for `:page/:type` the `RegExp` is `/([\w\.]*)/([\w\.]*)/` which
       
  4534                 // will match for any value of `:page` and `:type` (word chars or period).
       
  4535                 test: new RegExp("^" + test + "($|" + wrapQuote(querySeparator) + ")"),
       
  4536                 // The original URL, same as the index for this entry in routes.
       
  4537                 route: url,
       
  4538                 // An `array` of all the variable names in this route.
       
  4539                 names: names,
       
  4540                 // Default values provided for the variables.
       
  4541                 defaults: defaults,
       
  4542                 // The number of parts in the URL separated by `/`.
       
  4543                 length: url.split('/')
       
  4544                     .length
       
  4545             };
       
  4546             return can.route;
       
  4547         };
       
  4548 
       
  4549 
       
  4550         extend(can.route, {
       
  4551 
       
  4552 
       
  4553                 param: function(data, _setRoute) {
       
  4554                     // Check if the provided data keys match the names in any routes;
       
  4555                     // Get the one with the most matches.
       
  4556                     var route,
       
  4557                         // Need to have at least 1 match.
       
  4558                         matches = 0,
       
  4559                         matchCount,
       
  4560                         routeName = data.route,
       
  4561                         propCount = 0;
       
  4562 
       
  4563                     delete data.route;
       
  4564 
       
  4565                     each(data, function() {
       
  4566                         propCount++;
       
  4567                     });
       
  4568                     // Otherwise find route.
       
  4569                     each(can.route.routes, function(temp, name) {
       
  4570                         // best route is the first with all defaults matching
       
  4571 
       
  4572                         matchCount = matchesData(temp, data);
       
  4573                         if (matchCount > matches) {
       
  4574                             route = temp;
       
  4575                             matches = matchCount;
       
  4576                         }
       
  4577                         if (matchCount >= propCount) {
       
  4578                             return false;
       
  4579                         }
       
  4580                     });
       
  4581                     // If we have a route name in our `can.route` data, and it's
       
  4582                     // just as good as what currently matches, use that
       
  4583                     if (can.route.routes[routeName] && matchesData(can.route.routes[routeName], data) === matches) {
       
  4584                         route = can.route.routes[routeName];
       
  4585                     }
       
  4586                     // If this is match...
       
  4587                     if (route) {
       
  4588                         var cpy = extend({}, data),
       
  4589                             // Create the url by replacing the var names with the provided data.
       
  4590                             // If the default value is found an empty string is inserted.
       
  4591                             res = route.route.replace(matcher, function(whole, name) {
       
  4592                                 delete cpy[name];
       
  4593                                 return data[name] === route.defaults[name] ? "" : encodeURIComponent(data[name]);
       
  4594                             })
       
  4595                                 .replace("\\", ""),
       
  4596                             after;
       
  4597                         // Remove matching default values
       
  4598                         each(route.defaults, function(val, name) {
       
  4599                             if (cpy[name] === val) {
       
  4600                                 delete cpy[name];
       
  4601                             }
       
  4602                         });
       
  4603 
       
  4604                         // The remaining elements of data are added as
       
  4605                         // `&amp;` separated parameters to the url.
       
  4606                         after = can.param(cpy);
       
  4607                         // if we are paraming for setting the hash
       
  4608                         // we also want to make sure the route value is updated
       
  4609                         if (_setRoute) {
       
  4610                             can.route.attr('route', route.route);
       
  4611                         }
       
  4612                         return res + (after ? can.route._call("querySeparator") + after : "");
       
  4613                     }
       
  4614                     // If no route was found, there is no hash URL, only paramters.
       
  4615                     return can.isEmptyObject(data) ? "" : can.route._call("querySeparator") + can.param(data);
       
  4616                 },
       
  4617 
       
  4618                 deparam: function(url) {
       
  4619 
       
  4620                     // remove the url
       
  4621                     var root = can.route._call("root");
       
  4622                     if (root.lastIndexOf("/") === root.length - 1 &&
       
  4623                         url.indexOf("/") === 0) {
       
  4624                         url = url.substr(1);
       
  4625                     }
       
  4626 
       
  4627                     // See if the url matches any routes by testing it against the `route.test` `RegExp`.
       
  4628                     // By comparing the URL length the most specialized route that matches is used.
       
  4629                     var route = {
       
  4630                         length: -1
       
  4631                     },
       
  4632                         querySeparator = can.route._call("querySeparator"),
       
  4633                         paramsMatcher = can.route._call("paramsMatcher");
       
  4634 
       
  4635                     each(can.route.routes, function(temp, name) {
       
  4636                         if (temp.test.test(url) && temp.length > route.length) {
       
  4637                             route = temp;
       
  4638                         }
       
  4639                     });
       
  4640                     // If a route was matched.
       
  4641                     if (route.length > -1) {
       
  4642 
       
  4643                         var // Since `RegExp` backreferences are used in `route.test` (parens)
       
  4644                         // the parts will contain the full matched string and each variable (back-referenced) value.
       
  4645                         parts = url.match(route.test),
       
  4646                             // Start will contain the full matched string; parts contain the variable values.
       
  4647                             start = parts.shift(),
       
  4648                             // The remainder will be the `&amp;key=value` list at the end of the URL.
       
  4649                             remainder = url.substr(start.length - (parts[parts.length - 1] === querySeparator ? 1 : 0)),
       
  4650                             // If there is a remainder and it contains a `&amp;key=value` list deparam it.
       
  4651                             obj = (remainder && paramsMatcher.test(remainder)) ? can.deparam(remainder.slice(1)) : {};
       
  4652 
       
  4653                         // Add the default values for this route.
       
  4654                         obj = extend(true, {}, route.defaults, obj);
       
  4655                         // Overwrite each of the default values in `obj` with those in
       
  4656                         // parts if that part is not empty.
       
  4657                         each(parts, function(part, i) {
       
  4658                             if (part && part !== querySeparator) {
       
  4659                                 obj[route.names[i]] = decodeURIComponent(part);
       
  4660                             }
       
  4661                         });
       
  4662                         obj.route = route.route;
       
  4663                         return obj;
       
  4664                     }
       
  4665                     // If no route was matched, it is parsed as a `&amp;key=value` list.
       
  4666                     if (url.charAt(0) !== querySeparator) {
       
  4667                         url = querySeparator + url;
       
  4668                     }
       
  4669                     return paramsMatcher.test(url) ? can.deparam(url.slice(1)) : {};
       
  4670                 },
       
  4671 
       
  4672                 data: new can.Map({}),
       
  4673                 map: function(data) {
       
  4674                     var appState;
       
  4675                     // appState is a can.Map constructor function
       
  4676                     if (data.prototype instanceof can.Map) {
       
  4677                         appState = new data();
       
  4678                     }
       
  4679                     // appState is an instance of can.Map
       
  4680                     else {
       
  4681                         appState = data;
       
  4682                     }
       
  4683                     can.route.data = appState;
       
  4684                 },
       
  4685 
       
  4686                 routes: {},
       
  4687 
       
  4688                 ready: function(val) {
       
  4689                     if (val !== true) {
       
  4690                         can.route._setup();
       
  4691                         can.route.setState();
       
  4692                     }
       
  4693                     return can.route;
       
  4694                 },
       
  4695 
       
  4696                 url: function(options, merge) {
       
  4697 
       
  4698                     if (merge) {
       
  4699                         options = can.extend({}, can.route.deparam(can.route._call("matchingPartOfURL")), options);
       
  4700                     }
       
  4701                     return can.route._call("root") + can.route.param(options);
       
  4702                 },
       
  4703 
       
  4704                 link: function(name, options, props, merge) {
       
  4705                     return "<a " + makeProps(
       
  4706                         extend({
       
  4707                                 href: can.route.url(options, merge)
       
  4708                             }, props)) + ">" + name + "</a>";
       
  4709                 },
       
  4710 
       
  4711                 current: function(options) {
       
  4712                     return this._call("matchingPartOfURL") === can.route.param(options);
       
  4713                 },
       
  4714                 bindings: {
       
  4715                     hashchange: {
       
  4716                         paramsMatcher: paramsMatcher,
       
  4717                         querySeparator: "&",
       
  4718                         bind: function() {
       
  4719                             can.bind.call(window, 'hashchange', setState);
       
  4720                         },
       
  4721                         unbind: function() {
       
  4722                             can.unbind.call(window, 'hashchange', setState);
       
  4723                         },
       
  4724                         // Gets the part of the url we are determinging the route from.
       
  4725                         // For hashbased routing, it's everything after the #, for
       
  4726                         // pushState it's configurable
       
  4727                         matchingPartOfURL: function() {
       
  4728                             return location.href.split(/#!?/)[1] || "";
       
  4729                         },
       
  4730                         // gets called with the serialized can.route data after a route has changed
       
  4731                         // returns what the url has been updated to (for matching purposes)
       
  4732                         setURL: function(path) {
       
  4733                             location.hash = "#!" + path;
       
  4734                             return path;
       
  4735                         },
       
  4736                         root: "#!"
       
  4737                     }
       
  4738                 },
       
  4739                 defaultBinding: "hashchange",
       
  4740                 currentBinding: null,
       
  4741                 // ready calls setup
       
  4742                 // setup binds and listens to data changes
       
  4743                 // bind listens to whatever you should be listening to
       
  4744                 // data changes tries to set the path
       
  4745 
       
  4746                 // we need to be able to
       
  4747                 // easily kick off calling setState
       
  4748                 // 	teardown whatever is there
       
  4749                 //  turn on a particular binding
       
  4750 
       
  4751                 // called when the route is ready
       
  4752                 _setup: function() {
       
  4753                     if (!can.route.currentBinding) {
       
  4754                         can.route._call("bind");
       
  4755                         can.route.bind("change", onRouteDataChange);
       
  4756                         can.route.currentBinding = can.route.defaultBinding;
       
  4757                     }
       
  4758                 },
       
  4759                 _teardown: function() {
       
  4760                     if (can.route.currentBinding) {
       
  4761                         can.route._call("unbind");
       
  4762                         can.route.unbind("change", onRouteDataChange);
       
  4763                         can.route.currentBinding = null;
       
  4764                     }
       
  4765                     clearTimeout(timer);
       
  4766                     changingData = 0;
       
  4767                 },
       
  4768                 // a helper to get stuff from the current or default bindings
       
  4769                 _call: function() {
       
  4770                     var args = can.makeArray(arguments),
       
  4771                         prop = args.shift(),
       
  4772                         binding = can.route.bindings[can.route.currentBinding || can.route.defaultBinding],
       
  4773                         method = binding[prop];
       
  4774                     if (method.apply) {
       
  4775                         return method.apply(binding, args);
       
  4776                     } else {
       
  4777                         return method;
       
  4778                     }
       
  4779                 }
       
  4780             });
       
  4781 
       
  4782         // The functions in the following list applied to `can.route` (e.g. `can.route.attr('...')`) will
       
  4783         // instead act on the `can.route.data` observe.
       
  4784         each(['bind', 'unbind', 'on', 'off', 'delegate', 'undelegate', 'removeAttr', 'compute', '_get', '__get'], function(name) {
       
  4785             can.route[name] = function() {
       
  4786                 // `delegate` and `undelegate` require
       
  4787                 // the `can/map/delegate` plugin
       
  4788                 if (!can.route.data[name]) {
       
  4789                     return;
       
  4790                 }
       
  4791 
       
  4792                 return can.route.data[name].apply(can.route.data, arguments);
       
  4793             };
       
  4794         });
       
  4795 
       
  4796         // Because everything in hashbang is in fact a string this will automaticaly convert new values to string. Works with single value, or deep hashes.
       
  4797         // Main motivation for this is to prevent double route event call for same value.
       
  4798         // Example (the problem):
       
  4799         // When you load page with hashbang like #!&some_number=2 and bind 'some_number' on routes.
       
  4800         // It will fire event with adding of "2" (string) to 'some_number' property
       
  4801         // But when you after this set can.route.attr({some_number: 2}) or can.route.attr('some_number', 2). it fires another event with change of 'some_number' from "2" (string) to 2 (integer)
       
  4802         // This wont happen again with this normalization
       
  4803         can.route.attr = function(attr, val) {
       
  4804             var type = typeof attr,
       
  4805                 newArguments;
       
  4806 
       
  4807             // Reading
       
  4808             if (val === undefined) {
       
  4809                 newArguments = arguments;
       
  4810                 // Sets object
       
  4811             } else if (type !== "string" && type !== "number") {
       
  4812                 newArguments = [stringify(attr), val];
       
  4813                 // Sets key - value
       
  4814             } else {
       
  4815                 newArguments = [attr, stringify(val)];
       
  4816             }
       
  4817 
       
  4818             return can.route.data.attr.apply(can.route.data, newArguments);
       
  4819         };
       
  4820 
       
  4821         var // Deparameterizes the portion of the hash of interest and assign the
       
  4822         // values to the `can.route.data` removing existing values no longer in the hash.
       
  4823         // setState is called typically by hashchange which fires asynchronously
       
  4824         // So it's possible that someone started changing the data before the
       
  4825         // hashchange event fired.  For this reason, it will not set the route data
       
  4826         // if the data is changing or the hash already matches the hash that was set.
       
  4827         setState = can.route.setState = function() {
       
  4828             var hash = can.route._call("matchingPartOfURL");
       
  4829             var oldParams = curParams;
       
  4830             curParams = can.route.deparam(hash);
       
  4831 
       
  4832             // if the hash data is currently changing, or
       
  4833             // the hash is what we set it to anyway, do NOT change the hash
       
  4834             if (!changingData || hash !== lastHash) {
       
  4835                 can.batch.start();
       
  4836                 for (var attr in oldParams) {
       
  4837                     if (!curParams[attr]) {
       
  4838                         can.route.removeAttr(attr);
       
  4839                     }
       
  4840                 }
       
  4841                 can.route.attr(curParams);
       
  4842                 can.batch.stop();
       
  4843             }
       
  4844         };
       
  4845 
       
  4846         return can.route;
       
  4847     })(__m3, __m10, __m14, __m20);
       
  4848 
       
  4849     // ## can/control/route/route.js
       
  4850     var __m21 = (function(can) {
       
  4851 
       
  4852         // ## control/route.js
       
  4853         // _Controller route integration._
       
  4854 
       
  4855         can.Control.processors.route = function(el, event, selector, funcName, controller) {
       
  4856             selector = selector || "";
       
  4857             if (!can.route.routes[selector]) {
       
  4858                 if (selector[0] === '/') {
       
  4859                     selector = selector.substring(1);
       
  4860                 }
       
  4861                 can.route(selector);
       
  4862             }
       
  4863             var batchNum,
       
  4864                 check = function(ev, attr, how) {
       
  4865                     if (can.route.attr('route') === (selector) &&
       
  4866                         (ev.batchNum === undefined || ev.batchNum !== batchNum)) {
       
  4867 
       
  4868                         batchNum = ev.batchNum;
       
  4869 
       
  4870                         var d = can.route.attr();
       
  4871                         delete d.route;
       
  4872                         if (can.isFunction(controller[funcName])) {
       
  4873                             controller[funcName](d);
       
  4874                         } else {
       
  4875                             controller[controller[funcName]](d);
       
  4876                         }
       
  4877 
       
  4878                     }
       
  4879                 };
       
  4880             can.route.bind('change', check);
       
  4881             return function() {
       
  4882                 can.route.unbind('change', check);
       
  4883             };
       
  4884         };
       
  4885 
       
  4886         return can;
       
  4887     })(__m3, __m19, __m18);
       
  4888 
       
  4889     // ## can/view/elements.js
       
  4890     var __m24 = (function(can) {
       
  4891 
       
  4892         var selectsCommentNodes = (function() {
       
  4893             return can.$(document.createComment('~')).length === 1;
       
  4894         })();
       
  4895 
       
  4896 
       
  4897         var elements = {
       
  4898             tagToContentPropMap: {
       
  4899                 option: 'textContent' in document.createElement('option') ? 'textContent' : 'innerText',
       
  4900                 textarea: 'value'
       
  4901             },
       
  4902 
       
  4903             // 3.0 TODO: remove
       
  4904             attrMap: can.attr.map,
       
  4905             // matches the attrName of a regexp
       
  4906             attrReg: /([^\s=]+)[\s]*=[\s]*/,
       
  4907             // 3.0 TODO: remove
       
  4908             defaultValue: can.attr.defaultValue,
       
  4909             // a map of parent element to child elements
       
  4910 
       
  4911             tagMap: {
       
  4912                 '': 'span',
       
  4913                 table: 'tbody',
       
  4914                 tr: 'td',
       
  4915                 ol: 'li',
       
  4916                 ul: 'li',
       
  4917                 tbody: 'tr',
       
  4918                 thead: 'tr',
       
  4919                 tfoot: 'tr',
       
  4920                 select: 'option',
       
  4921                 optgroup: 'option'
       
  4922             },
       
  4923             // a tag's parent element
       
  4924             reverseTagMap: {
       
  4925                 tr: 'tbody',
       
  4926                 option: 'select',
       
  4927                 td: 'tr',
       
  4928                 th: 'tr',
       
  4929                 li: 'ul'
       
  4930             },
       
  4931             // Used to determine the parentNode if el is directly within a documentFragment
       
  4932             getParentNode: function(el, defaultParentNode) {
       
  4933                 return defaultParentNode && el.parentNode.nodeType === 11 ? defaultParentNode : el.parentNode;
       
  4934             },
       
  4935             // 3.0 TODO: remove
       
  4936             setAttr: can.attr.set,
       
  4937             // 3.0 TODO: remove
       
  4938             getAttr: can.attr.get,
       
  4939             // 3.0 TODO: remove
       
  4940             removeAttr: can.attr.remove,
       
  4941             // Gets a "pretty" value for something
       
  4942             contentText: function(text) {
       
  4943                 if (typeof text === 'string') {
       
  4944                     return text;
       
  4945                 }
       
  4946                 // If has no value, return an empty string.
       
  4947                 if (!text && text !== 0) {
       
  4948                     return '';
       
  4949                 }
       
  4950                 return '' + text;
       
  4951             },
       
  4952 
       
  4953             after: function(oldElements, newFrag) {
       
  4954                 var last = oldElements[oldElements.length - 1];
       
  4955                 // Insert it in the `document` or `documentFragment`
       
  4956                 if (last.nextSibling) {
       
  4957                     can.insertBefore(last.parentNode, newFrag, last.nextSibling);
       
  4958                 } else {
       
  4959                     can.appendChild(last.parentNode, newFrag);
       
  4960                 }
       
  4961             },
       
  4962 
       
  4963             replace: function(oldElements, newFrag) {
       
  4964                 elements.after(oldElements, newFrag);
       
  4965                 if (can.remove(can.$(oldElements)).length < oldElements.length && !selectsCommentNodes) {
       
  4966                     can.each(oldElements, function(el) {
       
  4967                         if (el.nodeType === 8) {
       
  4968                             el.parentNode.removeChild(el);
       
  4969                         }
       
  4970                     });
       
  4971                 }
       
  4972             }
       
  4973         };
       
  4974 
       
  4975         can.view.elements = elements;
       
  4976 
       
  4977         return elements;
       
  4978     })(__m3, __m17);
       
  4979 
       
  4980     // ## can/view/callbacks/callbacks.js
       
  4981     var __m25 = (function(can) {
       
  4982 
       
  4983         var attr = can.view.attr = function(attributeName, attrHandler) {
       
  4984             if (attrHandler) {
       
  4985                 if (typeof attributeName === "string") {
       
  4986                     attributes[attributeName] = attrHandler;
       
  4987                 } else {
       
  4988                     regExpAttributes.push({
       
  4989                             match: attributeName,
       
  4990                             handler: attrHandler
       
  4991                         });
       
  4992                 }
       
  4993             } else {
       
  4994                 var cb = attributes[attributeName];
       
  4995                 if (!cb) {
       
  4996 
       
  4997                     for (var i = 0, len = regExpAttributes.length; i < len; i++) {
       
  4998                         var attrMatcher = regExpAttributes[i];
       
  4999                         if (attrMatcher.match.test(attributeName)) {
       
  5000                             cb = attrMatcher.handler;
       
  5001                             break;
       
  5002                         }
       
  5003                     }
       
  5004                 }
       
  5005                 return cb;
       
  5006             }
       
  5007         };
       
  5008 
       
  5009         var attributes = {},
       
  5010             regExpAttributes = [],
       
  5011             automaticCustomElementCharacters = /[-\:]/;
       
  5012 
       
  5013         var tag = can.view.tag = function(tagName, tagHandler) {
       
  5014             if (tagHandler) {
       
  5015                 // if we have html5shive ... re-generate
       
  5016                 if (window.html5) {
       
  5017                     window.html5.elements += " " + tagName;
       
  5018                     window.html5.shivDocument();
       
  5019                 }
       
  5020 
       
  5021                 tags[tagName.toLowerCase()] = tagHandler;
       
  5022             } else {
       
  5023                 var cb = tags[tagName.toLowerCase()];
       
  5024                 if (!cb && automaticCustomElementCharacters.test(tagName)) {
       
  5025                     // empty callback for things that look like special tags
       
  5026                     cb = function() {};
       
  5027                 }
       
  5028                 return cb;
       
  5029             }
       
  5030 
       
  5031         };
       
  5032         var tags = {};
       
  5033 
       
  5034         can.view.callbacks = {
       
  5035             _tags: tags,
       
  5036             _attributes: attributes,
       
  5037             _regExpAttributes: regExpAttributes,
       
  5038             tag: tag,
       
  5039             attr: attr,
       
  5040             // handles calling back a tag callback
       
  5041             tagHandler: function(el, tagName, tagData) {
       
  5042                 var helperTagCallback = tagData.options.read('tags.' + tagName, {
       
  5043                         isArgument: true,
       
  5044                         proxyMethods: false
       
  5045                     })
       
  5046                     .value,
       
  5047                     tagCallback = helperTagCallback || tags[tagName];
       
  5048 
       
  5049                 // If this was an element like <foo-bar> that doesn't have a component, just render its content
       
  5050                 var scope = tagData.scope,
       
  5051                     res;
       
  5052 
       
  5053                 if (tagCallback) {
       
  5054                     var reads = can.__clearReading();
       
  5055                     res = tagCallback(el, tagData);
       
  5056                     can.__setReading(reads);
       
  5057                 } else {
       
  5058                     res = scope;
       
  5059                 }
       
  5060 
       
  5061 
       
  5062 
       
  5063                 // If the tagCallback gave us something to render with, and there is content within that element
       
  5064                 // render it!
       
  5065                 if (res && tagData.subtemplate) {
       
  5066 
       
  5067                     if (scope !== res) {
       
  5068                         scope = scope.add(res);
       
  5069                     }
       
  5070                     var result = tagData.subtemplate(scope, tagData.options);
       
  5071                     var frag = typeof result === "string" ? can.view.frag(result) : result;
       
  5072                     can.appendChild(el, frag);
       
  5073                 }
       
  5074             }
       
  5075         };
       
  5076         return can.view.callbacks;
       
  5077     })(__m3, __m17);
       
  5078 
       
  5079     // ## can/view/scanner.js
       
  5080     var __m23 = (function(can, elements, viewCallbacks) {
       
  5081 
       
  5082 
       
  5083         var newLine = /(\r|\n)+/g,
       
  5084             notEndTag = /\//,
       
  5085             // Escapes characters starting with `\`.
       
  5086             clean = function(content) {
       
  5087                 return content
       
  5088                     .split('\\')
       
  5089                     .join("\\\\")
       
  5090                     .split("\n")
       
  5091                     .join("\\n")
       
  5092                     .split('"')
       
  5093                     .join('\\"')
       
  5094                     .split("\t")
       
  5095                     .join("\\t");
       
  5096             },
       
  5097             // Returns a tagName to use as a temporary placeholder for live content
       
  5098             // looks forward ... could be slow, but we only do it when necessary
       
  5099             getTag = function(tagName, tokens, i) {
       
  5100                 // if a tagName is provided, use that
       
  5101                 if (tagName) {
       
  5102                     return tagName;
       
  5103                 } else {
       
  5104                     // otherwise go searching for the next two tokens like "<",TAG
       
  5105                     while (i < tokens.length) {
       
  5106                         if (tokens[i] === "<" && !notEndTag.test(tokens[i + 1])) {
       
  5107                             return elements.reverseTagMap[tokens[i + 1]] || 'span';
       
  5108                         }
       
  5109                         i++;
       
  5110                     }
       
  5111                 }
       
  5112                 return '';
       
  5113             },
       
  5114             bracketNum = function(content) {
       
  5115                 return (--content.split("{")
       
  5116                     .length) - (--content.split("}")
       
  5117                     .length);
       
  5118             },
       
  5119             myEval = function(script) {
       
  5120                 eval(script);
       
  5121             },
       
  5122             attrReg = /([^\s]+)[\s]*=[\s]*$/,
       
  5123             // Commands for caching.
       
  5124             startTxt = 'var ___v1ew = [];',
       
  5125             finishTxt = "return ___v1ew.join('')",
       
  5126             put_cmd = "___v1ew.push(\n",
       
  5127             insert_cmd = put_cmd,
       
  5128             // Global controls (used by other functions to know where we are).
       
  5129             // Are we inside a tag?
       
  5130             htmlTag = null,
       
  5131             // Are we within a quote within a tag?
       
  5132             quote = null,
       
  5133             // What was the text before the current quote? (used to get the `attr` name)
       
  5134             beforeQuote = null,
       
  5135             // Whether a rescan is in progress
       
  5136             rescan = null,
       
  5137             getAttrName = function() {
       
  5138                 var matches = beforeQuote.match(attrReg);
       
  5139                 return matches && matches[1];
       
  5140             },
       
  5141             // Used to mark where the element is.
       
  5142             status = function() {
       
  5143                 // `t` - `1`.
       
  5144                 // `h` - `0`.
       
  5145                 // `q` - String `beforeQuote`.
       
  5146                 return quote ? "'" + getAttrName() + "'" : (htmlTag ? 1 : 0);
       
  5147             },
       
  5148             // returns the top of a stack
       
  5149             top = function(stack) {
       
  5150                 return stack[stack.length - 1];
       
  5151             },
       
  5152             Scanner;
       
  5153 
       
  5154 
       
  5155         can.view.Scanner = Scanner = function(options) {
       
  5156             // Set options on self
       
  5157             can.extend(this, {
       
  5158 
       
  5159                     text: {},
       
  5160                     tokens: []
       
  5161                 }, options);
       
  5162             // make sure it's an empty string if it's not
       
  5163             this.text.options = this.text.options || "";
       
  5164 
       
  5165             // Cache a token lookup
       
  5166             this.tokenReg = [];
       
  5167             this.tokenSimple = {
       
  5168                 "<": "<",
       
  5169                 ">": ">",
       
  5170                 '"': '"',
       
  5171                 "'": "'"
       
  5172             };
       
  5173             this.tokenComplex = [];
       
  5174             this.tokenMap = {};
       
  5175             for (var i = 0, token; token = this.tokens[i]; i++) {
       
  5176 
       
  5177 
       
  5178                 // Save complex mappings (custom regexp)
       
  5179                 if (token[2]) {
       
  5180                     this.tokenReg.push(token[2]);
       
  5181                     this.tokenComplex.push({
       
  5182                             abbr: token[1],
       
  5183                             re: new RegExp(token[2]),
       
  5184                             rescan: token[3]
       
  5185                         });
       
  5186                 }
       
  5187                 // Save simple mappings (string only, no regexp)
       
  5188                 else {
       
  5189                     this.tokenReg.push(token[1]);
       
  5190                     this.tokenSimple[token[1]] = token[0];
       
  5191                 }
       
  5192                 this.tokenMap[token[0]] = token[1];
       
  5193             }
       
  5194 
       
  5195             // Cache the token registry.
       
  5196             this.tokenReg = new RegExp("(" + this.tokenReg.slice(0)
       
  5197                 .concat(["<", ">", '"', "'"])
       
  5198                 .join("|") + ")", "g");
       
  5199         };
       
  5200 
       
  5201 
       
  5202         Scanner.prototype = {
       
  5203             // a default that can be overwritten
       
  5204             helpers: [],
       
  5205 
       
  5206             scan: function(source, name) {
       
  5207                 var tokens = [],
       
  5208                     last = 0,
       
  5209                     simple = this.tokenSimple,
       
  5210                     complex = this.tokenComplex;
       
  5211 
       
  5212                 source = source.replace(newLine, "\n");
       
  5213                 if (this.transform) {
       
  5214                     source = this.transform(source);
       
  5215                 }
       
  5216                 source.replace(this.tokenReg, function(whole, part) {
       
  5217                     // offset is the second to last argument
       
  5218                     var offset = arguments[arguments.length - 2];
       
  5219 
       
  5220                     // if the next token starts after the last token ends
       
  5221                     // push what's in between
       
  5222                     if (offset > last) {
       
  5223                         tokens.push(source.substring(last, offset));
       
  5224                     }
       
  5225 
       
  5226                     // push the simple token (if there is one)
       
  5227                     if (simple[whole]) {
       
  5228                         tokens.push(whole);
       
  5229                     }
       
  5230                     // otherwise lookup complex tokens
       
  5231                     else {
       
  5232                         for (var i = 0, token; token = complex[i]; i++) {
       
  5233                             if (token.re.test(whole)) {
       
  5234                                 tokens.push(token.abbr);
       
  5235                                 // Push a rescan function if one exists
       
  5236                                 if (token.rescan) {
       
  5237                                     tokens.push(token.rescan(part));
       
  5238                                 }
       
  5239                                 break;
       
  5240                             }
       
  5241                         }
       
  5242                     }
       
  5243 
       
  5244                     // update the position of the last part of the last token
       
  5245                     last = offset + part.length;
       
  5246                 });
       
  5247 
       
  5248                 // if there's something at the end, add it
       
  5249                 if (last < source.length) {
       
  5250                     tokens.push(source.substr(last));
       
  5251                 }
       
  5252 
       
  5253                 var content = '',
       
  5254                     buff = [startTxt + (this.text.start || '')],
       
  5255                     // Helper `function` for putting stuff in the view concat.
       
  5256                     put = function(content, bonus) {
       
  5257                         buff.push(put_cmd, '"', clean(content), '"' + (bonus || '') + ');');
       
  5258                     },
       
  5259                     // A stack used to keep track of how we should end a bracket
       
  5260                     // `}`.
       
  5261                     // Once we have a `<%= %>` with a `leftBracket`,
       
  5262                     // we store how the file should end here (either `))` or `;`).
       
  5263                     endStack = [],
       
  5264                     // The last token, used to remember which tag we are in.
       
  5265                     lastToken,
       
  5266                     // The corresponding magic tag.
       
  5267                     startTag = null,
       
  5268                     // Was there a magic tag inside an html tag?
       
  5269                     magicInTag = false,
       
  5270                     // was there a special state
       
  5271                     specialStates = {
       
  5272                         attributeHookups: [],
       
  5273                         // a stack of tagHookups
       
  5274                         tagHookups: [],
       
  5275                         //last tag hooked up
       
  5276                         lastTagHookup: ''
       
  5277                     },
       
  5278                     // Helper `function` for removing tagHookups from the hookup stack
       
  5279                     popTagHookup = function() {
       
  5280                         // The length of tagHookups is the nested depth which can be used to uniquely identify custom tags of the same type
       
  5281                         specialStates.lastTagHookup = specialStates.tagHookups.pop() + specialStates.tagHookups.length;
       
  5282                     },
       
  5283                     // The current tag name.
       
  5284                     tagName = '',
       
  5285                     // stack of tagNames
       
  5286                     tagNames = [],
       
  5287                     // Pop from tagNames?
       
  5288                     popTagName = false,
       
  5289                     // Declared here.
       
  5290                     bracketCount,
       
  5291                     // in a special attr like src= or style=
       
  5292                     specialAttribute = false,
       
  5293 
       
  5294                     i = 0,
       
  5295                     token,
       
  5296                     tmap = this.tokenMap,
       
  5297                     attrName;
       
  5298 
       
  5299                 // Reinitialize the tag state goodness.
       
  5300                 htmlTag = quote = beforeQuote = null;
       
  5301                 for (;
       
  5302                     (token = tokens[i++]) !== undefined;) {
       
  5303                     if (startTag === null) {
       
  5304                         switch (token) {
       
  5305                             case tmap.left:
       
  5306                             case tmap.escapeLeft:
       
  5307                             case tmap.returnLeft:
       
  5308                                 magicInTag = htmlTag && 1;
       
  5309 
       
  5310                             case tmap.commentLeft:
       
  5311                                 // A new line -- just add whatever content within a clean.
       
  5312                                 // Reset everything.
       
  5313                                 startTag = token;
       
  5314                                 if (content.length) {
       
  5315                                     put(content);
       
  5316                                 }
       
  5317                                 content = '';
       
  5318                                 break;
       
  5319                             case tmap.escapeFull:
       
  5320                                 // This is a full line escape (a line that contains only whitespace and escaped logic)
       
  5321                                 // Break it up into escape left and right
       
  5322                                 magicInTag = htmlTag && 1;
       
  5323                                 rescan = 1;
       
  5324                                 startTag = tmap.escapeLeft;
       
  5325                                 if (content.length) {
       
  5326                                     put(content);
       
  5327                                 }
       
  5328                                 rescan = tokens[i++];
       
  5329                                 content = rescan.content || rescan;
       
  5330                                 if (rescan.before) {
       
  5331                                     put(rescan.before);
       
  5332                                 }
       
  5333                                 tokens.splice(i, 0, tmap.right);
       
  5334                                 break;
       
  5335                             case tmap.commentFull:
       
  5336                                 // Ignore full line comments.
       
  5337                                 break;
       
  5338                             case tmap.templateLeft:
       
  5339                                 content += tmap.left;
       
  5340                                 break;
       
  5341                             case '<':
       
  5342                                 // Make sure we are not in a comment.
       
  5343                                 if (tokens[i].indexOf("!--") !== 0) {
       
  5344                                     htmlTag = 1;
       
  5345                                     magicInTag = 0;
       
  5346                                 }
       
  5347 
       
  5348                                 content += token;
       
  5349 
       
  5350                                 break;
       
  5351                             case '>':
       
  5352                                 htmlTag = 0;
       
  5353                                 // content.substr(-1) doesn't work in IE7/8
       
  5354                                 var emptyElement = (content.substr(content.length - 1) === "/" || content.substr(content.length - 2) === "--"),
       
  5355                                     attrs = "";
       
  5356                                 // if there was a magic tag
       
  5357                                 // or it's an element that has text content between its tags,
       
  5358                                 // but content is not other tags add a hookup
       
  5359                                 // TODO: we should only add `can.EJS.pending()` if there's a magic tag
       
  5360                                 // within the html tags.
       
  5361                                 if (specialStates.attributeHookups.length) {
       
  5362                                     attrs = "attrs: ['" + specialStates.attributeHookups.join("','") + "'], ";
       
  5363                                     specialStates.attributeHookups = [];
       
  5364                                 }
       
  5365                                 // this is the > of a special tag
       
  5366                                 // comparison to lastTagHookup makes sure the same custom tags can be nested
       
  5367                                 if ((tagName + specialStates.tagHookups.length) !== specialStates.lastTagHookup && tagName === top(specialStates.tagHookups)) {
       
  5368                                     // If it's a self closing tag (like <content/>) make sure we put the / at the end.
       
  5369                                     if (emptyElement) {
       
  5370                                         content = content.substr(0, content.length - 1);
       
  5371                                     }
       
  5372                                     // Put the start of the end
       
  5373                                     buff.push(put_cmd,
       
  5374                                         '"', clean(content), '"',
       
  5375                                         ",can.view.pending({tagName:'" + tagName + "'," + (attrs) + "scope: " + (this.text.scope || "this") + this.text.options);
       
  5376 
       
  5377                                     // if it's a self closing tag (like <content/>) close and end the tag
       
  5378                                     if (emptyElement) {
       
  5379                                         buff.push("}));");
       
  5380                                         content = "/>";
       
  5381                                         popTagHookup();
       
  5382                                     }
       
  5383                                     // if it's an empty tag	 
       
  5384                                     else if (tokens[i] === "<" && tokens[i + 1] === "/" + tagName) {
       
  5385                                         buff.push("}));");
       
  5386                                         content = token;
       
  5387                                         popTagHookup();
       
  5388                                     } else {
       
  5389                                         // it has content
       
  5390                                         buff.push(",subtemplate: function(" + this.text.argNames + "){\n" + startTxt + (this.text.start || ''));
       
  5391                                         content = '';
       
  5392                                     }
       
  5393 
       
  5394                                 } else if (magicInTag || (!popTagName && elements.tagToContentPropMap[tagNames[tagNames.length - 1]]) || attrs) {
       
  5395                                     // make sure / of /> is on the right of pending
       
  5396                                     var pendingPart = ",can.view.pending({" + attrs + "scope: " + (this.text.scope || "this") + this.text.options + "}),\"";
       
  5397                                     if (emptyElement) {
       
  5398                                         put(content.substr(0, content.length - 1), pendingPart + "/>\"");
       
  5399                                     } else {
       
  5400                                         put(content, pendingPart + ">\"");
       
  5401                                     }
       
  5402                                     content = '';
       
  5403                                     magicInTag = 0;
       
  5404                                 } else {
       
  5405                                     content += token;
       
  5406                                 }
       
  5407 
       
  5408                                 // if it's a tag like <input/>
       
  5409                                 if (emptyElement || popTagName) {
       
  5410                                     // remove the current tag in the stack
       
  5411                                     tagNames.pop();
       
  5412                                     // set the current tag to the previous parent
       
  5413                                     tagName = tagNames[tagNames.length - 1];
       
  5414                                     // Don't pop next time
       
  5415                                     popTagName = false;
       
  5416                                 }
       
  5417                                 specialStates.attributeHookups = [];
       
  5418                                 break;
       
  5419                             case "'":
       
  5420                             case '"':
       
  5421                                 // If we are in an html tag, finding matching quotes.
       
  5422                                 if (htmlTag) {
       
  5423                                     // We have a quote and it matches.
       
  5424                                     if (quote && quote === token) {
       
  5425                                         // We are exiting the quote.
       
  5426                                         quote = null;
       
  5427                                         // Otherwise we are creating a quote.
       
  5428                                         // TODO: does this handle `\`?
       
  5429                                         var attr = getAttrName();
       
  5430                                         if (viewCallbacks.attr(attr)) {
       
  5431                                             specialStates.attributeHookups.push(attr);
       
  5432                                         }
       
  5433 
       
  5434                                         if (specialAttribute) {
       
  5435 
       
  5436                                             content += token;
       
  5437                                             put(content);
       
  5438                                             buff.push(finishTxt, "}));\n");
       
  5439                                             content = "";
       
  5440                                             specialAttribute = false;
       
  5441 
       
  5442                                             break;
       
  5443                                         }
       
  5444 
       
  5445                                     } else if (quote === null) {
       
  5446                                         quote = token;
       
  5447                                         beforeQuote = lastToken;
       
  5448                                         attrName = getAttrName();
       
  5449                                         // TODO: check if there's magic!!!!
       
  5450                                         if ((tagName === "img" && attrName === "src") || attrName === "style") {
       
  5451                                             // put content that was before the attr name, but don't include the src=
       
  5452                                             put(content.replace(attrReg, ""));
       
  5453                                             content = "";
       
  5454 
       
  5455                                             specialAttribute = true;
       
  5456 
       
  5457                                             buff.push(insert_cmd, "can.view.txt(2,'" + getTag(tagName, tokens, i) + "'," + status() + ",this,function(){", startTxt);
       
  5458                                             put(attrName + "=" + token);
       
  5459                                             break;
       
  5460                                         }
       
  5461 
       
  5462                                     }
       
  5463                                 }
       
  5464 
       
  5465                             default:
       
  5466                                 // Track the current tag
       
  5467                                 if (lastToken === '<') {
       
  5468 
       
  5469                                     tagName = token.substr(0, 3) === "!--" ?
       
  5470                                         "!--" : token.split(/\s/)[0];
       
  5471 
       
  5472                                     var isClosingTag = false,
       
  5473                                         cleanedTagName;
       
  5474 
       
  5475                                     if (tagName.indexOf("/") === 0) {
       
  5476                                         isClosingTag = true;
       
  5477                                         cleanedTagName = tagName.substr(1);
       
  5478                                     }
       
  5479 
       
  5480                                     if (isClosingTag) { // </tag>
       
  5481 
       
  5482                                         // when we enter a new tag, pop the tag name stack
       
  5483                                         if (top(tagNames) === cleanedTagName) {
       
  5484                                             // set tagName to the last tagName
       
  5485                                             // if there are no more tagNames, we'll rely on getTag.
       
  5486                                             tagName = cleanedTagName;
       
  5487                                             popTagName = true;
       
  5488                                         }
       
  5489                                         // if we are in a closing tag of a custom tag
       
  5490                                         if (top(specialStates.tagHookups) === cleanedTagName) {
       
  5491 
       
  5492                                             // remove the last < from the content
       
  5493                                             put(content.substr(0, content.length - 1));
       
  5494 
       
  5495                                             // finish the "section"
       
  5496                                             buff.push(finishTxt + "}}) );");
       
  5497                                             // the < belongs to the outside
       
  5498                                             content = "><";
       
  5499                                             popTagHookup();
       
  5500                                         }
       
  5501 
       
  5502                                     } else {
       
  5503                                         if (tagName.lastIndexOf("/") === tagName.length - 1) {
       
  5504                                             tagName = tagName.substr(0, tagName.length - 1);
       
  5505 
       
  5506                                         }
       
  5507 
       
  5508                                         if (tagName !== "!--" && (viewCallbacks.tag(tagName))) {
       
  5509                                             // if the content tag is inside something it doesn't belong ...
       
  5510                                             if (tagName === "content" && elements.tagMap[top(tagNames)]) {
       
  5511                                                 // convert it to an element that will work
       
  5512                                                 token = token.replace("content", elements.tagMap[top(tagNames)]);
       
  5513                                             }
       
  5514                                             // we will hookup at the ending tag>
       
  5515                                             specialStates.tagHookups.push(tagName);
       
  5516                                         }
       
  5517 
       
  5518                                         tagNames.push(tagName);
       
  5519 
       
  5520                                     }
       
  5521 
       
  5522                                 }
       
  5523                                 content += token;
       
  5524                                 break;
       
  5525                         }
       
  5526                     } else {
       
  5527                         // We have a start tag.
       
  5528                         switch (token) {
       
  5529                             case tmap.right:
       
  5530                             case tmap.returnRight:
       
  5531                                 switch (startTag) {
       
  5532                                     case tmap.left:
       
  5533                                         // Get the number of `{ minus }`
       
  5534                                         bracketCount = bracketNum(content);
       
  5535 
       
  5536                                         // We are ending a block.
       
  5537                                         if (bracketCount === 1) {
       
  5538                                             // We are starting on. 
       
  5539                                             buff.push(insert_cmd, 'can.view.txt(0,\'' + getTag(tagName, tokens, i) + '\',' + status() + ',this,function(){', startTxt, content);
       
  5540                                             endStack.push({
       
  5541                                                     before: "",
       
  5542                                                     after: finishTxt + "}));\n"
       
  5543                                                 });
       
  5544                                         } else {
       
  5545 
       
  5546                                             // How are we ending this statement?
       
  5547                                             last = // If the stack has value and we are ending a block...
       
  5548                                             endStack.length && bracketCount === -1 ? // Use the last item in the block stack.
       
  5549                                             endStack.pop() : // Or use the default ending.
       
  5550                                             {
       
  5551                                                 after: ";"
       
  5552                                             };
       
  5553 
       
  5554                                             // If we are ending a returning block,
       
  5555                                             // add the finish text which returns the result of the
       
  5556                                             // block.
       
  5557                                             if (last.before) {
       
  5558                                                 buff.push(last.before);
       
  5559                                             }
       
  5560                                             // Add the remaining content.
       
  5561                                             buff.push(content, ";", last.after);
       
  5562                                         }
       
  5563                                         break;
       
  5564                                     case tmap.escapeLeft:
       
  5565                                     case tmap.returnLeft:
       
  5566                                         // We have an extra `{` -> `block`.
       
  5567                                         // Get the number of `{ minus }`.
       
  5568                                         bracketCount = bracketNum(content);
       
  5569                                         // If we have more `{`, it means there is a block.
       
  5570                                         if (bracketCount) {
       
  5571                                             // When we return to the same # of `{` vs `}` end with a `doubleParent`.
       
  5572                                             endStack.push({
       
  5573                                                     before: finishTxt,
       
  5574                                                     after: "}));\n"
       
  5575                                                 });
       
  5576                                         }
       
  5577 
       
  5578                                         var escaped = startTag === tmap.escapeLeft ? 1 : 0,
       
  5579                                             commands = {
       
  5580                                                 insert: insert_cmd,
       
  5581                                                 tagName: getTag(tagName, tokens, i),
       
  5582                                                 status: status(),
       
  5583                                                 specialAttribute: specialAttribute
       
  5584                                             };
       
  5585 
       
  5586                                         for (var ii = 0; ii < this.helpers.length; ii++) {
       
  5587                                             // Match the helper based on helper
       
  5588                                             // regex name value
       
  5589                                             var helper = this.helpers[ii];
       
  5590                                             if (helper.name.test(content)) {
       
  5591                                                 content = helper.fn(content, commands);
       
  5592 
       
  5593                                                 // dont escape partials
       
  5594                                                 if (helper.name.source === /^>[\s]*\w*/.source) {
       
  5595                                                     escaped = 0;
       
  5596                                                 }
       
  5597                                                 break;
       
  5598                                             }
       
  5599                                         }
       
  5600 
       
  5601                                         // Handle special cases
       
  5602                                         if (typeof content === 'object') {
       
  5603 
       
  5604                                             if (content.startTxt && content.end && specialAttribute) {
       
  5605                                                 buff.push(insert_cmd, "can.view.toStr( ", content.content, '() ) );');
       
  5606 
       
  5607                                             } else {
       
  5608 
       
  5609                                                 if (content.startTxt) {
       
  5610                                                     buff.push(insert_cmd, "can.view.txt(\n" +
       
  5611                                                         (typeof status() === "string" || (content.escaped != null ? content.escaped : escaped)) + ",\n'" + tagName + "',\n" + status() + ",\nthis,\n");
       
  5612                                                 } else if (content.startOnlyTxt) {
       
  5613                                                     buff.push(insert_cmd, 'can.view.onlytxt(this,\n');
       
  5614                                                 }
       
  5615                                                 buff.push(content.content);
       
  5616                                                 if (content.end) {
       
  5617                                                     buff.push('));');
       
  5618                                                 }
       
  5619 
       
  5620                                             }
       
  5621 
       
  5622                                         } else if (specialAttribute) {
       
  5623 
       
  5624                                             buff.push(insert_cmd, content, ');');
       
  5625 
       
  5626                                         } else {
       
  5627                                             // If we have `<%== a(function(){ %>` then we want
       
  5628                                             // `can.EJS.text(0,this, function(){ return a(function(){ var _v1ew = [];`.
       
  5629 
       
  5630                                             buff.push(insert_cmd, "can.view.txt(\n" + (typeof status() === "string" || escaped) +
       
  5631                                                 ",\n'" + tagName + "',\n" + status() + ",\nthis,\nfunction(){ " +
       
  5632                                                 (this.text.escape || '') +
       
  5633                                                 "return ", content,
       
  5634                                                 // If we have a block.
       
  5635                                                 bracketCount ?
       
  5636                                                 // Start with startTxt `"var _v1ew = [];"`.
       
  5637                                                 startTxt :
       
  5638                                                 // If not, add `doubleParent` to close push and text.
       
  5639                                                 "}));\n");
       
  5640 
       
  5641 
       
  5642 
       
  5643                                         }
       
  5644 
       
  5645                                         if (rescan && rescan.after && rescan.after.length) {
       
  5646                                             put(rescan.after.length);
       
  5647                                             rescan = null;
       
  5648                                         }
       
  5649                                         break;
       
  5650                                 }
       
  5651                                 startTag = null;
       
  5652                                 content = '';
       
  5653                                 break;
       
  5654                             case tmap.templateLeft:
       
  5655                                 content += tmap.left;
       
  5656                                 break;
       
  5657                             default:
       
  5658                                 content += token;
       
  5659                                 break;
       
  5660                         }
       
  5661                     }
       
  5662                     lastToken = token;
       
  5663                 }
       
  5664 
       
  5665                 // Put it together...
       
  5666                 if (content.length) {
       
  5667                     // Should be `content.dump` in Ruby.
       
  5668                     put(content);
       
  5669                 }
       
  5670                 buff.push(";");
       
  5671                 var template = buff.join(''),
       
  5672                     out = {
       
  5673                         out: (this.text.outStart || "") + template + " " + finishTxt + (this.text.outEnd || "")
       
  5674                     };
       
  5675 
       
  5676                 // Use `eval` instead of creating a function, because it is easier to debug.
       
  5677                 myEval.call(out, 'this.fn = (function(' + this.text.argNames + '){' + out.out + '});\r\n//# sourceURL=' + name + '.js');
       
  5678                 return out;
       
  5679             }
       
  5680         };
       
  5681 
       
  5682         // can.view.attr
       
  5683 
       
  5684         // This is called when there is a special tag
       
  5685         can.view.pending = function(viewData) {
       
  5686             // we need to call any live hookups
       
  5687             // so get that and return the hook
       
  5688             // a better system will always be called with the same stuff
       
  5689             var hooks = can.view.getHooks();
       
  5690             return can.view.hook(function(el) {
       
  5691                 can.each(hooks, function(fn) {
       
  5692                     fn(el);
       
  5693                 });
       
  5694                 viewData.templateType = "legacy";
       
  5695                 if (viewData.tagName) {
       
  5696                     viewCallbacks.tagHandler(el, viewData.tagName, viewData);
       
  5697                 }
       
  5698 
       
  5699                 can.each(viewData && viewData.attrs || [], function(attributeName) {
       
  5700                     viewData.attributeName = attributeName;
       
  5701                     var callback = viewCallbacks.attr(attributeName);
       
  5702                     if (callback) {
       
  5703                         callback(el, viewData);
       
  5704                     }
       
  5705                 });
       
  5706 
       
  5707             });
       
  5708 
       
  5709         };
       
  5710 
       
  5711         can.view.tag("content", function(el, tagData) {
       
  5712             return tagData.scope;
       
  5713         });
       
  5714 
       
  5715         can.view.Scanner = Scanner;
       
  5716 
       
  5717         return Scanner;
       
  5718     })(__m17, __m24, __m25);
       
  5719 
       
  5720     // ## can/view/node_lists/node_lists.js
       
  5721     var __m28 = (function(can) {
       
  5722         // ## Helpers
       
  5723         // Some browsers don't allow expando properties on HTMLTextNodes
       
  5724         // so let's try to assign a custom property, an 'expando' property.
       
  5725         // We use this boolean to determine how we are going to hold on
       
  5726         // to HTMLTextNode within a nodeList.  More about this in the 'id'
       
  5727         // function.
       
  5728         var canExpando = true;
       
  5729         try {
       
  5730             document.createTextNode('')._ = 0;
       
  5731         } catch (ex) {
       
  5732             canExpando = false;
       
  5733         }
       
  5734 
       
  5735         // A mapping of element ids to nodeList id allowing us to quickly find an element
       
  5736         // that needs to be replaced when updated.
       
  5737         var nodeMap = {},
       
  5738             // A mapping of ids to text nodes, this map will be used in the 
       
  5739             // case of the browser not supporting expando properties.
       
  5740             textNodeMap = {},
       
  5741             // The name of the expando property; the value returned 
       
  5742             // given a nodeMap key.
       
  5743             expando = 'ejs_' + Math.random(),
       
  5744             // The id used as the key in our nodeMap, this integer
       
  5745             // will be preceded by 'element_' or 'obj_' depending on whether
       
  5746             // the element has a nodeName.
       
  5747             _id = 0,
       
  5748 
       
  5749             // ## nodeLists.id
       
  5750             // Given a template node, create an id on the node as a expando
       
  5751             // property, or if the node is an HTMLTextNode and the browser
       
  5752             // doesn't support expando properties store the id with a
       
  5753             // reference to the text node in an internal collection then return
       
  5754             // the lookup id.
       
  5755             id = function(node) {
       
  5756                 // If the browser supports expando properties or the node
       
  5757                 // provided is not an HTMLTextNode, we don't need to work
       
  5758                 // with the internal textNodeMap and we can place the property
       
  5759                 // on the node.
       
  5760                 if (canExpando || node.nodeType !== 3) {
       
  5761                     // If the node already has an (internal) id, then just 
       
  5762                     // return the key of the nodeMap. This would be the case
       
  5763                     // in updating and unregistering a nodeList.
       
  5764                     if (node[expando]) {
       
  5765                         return node[expando];
       
  5766                     } else {
       
  5767                         // If the node isn't already referenced in the map we need
       
  5768                         // to generate a lookup id and place it on the node itself.
       
  5769                         ++_id;
       
  5770                         return node[expando] = (node.nodeName ? 'element_' : 'obj_') + _id;
       
  5771                     }
       
  5772                 } else {
       
  5773                     // The nodeList has a specific collection for HTMLTextNodes for 
       
  5774                     // (older) browsers that do not support expando properties.
       
  5775                     for (var textNodeID in textNodeMap) {
       
  5776                         if (textNodeMap[textNodeID] === node) {
       
  5777                             return textNodeID;
       
  5778                         }
       
  5779                     }
       
  5780                     // If we didn't find the node, we need to register it and return
       
  5781                     // the id used.
       
  5782                     ++_id;
       
  5783 
       
  5784                     // If we didn't find the node, we need to register it and return
       
  5785                     // the id used.
       
  5786                     // We have to store the node itself because of the browser's lack
       
  5787                     // of support for expando properties (i.e. we can't use a look-up
       
  5788                     // table and store the id on the node as a custom property).
       
  5789                     textNodeMap['text_' + _id] = node;
       
  5790                     return 'text_' + _id;
       
  5791                 }
       
  5792             },
       
  5793             splice = [].splice,
       
  5794             push = [].push,
       
  5795 
       
  5796             // ## nodeLists.itemsInChildListTree
       
  5797             // Given a nodeList return the number of child items in the provided
       
  5798             // list and any child lists.
       
  5799             itemsInChildListTree = function(list) {
       
  5800                 var count = 0;
       
  5801                 for (var i = 0, len = list.length; i < len; i++) {
       
  5802                     var item = list[i];
       
  5803                     // If the item is an HTMLElement then increment the count by 1.
       
  5804                     if (item.nodeType) {
       
  5805                         count++;
       
  5806                     } else {
       
  5807                         // If the item is not an HTMLElement it is a list, so
       
  5808                         // increment the count by the number of items in the child
       
  5809                         // list.
       
  5810                         count += itemsInChildListTree(item);
       
  5811                     }
       
  5812                 }
       
  5813                 return count;
       
  5814             };
       
  5815 
       
  5816         // ## Registering & Updating
       
  5817         // To keep all live-bound sections knowing which elements they are managing,
       
  5818         // all live-bound elments are registered and updated when they change.
       
  5819         // For example, the above template, when rendered with data like:
       
  5820         //     data = new can.Map({
       
  5821         //         items: ["first","second"]
       
  5822         //     })
       
  5823         // This will first render the following content:
       
  5824         //     <div>
       
  5825         //         <span data-view-id='5'/>
       
  5826         //     </div>
       
  5827         // When the `5` callback is called, this will register the `<span>` like:
       
  5828         //     var ifsNodes = [<span 5>]
       
  5829         //     nodeLists.register(ifsNodes);
       
  5830         // And then render `{{if}}`'s contents and update `ifsNodes` with it:
       
  5831         //     nodeLists.update( ifsNodes, [<"\nItems:\n">, <span data-view-id="6">] );
       
  5832         // Next, hookup `6` is called which will regsiter the `<span>` like:
       
  5833         //     var eachsNodes = [<span 6>];
       
  5834         //     nodeLists.register(eachsNodes);
       
  5835         // And then it will render `{{#each}}`'s content and update `eachsNodes` with it:
       
  5836         //     nodeLists.update(eachsNodes, [<label>,<label>]);
       
  5837         // As `nodeLists` knows that `eachsNodes` is inside `ifsNodes`, it also updates
       
  5838         // `ifsNodes`'s nodes to look like:
       
  5839         //     [<"\nItems:\n">,<label>,<label>]
       
  5840         // Now, if all items were removed, `{{#if}}` would be able to remove
       
  5841         // all the `<label>` elements.
       
  5842         // When you regsiter a nodeList, you can also provide a callback to know when
       
  5843         // that nodeList has been replaced by a parent nodeList.  This is
       
  5844         // useful for tearing down live-binding.
       
  5845         var nodeLists = {
       
  5846             id: id,
       
  5847 
       
  5848             // ## nodeLists.update
       
  5849             // Updates a nodeList with new items, i.e. when values for the template have changed.
       
  5850             update: function(nodeList, newNodes) {
       
  5851                 // Unregister all childNodeLists.
       
  5852                 var oldNodes = nodeLists.unregisterChildren(nodeList);
       
  5853 
       
  5854                 newNodes = can.makeArray(newNodes);
       
  5855 
       
  5856                 var oldListLength = nodeList.length;
       
  5857 
       
  5858                 // Replace oldNodeLists's contents.
       
  5859                 splice.apply(nodeList, [
       
  5860                         0,
       
  5861                         oldListLength
       
  5862                     ].concat(newNodes));
       
  5863 
       
  5864                 nodeLists.nestList(nodeList);
       
  5865 
       
  5866                 return oldNodes;
       
  5867             },
       
  5868 
       
  5869             // ## nodeLists.nestList
       
  5870             // If a given list does not exist in the nodeMap then create an lookup
       
  5871             // id for it in the nodeMap and assign the list to it.
       
  5872             // If the the provided does happen to exist in the nodeMap update the
       
  5873             // elements in the list.
       
  5874             // @param {Array.<HTMLElement>} nodeList The nodeList being nested.
       
  5875             nestList: function(list) {
       
  5876                 var index = 0;
       
  5877                 while (index < list.length) {
       
  5878                     var node = list[index],
       
  5879                         childNodeList = nodeMap[id(node)];
       
  5880                     if (childNodeList) {
       
  5881                         if (childNodeList !== list) {
       
  5882                             list.splice(index, itemsInChildListTree(childNodeList), childNodeList);
       
  5883                         }
       
  5884                     } else {
       
  5885                         // Indicate the new nodes belong to this list.
       
  5886                         nodeMap[id(node)] = list;
       
  5887                     }
       
  5888                     index++;
       
  5889                 }
       
  5890             },
       
  5891 
       
  5892             // ## nodeLists.last
       
  5893             // Return the last HTMLElement in a nodeList, if the last
       
  5894             // element is a nodeList, returns the last HTMLElement of
       
  5895             // the child list, etc.
       
  5896             last: function(nodeList) {
       
  5897                 var last = nodeList[nodeList.length - 1];
       
  5898                 // If the last node in the list is not an HTMLElement
       
  5899                 // it is a nodeList so call `last` again.
       
  5900                 if (last.nodeType) {
       
  5901                     return last;
       
  5902                 } else {
       
  5903                     return nodeLists.last(last);
       
  5904                 }
       
  5905             },
       
  5906 
       
  5907             // ## nodeLists.first
       
  5908             // Return the first HTMLElement in a nodeList, if the first
       
  5909             // element is a nodeList, returns the first HTMLElement of
       
  5910             // the child list, etc.
       
  5911             first: function(nodeList) {
       
  5912                 var first = nodeList[0];
       
  5913                 // If the first node in the list is not an HTMLElement
       
  5914                 // it is a nodeList so call `first` again. 
       
  5915                 if (first.nodeType) {
       
  5916                     return first;
       
  5917                 } else {
       
  5918                     return nodeLists.first(first);
       
  5919                 }
       
  5920             },
       
  5921 
       
  5922             // ## nodeLists.register
       
  5923             // Registers a nodeList and returns the nodeList passed to register
       
  5924             register: function(nodeList, unregistered, parent) {
       
  5925                 // If a unregistered callback has been provided assign it to the nodeList
       
  5926                 // as a property to be called when the nodeList is unregistred.
       
  5927                 nodeList.unregistered = unregistered;
       
  5928 
       
  5929                 nodeLists.nestList(nodeList);
       
  5930 
       
  5931                 return nodeList;
       
  5932             },
       
  5933 
       
  5934             // ## nodeLists.unregisterChildren
       
  5935             // Unregister all childen within the provided list and return the 
       
  5936             // unregistred nodes.
       
  5937             // @param {Array.<HTMLElement>} nodeList The child list to unregister.
       
  5938             unregisterChildren: function(nodeList) {
       
  5939                 var nodes = [];
       
  5940                 // For each node in the nodeList we want to compute it's id
       
  5941                 // and delete it from the nodeList's internal map.
       
  5942                 can.each(nodeList, function(node) {
       
  5943                     // If the node does not have a nodeType it is an array of
       
  5944                     // nodes.
       
  5945                     if (node.nodeType) {
       
  5946                         delete nodeMap[id(node)];
       
  5947                         nodes.push(node);
       
  5948                     } else {
       
  5949                         // Recursively unregister each of the child lists in 
       
  5950                         // the nodeList.
       
  5951                         push.apply(nodes, nodeLists.unregister(node));
       
  5952                     }
       
  5953                 });
       
  5954                 return nodes;
       
  5955             },
       
  5956 
       
  5957             // ## nodeLists.unregister
       
  5958             // Unregister's a nodeList and returns the unregistered nodes.  
       
  5959             // Call if the nodeList is no longer being updated. This will 
       
  5960             // also unregister all child nodeLists.
       
  5961             unregister: function(nodeList) {
       
  5962                 var nodes = nodeLists.unregisterChildren(nodeList);
       
  5963                 // If an 'unregisted' function was provided during registration, remove
       
  5964                 // it from the list, and call the function provided.
       
  5965                 if (nodeList.unregistered) {
       
  5966                     var unregisteredCallback = nodeList.unregistered;
       
  5967                     delete nodeList.unregistered;
       
  5968 
       
  5969                     unregisteredCallback();
       
  5970                 }
       
  5971                 return nodes;
       
  5972             },
       
  5973 
       
  5974             nodeMap: nodeMap
       
  5975         };
       
  5976         can.view.nodeLists = nodeLists;
       
  5977         return nodeLists;
       
  5978     })(__m3, __m24);
       
  5979 
       
  5980     // ## can/view/parser/parser.js
       
  5981     var __m29 = (function(can) {
       
  5982 
       
  5983 
       
  5984         function makeMap(str) {
       
  5985             var obj = {}, items = str.split(",");
       
  5986             for (var i = 0; i < items.length; i++) {
       
  5987                 obj[items[i]] = true;
       
  5988             }
       
  5989 
       
  5990             return obj;
       
  5991         }
       
  5992 
       
  5993         var alphaNumericHU = "-A-Za-z0-9_",
       
  5994             attributeNames = "[a-zA-Z_:][" + alphaNumericHU + ":.]+",
       
  5995             spaceEQspace = "\\s*=\\s*",
       
  5996             dblQuote2dblQuote = "\"((?:\\\\.|[^\"])*)\"",
       
  5997             quote2quote = "'((?:\\\\.|[^'])*)'",
       
  5998             attributeEqAndValue = "(?:" + spaceEQspace + "(?:" +
       
  5999                 "(?:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?",
       
  6000             matchStash = "\\{\\{[^\\}]*\\}\\}\\}?",
       
  6001             stash = "\\{\\{([^\\}]*)\\}\\}\\}?",
       
  6002             startTag = new RegExp("^<([" + alphaNumericHU + "]+)" +
       
  6003                 "(" +
       
  6004                 "(?:\\s*" +
       
  6005                 "(?:(?:" +
       
  6006                 "(?:" + attributeNames + ")?" +
       
  6007                 attributeEqAndValue + ")|" +
       
  6008                 "(?:" + matchStash + ")+)" +
       
  6009                 ")*" +
       
  6010                 ")\\s*(\\/?)>"),
       
  6011             endTag = new RegExp("^<\\/([" + alphaNumericHU + "]+)[^>]*>"),
       
  6012             attr = new RegExp("(?:" +
       
  6013                 "(?:(" + attributeNames + ")|" + stash + ")" +
       
  6014                 "(?:" + spaceEQspace +
       
  6015                 "(?:" +
       
  6016                 "(?:" + dblQuote2dblQuote + ")|(?:" + quote2quote + ")|([^>\\s]+)" +
       
  6017                 ")" +
       
  6018                 ")?)", "g"),
       
  6019             mustache = new RegExp(stash, "g"),
       
  6020             txtBreak = /<|\{\{/;
       
  6021 
       
  6022         // Empty Elements - HTML 5
       
  6023         var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed");
       
  6024 
       
  6025         // Block Elements - HTML 5
       
  6026         var block = makeMap("address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video");
       
  6027 
       
  6028         // Inline Elements - HTML 5
       
  6029         var inline = makeMap("a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var");
       
  6030 
       
  6031         // Elements that you can, intentionally, leave open
       
  6032         // (and which close themselves)
       
  6033         var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");
       
  6034 
       
  6035         // Attributes that have their values filled in disabled="disabled"
       
  6036         var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected");
       
  6037 
       
  6038         // Special Elements (can contain anything)
       
  6039         var special = makeMap("script,style");
       
  6040 
       
  6041         var HTMLParser = function(html, handler) {
       
  6042 
       
  6043             function parseStartTag(tag, tagName, rest, unary) {
       
  6044                 tagName = tagName.toLowerCase();
       
  6045 
       
  6046                 if (block[tagName]) {
       
  6047                     while (stack.last() && inline[stack.last()]) {
       
  6048                         parseEndTag("", stack.last());
       
  6049                     }
       
  6050                 }
       
  6051 
       
  6052                 if (closeSelf[tagName] && stack.last() === tagName) {
       
  6053                     parseEndTag("", tagName);
       
  6054                 }
       
  6055 
       
  6056                 unary = empty[tagName] || !! unary;
       
  6057 
       
  6058                 handler.start(tagName, unary);
       
  6059 
       
  6060                 if (!unary) {
       
  6061                     stack.push(tagName);
       
  6062                 }
       
  6063                 // find attribute or special
       
  6064                 HTMLParser.parseAttrs(rest, handler);
       
  6065 
       
  6066                 handler.end(tagName, unary);
       
  6067 
       
  6068             }
       
  6069 
       
  6070             function parseEndTag(tag, tagName) {
       
  6071                 // If no tag name is provided, clean shop
       
  6072                 var pos;
       
  6073                 if (!tagName) {
       
  6074                     pos = 0;
       
  6075                 }
       
  6076 
       
  6077 
       
  6078                 // Find the closest opened tag of the same type
       
  6079                 else {
       
  6080                     for (pos = stack.length - 1; pos >= 0; pos--) {
       
  6081                         if (stack[pos] === tagName) {
       
  6082                             break;
       
  6083                         }
       
  6084                     }
       
  6085 
       
  6086                 }
       
  6087 
       
  6088 
       
  6089                 if (pos >= 0) {
       
  6090                     // Close all the open elements, up the stack
       
  6091                     for (var i = stack.length - 1; i >= pos; i--) {
       
  6092                         if (handler.close) {
       
  6093                             handler.close(stack[i]);
       
  6094                         }
       
  6095                     }
       
  6096 
       
  6097                     // Remove the open elements from the stack
       
  6098                     stack.length = pos;
       
  6099                 }
       
  6100             }
       
  6101 
       
  6102             function parseMustache(mustache, inside) {
       
  6103                 if (handler.special) {
       
  6104                     handler.special(inside);
       
  6105                 }
       
  6106             }
       
  6107 
       
  6108 
       
  6109             var index, chars, match, stack = [],
       
  6110                 last = html;
       
  6111             stack.last = function() {
       
  6112                 return this[this.length - 1];
       
  6113             };
       
  6114 
       
  6115             while (html) {
       
  6116                 chars = true;
       
  6117 
       
  6118                 // Make sure we're not in a script or style element
       
  6119                 if (!stack.last() || !special[stack.last()]) {
       
  6120 
       
  6121                     // Comment
       
  6122                     if (html.indexOf("<!--") === 0) {
       
  6123                         index = html.indexOf("-->");
       
  6124 
       
  6125                         if (index >= 0) {
       
  6126                             if (handler.comment) {
       
  6127                                 handler.comment(html.substring(4, index));
       
  6128                             }
       
  6129                             html = html.substring(index + 3);
       
  6130                             chars = false;
       
  6131                         }
       
  6132 
       
  6133                         // end tag
       
  6134                     } else if (html.indexOf("</") === 0) {
       
  6135                         match = html.match(endTag);
       
  6136 
       
  6137                         if (match) {
       
  6138                             html = html.substring(match[0].length);
       
  6139                             match[0].replace(endTag, parseEndTag);
       
  6140                             chars = false;
       
  6141                         }
       
  6142 
       
  6143                         // start tag
       
  6144                     } else if (html.indexOf("<") === 0) {
       
  6145                         match = html.match(startTag);
       
  6146 
       
  6147                         if (match) {
       
  6148                             html = html.substring(match[0].length);
       
  6149                             match[0].replace(startTag, parseStartTag);
       
  6150                             chars = false;
       
  6151                         }
       
  6152                     } else if (html.indexOf("{{") === 0) {
       
  6153                         match = html.match(mustache);
       
  6154 
       
  6155                         if (match) {
       
  6156                             html = html.substring(match[0].length);
       
  6157                             match[0].replace(mustache, parseMustache);
       
  6158                         }
       
  6159                     }
       
  6160 
       
  6161                     if (chars) {
       
  6162                         index = html.search(txtBreak);
       
  6163 
       
  6164                         var text = index < 0 ? html : html.substring(0, index);
       
  6165                         html = index < 0 ? "" : html.substring(index);
       
  6166 
       
  6167                         if (handler.chars && text) {
       
  6168                             handler.chars(text);
       
  6169                         }
       
  6170                     }
       
  6171 
       
  6172                 } else {
       
  6173                     html = html.replace(new RegExp("([\\s\\S]*?)<\/" + stack.last() + "[^>]*>"), function(all, text) {
       
  6174                         text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, "$1$2");
       
  6175                         if (handler.chars) {
       
  6176                             handler.chars(text);
       
  6177                         }
       
  6178                         return "";
       
  6179                     });
       
  6180 
       
  6181                     parseEndTag("", stack.last());
       
  6182                 }
       
  6183 
       
  6184                 if (html === last) {
       
  6185                     throw "Parse Error: " + html;
       
  6186                 }
       
  6187 
       
  6188                 last = html;
       
  6189             }
       
  6190 
       
  6191             // Clean up any remaining tags
       
  6192             parseEndTag();
       
  6193 
       
  6194 
       
  6195             handler.done();
       
  6196         };
       
  6197         HTMLParser.parseAttrs = function(rest, handler) {
       
  6198 
       
  6199 
       
  6200             (rest != null ? rest : "").replace(attr, function(text, name, special, dblQuote, singleQuote, val) {
       
  6201                 if (special) {
       
  6202                     handler.special(special);
       
  6203 
       
  6204                 }
       
  6205                 if (name || dblQuote || singleQuote || val) {
       
  6206                     var value = arguments[3] ? arguments[3] :
       
  6207                         arguments[4] ? arguments[4] :
       
  6208                         arguments[5] ? arguments[5] :
       
  6209                         fillAttrs[name.toLowerCase()] ? name : "";
       
  6210                     handler.attrStart(name || "");
       
  6211 
       
  6212                     var last = mustache.lastIndex = 0,
       
  6213                         res = mustache.exec(value),
       
  6214                         chars;
       
  6215                     while (res) {
       
  6216                         chars = value.substring(
       
  6217                             last,
       
  6218                             mustache.lastIndex - res[0].length);
       
  6219                         if (chars.length) {
       
  6220                             handler.attrValue(chars);
       
  6221                         }
       
  6222                         handler.special(res[1]);
       
  6223                         last = mustache.lastIndex;
       
  6224                         res = mustache.exec(value);
       
  6225                     }
       
  6226                     chars = value.substr(
       
  6227                         last,
       
  6228                         value.length);
       
  6229                     if (chars) {
       
  6230                         handler.attrValue(chars);
       
  6231                     }
       
  6232                     handler.attrEnd(name || "");
       
  6233                 }
       
  6234 
       
  6235 
       
  6236             });
       
  6237 
       
  6238 
       
  6239         };
       
  6240 
       
  6241         can.view.parser = HTMLParser;
       
  6242 
       
  6243         return HTMLParser;
       
  6244 
       
  6245     })(__m17);
       
  6246 
       
  6247     // ## can/view/live/live.js
       
  6248     var __m27 = (function(can, elements, view, nodeLists, parser) {
       
  6249 
       
  6250         elements = elements || can.view.elements;
       
  6251         nodeLists = nodeLists || can.view.NodeLists;
       
  6252         parser = parser || can.view.parser;
       
  6253 
       
  6254         // ## live.js
       
  6255         // The live module provides live binding for computes
       
  6256         // and can.List.
       
  6257         // Currently, it's API is designed for `can/view/render`, but
       
  6258         // it could easily be used for other purposes.
       
  6259         // ### Helper methods
       
  6260         // #### setup
       
  6261         // `setup(HTMLElement, bind(data), unbind(data)) -> data`
       
  6262         // Calls bind right away, but will call unbind
       
  6263         // if the element is "destroyed" (removed from the DOM).
       
  6264         var setup = function(el, bind, unbind) {
       
  6265             // Removing an element can call teardown which
       
  6266             // unregister the nodeList which calls teardown
       
  6267             var tornDown = false,
       
  6268                 teardown = function() {
       
  6269                     if (!tornDown) {
       
  6270                         tornDown = true;
       
  6271                         unbind(data);
       
  6272                         can.unbind.call(el, 'removed', teardown);
       
  6273                     }
       
  6274                     return true;
       
  6275                 }, data = {
       
  6276                     teardownCheck: function(parent) {
       
  6277                         return parent ? false : teardown();
       
  6278                     }
       
  6279                 };
       
  6280             can.bind.call(el, 'removed', teardown);
       
  6281             bind(data);
       
  6282             return data;
       
  6283         },
       
  6284             // #### listen
       
  6285             // Calls setup, but presets bind and unbind to
       
  6286             // operate on a compute
       
  6287             listen = function(el, compute, change) {
       
  6288                 return setup(el, function() {
       
  6289                     compute.bind('change', change);
       
  6290                 }, function(data) {
       
  6291                     compute.unbind('change', change);
       
  6292                     if (data.nodeList) {
       
  6293                         nodeLists.unregister(data.nodeList);
       
  6294                     }
       
  6295                 });
       
  6296             },
       
  6297             // #### getAttributeParts
       
  6298             // Breaks up a string like foo='bar' into ["foo","'bar'""]
       
  6299             getAttributeParts = function(newVal) {
       
  6300                 var attrs = {},
       
  6301                     attr;
       
  6302                 parser.parseAttrs(newVal, {
       
  6303                         attrStart: function(name) {
       
  6304                             attrs[name] = "";
       
  6305                             attr = name;
       
  6306                         },
       
  6307                         attrValue: function(value) {
       
  6308                             attrs[attr] += value;
       
  6309                         },
       
  6310                         attrEnd: function() {}
       
  6311                     });
       
  6312                 return attrs;
       
  6313             },
       
  6314             splice = [].splice,
       
  6315             isNode = function(obj) {
       
  6316                 return obj && obj.nodeType;
       
  6317             },
       
  6318             addTextNodeIfNoChildren = function(frag) {
       
  6319                 if (!frag.childNodes.length) {
       
  6320                     frag.appendChild(document.createTextNode(""));
       
  6321                 }
       
  6322             };
       
  6323 
       
  6324         var live = {
       
  6325 
       
  6326             list: function(el, compute, render, context, parentNode) {
       
  6327 
       
  6328                 // A nodeList of all elements this live-list manages.
       
  6329                 // This is here so that if this live list is within another section
       
  6330                 // that section is able to remove the items in this list.
       
  6331                 var masterNodeList = [el],
       
  6332                     // A mapping of items to their indicies'
       
  6333                     indexMap = [],
       
  6334                     // Called when items are added to the list.
       
  6335                     add = function(ev, items, index) {
       
  6336                         // Collect new html and mappings
       
  6337                         var frag = document.createDocumentFragment(),
       
  6338                             newNodeLists = [],
       
  6339                             newIndicies = [];
       
  6340                         // For each new item,
       
  6341                         can.each(items, function(item, key) {
       
  6342                             var itemIndex = can.compute(key + index),
       
  6343                                 // get its string content
       
  6344                                 itemHTML = render.call(context, item, itemIndex),
       
  6345                                 gotText = typeof itemHTML === "string",
       
  6346                                 // and convert it into elements.
       
  6347                                 itemFrag = can.frag(itemHTML);
       
  6348                             // Add those elements to the mappings.
       
  6349 
       
  6350                             itemFrag = gotText ? can.view.hookup(itemFrag) : itemFrag;
       
  6351 
       
  6352                             var childNodes = can.makeArray(itemFrag.childNodes);
       
  6353 
       
  6354 
       
  6355 
       
  6356                             newNodeLists.push(nodeLists.register(childNodes));
       
  6357                             // Hookup the fragment (which sets up child live-bindings) and
       
  6358                             // add it to the collection of all added elements.
       
  6359                             frag.appendChild(itemFrag);
       
  6360                             // track indicies;
       
  6361                             newIndicies.push(itemIndex);
       
  6362                         });
       
  6363                         // The position of elements is always after the initial text placeholder node
       
  6364                         var masterListIndex = index + 1;
       
  6365 
       
  6366 
       
  6367                         // Check if we are adding items at the end
       
  6368                         if (!masterNodeList[masterListIndex]) {
       
  6369                             elements.after(masterListIndex === 1 ? [text] : [nodeLists.last(masterNodeList[masterListIndex - 1])], frag);
       
  6370                         } else {
       
  6371                             // Add elements before the next index's first element.
       
  6372                             var el = nodeLists.first(masterNodeList[masterListIndex]);
       
  6373                             can.insertBefore(el.parentNode, frag, el);
       
  6374                         }
       
  6375                         splice.apply(masterNodeList, [
       
  6376                                 masterListIndex,
       
  6377                                 0
       
  6378                             ].concat(newNodeLists));
       
  6379 
       
  6380                         // update indices after insert point
       
  6381                         splice.apply(indexMap, [
       
  6382                                 index,
       
  6383                                 0
       
  6384                             ].concat(newIndicies));
       
  6385 
       
  6386                         for (var i = index + newIndicies.length, len = indexMap.length; i < len; i++) {
       
  6387                             indexMap[i](i);
       
  6388                         }
       
  6389                     },
       
  6390                     // Called when items are removed or when the bindings are torn down.
       
  6391                     remove = function(ev, items, index, duringTeardown, fullTeardown) {
       
  6392                         // If this is because an element was removed, we should
       
  6393                         // check to make sure the live elements are still in the page.
       
  6394                         // If we did this during a teardown, it would cause an infinite loop.
       
  6395                         if (!duringTeardown && data.teardownCheck(text.parentNode)) {
       
  6396                             return;
       
  6397                         }
       
  6398                         var removedMappings = masterNodeList.splice(index + 1, items.length),
       
  6399                             itemsToRemove = [];
       
  6400                         can.each(removedMappings, function(nodeList) {
       
  6401 
       
  6402                             // Unregister to free up event bindings.
       
  6403                             var nodesToRemove = nodeLists.unregister(nodeList);
       
  6404 
       
  6405                             // add items that we will remove all at once
       
  6406                             [].push.apply(itemsToRemove, nodesToRemove);
       
  6407                         });
       
  6408                         // update indices after remove point
       
  6409                         indexMap.splice(index, items.length);
       
  6410                         for (var i = index, len = indexMap.length; i < len; i++) {
       
  6411                             indexMap[i](i);
       
  6412                         }
       
  6413                         // don't remove elements during teardown.  Something else will probably be doing that.
       
  6414                         if (!fullTeardown) {
       
  6415                             can.remove(can.$(itemsToRemove));
       
  6416                         }
       
  6417 
       
  6418                     },
       
  6419                     // A text node placeholder
       
  6420                     text = document.createTextNode(''),
       
  6421                     // The current list.
       
  6422                     list,
       
  6423                     // Called when the list is replaced with a new list or the binding is torn-down.
       
  6424                     teardownList = function(fullTeardown) {
       
  6425                         // there might be no list right away, and the list might be a plain
       
  6426                         // array
       
  6427                         if (list && list.unbind) {
       
  6428                             list.unbind('add', add)
       
  6429                                 .unbind('remove', remove);
       
  6430                         }
       
  6431                         // use remove to clean stuff up for us
       
  6432                         remove({}, {
       
  6433                                 length: masterNodeList.length - 1
       
  6434                             }, 0, true, fullTeardown);
       
  6435                     },
       
  6436                     // Called when the list is replaced or setup.
       
  6437                     updateList = function(ev, newList, oldList) {
       
  6438                         teardownList();
       
  6439                         // make an empty list if the compute returns null or undefined
       
  6440                         list = newList || [];
       
  6441                         // list might be a plain array
       
  6442                         if (list.bind) {
       
  6443                             list.bind('add', add)
       
  6444                                 .bind('remove', remove);
       
  6445                         }
       
  6446                         add({}, list, 0);
       
  6447                     };
       
  6448                 parentNode = elements.getParentNode(el, parentNode);
       
  6449                 // Setup binding and teardown to add and remove events
       
  6450                 var data = setup(parentNode, function() {
       
  6451                     if (can.isFunction(compute)) {
       
  6452                         compute.bind('change', updateList);
       
  6453                     }
       
  6454                 }, function() {
       
  6455                     if (can.isFunction(compute)) {
       
  6456                         compute.unbind('change', updateList);
       
  6457                     }
       
  6458                     teardownList(true);
       
  6459                 });
       
  6460 
       
  6461                 live.replace(masterNodeList, text, data.teardownCheck);
       
  6462                 // run the list setup
       
  6463                 updateList({}, can.isFunction(compute) ? compute() : compute);
       
  6464             },
       
  6465 
       
  6466             html: function(el, compute, parentNode) {
       
  6467                 var data;
       
  6468                 parentNode = elements.getParentNode(el, parentNode);
       
  6469                 data = listen(parentNode, compute, function(ev, newVal, oldVal) {
       
  6470 
       
  6471                     // TODO: remove teardownCheck in 2.1
       
  6472                     var attached = nodeLists.first(nodes).parentNode;
       
  6473                     // update the nodes in the DOM with the new rendered value
       
  6474                     if (attached) {
       
  6475                         makeAndPut(newVal);
       
  6476                     }
       
  6477                     data.teardownCheck(nodeLists.first(nodes).parentNode);
       
  6478                 });
       
  6479 
       
  6480                 var nodes = [el],
       
  6481                     makeAndPut = function(val) {
       
  6482                         var isString = !isNode(val),
       
  6483                             frag = can.frag(val),
       
  6484                             oldNodes = can.makeArray(nodes);
       
  6485 
       
  6486                         // Add a placeholder textNode if necessary.
       
  6487                         addTextNodeIfNoChildren(frag);
       
  6488 
       
  6489                         if (isString) {
       
  6490                             frag = can.view.hookup(frag, parentNode);
       
  6491                         }
       
  6492                         // We need to mark each node as belonging to the node list.
       
  6493                         oldNodes = nodeLists.update(nodes, frag.childNodes);
       
  6494                         elements.replace(oldNodes, frag);
       
  6495                     };
       
  6496                 data.nodeList = nodes;
       
  6497 
       
  6498                 // register the span so nodeLists knows the parentNodeList
       
  6499                 nodeLists.register(nodes, data.teardownCheck);
       
  6500                 makeAndPut(compute());
       
  6501             },
       
  6502 
       
  6503             replace: function(nodes, val, teardown) {
       
  6504                 var oldNodes = nodes.slice(0),
       
  6505                     frag = can.frag(val);
       
  6506                 nodeLists.register(nodes, teardown);
       
  6507 
       
  6508 
       
  6509                 if (typeof val === 'string') {
       
  6510                     // if it was a string, check for hookups
       
  6511                     frag = can.view.hookup(frag, nodes[0].parentNode);
       
  6512                 }
       
  6513                 // We need to mark each node as belonging to the node list.
       
  6514                 nodeLists.update(nodes, frag.childNodes);
       
  6515                 elements.replace(oldNodes, frag);
       
  6516                 return nodes;
       
  6517             },
       
  6518 
       
  6519             text: function(el, compute, parentNode) {
       
  6520                 var parent = elements.getParentNode(el, parentNode);
       
  6521                 // setup listening right away so we don't have to re-calculate value
       
  6522                 var data = listen(parent, compute, function(ev, newVal, oldVal) {
       
  6523                     // Sometimes this is 'unknown' in IE and will throw an exception if it is
       
  6524 
       
  6525                     if (typeof node.nodeValue !== 'unknown') {
       
  6526                         node.nodeValue = can.view.toStr(newVal);
       
  6527                     }
       
  6528 
       
  6529                     // TODO: remove in 2.1
       
  6530                     data.teardownCheck(node.parentNode);
       
  6531                 }),
       
  6532                     // The text node that will be updated
       
  6533                     node = document.createTextNode(can.view.toStr(compute()));
       
  6534                 // Replace the placeholder with the live node and do the nodeLists thing.
       
  6535                 // Add that node to nodeList so we can remove it when the parent element is removed from the page
       
  6536                 data.nodeList = live.replace([el], node, data.teardownCheck);
       
  6537             },
       
  6538             setAttributes: function(el, newVal) {
       
  6539                 var attrs = getAttributeParts(newVal);
       
  6540                 for (var name in attrs) {
       
  6541                     can.attr.set(el, name, attrs[name]);
       
  6542                 }
       
  6543             },
       
  6544 
       
  6545             attributes: function(el, compute, currentValue) {
       
  6546                 var oldAttrs = {};
       
  6547 
       
  6548                 var setAttrs = function(newVal) {
       
  6549                     var newAttrs = getAttributeParts(newVal),
       
  6550                         name;
       
  6551                     for (name in newAttrs) {
       
  6552                         var newValue = newAttrs[name],
       
  6553                             oldValue = oldAttrs[name];
       
  6554                         if (newValue !== oldValue) {
       
  6555                             can.attr.set(el, name, newValue);
       
  6556                         }
       
  6557                         delete oldAttrs[name];
       
  6558                     }
       
  6559                     for (name in oldAttrs) {
       
  6560                         elements.removeAttr(el, name);
       
  6561                     }
       
  6562                     oldAttrs = newAttrs;
       
  6563                 };
       
  6564                 listen(el, compute, function(ev, newVal) {
       
  6565                     setAttrs(newVal);
       
  6566                 });
       
  6567                 // current value has been set
       
  6568                 if (arguments.length >= 3) {
       
  6569                     oldAttrs = getAttributeParts(currentValue);
       
  6570                 } else {
       
  6571                     setAttrs(compute());
       
  6572                 }
       
  6573             },
       
  6574             attributePlaceholder: '__!!__',
       
  6575             attributeReplace: /__!!__/g,
       
  6576             attribute: function(el, attributeName, compute) {
       
  6577                 listen(el, compute, function(ev, newVal) {
       
  6578                     elements.setAttr(el, attributeName, hook.render());
       
  6579                 });
       
  6580                 var wrapped = can.$(el),
       
  6581                     hooks;
       
  6582                 // Get the list of hookups or create one for this element.
       
  6583                 // Hooks is a map of attribute names to hookup `data`s.
       
  6584                 // Each hookup data has:
       
  6585                 // `render` - A `function` to render the value of the attribute.
       
  6586                 // `funcs` - A list of hookup `function`s on that attribute.
       
  6587                 // `batchNum` - The last event `batchNum`, used for performance.
       
  6588                 hooks = can.data(wrapped, 'hooks');
       
  6589                 if (!hooks) {
       
  6590                     can.data(wrapped, 'hooks', hooks = {});
       
  6591                 }
       
  6592                 // Get the attribute value.
       
  6593                 var attr = elements.getAttr(el, attributeName),
       
  6594                     // Split the attribute value by the template.
       
  6595                     // Only split out the first __!!__ so if we have multiple hookups in the same attribute,
       
  6596                     // they will be put in the right spot on first render
       
  6597                     parts = attr.split(live.attributePlaceholder),
       
  6598                     goodParts = [],
       
  6599                     hook;
       
  6600                 goodParts.push(parts.shift(), parts.join(live.attributePlaceholder));
       
  6601                 // If we already had a hookup for this attribute...
       
  6602                 if (hooks[attributeName]) {
       
  6603                     // Just add to that attribute's list of `function`s.
       
  6604                     hooks[attributeName].computes.push(compute);
       
  6605                 } else {
       
  6606                     // Create the hookup data.
       
  6607                     hooks[attributeName] = {
       
  6608                         render: function() {
       
  6609                             var i = 0,
       
  6610                                 // attr doesn't have a value in IE
       
  6611                                 newAttr = attr ? attr.replace(live.attributeReplace, function() {
       
  6612                                     return elements.contentText(hook.computes[i++]());
       
  6613                                 }) : elements.contentText(hook.computes[i++]());
       
  6614                             return newAttr;
       
  6615                         },
       
  6616                         computes: [compute],
       
  6617                         batchNum: undefined
       
  6618                     };
       
  6619                 }
       
  6620                 // Save the hook for slightly faster performance.
       
  6621                 hook = hooks[attributeName];
       
  6622                 // Insert the value in parts.
       
  6623                 goodParts.splice(1, 0, compute());
       
  6624 
       
  6625                 // Set the attribute.
       
  6626                 elements.setAttr(el, attributeName, goodParts.join(''));
       
  6627             },
       
  6628             specialAttribute: function(el, attributeName, compute) {
       
  6629                 listen(el, compute, function(ev, newVal) {
       
  6630                     elements.setAttr(el, attributeName, getValue(newVal));
       
  6631                 });
       
  6632                 elements.setAttr(el, attributeName, getValue(compute()));
       
  6633             },
       
  6634 
       
  6635             simpleAttribute: function(el, attributeName, compute) {
       
  6636                 listen(el, compute, function(ev, newVal) {
       
  6637                     elements.setAttr(el, attributeName, newVal);
       
  6638                 });
       
  6639                 elements.setAttr(el, attributeName, compute());
       
  6640             }
       
  6641         };
       
  6642         live.attr = live.simpleAttribute;
       
  6643         live.attrs = live.attributes;
       
  6644         var newLine = /(\r|\n)+/g;
       
  6645         var getValue = function(val) {
       
  6646             var regexp = /^["'].*["']$/;
       
  6647             val = val.replace(elements.attrReg, '')
       
  6648                 .replace(newLine, '');
       
  6649             // check if starts and ends with " or '
       
  6650             return regexp.test(val) ? val.substr(1, val.length - 2) : val;
       
  6651         };
       
  6652         can.view.live = live;
       
  6653 
       
  6654         return live;
       
  6655     })(__m3, __m24, __m17, __m28, __m29);
       
  6656 
       
  6657     // ## can/view/render.js
       
  6658     var __m26 = (function(can, elements, live) {
       
  6659 
       
  6660 
       
  6661         var pendingHookups = [],
       
  6662             tagChildren = function(tagName) {
       
  6663                 var newTag = elements.tagMap[tagName] || "span";
       
  6664                 if (newTag === "span") {
       
  6665                     //innerHTML in IE doesn't honor leading whitespace after empty elements
       
  6666                     return "@@!!@@";
       
  6667                 }
       
  6668                 return "<" + newTag + ">" + tagChildren(newTag) + "</" + newTag + ">";
       
  6669             },
       
  6670             contentText = function(input, tag) {
       
  6671 
       
  6672                 // If it's a string, return.
       
  6673                 if (typeof input === 'string') {
       
  6674                     return input;
       
  6675                 }
       
  6676                 // If has no value, return an empty string.
       
  6677                 if (!input && input !== 0) {
       
  6678                     return '';
       
  6679                 }
       
  6680 
       
  6681                 // If it's an object, and it has a hookup method.
       
  6682                 var hook = (input.hookup &&
       
  6683 
       
  6684                     // Make a function call the hookup method.
       
  6685 
       
  6686                     function(el, id) {
       
  6687                         input.hookup.call(input, el, id);
       
  6688                     }) ||
       
  6689 
       
  6690                 // Or if it's a `function`, just use the input.
       
  6691                 (typeof input === 'function' && input);
       
  6692 
       
  6693                 // Finally, if there is a `function` to hookup on some dom,
       
  6694                 // add it to pending hookups.
       
  6695                 if (hook) {
       
  6696                     if (tag) {
       
  6697                         return "<" + tag + " " + can.view.hook(hook) + "></" + tag + ">";
       
  6698                     } else {
       
  6699                         pendingHookups.push(hook);
       
  6700                     }
       
  6701 
       
  6702                     return '';
       
  6703                 }
       
  6704 
       
  6705                 // Finally, if all else is `false`, `toString()` it.
       
  6706                 return "" + input;
       
  6707             },
       
  6708             // Returns escaped/sanatized content for anything other than a live-binding
       
  6709             contentEscape = function(txt, tag) {
       
  6710                 return (typeof txt === 'string' || typeof txt === 'number') ?
       
  6711                     can.esc(txt) :
       
  6712                     contentText(txt, tag);
       
  6713             },
       
  6714             // A flag to indicate if .txt was called within a live section within an element like the {{name}}
       
  6715             // within `<div {{#person}}{{name}}{{/person}}/>`.
       
  6716             withinTemplatedSectionWithinAnElement = false,
       
  6717             emptyHandler = function() {};
       
  6718 
       
  6719         var lastHookups;
       
  6720 
       
  6721         can.extend(can.view, {
       
  6722                 live: live,
       
  6723                 // called in text to make a temporary 
       
  6724                 // can.view.lists function that can be called with
       
  6725                 // the list to iterate over and the template
       
  6726                 // used to produce the content within the list
       
  6727                 setupLists: function() {
       
  6728 
       
  6729                     var old = can.view.lists,
       
  6730                         data;
       
  6731 
       
  6732                     can.view.lists = function(list, renderer) {
       
  6733                         data = {
       
  6734                             list: list,
       
  6735                             renderer: renderer
       
  6736                         };
       
  6737                         return Math.random();
       
  6738                     };
       
  6739                     // sets back to the old data
       
  6740                     return function() {
       
  6741                         can.view.lists = old;
       
  6742                         return data;
       
  6743                     };
       
  6744                 },
       
  6745                 getHooks: function() {
       
  6746                     var hooks = pendingHookups.slice(0);
       
  6747                     lastHookups = hooks;
       
  6748                     pendingHookups = [];
       
  6749                     return hooks;
       
  6750                 },
       
  6751                 onlytxt: function(self, func) {
       
  6752                     return contentEscape(func.call(self));
       
  6753                 },
       
  6754 
       
  6755                 txt: function(escape, tagName, status, self, func) {
       
  6756                     // the temporary tag needed for any live setup
       
  6757                     var tag = (elements.tagMap[tagName] || "span"),
       
  6758                         // should live-binding be setup
       
  6759                         setupLiveBinding = false,
       
  6760                         // the compute's value
       
  6761                         value,
       
  6762                         listData,
       
  6763                         compute,
       
  6764                         unbind = emptyHandler,
       
  6765                         attributeName;
       
  6766 
       
  6767                     // Are we currently within a live section within an element like the {{name}}
       
  6768                     // within `<div {{#person}}{{name}}{{/person}}/>`.
       
  6769                     if (withinTemplatedSectionWithinAnElement) {
       
  6770                         value = func.call(self);
       
  6771                     } else {
       
  6772 
       
  6773                         // If this magic tag is within an attribute or an html element,
       
  6774                         // set the flag to true so we avoid trying to live bind
       
  6775                         // anything that func might be setup.
       
  6776                         // TODO: the scanner should be able to set this up.
       
  6777                         if (typeof status === "string" || status === 1) {
       
  6778                             withinTemplatedSectionWithinAnElement = true;
       
  6779                         }
       
  6780 
       
  6781                         // Sets up a listener so we know any can.view.lists called 
       
  6782                         // when func is called
       
  6783                         var listTeardown = can.view.setupLists();
       
  6784                         unbind = function() {
       
  6785                             compute.unbind("change", emptyHandler);
       
  6786                         };
       
  6787                         // Create a compute that calls func and looks for dependencies.
       
  6788                         // By passing `false`, this compute can not be a dependency of other 
       
  6789                         // computes.  This is because live-bits are nested, but 
       
  6790                         // handle their own updating. For example:
       
  6791                         //     {{#if items.length}}{{#items}}{{.}}{{/items}}{{/if}}
       
  6792                         // We do not want `{{#if items.length}}` changing the DOM if
       
  6793                         // `{{#items}}` text changes.
       
  6794                         compute = can.compute(func, self, false);
       
  6795 
       
  6796                         // Bind to get and temporarily cache the value of the compute.
       
  6797                         compute.bind("change", emptyHandler);
       
  6798 
       
  6799                         // Call the "wrapping" function and get the binding information
       
  6800                         listData = listTeardown();
       
  6801 
       
  6802                         // Get the value of the compute
       
  6803                         value = compute();
       
  6804 
       
  6805                         // Let people know we are no longer within an element.
       
  6806                         withinTemplatedSectionWithinAnElement = false;
       
  6807 
       
  6808                         // If we should setup live-binding.
       
  6809                         setupLiveBinding = compute.hasDependencies;
       
  6810                     }
       
  6811 
       
  6812                     if (listData) {
       
  6813                         unbind();
       
  6814                         return "<" + tag + can.view.hook(function(el, parentNode) {
       
  6815                             live.list(el, listData.list, listData.renderer, self, parentNode);
       
  6816                         }) + "></" + tag + ">";
       
  6817                     }
       
  6818 
       
  6819                     // If we had no observes just return the value returned by func.
       
  6820                     if (!setupLiveBinding || typeof value === "function") {
       
  6821                         unbind();
       
  6822                         return ((withinTemplatedSectionWithinAnElement || escape === 2 || !escape) ?
       
  6823                             contentText :
       
  6824                             contentEscape)(value, status === 0 && tag);
       
  6825                     }
       
  6826 
       
  6827                     // the property (instead of innerHTML elements) to adjust. For
       
  6828                     // example options should use textContent
       
  6829                     var contentProp = elements.tagToContentPropMap[tagName];
       
  6830 
       
  6831                     // The magic tag is outside or between tags.
       
  6832                     if (status === 0 && !contentProp) {
       
  6833                         // Return an element tag with a hookup in place of the content
       
  6834                         return "<" + tag + can.view.hook(
       
  6835                             // if value is an object, it's likely something returned by .safeString
       
  6836                             escape && typeof value !== "object" ?
       
  6837                             // If we are escaping, replace the parentNode with 
       
  6838                             // a text node who's value is `func`'s return value.
       
  6839 
       
  6840                             function(el, parentNode) {
       
  6841                                 live.text(el, compute, parentNode);
       
  6842                                 unbind();
       
  6843                             } :
       
  6844                             // If we are not escaping, replace the parentNode with a
       
  6845                             // documentFragment created as with `func`'s return value.
       
  6846 
       
  6847                             function(el, parentNode) {
       
  6848                                 live.html(el, compute, parentNode);
       
  6849                                 unbind();
       
  6850                                 //children have to be properly nested HTML for buildFragment to work properly
       
  6851                             }) + ">" + tagChildren(tag) + "</" + tag + ">";
       
  6852                         // In a tag, but not in an attribute
       
  6853                     } else if (status === 1) {
       
  6854                         // remember the old attr name
       
  6855                         pendingHookups.push(function(el) {
       
  6856                             live.attributes(el, compute, compute());
       
  6857                             unbind();
       
  6858                         });
       
  6859 
       
  6860                         return compute();
       
  6861                     } else if (escape === 2) { // In a special attribute like src or style
       
  6862 
       
  6863                         attributeName = status;
       
  6864                         pendingHookups.push(function(el) {
       
  6865                             live.specialAttribute(el, attributeName, compute);
       
  6866                             unbind();
       
  6867                         });
       
  6868                         return compute();
       
  6869                     } else { // In an attribute...
       
  6870                         attributeName = status === 0 ? contentProp : status;
       
  6871                         // if the magic tag is inside the element, like `<option><% TAG %></option>`,
       
  6872                         // we add this hookup to the last element (ex: `option`'s) hookups.
       
  6873                         // Otherwise, the magic tag is in an attribute, just add to the current element's
       
  6874                         // hookups.
       
  6875                         (status === 0 ? lastHookups : pendingHookups)
       
  6876                             .push(function(el) {
       
  6877                                 live.attribute(el, attributeName, compute);
       
  6878                                 unbind();
       
  6879                             });
       
  6880                         return live.attributePlaceholder;
       
  6881                     }
       
  6882                 }
       
  6883             });
       
  6884 
       
  6885         return can;
       
  6886     })(__m17, __m24, __m27, __m2);
       
  6887 
       
  6888     // ## can/view/ejs/ejs.js
       
  6889     var __m22 = (function(can) {
       
  6890         // ## Helper methods
       
  6891         var extend = can.extend,
       
  6892             EJS = function(options) {
       
  6893                 // Supports calling EJS without the constructor.
       
  6894                 // This returns a function that renders the template.
       
  6895                 if (this.constructor !== EJS) {
       
  6896                     var ejs = new EJS(options);
       
  6897                     return function(data, helpers) {
       
  6898                         return ejs.render(data, helpers);
       
  6899                     };
       
  6900                 }
       
  6901                 // If we get a `function` directly, it probably is coming from
       
  6902                 // a `steal`-packaged view.
       
  6903                 if (typeof options === 'function') {
       
  6904                     this.template = {
       
  6905                         fn: options
       
  6906                     };
       
  6907                     return;
       
  6908                 }
       
  6909                 // Set options on self.
       
  6910                 extend(this, options);
       
  6911                 this.template = this.scanner.scan(this.text, this.name);
       
  6912             };
       
  6913         // Expose EJS via the `can` object.
       
  6914         can.EJS = EJS;
       
  6915 
       
  6916         EJS.prototype.
       
  6917         // ## Render
       
  6918         // Render a view object with data and helpers.
       
  6919         render = function(object, extraHelpers) {
       
  6920             object = object || {};
       
  6921             return this.template.fn.call(object, object, new EJS.Helpers(object, extraHelpers || {}));
       
  6922         };
       
  6923         extend(EJS.prototype, {
       
  6924                 // ## Scanner
       
  6925                 // Singleton scanner instance for parsing templates. See [scanner.js](scanner.html)
       
  6926                 // for more information.
       
  6927                 // ### Text
       
  6928                 // #### Definitions
       
  6929                 // * `outStart` - Wrapper start text for view function.
       
  6930                 // * `outEnd` - Wrapper end text for view function.
       
  6931                 // * `argNames` - Arguments passed into view function.
       
  6932                 scanner: new can.view.Scanner({
       
  6933                         text: {
       
  6934                             outStart: 'with(_VIEW) { with (_CONTEXT) {',
       
  6935                             outEnd: "}}",
       
  6936                             argNames: '_CONTEXT,_VIEW',
       
  6937                             context: "this"
       
  6938                         },
       
  6939                         // ### Tokens
       
  6940                         // An ordered token registry for the scanner. Scanner makes evaluations
       
  6941                         // based on which tags are considered opening/closing as well as escaped, etc.
       
  6942                         tokens: [
       
  6943                             ["templateLeft", "<%%"],
       
  6944                             ["templateRight", "%>"],
       
  6945                             ["returnLeft", "<%=="],
       
  6946                             ["escapeLeft", "<%="],
       
  6947                             ["commentLeft", "<%#"],
       
  6948                             ["left", "<%"],
       
  6949                             ["right", "%>"],
       
  6950                             ["returnRight", "%>"]
       
  6951                         ],
       
  6952                         // ### Helpers
       
  6953                         helpers: [{
       
  6954                                 // Regex to see if its a func like `()->`.
       
  6955                                 name: /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
       
  6956                                 // Evaluate rocket syntax function with correct context.
       
  6957                                 fn: function(content) {
       
  6958                                     var quickFunc = /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
       
  6959                                         parts = content.match(quickFunc);
       
  6960 
       
  6961                                     return "can.proxy(function(__){var " + parts[1] + "=can.$(__);" + parts[2] + "}, this);";
       
  6962                                 }
       
  6963                             }
       
  6964                         ],
       
  6965                         // ### transform
       
  6966                         // Transforms the EJS template to add support for shared blocks.
       
  6967                         // Essentially, this breaks up EJS tags into multiple EJS tags
       
  6968                         // if they contained unmatched brackets.
       
  6969                         // For example, this doesn't work:
       
  6970                         // `<% if (1) { %><% if (1) { %> hi <% } } %>`
       
  6971                         // ...without isolated EJS blocks:
       
  6972                         // `<% if (1) { %><% if (1) { %> hi <% } %><% } %>`
       
  6973                         // The result of transforming:
       
  6974                         // `<% if (1) { %><% %><% if (1) { %><% %> hi <% } %><% } %>`
       
  6975                         transform: function(source) {
       
  6976                             return source.replace(/<%([\s\S]+?)%>/gm, function(whole, part) {
       
  6977                                 var brackets = [],
       
  6978                                     foundBracketPair, i;
       
  6979                                 // Look for brackets (for removing self-contained blocks)
       
  6980                                 part.replace(/[{}]/gm, function(bracket, offset) {
       
  6981                                     brackets.push([
       
  6982                                             bracket,
       
  6983                                             offset
       
  6984                                         ]);
       
  6985                                 });
       
  6986                                 // Remove bracket pairs from the list of replacements
       
  6987                                 do {
       
  6988                                     foundBracketPair = false;
       
  6989                                     for (i = brackets.length - 2; i >= 0; i--) {
       
  6990                                         if (brackets[i][0] === '{' && brackets[i + 1][0] === '}') {
       
  6991                                             brackets.splice(i, 2);
       
  6992                                             foundBracketPair = true;
       
  6993                                             break;
       
  6994                                         }
       
  6995                                     }
       
  6996                                 } while (foundBracketPair);
       
  6997                                 // Unmatched brackets found, inject EJS tags
       
  6998                                 if (brackets.length >= 2) {
       
  6999                                     var result = ['<%'],
       
  7000                                         bracket, last = 0;
       
  7001                                     for (i = 0; bracket = brackets[i]; i++) {
       
  7002                                         result.push(part.substring(last, last = bracket[1]));
       
  7003                                         if (bracket[0] === '{' && i < brackets.length - 1 || bracket[0] === '}' && i > 0) {
       
  7004                                             result.push(bracket[0] === '{' ? '{ %><% ' : ' %><% }');
       
  7005                                         } else {
       
  7006                                             result.push(bracket[0]);
       
  7007                                         }
       
  7008                                         ++last;
       
  7009                                     }
       
  7010                                     result.push(part.substring(last), '%>');
       
  7011                                     return result.join('');
       
  7012                                 }
       
  7013                                 // Otherwise return the original
       
  7014                                 else {
       
  7015                                     return '<%' + part + '%>';
       
  7016                                 }
       
  7017                             });
       
  7018                         }
       
  7019                     })
       
  7020             });
       
  7021 
       
  7022         // ## Helpers
       
  7023         // In your EJS view you can then call the helper on an element tag:
       
  7024         // `<div <%= upperHtml('javascriptmvc') %>></div>`
       
  7025         EJS.Helpers = function(data, extras) {
       
  7026             this._data = data;
       
  7027             this._extras = extras;
       
  7028             extend(this, extras);
       
  7029         };
       
  7030 
       
  7031         EJS.Helpers.prototype = {
       
  7032             // List allows for live binding a can.List easily within a template.
       
  7033             list: function(list, cb) {
       
  7034                 can.each(list, function(item, i) {
       
  7035                     cb(item, i, list);
       
  7036                 });
       
  7037             },
       
  7038             // `each` iterates through a enumerated source(such as can.List or array)
       
  7039             // and sets up live binding when possible.
       
  7040             each: function(list, cb) {
       
  7041                 // Normal arrays don't get live updated
       
  7042                 if (can.isArray(list)) {
       
  7043                     this.list(list, cb);
       
  7044                 } else {
       
  7045                     can.view.lists(list, cb);
       
  7046                 }
       
  7047             }
       
  7048         };
       
  7049         // Registers options for a `steal` build.
       
  7050         can.view.register({
       
  7051                 suffix: 'ejs',
       
  7052                 script: function(id, src) {
       
  7053                     return 'can.EJS(function(_CONTEXT,_VIEW) { ' + new EJS({
       
  7054                             text: src,
       
  7055                             name: id
       
  7056                         })
       
  7057                         .template.out + ' })';
       
  7058                 },
       
  7059                 renderer: function(id, text) {
       
  7060                     return EJS({
       
  7061                             text: text,
       
  7062                             name: id
       
  7063                         });
       
  7064                 }
       
  7065             });
       
  7066         can.ejs.Helpers = EJS.Helpers;
       
  7067 
       
  7068 
       
  7069         return can;
       
  7070     })(__m3, __m17, __m2, __m15, __m23, __m26);
       
  7071 
       
  7072     // ## can/util/object/object.js
       
  7073     var __m31 = (function(can) {
       
  7074         var isArray = can.isArray;
       
  7075 
       
  7076         can.Object = {};
       
  7077 
       
  7078         var same = can.Object.same = function(a, b, compares, aParent, bParent, deep) {
       
  7079             var aType = typeof a,
       
  7080                 aArray = isArray(a),
       
  7081                 comparesType = typeof compares,
       
  7082                 compare;
       
  7083             if (comparesType === 'string' || compares === null) {
       
  7084                 compares = compareMethods[compares];
       
  7085                 comparesType = 'function';
       
  7086             }
       
  7087             if (comparesType === 'function') {
       
  7088                 return compares(a, b, aParent, bParent);
       
  7089             }
       
  7090             compares = compares || {};
       
  7091             if (a === null || b === null) {
       
  7092                 return a === b;
       
  7093             }
       
  7094             if (a instanceof Date || b instanceof Date) {
       
  7095                 return a === b;
       
  7096             }
       
  7097             if (deep === -1) {
       
  7098                 return aType === 'object' || a === b;
       
  7099             }
       
  7100             if (aType !== typeof b || aArray !== isArray(b)) {
       
  7101                 return false;
       
  7102             }
       
  7103             if (a === b) {
       
  7104                 return true;
       
  7105             }
       
  7106             if (aArray) {
       
  7107                 if (a.length !== b.length) {
       
  7108                     return false;
       
  7109                 }
       
  7110                 for (var i = 0; i < a.length; i++) {
       
  7111                     compare = compares[i] === undefined ? compares['*'] : compares[i];
       
  7112                     if (!same(a[i], b[i], a, b, compare)) {
       
  7113                         return false;
       
  7114                     }
       
  7115                 }
       
  7116                 return true;
       
  7117             } else if (aType === 'object' || aType === 'function') {
       
  7118                 var bCopy = can.extend({}, b);
       
  7119                 for (var prop in a) {
       
  7120                     compare = compares[prop] === undefined ? compares['*'] : compares[prop];
       
  7121                     if (!same(a[prop], b[prop], compare, a, b, deep === false ? -1 : undefined)) {
       
  7122                         return false;
       
  7123                     }
       
  7124                     delete bCopy[prop];
       
  7125                 }
       
  7126                 // go through bCopy props ... if there is no compare .. return false
       
  7127                 for (prop in bCopy) {
       
  7128                     if (compares[prop] === undefined || !same(undefined, b[prop], compares[prop], a, b, deep === false ? -1 : undefined)) {
       
  7129                         return false;
       
  7130                     }
       
  7131                 }
       
  7132                 return true;
       
  7133             }
       
  7134             return false;
       
  7135         };
       
  7136 
       
  7137         can.Object.subsets = function(checkSet, sets, compares) {
       
  7138             var len = sets.length,
       
  7139                 subsets = [];
       
  7140             for (var i = 0; i < len; i++) {
       
  7141                 //check this subset
       
  7142                 var set = sets[i];
       
  7143                 if (can.Object.subset(checkSet, set, compares)) {
       
  7144                     subsets.push(set);
       
  7145                 }
       
  7146             }
       
  7147             return subsets;
       
  7148         };
       
  7149 
       
  7150         can.Object.subset = function(subset, set, compares) {
       
  7151             // go through set {type: 'folder'} and make sure every property
       
  7152             // is in subset {type: 'folder', parentId :5}
       
  7153             // then make sure that set has fewer properties
       
  7154             // make sure we are only checking 'important' properties
       
  7155             // in subset (ones that have to have a value)
       
  7156             compares = compares || {};
       
  7157             for (var prop in set) {
       
  7158                 if (!same(subset[prop], set[prop], compares[prop], subset, set)) {
       
  7159                     return false;
       
  7160                 }
       
  7161             }
       
  7162             return true;
       
  7163         };
       
  7164         var compareMethods = {
       
  7165             'null': function() {
       
  7166                 return true;
       
  7167             },
       
  7168             i: function(a, b) {
       
  7169                 return ('' + a)
       
  7170                     .toLowerCase() === ('' + b)
       
  7171                     .toLowerCase();
       
  7172             },
       
  7173             eq: function(a, b) {
       
  7174                 return a === b;
       
  7175             },
       
  7176             similar: function(a, b) {
       
  7177 
       
  7178                 return a == b;
       
  7179             }
       
  7180         };
       
  7181         compareMethods.eqeq = compareMethods.similar;
       
  7182         return can.Object;
       
  7183     })(__m3);
       
  7184 
       
  7185     // ## can/map/backup/backup.js
       
  7186     var __m30 = (function(can) {
       
  7187         var flatProps = function(a, cur) {
       
  7188             var obj = {};
       
  7189             for (var prop in a) {
       
  7190                 if (typeof a[prop] !== 'object' || a[prop] === null || a[prop] instanceof Date) {
       
  7191                     obj[prop] = a[prop];
       
  7192                 } else {
       
  7193                     obj[prop] = cur.attr(prop);
       
  7194                 }
       
  7195             }
       
  7196             return obj;
       
  7197         };
       
  7198         can.extend(can.Map.prototype, {
       
  7199 
       
  7200                 backup: function() {
       
  7201                     this._backupStore = this._attrs();
       
  7202                     return this;
       
  7203                 },
       
  7204                 isDirty: function(checkAssociations) {
       
  7205                     return this._backupStore && !can.Object.same(this._attrs(), this._backupStore, undefined, undefined, undefined, !! checkAssociations);
       
  7206                 },
       
  7207                 restore: function(restoreAssociations) {
       
  7208                     var props = restoreAssociations ? this._backupStore : flatProps(this._backupStore, this);
       
  7209                     if (this.isDirty(restoreAssociations)) {
       
  7210                         this._attrs(props, true);
       
  7211                     }
       
  7212                     return this;
       
  7213                 }
       
  7214             });
       
  7215         return can.Map;
       
  7216     })(__m3, __m10, __m31);
       
  7217 
       
  7218     window['can'] = __m5;
       
  7219 })();