Options mixed in.View methods.# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.# On branch master# Changes to be committed:#   (use "git reset HEAD <file>..." to unstage)##	modified:   Truss-min.js#	modified:   Truss.js#	modified:   examples/todo/public/javascripts/Truss.js#	modified:   examples/todo/public/javascripts/bootstrap.js#	modified:   examples/todo/public/javascripts/views/Notes.View.Count.js#	modified:   examples/todo/public/javascripts/views/Notes.View.Edit_Note.js#	modified:   examples/todo/public/javascripts/views/Notes.View.Form.js#	modified:   examples/todo/public/javascripts/views/Notes.View.List.js#	modified:   examples/todo/public/javascripts/views/Notes.View.Note.js#	modified:   spec/Base.spec.js#	modified:   spec/View.spec.js#	modified:   src/Base.js#	modified:   src/View.js#diff --git Truss-min.js Truss-min.jsindex 86041d0..8b972ce 100644--- Truss-min.js+++ Truss-min.js@@ -43,20 +43,20 @@ Error("fire() needs an event");r=[].slice.call(arguments,1),i=r[0],s=r[1];if(thi .isArray?Array.isArray(e):this.realTypeOf(e)==="array"},isString:function(e){return this.realTypeOf(e )==="string"},isNumber:function(e){return this.realTypeOf(e)==="number"},isFunction:function(e){return this .realTypeOf(e)==="function"}}}),t("Base",["events","utils"],function(e,t){var n=function(e){"undefined"!=typeof-e&&(this.options=e),t.isFunction(this.start)&&this.start(e)};return n.mixin=function(e,r){var i,s=[].-slice.call(arguments,1);while(r=s.shift())for(i in r)r.hasOwnProperty(i)&&(t.isObject(r[i])?(e[i]=e[i-]||r[i],n.mixin(e[i],r[i])):e[i]=r[i]);return e},n.construct=function(e){function i(){}function s(e){-var t=o();return n.call(t,e),t}function o(){var e=e||n.mixin(new i,r);return e}function u(){}var t=this-,r=e||{};return i.prototype=t.prototype,i.prototype.constructor=n.mixin(i,t),u.prototype=o(),u.construct=-i.construct,u.create=s,u},n.mixin(n.prototype,e,t),n}),t("mediator",[],function(){function e(e,t,n){i-[s][e].push({obj:t,eventName:n})}function t(e,t){if(e===t)return e!==0||1/e===1/t;if(e===null||t===null-)return e===t;if(Object.prototype.toString.call(e)!==Object.prototype.toString.call(t))return!1}function n-(e,t,n){var r;if(typeof Array.prototype.forEach=="function"&&e.length)e.forEach(t,n||this);else if(e.-length)Array.prototype.forEach=function(t,n){for(var r=0,i=e.length;r<i;++r)t.call(n,e[r],r,e)};else for(-r in e)e.hasOwnProperty(r)&&t.call(n||this,e[r],r,e)}function r(){n(i[s],function(e,t,r){n(r,function(-e,t,r){n(r.from,function(e){e.obj.off(e.eventName),e.obj.on(e.eventName,function(e){n(r.to,function(t-){t.obj.fire(t.eventName,e)},this)},this)},this)},this)},this)}var i={},s=null;return{from:function(t-,r){if(!arguments.length)throw{name:"NoArgumentsException",message:"From cannot be called with no arguments"+e&&(this.options=e,n.mixin(this,e)),this.isFunction(this.start)&&this.start()};return n.mixin=function(+e,r){var i,s=[].slice.call(arguments,1);while(r=s.shift())for(i in r)r.hasOwnProperty(i)&&(t.isObject+(r[i])?(e[i]=e[i]||r[i],n.mixin(e[i],r[i])):e[i]=r[i]);return e},n.construct=function(e){function i()+{}function s(e){var t=o();return n.call(t,e),t}function o(){var e=e||n.mixin(new i,r);return e}function u+(){}var t=this,r=e||{};return i.prototype=t.prototype,i.prototype.constructor=n.mixin(i,t),u.prototype=+o(),u.construct=i.construct,u.create=s,u},n.mixin(n.prototype,e,t),n}),t("mediator",[],function(){function e+(e,t,n){i[s][e].push({obj:t,eventName:n})}function t(e,t){if(e===t)return e!==0||1/e===1/t;if(e===null||+t===null)return e===t;if(Object.prototype.toString.call(e)!==Object.prototype.toString.call(t))return!1+}function n(e,t,n){var r;if(typeof Array.prototype.forEach=="function"&&e.length)e.forEach(t,n||this)+;else if(e.length)Array.prototype.forEach=function(t,n){for(var r=0,i=e.length;r<i;++r)t.call(n,e[r],+r,e)};else for(r in e)e.hasOwnProperty(r)&&t.call(n||this,e[r],r,e)}function r(){n(i[s],function(e,t,+r){n(r,function(e,t,r){n(r.from,function(e){e.obj.off(e.eventName),e.obj.on(e.eventName,function(e){n+(r.to,function(t){t.obj.fire(t.eventName,e)},this)},this)},this)},this)},this)}var i={},s=null;return{+from:function(t,r){if(!arguments.length)throw{name:"NoArgumentsException",message:"From cannot be called with no arguments" };return s=r||"all",i[s]||(i[s]={}),i[s].from||(i[s].from=[]),e("from",t,r),this.removing&&(n(i,function( e,t){n(e.to,function(n,r){e.to[r].remove&&e.to[r].remove===!0&&(delete i[t].to[r],s=null)},this)},this ),this.removing=!1),this},to:function(t,n){if(!s)throw{name:"ToFunctionBadUsage",message:"Cannot call to before from."@@ -88,9 +88,13 @@ else{i=t[n];if(this.isFunction(this.model)){r=this.model.create(),this.getModels ,e)},removeByText:function(e){i.call(this,"text",e)},removeById:function(e){i.call(this,"id",e)},getModels :function(){return this.models},setCurrentModel:function(e){s=e},getCurrentModel:function(){return s} })}),t("View",["Base"],function(e){function n(){return document.getElementsByTagName("body")[0]}var t="div"-;return e.construct({start:function(){this.tagName=this.options?this.options.tagName:t,this.rootNode=-this.options?this.options.rootNode:n()},make:function(){var e=[].slice.call(arguments),t=e[0]||this.tagName-,n=e[1],r=e[2],i,s,o=document.createElement(t);e.length===2&&this.isObject(n)&&(n=undefined,r=e[1]);if(typeof+;return e.construct({tagName:"div",start:function(){this.tagName=this.options&&this.options.tagName?this+.options.tagName:this.tagName},setElement:function(e){this.element=e},removeElement:function(){arguments+[0]&&arguments[0].nodeType===1&&this.setElement(arguments[0]),this.element.parentNode&&this.element.parentNode+.removeChild(this.element),this.element=null,delete this.element},replaceElement:function(e){var t=this+.element;arguments[1]&&arguments[1].nodeType===1&&(t=arguments[1]),t&&t.parentNode&&(this.oldElement=+t.parentNode.replaceChild(e,t))},make:function(){var e=[].slice.call(arguments),t=e[0]||this.tagName,+n=e[1],r=e[2],i,s,o=document.createElement(t);e.length===2&&this.isObject(n)&&(n=undefined,r=e[1]);if(typeof n!="undefined"){if(this.isNumber(n)||this.isString(n))n=document.createTextNode(n);if(this.isArray(n) )while(i=n.shift())o.appendChild(i);else o.appendChild(n)}if(r)for(s in r)r.hasOwnProperty(s)&&(o[s]= r[s],s in o.attributes||o.setAttribute(s,r[s]));return o}})}),t("main",["Base","events","mediator","utils"diff --git Truss.js Truss.jsindex a30ae75..54895fd 100644--- Truss.js+++ Truss.js@@ -465,12 +465,13 @@ define('Base', ['events', 'utils'], function ( events, utils ) {     // Add any arguments to this.options     if ( "undefined" != typeof options ) {-      this.options = options;+        this.options = options;+        Base.mixin(this, options);     }     // Call the start function to do any setup-    if ( utils.isFunction(this.start) ) {-      this.start( options );+    if ( this.isFunction(this.start) ) {+        this.start();     }   };@@ -736,7 +737,7 @@ define ('Collection', ['Base', 'Model'], function ( Base, Model ) { });-define ('View',['Base'], function ( Base ) {    var TAGNAME = 'div';    function getRootNode () {        return document.getElementsByTagName("body")[0];    }    // Build the constructor    return Base.construct({        // Start is optional, it's called if present,        // like a constructor        start: function () {            // Option properties override view properties            this.tagName = this.options ? this.options.tagName : TAGNAME;            this.rootNode = this.options ? this.options.rootNode : getRootNode();        },        /**         * Make a Tag         */        make: function () {            // All arguments are optional            var args = [].slice.call(arguments),                name = args[0] || this.tagName,                contents = args[1],                attrs = args[2],                i,                attr,                tag = document.createElement(name);            if (args.length === 2 && this.isObject(contents)) {                contents = undefined;                attrs = args[1];            }            // Add the contents            if (typeof contents !== "undefined") {                if (this.isNumber(contents) || this.isString(contents)) {                    // If the contents is a Number or a String,                    // parse it to a textnode                    contents = document.createTextNode(contents);                }                if (this.isArray(contents)) {                    // If our contents is an array,                    // append each one to the tag                    while ( i = contents.shift() ) {                        tag.appendChild(i);                    }                } else {                    tag.appendChild(contents);                }            }            // Add the attributes            if ( attrs ) {                for ( attr in attrs ) {                    if (attrs.hasOwnProperty( attr )) {                        // Add each attribute to the tag                        tag[ attr ] = attrs[ attr ];                        if ( !( attr in tag.attributes ) ) {                            // If the attribute wasnt't successfully added,                            // try again with setAttribute                            tag.setAttribute( attr, attrs[ attr ] );                        }                    }                }            }            // Finally return the new tag            return tag;        }    });});+define ('View',['Base'], function ( Base ) {    var TAGNAME = 'div';    function getRootNode () {        return document.getElementsByTagName("body")[0];    }    // Build the constructor    return Base.construct({        tagName: 'div',        start: function () {            this.tagName = this.options && this.options.tagName ? this.options.tagName : this.tagName;        },        setElement: function (element) {            this.element = element;        },        removeElement: function () {            if (arguments[0] && arguments[0].nodeType === 1) {                this.setElement(arguments[0]);            }            if (this.element.parentNode) {                this.element.parentNode.removeChild(this.element);            }            this.element = null;            delete this.element;        },        replaceElement: function (replacement) {            var replacee = this.element;            if (arguments[1] && arguments[1].nodeType === 1) {                replacee = arguments[1];            }            if (replacee && replacee.parentNode) {                this.oldElement = replacee.parentNode.replaceChild(replacement, replacee);            }        },        make: function () {            // All arguments are optional            var args = [].slice.call(arguments),                name = args[0] || this.tagName,                contents = args[1],                attrs = args[2],                i,                attr,                tag = document.createElement(name);            if (args.length === 2 && this.isObject(contents)) {                contents = undefined;                attrs = args[1];            }            // Add the contents            if (typeof contents !== "undefined") {                if (this.isNumber(contents) || this.isString(contents)) {                    // If the contents is a Number or a String,                    // parse it to a textnode                    contents = document.createTextNode(contents);                }                if (this.isArray(contents)) {                    // If our contents is an array,                    // append each one to the tag                    while ( i = contents.shift() ) {                        tag.appendChild(i);                    }                } else {                    tag.appendChild(contents);                }            }            // Add the attributes            if ( attrs ) {                for ( attr in attrs ) {                    if (attrs.hasOwnProperty( attr )) {                        // Add each attribute to the tag                        tag[ attr ] = attrs[ attr ];                        if ( !( attr in tag.attributes ) ) {                            // If the attribute wasnt't successfully added,                            // try again with setAttribute                            tag.setAttribute( attr, attrs[ attr ] );                        }                    }                }            }            // Finally return the new tag            return tag;        }    });}); define('main', [     'Base',     'events',diff --git examples/todo/public/javascripts/Truss.js examples/todo/public/javascripts/Truss.jsindex a30ae75..b910086 100644--- examples/todo/public/javascripts/Truss.js+++ examples/todo/public/javascripts/Truss.js@@ -1,772 +1 @@-(function(global, define) {-  var globalDefine = global.define;--/**- * almond 0.2.5 Copyright (c) 2011-2012, The Dojo Foundation All Rights Reserved.- * Available via the MIT or new BSD license.- * see: http://github.com/jrburke/almond for details- */-//Going sloppy to avoid 'use strict' string cost, but strict practices should-//be followed.-/*jslint sloppy: true */-/*global setTimeout: false */--var requirejs, require, define;-(function (undef) {-    var main, req, makeMap, handlers,-        defined = {},-        waiting = {},-        config = {},-        defining = {},-        hasOwn = Object.prototype.hasOwnProperty,-        aps = [].slice;--    function hasProp(obj, prop) {-        return hasOwn.call(obj, prop);-    }--    /**-     * Given a relative module name, like ./something, normalize it to-     * a real name that can be mapped to a path.-     * @param {String} name the relative name-     * @param {String} baseName a real name that the name arg is relative-     * to.-     * @returns {String} normalized name-     */-    function normalize(name, baseName) {-        var nameParts, nameSegment, mapValue, foundMap,-            foundI, foundStarMap, starI, i, j, part,-            baseParts = baseName && baseName.split("/"),-            map = config.map,-            starMap = (map && map['*']) || {};--        //Adjust any relative paths.-        if (name && name.charAt(0) === ".") {-            //If have a base name, try to normalize against it,-            //otherwise, assume it is a top-level require that will-            //be relative to baseUrl in the end.-            if (baseName) {-                //Convert baseName to array, and lop off the last part,-                //so that . matches that "directory" and not name of the baseName's-                //module. For instance, baseName of "one/two/three", maps to-                //"one/two/three.js", but we want the directory, "one/two" for-                //this normalization.-                baseParts = baseParts.slice(0, baseParts.length - 1);--                name = baseParts.concat(name.split("/"));--                //start trimDots-                for (i = 0; i < name.length; i += 1) {-                    part = name[i];-                    if (part === ".") {-                        name.splice(i, 1);-                        i -= 1;-                    } else if (part === "..") {-                        if (i === 1 && (name[2] === '..' || name[0] === '..')) {-                            //End of the line. Keep at least one non-dot-                            //path segment at the front so it can be mapped-                            //correctly to disk. Otherwise, there is likely-                            //no path mapping for a path starting with '..'.-                            //This can still fail, but catches the most reasonable-                            //uses of ..-                            break;-                        } else if (i > 0) {-                            name.splice(i - 1, 2);-                            i -= 2;-                        }-                    }-                }-                //end trimDots--                name = name.join("/");-            } else if (name.indexOf('./') === 0) {-                // No baseName, so this is ID is resolved relative-                // to baseUrl, pull off the leading dot.-                name = name.substring(2);-            }-        }--        //Apply map config if available.-        if ((baseParts || starMap) && map) {-            nameParts = name.split('/');--            for (i = nameParts.length; i > 0; i -= 1) {-                nameSegment = nameParts.slice(0, i).join("/");--                if (baseParts) {-                    //Find the longest baseName segment match in the config.-                    //So, do joins on the biggest to smallest lengths of baseParts.-                    for (j = baseParts.length; j > 0; j -= 1) {-                        mapValue = map[baseParts.slice(0, j).join('/')];--                        //baseName segment has  config, find if it has one for-                        //this name.-                        if (mapValue) {-                            mapValue = mapValue[nameSegment];-                            if (mapValue) {-                                //Match, update name to the new value.-                                foundMap = mapValue;-                                foundI = i;-                                break;-                            }-                        }-                    }-                }--                if (foundMap) {-                    break;-                }--                //Check for a star map match, but just hold on to it,-                //if there is a shorter segment match later in a matching-                //config, then favor over this star map.-                if (!foundStarMap && starMap && starMap[nameSegment]) {-                    foundStarMap = starMap[nameSegment];-                    starI = i;-                }-            }--            if (!foundMap && foundStarMap) {-                foundMap = foundStarMap;-                foundI = starI;-            }--            if (foundMap) {-                nameParts.splice(0, foundI, foundMap);-                name = nameParts.join('/');-            }-        }--        return name;-    }--    function makeRequire(relName, forceSync) {-        return function () {-            //A version of a require function that passes a moduleName-            //value for items that may need to-            //look up paths relative to the moduleName-            return req.apply(undef, aps.call(arguments, 0).concat([relName, forceSync]));-        };-    }--    function makeNormalize(relName) {-        return function (name) {-            return normalize(name, relName);-        };-    }--    function makeLoad(depName) {-        return function (value) {-            defined[depName] = value;-        };-    }--    function callDep(name) {-        if (hasProp(waiting, name)) {-            var args = waiting[name];-            delete waiting[name];-            defining[name] = true;-            main.apply(undef, args);-        }--        if (!hasProp(defined, name) && !hasProp(defining, name)) {-            throw new Error('No ' + name);-        }-        return defined[name];-    }--    //Turns a plugin!resource to [plugin, resource]-    //with the plugin being undefined if the name-    //did not have a plugin prefix.-    function splitPrefix(name) {-        var prefix,-            index = name ? name.indexOf('!') : -1;-        if (index > -1) {-            prefix = name.substring(0, index);-            name = name.substring(index + 1, name.length);-        }-        return [prefix, name];-    }--    /**-     * Makes a name map, normalizing the name, and using a plugin-     * for normalization if necessary. Grabs a ref to plugin-     * too, as an optimization.-     */-    makeMap = function (name, relName) {-        var plugin,-            parts = splitPrefix(name),-            prefix = parts[0];--        name = parts[1];--        if (prefix) {-            prefix = normalize(prefix, relName);-            plugin = callDep(prefix);-        }--        //Normalize according-        if (prefix) {-            if (plugin && plugin.normalize) {-                name = plugin.normalize(name, makeNormalize(relName));-            } else {-                name = normalize(name, relName);-            }-        } else {-            name = normalize(name, relName);-            parts = splitPrefix(name);-            prefix = parts[0];-            name = parts[1];-            if (prefix) {-                plugin = callDep(prefix);-            }-        }--        //Using ridiculous property names for space reasons-        return {-            f: prefix ? prefix + '!' + name : name, //fullName-            n: name,-            pr: prefix,-            p: plugin-        };-    };--    function makeConfig(name) {-        return function () {-            return (config && config.config && config.config[name]) || {};-        };-    }--    handlers = {-        require: function (name) {-            return makeRequire(name);-        },-        exports: function (name) {-            var e = defined[name];-            if (typeof e !== 'undefined') {-                return e;-            } else {-                return (defined[name] = {});-            }-        },-        module: function (name) {-            return {-                id: name,-                uri: '',-                exports: defined[name],-                config: makeConfig(name)-            };-        }-    };--    main = function (name, deps, callback, relName) {-        var cjsModule, depName, ret, map, i,-            args = [],-            usingExports;--        //Use name if no relName-        relName = relName || name;--        //Call the callback to define the module, if necessary.-        if (typeof callback === 'function') {--            //Pull out the defined dependencies and pass the ordered-            //values to the callback.-            //Default to [require, exports, module] if no deps-            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;-            for (i = 0; i < deps.length; i += 1) {-                map = makeMap(deps[i], relName);-                depName = map.f;--                //Fast path CommonJS standard dependencies.-                if (depName === "require") {-                    args[i] = handlers.require(name);-                } else if (depName === "exports") {-                    //CommonJS module spec 1.1-                    args[i] = handlers.exports(name);-                    usingExports = true;-                } else if (depName === "module") {-                    //CommonJS module spec 1.1-                    cjsModule = args[i] = handlers.module(name);-                } else if (hasProp(defined, depName) ||-                           hasProp(waiting, depName) ||-                           hasProp(defining, depName)) {-                    args[i] = callDep(depName);-                } else if (map.p) {-                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});-                    args[i] = defined[depName];-                } else {-                    throw new Error(name + ' missing ' + depName);-                }-            }--            ret = callback.apply(defined[name], args);--            if (name) {-                //If setting exports via "module" is in play,-                //favor that over return value and exports. After that,-                //favor a non-undefined return value over exports use.-                if (cjsModule && cjsModule.exports !== undef &&-                        cjsModule.exports !== defined[name]) {-                    defined[name] = cjsModule.exports;-                } else if (ret !== undef || !usingExports) {-                    //Use the return value from the function.-                    defined[name] = ret;-                }-            }-        } else if (name) {-            //May just be an object definition for the module. Only-            //worry about defining if have a module name.-            defined[name] = callback;-        }-    };--    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {-        if (typeof deps === "string") {-            if (handlers[deps]) {-                //callback in this case is really relName-                return handlers[deps](callback);-            }-            //Just return the module wanted. In this scenario, the-            //deps arg is the module name, and second arg (if passed)-            //is just the relName.-            //Normalize module name, if it contains . or ..-            return callDep(makeMap(deps, callback).f);-        } else if (!deps.splice) {-            //deps is a config object, not an array.-            config = deps;-            if (callback.splice) {-                //callback is an array, which means it is a dependency list.-                //Adjust args if there are dependencies-                deps = callback;-                callback = relName;-                relName = null;-            } else {-                deps = undef;-            }-        }--        //Support require(['a'])-        callback = callback || function () {};--        //If relName is a function, it is an errback handler,-        //so remove it.-        if (typeof relName === 'function') {-            relName = forceSync;-            forceSync = alt;-        }--        //Simulate async callback;-        if (forceSync) {-            main(undef, deps, callback, relName);-        } else {-            //Using a non-zero value because of concern for what old browsers-            //do, and latest browsers "upgrade" to 4 if lower value is used:-            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:-            //If want a value immediately, use require('id') instead -- something-            //that works in almond on the global level, but not guaranteed and-            //unlikely to work in other AMD implementations.-            setTimeout(function () {-                main(undef, deps, callback, relName);-            }, 4);-        }--        return req;-    };--    /**-     * Just drops the config on the floor, but returns req in case-     * the config return value is used.-     */-    req.config = function (cfg) {-        config = cfg;-        if (config.deps) {-            req(config.deps, config.callback);-        }-        return req;-    };--    define = function (name, deps, callback) {--        //This module may not have dependencies-        if (!deps.splice) {-            //deps is not an array, so probably means-            //an object literal or factory function for-            //the value. Adjust args.-            callback = deps;-            deps = [];-        }--        if (!hasProp(defined, name) && !hasProp(waiting, name)) {-            waiting[name] = [name, deps, callback];-        }-    };--    define.amd = {-        jQuery: true-    };-}());-define("vendor/almond", function(){});--define ('events',[], function ( ) {  return {    events: {},    on: function (event, callback) {      var context;      if ( "string" != typeof event ) {        throw new Error("on() needs an event name string");      }      if ( "function" != typeof callback ) {        throw new Error("on() needs a callback function");      }      context = [].slice.call( arguments, 2 )[0];      if ( !this.events[event] ) {        this.events[event] = [];      }      this.events[event].push({        callback: callback,        context: context      });    },    reset: function () {      this.events = {};    },    off: function (event) {      var ev, len, cb;      // Event must be a string      if ( "string" != typeof event ) {        throw new Error( "off() needs an event" );      }      cb = [].slice.call( arguments, 1 )[0];      // If the event has been registered      if ( this.events[event] ) {        ev = this.events[event];        len = ev.length;        // Loop over each event object that matches ours.        while ( len-- ) {          if ( "function" != typeof cb ) {            // If no callback was given, remove the event            // and all its callbacks            ev.splice(len, 1);          } else {            // If a callback was passed,            // remove the callback from the event            if ( ev[len].callback === cb ) {              ev[len].callback = null;              delete ev[len].callback;            }          }        }      }    },    fire: function ( event ) {      var ev, len, opt, data, ctx;      // event argument is mandatory      if ( "string" != typeof event ) {        throw new Error("fire() needs an event");      }      // Optional arguments      opt = [].slice.call( arguments, 1 );      data = opt[0];      ctx = opt[1];      // If this event has been registered      if ( this.events[event] ) {        len = this.events[event].length;        // Invoke the callback on each event object        while ( ev = this.events[event][--len] ) {          if ("function" == typeof ev.callback) {            // Invoke in either context with data if present            ev.callback.call( ( ctx || ev.context || this ), data );          }        }      }    }  };});-define('utils',[], function ( ) {--  return {--    realTypeOf: function ( value ) {-      // Borrow Object.toString to introspect the-      // class definition of the value i.e. ([object Object])-      // and return the latter portion which denotes-      // the real type of value.-      return ({}).toString.call(value).match( /\w+/g )[1].toLowerCase();-    },--    isObject: function ( value ) {-      //delegate to realTypeOf-      return this.realTypeOf(value) === 'object';-    },--    isArray: function ( value ) {-      if (Array.isArray) {-        return Array.isArray(value);-      }-      //delegate to realTypeOf if isArray is not supported-      return this.realTypeOf(value) === 'array';-    },--    isString: function ( value ) {-      //delegate to realTypeOf-      return this.realTypeOf(value) === 'string';-    },--    isNumber: function ( value ) {-      //delegate to realTypeOf-      return this.realTypeOf(value) === 'number';-    },--    isFunction: function ( value ) {-      //delegate to realTypeOf-      return this.realTypeOf(value) === 'function';-    }--  };--});-define('Base', ['events', 'utils'], function ( events, utils ) {--  /**-   * @constructor-   * @description-   * -> Core of Base framework-   * @param {Object} options-   * @return {this}-   */-  var Base = function ( options ) {--    // Add any arguments to this.options-    if ( "undefined" != typeof options ) {-      this.options = options;-    }--    // Call the start function to do any setup-    if ( utils.isFunction(this.start) ) {-      this.start( options );-    }--  };--  /**-   * @static-   * @description-   * -> Takes object params and adds all object properties to the first (dest) param.-   * @param {Object} dest-   * @param {Object} src-   * @return {Object} augmented dest-   */-  Base.mixin = function ( dest, src ) {--    var prop, sources = [].slice.call(arguments, 1);--    while(src = sources.shift()) {-      // Iterate over all src properties-      for (prop in src) {-        if (src.hasOwnProperty(prop)) {-          if ( utils.isObject(src[prop])  ) {-            dest[prop] = dest[prop] || src[prop];-            Base.mixin(dest[prop], src[prop]);-          } else {-            // Assign the value form the src to the destination-            dest[prop] = src[prop];-          }-        }-      }--    }--    return dest;-  };--  /**-   * @static-   * @description-   * -> Construct is a static inheritance function-   * @return {Function} constructor function-   */-  Base.construct = function (properties) {--    var parent = this,-        props = properties || {};--    function F () {}-    F.prototype = parent.prototype;-    F.prototype.constructor = Base.mixin( F, parent );--    function create (options) {-        var proto = getPrototype();-        Base.call(proto, options);-        return proto;-    }--    function getPrototype() {-      var proto = proto || Base.mixin( new F(), props );-      return proto;-    }--    function proxy () {}-    proxy.prototype = getPrototype();-    proxy.construct = F.construct;-    proxy.create = create;--    return proxy;--  };--  // Augment the Base prototype with the-  // properties of events;-  Base.mixin(Base.prototype, events, utils);---  // Return Base as the module definition-  return Base;--});-define('mediator',[], function ( ) {    /**        * A little helper to remove duplication        * @param type {String} to|from        * @param obj {Object}        * @param eventName {String}        * @private        */    function add (type, obj, eventName) {        passes[ currentEvent ][ type ].push({            obj: obj,            eventName: eventName        });    }    function isEqual (a, b) {        if (a === b) {            return a !== 0 || 1 / a === 1 / b;        }        if (a === null || b === null) {            return a === b;        }        if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) {            return false;        }    }    // Polyfill for nativeForEach    function each (list, callback, context) {        var i;        // Native forEach        if (typeof Array.prototype.forEach == "function" && list.length) {            list.forEach( callback, context || this);        } else if ( list.length ) {            // Polyfill            Array.prototype.forEach = function( callback, context ) {                for (var i = 0, len = list.length; i < len; ++i) {                    callback.call(context, list[i], i, list);                }            };        } else {            // If the list is an [object Object] (i.e. Not an Array)            for ( i in list ) {                if ( list.hasOwnProperty( i ) ) {                    callback.call( context || this, list[i], i, list );                }            }        }    }    /**    * Bind one or more target events to one or more source events    * @private    */    function bind () {        each( passes[ currentEvent ], function (sources, type, passes) {            each( passes, function ( sources, type, pass ) {                each( pass.from, function ( from ) {                    // Remove any previous binding                    from.obj.off( from.eventName );                    // Bind the event to a callback                    from.obj.on( from.eventName, function( args ) {                        each( pass.to, function ( to ) {                            // The callback binds the |to| event                            to.obj.fire( to.eventName, args);                        }, this);                    }, this);                }, this);            }, this);        }, this);    }    var passes = {},        currentEvent = null;    // Return medaitor api as module definition    return {        /**        * Registers the source subject subscriber and its event(s)        * @param subscribee {Object}        * @param eventName {String}        * @return {this}        */        from: function (subscribee, eventName) {            if (!arguments.length) {                throw {                    name: "NoArgumentsException",                    message: "From cannot be called with no arguments"                };            }            currentEvent = eventName || 'all';            if ( !passes[ currentEvent ] ) {                passes[ currentEvent ] = {};            }            if ( !passes[ currentEvent ].from ) {                passes[ currentEvent ].from = [];            }            add( "from", subscribee, eventName );            if ( this.removing ) {                // Has to object been marked for removal??                each( passes, function ( pass, j ) {                    each( pass.to, function ( to, i) {                        if (pass.to[i].remove && pass.to[i].remove === true) {                            // Dedlete the target object and event,                            // null the currentEvent                            delete passes[j].to[i];                            currentEvent = null;                        }                    }, this);                }, this);                this.removing = false;            }            // Make it chainable            return this;        },        /**        * Adds a target subscriber by eventName to the mediator        * @param subscriber {Object}        * @param eventName {String}        * @return {this}        */        to: function ( subscriber, eventName ) {            if ( !currentEvent ) {                throw {                    name: "ToFunctionBadUsage",                    message: "Cannot call to before from."                };            }            if ( !passes[ currentEvent ].to ) {                passes[ currentEvent ].to = [];            }            add( "to", subscriber, eventName );            // No config object parameter            this.register();            // Make it chainable            return this;        },        /**        * Marks target and eventName for removal        * @param target {Object}        * @param eventName {String}        * @return {this}        */        remove: function (obj, eventName) {            if (!arguments.length) {                throw {                    name: "NoArgumentException",                    message: "Remove cannot be called without arguments"                };            }            this.removing = true;            each(passes, function ( pass ) {                each( pass.to, function ( to, i ) {                    if (typeof obj == "string") {                        eventName = obj;                        if ( to.eventName === eventName ) {                            [].splice.call(pass.to, i, 1);                        }                    } else {                        if ( ( isEqual(to.obj, obj) || obj == null ) && ( to.eventName === eventName || typeof eventName == "undefined" ) ) {                            to.remove = true;                        }                    }                });            });            return this;        },        /**        * Registers the source and target subscriber objects and their events for binding        * @param optional config Object        */        register: function () {            var config = arguments[0];            if ( config ) {                if ( config.source ) {                    each(config.source, function ( from ) {                        this.from( from.subscriber, from.event );                    }, this);                } else {                    throw {                        name: "ConfigSourceNotDefined",                        message: "Config object needs a source defined."                    };                }                if ( config.target ) {                    each( config.target, function (to) {                        this.to( to.subscriber, to.event );                    }, this);                } else {                    throw {                        name: "ConfigTargetNotDefined",                        message: "Config object needs a target defined."                    };                }            } else {                bind();            }        },        /**        * Notifies mediator that target and source subscriber and events should be removed.        * @param config {Object}        */        unregister: function ( config ) {            if ( !config ) {                throw {                    name: "NoArgumentException",                    message: "Unregister cannot be called without arguments"                };            }            if ( config ) {                this.removing = true;                if ( config.target ) {                    each( config.target, function ( to ) {                    this.remove( to.subscriber, to.event );                    }, this );                } else {                    throw {                        name: "ConfigTargetNotDefined",                        message: "Config object needs a target defined."                    };                }                if ( config.source ) {                    each(config.source, function (from) {                        this.from(from.subscriber, from.eventName);                    }, this );                } else {                    throw {                        name: "ConfigSourceNotDefined",                        message: "Config object needs a source defined."                    };                }            }        }    };});-define('Model', ['Base'], function ( Base ) {--    var constants = {-            ID: 1,-            ORIGID: 1,-            IDPREFIX: "mid_"-        };--    function getNewId () {-        return constants.IDPREFIX + constants.ID++;-    }--    function resetId () {-        constants.ID = constants.ORIGID;-    }--    return Base.construct({--        start: function (options) {-            this.id = getNewId();-            this.resetId = resetId;-            this.properties = {};--            if (options) {-                this.set(options);-            }--            return this;-        },--        get: function ( name ) {-            return this[ name ] || this.properties[ name ];-        },--        set: function ( name, value ) {-            if ( this.isString(name) ) {-                this.properties[ name ] = value;-            } else {-                for (var n in name) {-                    if  (name.hasOwnProperty(n) ) {-                        this.properties[ n ] = name[n];-                    }-                }-            }--        }--    });--});--define ('Collection', ['Base', 'Model'], function ( Base, Model ) {--    function getCount () {-        return this.getModels().length;-    }--    function getBy (method, value) {-        var models = this.getModels(),-            len = models.length,-            found = [],-            i = 0;--        while (0 < len--) {-            if (typeof models[len][method] !== "undefined") {-                if (models[len][method] === value) {-                    found.push(models[len]);-                }-            } else {-                if (models[len].get(method) === value) {-                    found.push(models[len]);-                }-            }-        }-        return found = (found.length < 2) ? found[0] : found;-    }--    function removeBy (method, value) {-        var found = [].concat(getBy.call(this, method, value)),-            num = found.length,-            models = this.getModels(),-            len = models.length,-            index = -1;--        while (0 < len--) {-            while (0 < num--) {-                index = models.indexOf(found[num]);-                if (index !== -1) {-                    models.splice(index, 1);-                    this.fire("removed", this.getModels());-                }-            }-        }-    }--    var currentModel;--    // Use Base.construct to build a constructor for the Collection-    return Base.construct({--        start: function ( options ) {--            this.model = options && options.model ? options.model : Model;--        },--        models: [],--        add: function (data) {--            var items = [].concat(data),-                len = items.length,-                model,-                item,-                p,-                currentModel;--            while (len--) {--                model = items[len];--                if (this.isFunction(model.set)) {--                    this.getModels().push( model );--                } else {--                    item = items[len];--                    if ( this.isFunction(this.model) ) {--                        model = this.model.create();-                        this.getModels().push(model);--                        for ( p in item ) {-                            model.set( p, item[p] );-                        }--                    }-                }--                this.setCurrentModel(model);--                this.fire("add", model);-            }--        },--        reset: function () {-            this.models = [];-            this.fire("reset");-        },--        getById: function (id) {-            return getBy.call(this, "id", id);-        },--        getByText: function (text) {-            return getBy.call(this, "text", text);-        },--        removeByText: function (text) {-            removeBy.call(this, "text", text);-        },--        removeById: function (id) {-            removeBy.call(this, "id", id);-        },--        getModels: function () {-            return this.models;-        },--        setCurrentModel: function (model) {-            currentModel = model;-        },--        getCurrentModel: function () {-            return currentModel;-        }--    });--});--define ('View',['Base'], function ( Base ) {    var TAGNAME = 'div';    function getRootNode () {        return document.getElementsByTagName("body")[0];    }    // Build the constructor    return Base.construct({        // Start is optional, it's called if present,        // like a constructor        start: function () {            // Option properties override view properties            this.tagName = this.options ? this.options.tagName : TAGNAME;            this.rootNode = this.options ? this.options.rootNode : getRootNode();        },        /**         * Make a Tag         */        make: function () {            // All arguments are optional            var args = [].slice.call(arguments),                name = args[0] || this.tagName,                contents = args[1],                attrs = args[2],                i,                attr,                tag = document.createElement(name);            if (args.length === 2 && this.isObject(contents)) {                contents = undefined;                attrs = args[1];            }            // Add the contents            if (typeof contents !== "undefined") {                if (this.isNumber(contents) || this.isString(contents)) {                    // If the contents is a Number or a String,                    // parse it to a textnode                    contents = document.createTextNode(contents);                }                if (this.isArray(contents)) {                    // If our contents is an array,                    // append each one to the tag                    while ( i = contents.shift() ) {                        tag.appendChild(i);                    }                } else {                    tag.appendChild(contents);                }            }            // Add the attributes            if ( attrs ) {                for ( attr in attrs ) {                    if (attrs.hasOwnProperty( attr )) {                        // Add each attribute to the tag                        tag[ attr ] = attrs[ attr ];                        if ( !( attr in tag.attributes ) ) {                            // If the attribute wasnt't successfully added,                            // try again with setAttribute                            tag.setAttribute( attr, attrs[ attr ] );                        }                    }                }            }            // Finally return the new tag            return tag;        }    });});-define('main', [-    'Base',-    'events',-    'mediator',-    'utils',-    'Collection',-    'Model',-    'View'-    ],--    function ( Base, events, mediator, utils, Collection, Model, View ) {--        return {-            events: events,-            mediator: mediator,-            utils: utils,-            Collection: Collection,-            Model: Model,-            View: View-        };--    }-);  var library = require('main');-  if(typeof module !== 'undefined' && module.exports) {-    module.exports = library;-  } else if(globalDefine) {-    (function (define) {-      define(function () { return library; });-    }(globalDefine));-  } else {-    global['Truss'] = library;-  }-}(this));+(function(global, define) {  var globalDefine = global.define;/** * almond 0.2.5 Copyright (c) 2011-2012, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/almond for details *///Going sloppy to avoid 'use strict' string cost, but strict practices should//be followed./*jslint sloppy: true *//*global setTimeout: false */var requirejs, require, define;(function (undef) {    var main, req, makeMap, handlers,        defined = {},        waiting = {},        config = {},        defining = {},        hasOwn = Object.prototype.hasOwnProperty,        aps = [].slice;    function hasProp(obj, prop) {        return hasOwn.call(obj, prop);    }    /**     * Given a relative module name, like ./something, normalize it to     * a real name that can be mapped to a path.     * @param {String} name the relative name     * @param {String} baseName a real name that the name arg is relative     * to.     * @returns {String} normalized name     */    function normalize(name, baseName) {        var nameParts, nameSegment, mapValue, foundMap,            foundI, foundStarMap, starI, i, j, part,            baseParts = baseName && baseName.split("/"),            map = config.map,            starMap = (map && map['*']) || {};        //Adjust any relative paths.        if (name && name.charAt(0) === ".") {            //If have a base name, try to normalize against it,            //otherwise, assume it is a top-level require that will            //be relative to baseUrl in the end.            if (baseName) {                //Convert baseName to array, and lop off the last part,                //so that . matches that "directory" and not name of the baseName's                //module. For instance, baseName of "one/two/three", maps to                //"one/two/three.js", but we want the directory, "one/two" for                //this normalization.                baseParts = baseParts.slice(0, baseParts.length - 1);                name = baseParts.concat(name.split("/"));                //start trimDots                for (i = 0; i < name.length; i += 1) {                    part = name[i];                    if (part === ".") {                        name.splice(i, 1);                        i -= 1;                    } else if (part === "..") {                        if (i === 1 && (name[2] === '..' || name[0] === '..')) {                            //End of the line. Keep at least one non-dot                            //path segment at the front so it can be mapped                            //correctly to disk. Otherwise, there is likely                            //no path mapping for a path starting with '..'.                            //This can still fail, but catches the most reasonable                            //uses of ..                            break;                        } else if (i > 0) {                            name.splice(i - 1, 2);                            i -= 2;                        }                    }                }                //end trimDots                name = name.join("/");            } else if (name.indexOf('./') === 0) {                // No baseName, so this is ID is resolved relative                // to baseUrl, pull off the leading dot.                name = name.substring(2);            }        }        //Apply map config if available.        if ((baseParts || starMap) && map) {            nameParts = name.split('/');            for (i = nameParts.length; i > 0; i -= 1) {                nameSegment = nameParts.slice(0, i).join("/");                if (baseParts) {                    //Find the longest baseName segment match in the config.                    //So, do joins on the biggest to smallest lengths of baseParts.                    for (j = baseParts.length; j > 0; j -= 1) {                        mapValue = map[baseParts.slice(0, j).join('/')];                        //baseName segment has  config, find if it has one for                        //this name.                        if (mapValue) {                            mapValue = mapValue[nameSegment];                            if (mapValue) {                                //Match, update name to the new value.                                foundMap = mapValue;                                foundI = i;                                break;                            }                        }                    }                }                if (foundMap) {                    break;                }                //Check for a star map match, but just hold on to it,                //if there is a shorter segment match later in a matching                //config, then favor over this star map.                if (!foundStarMap && starMap && starMap[nameSegment]) {                    foundStarMap = starMap[nameSegment];                    starI = i;                }            }            if (!foundMap && foundStarMap) {                foundMap = foundStarMap;                foundI = starI;            }            if (foundMap) {                nameParts.splice(0, foundI, foundMap);                name = nameParts.join('/');            }        }        return name;    }    function makeRequire(relName, forceSync) {        return function () {            //A version of a require function that passes a moduleName            //value for items that may need to            //look up paths relative to the moduleName            return req.apply(undef, aps.call(arguments, 0).concat([relName, forceSync]));        };    }    function makeNormalize(relName) {        return function (name) {            return normalize(name, relName);        };    }    function makeLoad(depName) {        return function (value) {            defined[depName] = value;        };    }    function callDep(name) {        if (hasProp(waiting, name)) {            var args = waiting[name];            delete waiting[name];            defining[name] = true;            main.apply(undef, args);        }        if (!hasProp(defined, name) && !hasProp(defining, name)) {            throw new Error('No ' + name);        }        return defined[name];    }    //Turns a plugin!resource to [plugin, resource]    //with the plugin being undefined if the name    //did not have a plugin prefix.    function splitPrefix(name) {        var prefix,            index = name ? name.indexOf('!') : -1;        if (index > -1) {            prefix = name.substring(0, index);            name = name.substring(index + 1, name.length);        }        return [prefix, name];    }    /**     * Makes a name map, normalizing the name, and using a plugin     * for normalization if necessary. Grabs a ref to plugin     * too, as an optimization.     */    makeMap = function (name, relName) {        var plugin,            parts = splitPrefix(name),            prefix = parts[0];        name = parts[1];        if (prefix) {            prefix = normalize(prefix, relName);            plugin = callDep(prefix);        }        //Normalize according        if (prefix) {            if (plugin && plugin.normalize) {                name = plugin.normalize(name, makeNormalize(relName));            } else {                name = normalize(name, relName);            }        } else {            name = normalize(name, relName);            parts = splitPrefix(name);            prefix = parts[0];            name = parts[1];            if (prefix) {                plugin = callDep(prefix);            }        }        //Using ridiculous property names for space reasons        return {            f: prefix ? prefix + '!' + name : name, //fullName            n: name,            pr: prefix,            p: plugin        };    };    function makeConfig(name) {        return function () {            return (config && config.config && config.config[name]) || {};        };    }    handlers = {        require: function (name) {            return makeRequire(name);        },        exports: function (name) {            var e = defined[name];            if (typeof e !== 'undefined') {                return e;            } else {                return (defined[name] = {});            }        },        module: function (name) {            return {                id: name,                uri: '',                exports: defined[name],                config: makeConfig(name)            };        }    };    main = function (name, deps, callback, relName) {        var cjsModule, depName, ret, map, i,            args = [],            usingExports;        //Use name if no relName        relName = relName || name;        //Call the callback to define the module, if necessary.        if (typeof callback === 'function') {            //Pull out the defined dependencies and pass the ordered            //values to the callback.            //Default to [require, exports, module] if no deps            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;            for (i = 0; i < deps.length; i += 1) {                map = makeMap(deps[i], relName);                depName = map.f;                //Fast path CommonJS standard dependencies.                if (depName === "require") {                    args[i] = handlers.require(name);                } else if (depName === "exports") {                    //CommonJS module spec 1.1                    args[i] = handlers.exports(name);                    usingExports = true;                } else if (depName === "module") {                    //CommonJS module spec 1.1                    cjsModule = args[i] = handlers.module(name);                } else if (hasProp(defined, depName) ||                           hasProp(waiting, depName) ||                           hasProp(defining, depName)) {                    args[i] = callDep(depName);                } else if (map.p) {                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});                    args[i] = defined[depName];                } else {                    throw new Error(name + ' missing ' + depName);                }            }            ret = callback.apply(defined[name], args);            if (name) {                //If setting exports via "module" is in play,                //favor that over return value and exports. After that,                //favor a non-undefined return value over exports use.                if (cjsModule && cjsModule.exports !== undef &&                        cjsModule.exports !== defined[name]) {                    defined[name] = cjsModule.exports;                } else if (ret !== undef || !usingExports) {                    //Use the return value from the function.                    defined[name] = ret;                }            }        } else if (name) {            //May just be an object definition for the module. Only            //worry about defining if have a module name.            defined[name] = callback;        }    };    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {        if (typeof deps === "string") {            if (handlers[deps]) {                //callback in this case is really relName                return handlers[deps](callback);            }            //Just return the module wanted. In this scenario, the            //deps arg is the module name, and second arg (if passed)            //is just the relName.            //Normalize module name, if it contains . or ..            return callDep(makeMap(deps, callback).f);        } else if (!deps.splice) {            //deps is a config object, not an array.            config = deps;            if (callback.splice) {                //callback is an array, which means it is a dependency list.                //Adjust args if there are dependencies                deps = callback;                callback = relName;                relName = null;            } else {                deps = undef;            }        }        //Support require(['a'])        callback = callback || function () {};        //If relName is a function, it is an errback handler,        //so remove it.        if (typeof relName === 'function') {            relName = forceSync;            forceSync = alt;        }        //Simulate async callback;        if (forceSync) {            main(undef, deps, callback, relName);        } else {            //Using a non-zero value because of concern for what old browsers            //do, and latest browsers "upgrade" to 4 if lower value is used:            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:            //If want a value immediately, use require('id') instead -- something            //that works in almond on the global level, but not guaranteed and            //unlikely to work in other AMD implementations.            setTimeout(function () {                main(undef, deps, callback, relName);            }, 4);        }        return req;    };    /**     * Just drops the config on the floor, but returns req in case     * the config return value is used.     */    req.config = function (cfg) {        config = cfg;        if (config.deps) {            req(config.deps, config.callback);        }        return req;    };    define = function (name, deps, callback) {        //This module may not have dependencies        if (!deps.splice) {            //deps is not an array, so probably means            //an object literal or factory function for            //the value. Adjust args.            callback = deps;            deps = [];        }        if (!hasProp(defined, name) && !hasProp(waiting, name)) {            waiting[name] = [name, deps, callback];        }    };    define.amd = {        jQuery: true    };}());define("vendor/almond", function(){});define ('events',[], function ( ) {  return {    events: {},    on: function (event, callback) {      var context;      if ( "string" != typeof event ) {        throw new Error("on() needs an event name string");      }      if ( "function" != typeof callback ) {        throw new Error("on() needs a callback function");      }      context = [].slice.call( arguments, 2 )[0];      if ( !this.events[event] ) {        this.events[event] = [];      }      this.events[event].push({        callback: callback,        context: context      });    },    reset: function () {      this.events = {};    },    off: function (event) {      var ev, len, cb;      // Event must be a string      if ( "string" != typeof event ) {        throw new Error( "off() needs an event" );      }      cb = [].slice.call( arguments, 1 )[0];      // If the event has been registered      if ( this.events[event] ) {        ev = this.events[event];        len = ev.length;        // Loop over each event object that matches ours.        while ( len-- ) {          if ( "function" != typeof cb ) {            // If no callback was given, remove the event            // and all its callbacks            ev.splice(len, 1);          } else {            // If a callback was passed,            // remove the callback from the event            if ( ev[len].callback === cb ) {              ev[len].callback = null;              delete ev[len].callback;            }          }        }      }    },    fire: function ( event ) {      var ev, len, opt, data, ctx;      // event argument is mandatory      if ( "string" != typeof event ) {        throw new Error("fire() needs an event");      }      // Optional arguments      opt = [].slice.call( arguments, 1 );      data = opt[0];      ctx = opt[1];      // If this event has been registered      if ( this.events[event] ) {        len = this.events[event].length;        // Invoke the callback on each event object        while ( ev = this.events[event][--len] ) {          if ("function" == typeof ev.callback) {            // Invoke in either context with data if present            ev.callback.call( ( ctx || ev.context || this ), data );          }        }      }    }  };});define('utils',[], function ( ) {  return {    realTypeOf: function ( value ) {      // Borrow Object.toString to introspect the      // class definition of the value i.e. ([object Object])      // and return the latter portion which denotes      // the real type of value.      return ({}).toString.call(value).match( /\w+/g )[1].toLowerCase();    },    isObject: function ( value ) {      //delegate to realTypeOf      return this.realTypeOf(value) === 'object';    },    isArray: function ( value ) {      if (Array.isArray) {        return Array.isArray(value);      }      //delegate to realTypeOf if isArray is not supported      return this.realTypeOf(value) === 'array';    },    isString: function ( value ) {      //delegate to realTypeOf      return this.realTypeOf(value) === 'string';    },    isNumber: function ( value ) {      //delegate to realTypeOf      return this.realTypeOf(value) === 'number';    },    isFunction: function ( value ) {      //delegate to realTypeOf      return this.realTypeOf(value) === 'function';    }  };});define('Base', ['events', 'utils'], function ( events, utils ) {  /**   * @constructor   * @description   * -> Core of Base framework   * @param {Object} options   * @return {this}   */  var Base = function ( options ) {    if ( "undefined" != typeof options ) {        this.options = options;        Base.mixin(this, options);    }    // Call the start function to do any setup    if (this.isFunction(this.start)) {        this.start();    }  };  /**   * @static   * @description   * -> Takes object params and adds all object properties to the first (dest) param.   * @param {Object} dest   * @param {Object} src   * @return {Object} augmented dest   */  Base.mixin = function ( dest, src ) {    var prop, sources = [].slice.call(arguments, 1);    while(src = sources.shift()) {      // Iterate over all src properties      for (prop in src) {        if (src.hasOwnProperty(prop)) {          if ( utils.isObject(src[prop])  ) {            dest[prop] = dest[prop] || src[prop];            Base.mixin(dest[prop], src[prop]);          } else {            // Assign the value form the src to the destination            dest[prop] = src[prop];          }        }      }    }    return dest;  };  /**   * @static   * @description   * -> Construct is a static inheritance function   * @return {Function} constructor function   */  Base.construct = function (properties) {    var parent = this,        props = properties || {};    function F () {}    F.prototype = parent.prototype;    F.prototype.constructor = Base.mixin( F, parent );    function create (options) {        var proto = getPrototype();        Base.call(proto, options);        return proto;    }    function getPrototype() {      var proto = proto || Base.mixin( new F(), props );      return proto;    }    function proxy () {}    proxy.prototype = getPrototype();    proxy.construct = F.construct;    proxy.create = create;    return proxy;  };  // Augment the Base prototype with the  // properties of events;  Base.mixin(Base.prototype, events, utils);  // Return Base as the module definition  return Base;});define('mediator',[], function ( ) {    /**        * A little helper to remove duplication        * @param type {String} to|from        * @param obj {Object}        * @param eventName {String}        * @private        */    function add (type, obj, eventName) {        passes[ currentEvent ][ type ].push({            obj: obj,            eventName: eventName        });    }    function isEqual (a, b) {        if (a === b) {            return a !== 0 || 1 / a === 1 / b;        }        if (a === null || b === null) {            return a === b;        }        if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) {            return false;        }    }    // Polyfill for nativeForEach    function each (list, callback, context) {        var i;        // Native forEach        if (typeof Array.prototype.forEach == "function" && list.length) {            list.forEach( callback, context || this);        } else if ( list.length ) {            // Polyfill            Array.prototype.forEach = function( callback, context ) {                for (var i = 0, len = list.length; i < len; ++i) {                    callback.call(context, list[i], i, list);                }            };        } else {            // If the list is an [object Object] (i.e. Not an Array)            for ( i in list ) {                if ( list.hasOwnProperty( i ) ) {                    callback.call( context || this, list[i], i, list );                }            }        }    }    /**    * Bind one or more target events to one or more source events    * @private    */    function bind () {        each( passes[ currentEvent ], function (sources, type, passes) {            each( passes, function ( sources, type, pass ) {                each( pass.from, function ( from ) {                    // Remove any previous binding                    from.obj.off( from.eventName );                    // Bind the event to a callback                    from.obj.on( from.eventName, function( args ) {                        each( pass.to, function ( to ) {                            // The callback binds the |to| event                            to.obj.fire( to.eventName, args);                        }, this);                    }, this);                }, this);            }, this);        }, this);    }    var passes = {},        currentEvent = null;    // Return medaitor api as module definition    return {        /**        * Registers the source subject subscriber and its event(s)        * @param subscribee {Object}        * @param eventName {String}        * @return {this}        */        from: function (subscribee, eventName) {            if (!arguments.length) {                throw {                    name: "NoArgumentsException",                    message: "From cannot be called with no arguments"                };            }            currentEvent = eventName || 'all';            if ( !passes[ currentEvent ] ) {                passes[ currentEvent ] = {};            }            if ( !passes[ currentEvent ].from ) {                passes[ currentEvent ].from = [];            }            add( "from", subscribee, eventName );            if ( this.removing ) {                // Has to object been marked for removal??                each( passes, function ( pass, j ) {                    each( pass.to, function ( to, i) {                        if (pass.to[i].remove && pass.to[i].remove === true) {                            // Dedlete the target object and event,                            // null the currentEvent                            delete passes[j].to[i];                            currentEvent = null;                        }                    }, this);                }, this);                this.removing = false;            }            // Make it chainable            return this;        },        /**        * Adds a target subscriber by eventName to the mediator        * @param subscriber {Object}        * @param eventName {String}        * @return {this}        */        to: function ( subscriber, eventName ) {            if ( !currentEvent ) {                throw {                    name: "ToFunctionBadUsage",                    message: "Cannot call to before from."                };            }            if ( !passes[ currentEvent ].to ) {                passes[ currentEvent ].to = [];            }            add( "to", subscriber, eventName );            // No config object parameter            this.register();            // Make it chainable            return this;        },        /**        * Marks target and eventName for removal        * @param target {Object}        * @param eventName {String}        * @return {this}        */        remove: function (obj, eventName) {            if (!arguments.length) {                throw {                    name: "NoArgumentException",                    message: "Remove cannot be called without arguments"                };            }            this.removing = true;            each(passes, function ( pass ) {                each( pass.to, function ( to, i ) {                    if (typeof obj == "string") {                        eventName = obj;                        if ( to.eventName === eventName ) {                            [].splice.call(pass.to, i, 1);                        }                    } else {                        if ( ( isEqual(to.obj, obj) || obj == null ) && ( to.eventName === eventName || typeof eventName == "undefined" ) ) {                            to.remove = true;                        }                    }                });            });            return this;        },        /**        * Registers the source and target subscriber objects and their events for binding        * @param optional config Object        */        register: function () {            var config = arguments[0];            if ( config ) {                if ( config.source ) {                    each(config.source, function ( from ) {                        this.from( from.subscriber, from.event );                    }, this);                } else {                    throw {                        name: "ConfigSourceNotDefined",                        message: "Config object needs a source defined."                    };                }                if ( config.target ) {                    each( config.target, function (to) {                        this.to( to.subscriber, to.event );                    }, this);                } else {                    throw {                        name: "ConfigTargetNotDefined",                        message: "Config object needs a target defined."                    };                }            } else {                bind();            }        },        /**        * Notifies mediator that target and source subscriber and events should be removed.        * @param config {Object}        */        unregister: function ( config ) {            if ( !config ) {                throw {                    name: "NoArgumentException",                    message: "Unregister cannot be called without arguments"                };            }            if ( config ) {                this.removing = true;                if ( config.target ) {                    each( config.target, function ( to ) {                    this.remove( to.subscriber, to.event );                    }, this );                } else {                    throw {                        name: "ConfigTargetNotDefined",                        message: "Config object needs a target defined."                    };                }                if ( config.source ) {                    each(config.source, function (from) {                        this.from(from.subscriber, from.eventName);                    }, this );                } else {                    throw {                        name: "ConfigSourceNotDefined",                        message: "Config object needs a source defined."                    };                }            }        }    };});define('Model', ['Base'], function ( Base ) {    var constants = {            ID: 1,            ORIGID: 1,            IDPREFIX: "mid_"        };    function getNewId () {        return constants.IDPREFIX + constants.ID++;    }    function resetId () {        constants.ID = constants.ORIGID;    }    return Base.construct({        start: function (options) {            this.id = getNewId();            this.resetId = resetId;            this.properties = {};            if (options) {                this.set(options);            }            return this;        },        get: function ( name ) {            return this[ name ] || this.properties[ name ];        },        set: function ( name, value ) {            if ( this.isString(name) ) {                this.properties[ name ] = value;            } else {                for (var n in name) {                    if  (name.hasOwnProperty(n) ) {                        this.properties[ n ] = name[n];                    }                }            }        }    });});define ('Collection', ['Base', 'Model'], function ( Base, Model ) {    function getCount () {        return this.getModels().length;    }    function getBy (method, value) {        var models = this.getModels(),            len = models.length,            found = [],            i = 0;        while (0 < len--) {            if (typeof models[len][method] !== "undefined") {                if (models[len][method] === value) {                    found.push(models[len]);                }            } else {                if (models[len].get(method) === value) {                    found.push(models[len]);                }            }        }        return found = (found.length < 2) ? found[0] : found;    }    function removeBy (method, value) {        var found = [].concat(getBy.call(this, method, value)),            num = found.length,            models = this.getModels(),            len = models.length,            index = -1;        while (0 < len--) {            while (0 < num--) {                index = models.indexOf(found[num]);                if (index !== -1) {                    models.splice(index, 1);                    this.fire("removed", this.getModels());                }            }        }    }    var currentModel;    // Use Base.construct to build a constructor for the Collection    return Base.construct({        start: function ( options ) {            this.model = options && options.model ? options.model : Model;        },        models: [],        add: function (data) {            var items = [].concat(data),                len = items.length,                model,                item,                p,                currentModel;            while (len--) {                model = items[len];                if (this.isFunction(model.set)) {                    this.getModels().push( model );                } else {                    item = items[len];                    if ( this.isFunction(this.model) ) {                        model = this.model.create();                        this.getModels().push(model);                        for ( p in item ) {                            model.set( p, item[p] );                        }                    }                }                this.setCurrentModel(model);                this.fire("add", model);            }        },        reset: function () {            this.models = [];            this.fire("reset");        },        getById: function (id) {            return getBy.call(this, "id", id);        },        getByText: function (text) {            return getBy.call(this, "text", text);        },        removeByText: function (text) {            removeBy.call(this, "text", text);        },        removeById: function (id) {            removeBy.call(this, "id", id);        },        getModels: function () {            return this.models;        },        setCurrentModel: function (model) {            currentModel = model;        },        getCurrentModel: function () {            return currentModel;        }    });});define ('View',['Base'], function ( Base ) {    var TAGNAME = 'div';    // Build the constructor    return Base.construct({        tagName: TAGNAME,        start: function () {            this.tagName = this.options && this.options.tagName ? this.options.tagName : this.tagName;        },        addListener: function (type, element, handler) {            var el = (!this.isFunction(el)) ? element : this;            if (el.addEventListener) {                var evt = type.type || type;                el.addEventListener(evt, function (e) {                    if (type.key && type.key === e.keyCode) {                        handler(e);                    } else if (!type.key) {                        handler(e);                    }                });            }        },        addElement: function (element) {            this.element = element;        },        destroy: function () {            if (this.model && this.collection) {                this.collection.removeById(this.model.get("id"));            }            if (this.model) {                this.model.resetId();                this.model = null;                delete this.model;            }            this.remove();            this.element = null;            delete this.element;        },        remove: function () {            if (this.element && this.element.parentNode) {                this.element.parentNode.removeChild(this.element);            }        },        /**         * Make a Tag         */        make: function () {            // All arguments are optional            var args = [].slice.call(arguments),                name = args[0] || this.tagName,                contents = args[1],                attrs = args[2],                i,                attr,                tag = document.createElement(name);            if (args.length === 2 && this.isObject(contents)) {                contents = undefined;                attrs = args[1];            }            // Add the contents            if (typeof contents !== "undefined") {                if (this.isNumber(contents) || this.isString(contents)) {                    // If the contents is a Number or a String,                    // parse it to a textnode                    contents = document.createTextNode(contents);                }                if (this.isArray(contents)) {                    // If our contents is an array,                    // append each one to the tag                    while ( i = contents.shift() ) {                        tag.appendChild(i);                    }                } else {                    tag.appendChild(contents);                }            }            // Add the attributes            if ( attrs ) {                for ( attr in attrs ) {                    if (attrs.hasOwnProperty( attr )) {                        // Add each attribute to the tag                        tag[ attr ] = attrs[ attr ];                        if ( !( attr in tag.attributes ) ) {                            // If the attribute wasnt't successfully added,                            // try again with setAttribute                            tag.setAttribute( attr, attrs[ attr ] );                        }                    }                }            }            // Finally return the new tag            return tag;        }    });});define('main', [    'Base',    'events',    'mediator',    'utils',    'Collection',    'Model',    'View'    ],    function ( Base, events, mediator, utils, Collection, Model, View ) {        return {            events: events,            mediator: mediator,            utils: utils,            Collection: Collection,            Model: Model,            View: View        };    });  var library = require('main');  if(typeof module !== 'undefined' && module.exports) {    module.exports = library;  } else if(globalDefine) {    (function (define) {      define(function () { return library; });    }(globalDefine));  } else {    global['Truss'] = library;  }}(this));\ No newline at end of filediff --git examples/todo/public/javascripts/bootstrap.js examples/todo/public/javascripts/bootstrap.jsindex fe62b7e..e01c2fa 100644--- examples/todo/public/javascripts/bootstrap.js+++ examples/todo/public/javascripts/bootstrap.js@@ -1,11 +1 @@--var rootNode = document.getElementById("rootNode"),-	options = {-		rootNode: rootNode,-        tagName: 'div',-		collection: Truss.Collection.create()-	};--todoForm.create(options);-todoCount.create(options);-todoList.create(options);+var rootNode = document.getElementById("rootNode"),    options = {        rootNode: rootNode,        tagName: 'div',        collection: Truss.Collection.create()    };ViewTodoForm.create(options);ViewTodoCount.create(options);ViewTodoList.create(options);\ No newline at end of filediff --git examples/todo/public/javascripts/views/Notes.View.Count.js examples/todo/public/javascripts/views/Notes.View.Count.jsindex 9a4c325..75190f9 100644--- examples/todo/public/javascripts/views/Notes.View.Count.js+++ examples/todo/public/javascripts/views/Notes.View.Count.js@@ -1,34 +1,17 @@-    var todoCount = Truss.View.construct({+    var ViewTodoCount = Truss.View.construct({-        start: function (options) {+        start: function () {-            if (!options) {-                throw {-                    name: "ArgumentError",-                    message: "View requires options rootNode and collection"-                };-            }--            if (!options.rootNode) {-                throw {-                    name: "ArgumentError",-                    message: "View requires a rootNode of type HTMLElement"-                };-            }--            if (!options.collection) {-                throw {-                    name: "ArgumentError",-                    message: "View requires a collection"-                };+            if (!this.options.collection) {+                throw new Error("View requires a collection");             }             this.tagName = "output";             this.counter = 0;-            this.rootNode = options.rootNode;-            this.collection = options.collection;+            this.rootNode = this.options.rootNode;+            this.collection = this.options.collection;             this._render();             this.collection.on("add", this._increment.bind(this));diff --git examples/todo/public/javascripts/views/Notes.View.Edit_Note.js examples/todo/public/javascripts/views/Notes.View.Edit_Note.jsindex d620e8c..b1e5742 100644--- examples/todo/public/javascripts/views/Notes.View.Edit_Note.js+++ examples/todo/public/javascripts/views/Notes.View.Edit_Note.js@@ -1 +1 @@-var todoEdit = Truss.View.construct({        start: function (options) {            this.model = options.model;            this.parentEl = options.parentEl;            this.render();            this.element.addEventListener("blur", this.update.bind(this), false);        },        render: function () {            this.element = this.make("input", {                    autofocus: true,                    id: this.model.get("id"),                    value: this.model.get("text")                });            this.textEl = this.parentEl.firstChild;            this.parentEl.replaceChild(this.element, this.parentEl.firstChild);        },        update: function (e) {            // Set the new text value to the model            this.model.set("text", e.target.value);            // Update the text of the original element            this.textEl.innerHTML = this.model.get("text");            // Replace the element with the            this.parentEl.replaceChild(this.textEl, this.element)        }    });\ No newline at end of file+var ViewTodoEdit = Truss.View.construct({    start: function () {        this.model = this.options.model;        this.parentEl = this.options.parentEl;        this.render();        this.addListener({type: "keypress", key: 13}, this.element, this.update.bind(this));    },    render: function () {        this.element = this.make("input", {                autofocus: true,                id: this.model.get("id"),                value: this.model.get("text")            });        this.textEl = this.parentEl.firstChild;        this.parentEl.replaceChild(this.element, this.parentEl.firstChild);    },    update: function (e) {        this.model.set("text", e.target.value);        this.textEl.innerHTML = this.model.get("text");        this.parentEl.replaceChild(this.textEl, this.element);    }});\ No newline at end of filediff --git examples/todo/public/javascripts/views/Notes.View.Form.js examples/todo/public/javascripts/views/Notes.View.Form.jsindex c688e12..44cdc1e 100644--- examples/todo/public/javascripts/views/Notes.View.Form.js+++ examples/todo/public/javascripts/views/Notes.View.Form.js@@ -1,59 +1,63 @@-    var todoForm = Truss.View.construct({+var ViewTodoForm = Truss.View.construct({-        start: function (options) {+    start: function () {-            this.rootNode = options.rootNode;-            this.collection = options.collection;-            this._makeElements();-        },+        if (!this.options.collection) {+            throw new Error("View requires a collection");+        }-        _add: function (e) {+        this.rootNode = this.options.rootNode;+        this.collection = this.options.collection;+        this._makeElements();+    },-            e.preventDefault();-            var value = this.input.value;-            if (this._isValid(value)) {-                this.collection.add({'text': value});-            }-        },+    _add: function (e) {-        _isValid: function (value) {-            return (/\S/g).test(value);-        },+        e.preventDefault();+        var value = this.input.value;+        if (this._isValid(value)) {+            this.collection.add({'text': value});+        }+    },-        _makeElements: function () {+    _isValid: function (value) {+        return (/\S/g).test(value);+    },-            var fieldset;+    _makeElements: function () {-            this.submit = this.make("input", {-                                type: "submit",-                                value: "Add"-                            });+        var fieldset;-            this.input = this.make("input", {-                            type: 'text',-                            autofocus: 'true',-                            required: 'true',-                            placeholder: 'Add a note...'+        this.submit = this.make("input", {+                            type: "submit",+                            value: "Add"                         });-            fieldset = this.make("fieldset", [this.input, this.submit]);+        this.input = this.make("input", {+                        type: 'text',+                        autofocus: 'true',+                        required: 'true',+                        placeholder: 'Add a note...'+                    });-            this.element = this.make("form", fieldset, {-                                            action: "",-                                            method: "get"-                                        });+        fieldset = this.make("fieldset", [this.input, this.submit]);-            this._render();-        },+        this.element = this.make("form", fieldset, {+                                        action: "",+                                        method: "get"+                                    });-        _render: function () {-            this._submitListener();-            this.rootNode.appendChild(this.element);-        },+        this._render();+    },-        _submitListener: function () {-            this.submit.addEventListener("click", this._add.bind(this), false);-        }+    _render: function () {+        this._submitListener();+        this.rootNode.appendChild(this.element);+    },++    _submitListener: function () {+        this.submit.addEventListener("click", this._add.bind(this), false);+    }-    });+});diff --git examples/todo/public/javascripts/views/Notes.View.List.js examples/todo/public/javascripts/views/Notes.View.List.jsindex acb5f3c..1821896 100644--- examples/todo/public/javascripts/views/Notes.View.List.js+++ examples/todo/public/javascripts/views/Notes.View.List.js@@ -1 +1 @@-    var todoList = Truss.View.construct({        start:  function (options) {            if (!options) {                throw {                    name: "ArgumentError",                    message: "View requires options rootNode and collection"                };            }            if (!options.rootNode) {                throw {                    name: "ArgumentError",                    message: "View requires a rootNode of type HTMLElement"                };            }            if (!options.collection) {                throw {                    name: "ArgumentError",                    message: "View requires a collection"                };            }            this.tagName = "ul";            this.rootNode = options.rootNode;            this.collection = options.collection;            this.collection.on("add", this._renderNote.bind(this), this);            this.render();        },        render: function () {            this.element = document.createElement(this.tagName);            this.rootNode.appendChild(this.element);        },        _renderNote: function (model) {            todoItem.create({                parentEl: this._getElement(),                model: model,                collection: this._getCollection()            });        },        _getCollection: function () {            return this.collection;        },        _getElement: function () {            return this.element;        }    });\ No newline at end of file+var ViewTodoList = Truss.View.construct({    start:  function () {        if (!this.options.collection) {            throw new Error("View requires a collection");        }        this.tagName = "ul";        this.rootNode = this.options.rootNode;        this.collection = this.options.collection;        this.collection.on("add", this._renderNote.bind(this), this);        this.render();    },    render: function () {        this.element = document.createElement(this.tagName);        this.rootNode.appendChild(this.element);    },    _renderNote: function (model) {        ViewTodoItem.create({            parentEl: this._getElement(),            model: model,            collection: this._getCollection()        });    },    _getCollection: function () {        return this.collection;    },    _getElement: function () {        return this.element;    }});\ No newline at end of filediff --git examples/todo/public/javascripts/views/Notes.View.Note.js examples/todo/public/javascripts/views/Notes.View.Note.jsindex 7a62776..2173af7 100644--- examples/todo/public/javascripts/views/Notes.View.Note.js+++ examples/todo/public/javascripts/views/Notes.View.Note.js@@ -1 +1 @@-    var todoItem = Truss.View.construct({        start: function (options) {            this.parentEl = options.parentEl;            this.model = options.model;            this.collection = options.collection;            this.render();            this.button.addEventListener("click", this._delete.bind(this), false);            this.text.addEventListener("click", this.edit.bind(this), false);        },        edit: function () {            todoEdit.create({                parentEl: this.element,                model: this.model            });        },        render: function () {            var button = this.make("button"),                em = this.make("em", this.model.get("text") ),                element = this.make("li",                    [em, button], {                    id: this.model.get("id"),                    draggable: true                });            this.text = em;            this.button = button;            this.element = element;            this.parentEl.appendChild(element);        },        _delete: function () {            this.collection.removeById(this.model.get("id"));            this.parentEl.removeChild(this.element);            delete this.element;        }    });\ No newline at end of file+    var ViewTodoItem = Truss.View.construct({        start: function () {            if (!this.options.collection) {                throw new Error("View requires a collection");            }            this.parentEl = this.options.parentEl;            this.model = this.options.model;            this.collection = this.options.collection;            this.render();            this.button.addEventListener("click", this.destroy.bind(this), false);            this.text.addEventListener("click", this.edit.bind(this), false);        },        edit: function () {            ViewTodoEdit.create({                parentEl: this.element,                model: this.model            });        },        render: function () {            var button = this.make("button"),                em = this.make("em", this.model.get("text") ),                element = this.make("li",                    [em, button], {                    id: this.model.get("id"),                    draggable: true                });            this.text = em;            this.button = button;            this.element = element;            this.parentEl.appendChild(element);        }    });\ No newline at end of filediff --git spec/Base.spec.js spec/Base.spec.jsindex 2121eb9..f1bcf8a 100644--- spec/Base.spec.js+++ spec/Base.spec.js@@ -255,7 +255,11 @@ require( ['Base', 'events', 'utils'], function ( Base, events, utils ) {                 });                 it('invokes start with the options passed to create', function () {-                    expect(spyStart).toHaveBeenCalledWith(opts);+                    expect(spyStart).toHaveBeenCalled();+                });++                it('creates object with options passed to create', function () {+                    expect(factored.good).toEqual('times');                 });             });@@ -319,7 +323,11 @@ require( ['Base', 'events', 'utils'], function ( Base, events, utils ) {                 });                 it('invokes start with the options passed to create', function () {-                    expect(spyStart).toHaveBeenCalledWith(opts);+                    expect(spyStart).toHaveBeenCalled();+                });++                it('creates object with options passed to create', function () {+                    expect(factored.even).toEqual('better');                 });                 it('does not invoke startParent', function () {@@ -397,7 +405,11 @@ require( ['Base', 'events', 'utils'], function ( Base, events, utils ) {                 });                 it('invokes start with the options passed to create', function () {-                    expect(spyStart).toHaveBeenCalledWith(opts);+                    expect(spyStart).toHaveBeenCalled();+                });++                it('creates object with options passed to create', function () {+                    expect(factored.blatantly).toEqual('awesome');                 });                 it('does not invoke startParent', function () {diff --git spec/View.spec.js spec/View.spec.jsindex 85fa969..f62467f 100644--- spec/View.spec.js+++ spec/View.spec.js@@ -262,6 +262,95 @@ require( ['View'], function ( View ) { 					expect(html.unknown).toEqual("test"); 				}); 			});++			describe('calling setElement with an element', function () {+				var element;+				beforeEach(function () {+					element = view.make('div');+					view.setElement(element);+				});+				it('adds the element to the view object', function () {+					expect(view.element).toEqual(element);+				});+			});++			describe('Calling removeElement', function () {++				describe('with no arguments', function () {+					var parent,+						element;+					beforeEach(function () {+						parent = view.make('div');+						element = view.make('p');+						parent.appendChild(element);+						view.setElement(element);+						view.removeElement();+					});++					it('removes the element from the view', function () {+						expect(view.element).toEqual(null);+					});+					it('removes the element from the parent', function () {+						expect(parent.hasChildNodes()).toEqual(false);+					});+				});++				describe('with an element', function () {+					var parent,+						element;+					beforeEach(function () {+						parent = view.make('div');+						element = view.make('p');+						parent.appendChild(element);+						view.removeElement(element);+					});+					it('removes the element from the parent', function () {+						expect(parent.hasChildNodes()).toEqual(false);+					});+				});+			});++			describe('Calling replaceElement', function () {++				describe('with a replacement element', function () {+					var parent,+						element,+						replacement;+					beforeEach(function () {+						parent = view.make('div');+						element = view.make('p');+						parent.appendChild(element);+						replacement = view.make('span');+						view.setElement(element);+						view.replaceElement(replacement);+					});+					it('replaces the view element with the replacement', function () {+						expect(parent.firstChild).toEqual(replacement);+					});+					it('sets old element', function () {+						expect(view.oldElement.nodeName).toEqual('P');+					});+				});++				describe('with a replacement element and replacee', function () {+					var parent,+						replacee,+						replacement;+					beforeEach(function () {+						parent = view.make('div');+						replacee = view.make('p');+						parent.appendChild(replacee);+						replacement = view.make('span');+						view.replaceElement(replacement, replacee);+					});+					it('replaces the view element with the replacement', function () {+						expect(parent.firstChild).toEqual(replacement);+					});+					it('sets old element', function () {+						expect(view.oldElement.nodeName).toEqual('P');+					});+				});+			}); 		}); 	}); });diff --git src/Base.js src/Base.jsindex 3782131..c76dcc5 100644--- src/Base.js+++ src/Base.js@@ -11,12 +11,13 @@ define( ['events', 'utils'], function ( events, utils ) {     // Add any arguments to this.options     if ( "undefined" != typeof options ) {-      this.options = options;+        this.options = options;+        Base.mixin(this, options);     }     // Call the start function to do any setup-    if ( utils.isFunction(this.start) ) {-      this.start( options );+    if ( this.isFunction(this.start) ) {+        this.start();     }   };diff --git src/View.js src/View.jsindex 2fa3163..d1837c3 100644--- src/View.js+++ src/View.js@@ -1 +1 @@-define (['Base'], function ( Base ) {    var TAGNAME = 'div';    function getRootNode () {        return document.getElementsByTagName("body")[0];    }    // Build the constructor    return Base.construct({        // Start is optional, it's called if present,        // like a constructor        start: function () {            // Option properties override view properties            this.tagName = this.options ? this.options.tagName : TAGNAME;            this.rootNode = this.options ? this.options.rootNode : getRootNode();        },        /**         * Make a Tag         */        make: function () {            // All arguments are optional            var args = [].slice.call(arguments),                name = args[0] || this.tagName,                contents = args[1],                attrs = args[2],                i,                attr,                tag = document.createElement(name);            if (args.length === 2 && this.isObject(contents)) {                contents = undefined;                attrs = args[1];            }            // Add the contents            if (typeof contents !== "undefined") {                if (this.isNumber(contents) || this.isString(contents)) {                    // If the contents is a Number or a String,                    // parse it to a textnode                    contents = document.createTextNode(contents);                }                if (this.isArray(contents)) {                    // If our contents is an array,                    // append each one to the tag                    while ( i = contents.shift() ) {                        tag.appendChild(i);                    }                } else {                    tag.appendChild(contents);                }            }            // Add the attributes            if ( attrs ) {                for ( attr in attrs ) {                    if (attrs.hasOwnProperty( attr )) {                        // Add each attribute to the tag                        tag[ attr ] = attrs[ attr ];                        if ( !( attr in tag.attributes ) ) {                            // If the attribute wasnt't successfully added,                            // try again with setAttribute                            tag.setAttribute( attr, attrs[ attr ] );                        }                    }                }            }            // Finally return the new tag            return tag;        }    });});\ No newline at end of file+define (['Base'], function ( Base ) {    var TAGNAME = 'div';    function getRootNode () {        return document.getElementsByTagName("body")[0];    }    // Build the constructor    return Base.construct({        tagName: 'div',        start: function () {            this.tagName = this.options && this.options.tagName ? this.options.tagName : this.tagName;        },        setElement: function (element) {            this.element = element;        },        removeElement: function () {            if (arguments[0] && arguments[0].nodeType === 1) {                this.setElement(arguments[0]);            }            if (this.element.parentNode) {                this.element.parentNode.removeChild(this.element);            }            this.element = null;            delete this.element;        },        replaceElement: function (replacement) {            var replacee = this.element;            if (arguments[1] && arguments[1].nodeType === 1) {                replacee = arguments[1];            }            if (replacee && replacee.parentNode) {                this.oldElement = replacee.parentNode.replaceChild(replacement, replacee);            }        },        make: function () {            // All arguments are optional            var args = [].slice.call(arguments),                name = args[0] || this.tagName,                contents = args[1],                attrs = args[2],                i,                attr,                tag = document.createElement(name);            if (args.length === 2 && this.isObject(contents)) {                contents = undefined;                attrs = args[1];            }            // Add the contents            if (typeof contents !== "undefined") {                if (this.isNumber(contents) || this.isString(contents)) {                    // If the contents is a Number or a String,                    // parse it to a textnode                    contents = document.createTextNode(contents);                }                if (this.isArray(contents)) {                    // If our contents is an array,                    // append each one to the tag                    while ( i = contents.shift() ) {                        tag.appendChild(i);                    }                } else {                    tag.appendChild(contents);                }            }            // Add the attributes            if ( attrs ) {                for ( attr in attrs ) {                    if (attrs.hasOwnProperty( attr )) {                        // Add each attribute to the tag                        tag[ attr ] = attrs[ attr ];                        if ( !( attr in tag.attributes ) ) {                            // If the attribute wasnt't successfully added,                            // try again with setAttribute                            tag.setAttribute( attr, attrs[ attr ] );                        }                    }                }            }            // Finally return the new tag            return tag;        }    });});\ No newline at end of file